From 370d7b986794dbb355b1017ae352adab2e7321f1 Mon Sep 17 00:00:00 2001 From: Sergei Kuzmin Date: Thu, 22 Jun 2023 22:43:05 -0700 Subject: [PATCH] Secrets consistency for the chart (#1016) - Enabling existing secrets for external MySQL and Redis - Tolerate existing secrets for bundled charts. - README.md: secrets handling explained. - Fixed multiple bugs where missing required field was replaced with default instead of failing. - PHONE_NOTIFICATIONS_LIMIT was on the wrong level: it was not set if existingSecret was true. Next are the cosmetic changes. They improve chart consistency, e.g. prevent generation of multiple new lines in certain cases: - Common approach to spaces trimming. This typically allows curly blocks and actual strings indentation and nice `nindent` usage: - Two curly blocks should not trim the same space. I.e. "{{ ... -}} {{- ... }}" shouldn't happen. - Template generates either single line or multiline string. In both cases, no new line appears on both sides of the output string. So we delete unnecessary new lines inside and at the end of string with "trim-to-left" (`{{-` ) and the leading new line using "trim-to-right" (`-}}`). Note that trimming both leading and trailing new line is not always easily possible: https://github.com/Masterminds/sprig/issues/357 Example. ``` {{- define "mytemplate" -}} {{ if someBoolean -}} {{ .Value.some }} {{- else -}} some string {{- end }} {{- end }} ``` - `template` replaced with `include`. It is often recommended to use `include` by default, as it allows pipelining. ## Checklist - [ ] Tests updated - No tests for Helm chart - [X] Documentation added - [x] `CHANGELOG.md` updated Co-authored-by: Ildar Iskhakov --- CHANGELOG.md | 1 + helm/oncall/README.md | 106 ++++ helm/oncall/templates/_env.tpl | 494 +++++++++--------- helm/oncall/templates/celery/_deployment.tpl | 2 +- .../templates/celery/deployment-celery.yaml | 2 +- helm/oncall/templates/secrets.yaml | 41 +- .../__snapshot__/wait_for_db_test.yaml.snap | 8 +- helm/oncall/tests/extra_env_test.yaml | 2 + helm/oncall/tests/postgres_env_test.yaml | 3 +- .../tests/postgres_password_env_test.yaml | 7 +- helm/oncall/tests/rabbitmq_env_test.yaml | 20 +- helm/oncall/tests/redis_env_test.yaml | 10 + .../oncall/tests/redis_password_env_test.yaml | 7 +- helm/oncall/tests/wait_for_db_test.yaml | 1 + helm/oncall/values.yaml | 70 +-- 15 files changed, 480 insertions(+), 294 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23b0e04119..21ef48b5be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Secrets consistency for the chart. Bugfixing [#1016](https://github.com/grafana/oncall/pull/1016) - Make it possible to completely delete a rotation oncall ([#1505](https://github.com/grafana/oncall/issues/1505)) - Polish rotation modal form oncall ([#1506](https://github.com/grafana/oncall/issues/1506)) - Quick actions when editing a schedule oncall ([#1507](https://github.com/grafana/oncall/issues/1507)) diff --git a/helm/oncall/README.md b/helm/oncall/README.md index e8d7917f4f..e55bc6faed 100644 --- a/helm/oncall/README.md +++ b/helm/oncall/README.md @@ -86,6 +86,112 @@ helm upgrade \ grafana/oncall ``` +### Passwords and external secrets + +As OnCall subcharts are Bitname charts, there is a common approach to secrets. Bundled charts allow specifying passwords +in values.yaml explicitly or as K8s secret value. OnCall chart refers either to secret created in sub-chart or +to specified external secret. +Similarly, if component chart is disabled, the password(s) can be supplied in `external` value +(e.g. externalMysql) explicitly or as K8s secret value. In the first case, the secret is created with the specified +value. In the second case the external secret is used. + +- If `.auth.existingSecret` is non-empty, then this secret is used. Secret keys are pre-defined by chart. +- If subchart supports password files and `.customPasswordFiles` dictionary is non-empty, then password files + are used. Dictionary keys are pre-defined per sub-chart. Password files are not supported by OnCall chart and should + not be used with bundled sub-charts. +- Passwords are specified via `auth` section values, e.g. `auth.password`. K8s secret is created. + - If `.auth.forcePassword` is `true`, then passwords MUST be specified. Otherwise, missing passwords + are generated. + +If external component is used instead of the bundled one: + +- If existingSecret within appropriate external component values is non-empty (e.g. `externalMysql.existingSecret`) then + it is used together with corresponding key names, e.g. `externalMysql.passwordKey`. +- Otherwise, corresponding password values are used, e.g. `externalMysql.password`. K8s secret is created by OnCall chart. + +Below is the summary for the dependent charts. + +MySQL/MariaDB: + +```yaml +database: + type: "mysql" # This is default +mariaDB: + enabled: true # Default + auth: + existingSecret: "" + forcePassword: false + # Secret name: `-mariadb` + rootPassword: "" # Secret key: mariadb-root-password + password: "" # Secret key: mariadb-password + replicationPassword: "" # Secret key: mariadb-replication-password +externalMysql: + password: "" + existingSecret: "" + passwordKey: "" +``` + +Postgres: + +```yaml +database: + type: postgresql +mariadb: + enabled: false # Must be set to false for Postgres +postgresql: + enabled: true # Must be set to true for bundled Postgres + auth: + existingSecret: "" + secretKeys: + adminPasswordKey: "" + userPasswordKey: "" # Not needed + replicationPasswordKey: "" # Not needed with disabled replication + # Secret name: `-postgresql` + postgresPassword: "" # password for admin user postgres. As non-admin user is not created, only this one is relevant. + password: "" # Not needed + replicationPassword: "" # Not needed with disabled replication +externalPostgresql: + user: "" + password: "" + existingSecret: "" + passwordKey: "" +``` + +Rabbitmq: + +```yaml +rabbitmq: + enabled: true + auth: + existingPasswordSecret: "" # Must contain `rabbitmq-password` key + existingErlangSecret: "" # Must contain `rabbitmq-erlang-cookie` key + # Secret name: `-rabbitmq` + password: "" + erlangCookie: "" +externalRabbitmq: + user: "" + password: "" + existingSecret: "" + passwordKey: "" + usernameKey: "" +``` + +Redis: + +```yaml +redis: + enabled: true + auth: + existingSecret: "" + existingSecretPasswordKey: "" + # Secret name: `-redis` + password: "" +externalRedis: + password: "" + existingSecret: "" + passwordKey: "" +``` + ### Set up Slack and Telegram You can set up Slack connection via following variables: diff --git a/helm/oncall/templates/_env.tpl b/helm/oncall/templates/_env.tpl index 895d374a44..49b3094c46 100644 --- a/helm/oncall/templates/_env.tpl +++ b/helm/oncall/templates/_env.tpl @@ -4,65 +4,65 @@ - name: SECRET_KEY valueFrom: secretKeyRef: - name: {{ template "snippet.oncall.secret.name" . }} - key: {{ template "snippet.oncall.secret.secretKey" . }} + name: {{ include "snippet.oncall.secret.name" . }} + key: {{ include "snippet.oncall.secret.secretKey" . | quote }} - name: MIRAGE_SECRET_KEY valueFrom: secretKeyRef: - name: {{ template "snippet.oncall.secret.name" . }} - key: {{ template "snippet.oncall.secret.mirageSecretKey" . }} + name: {{ include "snippet.oncall.secret.name" . }} + key: {{ include "snippet.oncall.secret.mirageSecretKey" . | quote }} - name: MIRAGE_CIPHER_IV - value: "{{ .Values.oncall.mirageCipherIV | default "1234567890abcdef" }}" + value: {{ .Values.oncall.mirageCipherIV | default "1234567890abcdef" | quote }} - name: DJANGO_SETTINGS_MODULE value: "settings.helm" - name: AMIXR_DJANGO_ADMIN_PATH value: "admin" - name: OSS value: "True" -{{- template "snippet.oncall.uwsgi" . }} +{{- include "snippet.oncall.uwsgi" . }} - name: BROKER_TYPE value: {{ .Values.broker.type | default "rabbitmq" }} - name: GRAFANA_API_URL - value: {{ include "snippet.grafana.url" . }} -{{- end -}} + value: {{ include "snippet.grafana.url" . | quote }} +{{- end }} {{- define "snippet.oncall.secret.name" -}} -{{- if .Values.oncall.secrets.existingSecret -}} -{{ .Values.oncall.secrets.existingSecret }} +{{ if .Values.oncall.secrets.existingSecret -}} + {{ .Values.oncall.secrets.existingSecret }} {{- else -}} -{{ template "oncall.fullname" . }} -{{- end -}} -{{- end -}} + {{ include "oncall.fullname" . }} +{{- end }} +{{- end }} {{- define "snippet.oncall.secret.secretKey" -}} -{{- if .Values.oncall.secrets.existingSecret -}} -{{ required "oncall.secrets.secretKey is required if oncall.secret.existingSecret is not empty" .Values.oncall.secrets.secretKey }} +{{ if .Values.oncall.secrets.existingSecret -}} + {{ required "oncall.secrets.secretKey is required if oncall.secret.existingSecret is not empty" .Values.oncall.secrets.secretKey }} {{- else -}} -SECRET_KEY -{{- end -}} -{{- end -}} + SECRET_KEY +{{- end }} +{{- end }} {{- define "snippet.oncall.secret.mirageSecretKey" -}} -{{- if .Values.oncall.secrets.existingSecret -}} -{{ required "oncall.secrets.mirageSecretKey is required if oncall.secret.existingSecret is not empty" .Values.oncall.secrets.mirageSecretKey }} +{{ if .Values.oncall.secrets.existingSecret -}} + {{ required "oncall.secrets.mirageSecretKey is required if oncall.secret.existingSecret is not empty" .Values.oncall.secrets.mirageSecretKey }} {{- else -}} -MIRAGE_SECRET_KEY -{{- end -}} -{{- end -}} + MIRAGE_SECRET_KEY +{{- end }} +{{- end }} {{- define "snippet.oncall.uwsgi" -}} -{{- if .Values.uwsgi -}} +{{- if .Values.uwsgi }} {{- range $key, $value := .Values.uwsgi }} - name: UWSGI_{{ $key | upper | replace "-" "_" }} value: {{ $value | quote }} - {{- end -}} -{{- end -}} -{{- end -}} + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.oncall.slack.env" -}} -{{- if .Values.oncall.slack.enabled -}} - name: FEATURE_SLACK_INTEGRATION_ENABLED value: {{ .Values.oncall.slack.enabled | toString | title | quote }} +{{- if .Values.oncall.slack.enabled }} - name: SLACK_SLASH_COMMAND_NAME value: "/{{ .Values.oncall.slack.commandName | default "oncall" }}" {{- if .Values.oncall.slack.existingSecret }} @@ -70,17 +70,17 @@ MIRAGE_SECRET_KEY valueFrom: secretKeyRef: name: {{ .Values.oncall.slack.existingSecret }} - key: {{ required "oncall.slack.clientIdKey is required if oncall.slack.existingSecret is not empty" .Values.oncall.slack.clientIdKey }} + key: {{ required "oncall.slack.clientIdKey is required if oncall.slack.existingSecret is not empty" .Values.oncall.slack.clientIdKey | quote }} - name: SLACK_CLIENT_OAUTH_SECRET valueFrom: secretKeyRef: name: {{ .Values.oncall.slack.existingSecret }} - key: {{ required "oncall.slack.clientSecretKey is required if oncall.slack.existingSecret is not empty" .Values.oncall.slack.clientSecretKey }} + key: {{ required "oncall.slack.clientSecretKey is required if oncall.slack.existingSecret is not empty" .Values.oncall.slack.clientSecretKey | quote }} - name: SLACK_SIGNING_SECRET valueFrom: secretKeyRef: name: {{ .Values.oncall.slack.existingSecret }} - key: {{ required "oncall.slack.signingSecretKey is required if oncall.slack.existingSecret is not empty" .Values.oncall.slack.signingSecretKey }} + key: {{ required "oncall.slack.signingSecretKey is required if oncall.slack.existingSecret is not empty" .Values.oncall.slack.signingSecretKey | quote }} {{- else }} - name: SLACK_CLIENT_OAUTH_ID value: {{ .Values.oncall.slack.clientId | default "" | quote }} @@ -91,16 +91,13 @@ MIRAGE_SECRET_KEY {{- end }} - name: SLACK_INSTALL_RETURN_REDIRECT_HOST value: {{ .Values.oncall.slack.redirectHost | default (printf "https://%s" .Values.base_url) | quote }} -{{- else -}} -- name: FEATURE_SLACK_INTEGRATION_ENABLED - value: {{ .Values.oncall.slack.enabled | toString | title | quote }} -{{- end -}} -{{- end -}} +{{- end }} +{{- end }} {{- define "snippet.oncall.telegram.env" -}} -{{- if .Values.oncall.telegram.enabled -}} - name: FEATURE_TELEGRAM_INTEGRATION_ENABLED value: {{ .Values.oncall.telegram.enabled | toString | title | quote }} +{{- if .Values.oncall.telegram.enabled }} - name: TELEGRAM_WEBHOOK_HOST value: {{ .Values.oncall.telegram.webhookUrl | default "" | quote }} {{- if .Values.oncall.telegram.existingSecret }} @@ -108,366 +105,400 @@ MIRAGE_SECRET_KEY valueFrom: secretKeyRef: name: {{ .Values.oncall.telegram.existingSecret }} - key: {{ required "oncall.telegram.tokenKey is required if oncall.telegram.existingSecret is not empty" .Values.oncall.telegram.tokenKey }} + key: {{ required "oncall.telegram.tokenKey is required if oncall.telegram.existingSecret is not empty" .Values.oncall.telegram.tokenKey | quote }} {{- else }} - name: TELEGRAM_TOKEN value: {{ .Values.oncall.telegram.token | default "" | quote }} {{- end }} -{{- else -}} -- name: FEATURE_TELEGRAM_INTEGRATION_ENABLED - value: {{ .Values.oncall.telegram.enabled | toString | title | quote }} -{{- end -}} -{{- end -}} +{{- end }} +{{- end }} -{{- define "snippet.oncall.twilio.env" -}} -{{- with .Values.oncall.twilio -}} -{{- if .accountSid }} -- name: TWILIO_ACCOUNT_SID - value: {{ .accountSid | quote }} -{{- end -}} +{{- define "snippet.oncall.twilio.env" }} +{{- with .Values.oncall.twilio }} {{- if .existingSecret }} +- name: TWILIO_ACCOUNT_SID + valueFrom: + secretKeyRef: + name: {{ .existingSecret }} + key: {{ required "oncall.twilio.accountSid is required if oncall.twilio.existingSecret is not empty" .accountSid | quote }} - name: TWILIO_AUTH_TOKEN valueFrom: secretKeyRef: name: {{ .existingSecret }} - key: {{ required ".authTokenKey is required if .existingSecret is not empty" .authTokenKey }} + key: {{ required "oncall.twilio.authTokenKey is required if oncall.twilio.existingSecret is not empty" .authTokenKey | quote }} - name: TWILIO_NUMBER valueFrom: secretKeyRef: name: {{ .existingSecret }} - key: {{ required ".phoneNumberKey is required if .existingSecret is not empty" .phoneNumberKey }} + key: {{ required "oncall.twilio.phoneNumberKey is required if oncall.twilio.existingSecret is not empty" .phoneNumberKey | quote }} - name: TWILIO_VERIFY_SERVICE_SID valueFrom: secretKeyRef: name: {{ .existingSecret }} - key: {{ required ".verifySidKey is required if .existingSecret is not empty" .verifySidKey }} + key: {{ required "oncall.twilio.verifySidKey is required if oncall.twilio.existingSecret is not empty" .verifySidKey | quote }} - name: TWILIO_API_KEY_SID valueFrom: secretKeyRef: name: {{ .existingSecret }} - key: {{ required ".apiKeySidKey is required if .existingSecret is not empty" .apiKeySidKey }} + key: {{ required "oncall.twilio.apiKeySidKey is required if oncall.twilio.existingSecret is not empty" .apiKeySidKey | quote }} - name: TWILIO_API_KEY_SECRET valueFrom: secretKeyRef: name: {{ .existingSecret }} - key: {{ required ".apiKeySecretKey is required if .existingSecret is not empty" .apiKeySecretKey }} + key: {{ required "oncall.twilio.apiKeySecretKey is required if oncall.twilio.existingSecret is not empty" .apiKeySecretKey | quote }} {{- else }} +{{- if .accountSid }} +- name: TWILIO_ACCOUNT_SID + value: {{ .accountSid | quote }} +{{- end }} {{- if .authToken }} - name: TWILIO_AUTH_TOKEN value: {{ .authToken | quote }} -{{- end -}} +{{- end }} {{- if .phoneNumber }} - name: TWILIO_NUMBER value: {{ .phoneNumber | quote }} -{{- end -}} +{{- end }} {{- if .verifySid }} - name: TWILIO_VERIFY_SERVICE_SID value: {{ .verifySid | quote }} -{{- end -}} +{{- end }} {{- if .apiKeySid }} - name: TWILIO_API_KEY_SID value: {{ .apiKeySid | quote }} -{{- end -}} +{{- end }} {{- if .apiKeySecret }} - name: TWILIO_API_KEY_SECRET value: {{ .apiKeySecret | quote }} -{{- end -}} +{{- end }} +{{- end }} {{- if .limitPhone }} - name: PHONE_NOTIFICATIONS_LIMIT value: {{ .limitPhone | quote }} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} +{{- end }} +{{- end }} +{{- end }} -{{- define "snippet.celery.env" -}} +{{- define "snippet.celery.env" }} {{- if .Values.celery.worker_queue }} - name: CELERY_WORKER_QUEUE - value: {{ .Values.celery.worker_queue }} -{{- end -}} + value: {{ .Values.celery.worker_queue | quote }} +{{- end }} {{- if .Values.celery.worker_concurrency }} - name: CELERY_WORKER_CONCURRENCY value: {{ .Values.celery.worker_concurrency | quote }} -{{- end -}} +{{- end }} {{- if .Values.celery.worker_max_tasks_per_child }} - name: CELERY_WORKER_MAX_TASKS_PER_CHILD value: {{ .Values.celery.worker_max_tasks_per_child | quote }} -{{- end -}} +{{- end }} {{- if .Values.celery.worker_beat_enabled }} - name: CELERY_WORKER_BEAT_ENABLED value: {{ .Values.celery.worker_beat_enabled | quote }} -{{- end -}} +{{- end }} {{- if .Values.celery.worker_shutdown_interval }} - name: CELERY_WORKER_SHUTDOWN_INTERVAL - value: {{ .Values.celery.worker_shutdown_interval }} -{{- end -}} -{{- end -}} + value: {{ .Values.celery.worker_shutdown_interval | quote }} +{{- end }} +{{- end }} {{- define "snippet.grafana.url" -}} -{{- if .Values.externalGrafana.url -}} -{{- .Values.externalGrafana.url | quote }} -{{- else if .Values.grafana.enabled -}} -http://{{ include "oncall.grafana.fullname" . }} +{{ if .Values.grafana.enabled -}} + http://{{ include "oncall.grafana.fullname" . }} {{- else -}} -{{- required "externalGrafana.url is required when not grafana.enabled" .Values.externalGrafana.url | quote }} -{{- end -}} -{{- end -}} + {{ required "externalGrafana.url is required when not grafana.enabled" .Values.externalGrafana.url }} +{{- end }} +{{- end }} {{- define "snippet.mysql.env" -}} - name: MYSQL_HOST - value: {{ include "snippet.mysql.host" . }} + value: {{ include "snippet.mysql.host" . | quote }} - name: MYSQL_PORT - value: {{ include "snippet.mysql.port" . }} + value: {{ include "snippet.mysql.port" . | quote }} - name: MYSQL_DB_NAME - value: {{ include "snippet.mysql.db" . }} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.existingSecret .Values.externalMysql.usernameKey (not .Values.externalMysql.user) }} + value: {{ include "snippet.mysql.db" . | quote }} - name: MYSQL_USER +{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.existingSecret .Values.externalMysql.usernameKey (not .Values.externalMysql.user) }} valueFrom: secretKeyRef: name: {{ include "snippet.mysql.password.secret.name" . }} - key: {{ .Values.externalMysql.usernameKey }} + key: {{ .Values.externalMysql.usernameKey | quote }} {{- else }} -- name: MYSQL_USER - value: {{ include "snippet.mysql.user" . }} + value: {{ include "snippet.mysql.user" . | quote }} {{- end }} - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: {{ include "snippet.mysql.password.secret.name" . }} - key: {{ include "snippet.mysql.password.secret.key" . }} + key: {{ include "snippet.mysql.password.secret.key" . | quote }} {{- end }} {{- define "snippet.mysql.password.secret.name" -}} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.password -}} -{{ include "oncall.fullname" . }}-mysql-external -{{- else if and (not .Values.mariadb.enabled) .Values.externalMysql.existingSecret -}} -{{ .Values.externalMysql.existingSecret }} +{{ if .Values.mariadb.enabled -}} + {{ if .Values.mariadb.auth.existingSecret -}} + {{ .Values.mariadb.auth.existingSecret }} + {{- else -}} + {{ include "oncall.mariadb.fullname" . }} + {{- end }} {{- else -}} -{{ include "oncall.mariadb.fullname" . }} -{{- end -}} -{{- end -}} + {{ if .Values.externalMysql.existingSecret -}} + {{ .Values.externalMysql.existingSecret }} + {{- else -}} + {{ include "oncall.fullname" . }}-mysql-external + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.mysql.password.secret.key" -}} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.passwordKey -}} -{{ .Values.externalMysql.passwordKey }} +{{ if and (not .Values.mariadb.enabled) .Values.externalMysql.existingSecret .Values.externalMysql.passwordKey -}} + {{ .Values.externalMysql.passwordKey }} {{- else -}} -mariadb-root-password -{{- end -}} -{{- end -}} + mariadb-root-password +{{- end }} +{{- end }} {{- define "snippet.mysql.host" -}} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.host -}} -{{- required "externalMysql.host is required if not mariadb.enabled" .Values.externalMysql.host | quote }} +{{ if and (not .Values.mariadb.enabled) .Values.externalMysql.host -}} + {{ .Values.externalMysql.host }} {{- else -}} -{{ include "oncall.mariadb.fullname" . }} -{{- end -}} -{{- end -}} + {{ include "oncall.mariadb.fullname" . }} +{{- end }} +{{- end }} {{- define "snippet.mysql.port" -}} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.port -}} -{{- required "externalMysql.port is required if not mariadb.enabled" .Values.externalMysql.port | quote }} +{{ if and (not .Values.mariadb.enabled) .Values.externalMysql.port -}} + {{ .Values.externalMysql.port }} {{- else -}} -"3306" -{{- end -}} -{{- end -}} + 3306 +{{- end }} +{{- end }} {{- define "snippet.mysql.db" -}} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.db_name -}} -{{- required "externalMysql.db_name is required if not mariadb.enabled" .Values.externalMysql.db_name | quote}} +{{ if and (not .Values.mariadb.enabled) .Values.externalMysql.db_name -}} + {{ .Values.externalMysql.db_name }} {{- else -}} -{{- .Values.mariadb.auth.database | default "oncall" | quote -}} -{{- end -}} -{{- end -}} + {{ .Values.mariadb.auth.database | default "oncall" }} +{{- end }} +{{- end }} {{- define "snippet.mysql.user" -}} -{{- if and (not .Values.mariadb.enabled) .Values.externalMysql.user -}} -{{- .Values.externalMysql.user | quote }} +{{ if and (not .Values.mariadb.enabled) .Values.externalMysql.user -}} + {{ .Values.externalMysql.user }} {{- else -}} -{{- .Values.mariadb.auth.username | default "root" | quote -}} -{{- end -}} -{{- end -}} + {{ .Values.mariadb.auth.username | default "root" }} +{{- end }} +{{- end }} {{- define "snippet.postgresql.env" -}} - name: DATABASE_TYPE - value: {{ .Values.database.type }} + value: {{ .Values.database.type | quote }} - name: DATABASE_HOST - value: {{ include "snippet.postgresql.host" . }} + value: {{ include "snippet.postgresql.host" . | quote }} - name: DATABASE_PORT - value: {{ include "snippet.postgresql.port" . }} + value: {{ include "snippet.postgresql.port" . | quote }} - name: DATABASE_NAME - value: {{ include "snippet.postgresql.db" . }} + value: {{ include "snippet.postgresql.db" . | quote }} - name: DATABASE_USER - value: {{ include "snippet.postgresql.user" . }} + value: {{ include "snippet.postgresql.user" . | quote }} - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: {{ include "snippet.postgresql.password.secret.name" . }} - key: {{ include "snippet.postgresql.password.secret.key" . }} + key: {{ include "snippet.postgresql.password.secret.key" . | quote }} {{- end }} {{- define "snippet.postgresql.password.secret.name" -}} -{{- if and (not .Values.postgresql.enabled) .Values.externalPostgresql.password -}} -{{ include "oncall.fullname" . }}-postgresql-external -{{- else if and (not .Values.postgresql.enabled) .Values.externalPostgresql.existingSecret -}} -{{ .Values.externalPostgresql.existingSecret }} +{{ if .Values.postgresql.enabled -}} + {{ if .Values.postgresql.auth.existingSecret -}} + {{ .Values.postgresql.auth.existingSecret }} + {{- else -}} + {{ include "oncall.postgresql.fullname" . }} + {{- end }} {{- else -}} -{{ include "oncall.postgresql.fullname" . }} -{{- end -}} -{{- end -}} + {{ if .Values.externalPostgresql.existingSecret -}} + {{ .Values.externalPostgresql.existingSecret }} + {{- else -}} + {{ include "oncall.fullname" . }}-postgresql-external + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.postgresql.password.secret.key" -}} -{{- if and (not .Values.postgresql.enabled) .Values.externalPostgresql.passwordKey -}} -{{ .Values.externalPostgresql.passwordKey }} -{{- else if .Values.postgresql.enabled -}} -{{ include "postgresql.userPasswordKey" .Subcharts.postgresql }} +{{ if .Values.postgresql.enabled -}} + {{ if .Values.postgresql.auth.existingSecret -}} + {{ required "postgresql.auth.secretKeys.adminPasswordKey is required if database.type=postgres and postgresql.enabled and postgresql.auth.existingSecret" .Values.postgresql.auth.secretKeys.adminPasswordKey }} + {{- else -}} + {{ include "postgresql.userPasswordKey" .Subcharts.postgresql }} + {{- end }} {{- else -}} -"postgres-password" -{{- end -}} -{{- end -}} + {{ if .Values.externalPostgresql.existingSecret -}} + {{ required "externalPostgresql.passwordKey is required if database.type=postgres and not postgresql.enabled and postgresql.auth.existingSecret" .Values.externalPostgresql.passwordKey }} + {{- else -}} + postgres-password + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.postgresql.host" -}} -{{- if and (not .Values.postgresql.enabled) .Values.externalPostgresql.host -}} -{{- required "externalPostgresql.host is required if not postgresql.enabled" .Values.externalPostgresql.host | quote }} +{{ if not .Values.postgresql.enabled -}} + {{ required "externalPostgresql.host is required if database.type=postgres and not postgresql.enabled" .Values.externalPostgresql.host }} {{- else -}} -{{ include "oncall.postgresql.fullname" . }} -{{- end -}} -{{- end -}} + {{ include "oncall.postgresql.fullname" . }} +{{- end }} +{{- end }} {{- define "snippet.postgresql.port" -}} -{{- if and (not .Values.postgresql.enabled) .Values.externalPostgresql.port -}} -{{- required "externalPostgresql.port is required if not postgresql.enabled" .Values.externalPostgresql.port | quote }} +{{ if and (not .Values.postgresql.enabled) .Values.externalPostgresql.port -}} + {{ .Values.externalPostgresql.port }} {{- else -}} -"5432" -{{- end -}} -{{- end -}} + 5432 +{{- end }} +{{- end }} {{- define "snippet.postgresql.db" -}} -{{- if and (not .Values.postgresql.enabled) .Values.externalPostgresql.db_name -}} -{{- required "externalPostgresql.db_name is required if not postgresql.enabled" .Values.externalPostgresql.db_name | quote}} +{{ if not .Values.postgresql.enabled -}} + {{ .Values.externalPostgresql.db_name | default "oncall" }} {{- else -}} -{{- .Values.postgresql.auth.database | default "oncall" | quote -}} -{{- end -}} -{{- end -}} + {{ .Values.postgresql.auth.database | default "oncall" }} +{{- end }} +{{- end }} {{- define "snippet.postgresql.user" -}} -{{- if and (not .Values.postgresql.enabled) .Values.externalPostgresql.user -}} -{{- .Values.externalPostgresql.user | quote}} +{{ if and (not .Values.postgresql.enabled) -}} + {{ .Values.externalPostgresql.user | default "postgres" }} {{- else -}} -{{- .Values.postgresql.auth.username | default "postgres" | quote -}} -{{- end -}} -{{- end -}} + {{ .Values.postgresql.auth.username | default "postgres" }} +{{- end }} +{{- end }} -{{- define "snippet.rabbitmq.env" -}} +{{- define "snippet.rabbitmq.env" }} {{- if eq .Values.broker.type "rabbitmq" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.existingSecret .Values.externalRabbitmq.usernameKey (not .Values.externalRabbitmq.user) }} - name: RABBITMQ_USERNAME +{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.existingSecret .Values.externalRabbitmq.usernameKey (not .Values.externalRabbitmq.user) }} valueFrom: secretKeyRef: name: {{ include "snippet.rabbitmq.password.secret.name" . }} - key: {{ .Values.externalRabbitmq.usernameKey }} + key: {{ .Values.externalRabbitmq.usernameKey | quote }} {{- else }} -- name: RABBITMQ_USERNAME - value: {{ include "snippet.rabbitmq.user" . }} + value: {{ include "snippet.rabbitmq.user" . | quote }} {{- end }} - name: RABBITMQ_PASSWORD valueFrom: secretKeyRef: name: {{ include "snippet.rabbitmq.password.secret.name" . }} - key: {{ include "snippet.rabbitmq.password.secret.key" . }} + key: {{ include "snippet.rabbitmq.password.secret.key" . | quote }} - name: RABBITMQ_HOST - value: {{ include "snippet.rabbitmq.host" . }} + value: {{ include "snippet.rabbitmq.host" . | quote }} - name: RABBITMQ_PORT - value: {{ include "snippet.rabbitmq.port" . }} + value: {{ include "snippet.rabbitmq.port" . | quote }} - name: RABBITMQ_PROTOCOL - value: {{ include "snippet.rabbitmq.protocol" . }} + value: {{ include "snippet.rabbitmq.protocol" . | quote }} - name: RABBITMQ_VHOST - value: {{ include "snippet.rabbitmq.vhost" . }} + value: {{ include "snippet.rabbitmq.vhost" . | quote }} +{{- end }} {{- end }} -{{- end -}} {{- define "snippet.rabbitmq.user" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.user -}} -{{- required "externalRabbitmq.user is required if not rabbitmq.enabled" .Values.externalRabbitmq.user | quote }} +{{ if not .Values.rabbitmq.enabled -}} + {{ required "externalRabbitmq.user is required if not rabbitmq.enabled" .Values.externalRabbitmq.user }} {{- else -}} -"user" -{{- end -}} -{{- end -}} + user +{{- end }} +{{- end }} {{- define "snippet.rabbitmq.host" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.host -}} -{{- required "externalRabbitmq.host is required if not rabbitmq.enabled" .Values.externalRabbitmq.host | quote }} +{{ if not .Values.rabbitmq.enabled -}} + {{ required "externalRabbitmq.host is required if not rabbitmq.enabled" .Values.externalRabbitmq.host }} {{- else -}} -{{ include "oncall.rabbitmq.fullname" . }} -{{- end -}} -{{- end -}} + {{ include "oncall.rabbitmq.fullname" . }} +{{- end }} +{{- end }} {{- define "snippet.rabbitmq.port" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.port -}} -{{- required "externalRabbitmq.port is required if not rabbitmq.enabled" .Values.externalRabbitmq.port | quote }} +{{ if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.port -}} + {{ required "externalRabbitmq.port is required if not rabbitmq.enabled" .Values.externalRabbitmq.port }} {{- else -}} -"5672" -{{- end -}} -{{- end -}} + 5672 +{{- end }} +{{- end }} {{- define "snippet.rabbitmq.protocol" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.protocol -}} -{{ .Values.externalRabbitmq.protocol | quote }} +{{ if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.protocol -}} + {{ .Values.externalRabbitmq.protocol }} {{- else -}} -"amqp" -{{- end -}} -{{- end -}} + amqp +{{- end }} +{{- end }} {{- define "snippet.rabbitmq.vhost" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.vhost -}} -{{ .Values.externalRabbitmq.vhost | quote }} -{{- else -}} -"" -{{- end -}} -{{- end -}} +{{ if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.vhost -}} + {{ .Values.externalRabbitmq.vhost }} +{{- end }} +{{- end }} {{- define "snippet.rabbitmq.password.secret.name" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.password -}} -{{ include "oncall.fullname" . }}-rabbitmq-external -{{- else if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.existingSecret -}} -{{ .Values.externalRabbitmq.existingSecret }} +{{ if .Values.rabbitmq.enabled -}} + {{ if .Values.rabbitmq.auth.existingPasswordSecret -}} + {{ .Values.rabbitmq.auth.existingPasswordSecret }} + {{- else -}} + {{ include "oncall.rabbitmq.fullname" . }} + {{- end }} {{- else -}} -{{ include "oncall.rabbitmq.fullname" . }} -{{- end -}} -{{- end -}} + {{ if .Values.externalRabbitmq.existingSecret -}} + {{ .Values.externalRabbitmq.existingSecret }} + {{- else -}} + {{ include "oncall.fullname" . }}-rabbitmq-external + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.rabbitmq.password.secret.key" -}} -{{- if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.passwordKey -}} -{{ .Values.externalRabbitmq.passwordKey }} +{{ if and (not .Values.rabbitmq.enabled) .Values.externalRabbitmq.passwordKey -}} + {{ .Values.externalRabbitmq.passwordKey }} {{- else -}} -rabbitmq-password -{{- end -}} -{{- end -}} + rabbitmq-password +{{- end }} +{{- end }} {{- define "snippet.redis.host" -}} -{{- if and (not .Values.redis.enabled) .Values.externalRedis.host -}} -{{- required "externalRedis.host is required if not redis.enabled" .Values.externalRedis.host | quote }} +{{ if not .Values.redis.enabled -}} + {{ required "externalRedis.host is required if not redis.enabled" .Values.externalRedis.host | quote }} {{- else -}} -{{ include "oncall.redis.fullname" . }}-master -{{- end -}} -{{- end -}} + {{ include "oncall.redis.fullname" . }}-master +{{- end }} +{{- end }} {{- define "snippet.redis.password.secret.name" -}} -{{- if and (not .Values.redis.enabled) .Values.externalRedis.password -}} -{{ include "oncall.fullname" . }}-redis-external -{{- else if and (not .Values.redis.enabled) .Values.externalRedis.existingSecret -}} -{{ .Values.externalRedis.existingSecret }} +{{ if .Values.redis.enabled -}} + {{ if .Values.redis.auth.existingSecret -}} + {{ .Values.redis.auth.existingSecret }} + {{- else -}} + {{ include "oncall.redis.fullname" . }} + {{- end }} {{- else -}} -{{ include "oncall.redis.fullname" . }} -{{- end -}} -{{- end -}} + {{ if .Values.externalRedis.existingSecret -}} + {{ .Values.externalRedis.existingSecret }} + {{- else -}} + {{ include "oncall.fullname" . }}-redis-external + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.redis.password.secret.key" -}} -{{- if and (not .Values.redis.enabled) .Values.externalRedis.passwordKey -}} -{{ .Values.externalRedis.passwordKey }} +{{ if .Values.redis.enabled -}} + {{ if .Values.redis.auth.existingSecret -}} + {{ required "redis.auth.existingSecretPasswordKey is required if redis.auth.existingSecret is non-empty" .Values.redis.auth.existingSecretPasswordKey }} + {{- else -}} + redis-password + {{- end }} {{- else -}} -redis-password -{{- end -}} -{{- end -}} + {{ if .Values.externalRedis.existingSecret -}} + {{ required "externalRedis.passwordKey is required if externalRedis.existingSecret is non-empty" .Values.externalRedis.passwordKey }} + {{- else -}} + redis-password + {{- end }} +{{- end }} +{{- end }} {{- define "snippet.redis.env" -}} - name: REDIS_HOST @@ -478,13 +509,13 @@ redis-password valueFrom: secretKeyRef: name: {{ include "snippet.redis.password.secret.name" . }} - key: {{ include "snippet.redis.password.secret.key" . }} + key: {{ include "snippet.redis.password.secret.key" . | quote}} {{- end }} {{- define "snippet.oncall.smtp.env" -}} -{{- if .Values.oncall.smtp.enabled -}} - name: FEATURE_EMAIL_INTEGRATION_ENABLED value: {{ .Values.oncall.smtp.enabled | toString | title | quote }} +{{- if .Values.oncall.smtp.enabled }} - name: EMAIL_HOST value: {{ .Values.oncall.smtp.host | quote }} - name: EMAIL_PORT @@ -503,14 +534,11 @@ redis-password value: {{ .Values.oncall.smtp.fromEmail | quote }} - name: EMAIL_NOTIFICATIONS_LIMIT value: {{ .Values.oncall.smtp.limitEmail | default "200" | quote }} -{{- else -}} -- name: FEATURE_EMAIL_INTEGRATION_ENABLED - value: {{ .Values.oncall.smtp.enabled | toString | title | quote }} -{{- end -}} +{{- end }} {{- end }} {{- define "snippet.oncall.exporter.env" -}} -{{- if .Values.oncall.exporter.enabled -}} +{{ if .Values.oncall.exporter.enabled -}} - name: FEATURE_PROMETHEUS_EXPORTER_ENABLED value: {{ .Values.oncall.exporter.enabled | toString | title | quote }} - name: PROMETHEUS_EXPORTER_SECRET @@ -522,5 +550,5 @@ redis-password {{- else -}} - name: FEATURE_PROMETHEUS_EXPORTER_ENABLED value: {{ .Values.oncall.exporter.enabled | toString | title | quote }} -{{- end -}} +{{- end }} {{- end }} diff --git a/helm/oncall/templates/celery/_deployment.tpl b/helm/oncall/templates/celery/_deployment.tpl index 7a8361dd5b..faafc5479a 100644 --- a/helm/oncall/templates/celery/_deployment.tpl +++ b/helm/oncall/templates/celery/_deployment.tpl @@ -75,4 +75,4 @@ spec: {{- end }} resources: {{- toYaml .Values.celery.resources | nindent 12 }} -{{- end}} \ No newline at end of file +{{- end}} diff --git a/helm/oncall/templates/celery/deployment-celery.yaml b/helm/oncall/templates/celery/deployment-celery.yaml index a9d49bf1e2..c33c98faec 100644 --- a/helm/oncall/templates/celery/deployment-celery.yaml +++ b/helm/oncall/templates/celery/deployment-celery.yaml @@ -1 +1 @@ -{{ include "template.oncall.celery.deployment" . }} \ No newline at end of file +{{ include "template.oncall.celery.deployment" . }} diff --git a/helm/oncall/templates/secrets.yaml b/helm/oncall/templates/secrets.yaml index aa1c86fe73..0db331d597 100644 --- a/helm/oncall/templates/secrets.yaml +++ b/helm/oncall/templates/secrets.yaml @@ -7,11 +7,11 @@ metadata: {{- include "oncall.labels" . | nindent 4 }} type: Opaque data: - {{ template "snippet.oncall.secret.secretKey" . }}: {{ randAlphaNum 40 | b64enc | quote }} - {{ template "snippet.oncall.secret.mirageSecretKey" . }}: {{ randAlphaNum 40 | b64enc | quote }} -{{- end }} + {{ include "snippet.oncall.secret.secretKey" . }}: {{ randAlphaNum 40 | b64enc | quote }} + {{ include "snippet.oncall.secret.mirageSecretKey" . }}: {{ randAlphaNum 40 | b64enc | quote }} --- -{{ if and (not .Values.mariadb.enabled) (eq .Values.database.type "mysql") (not .Values.externalMysql.existingSecret) -}} +{{- end }} +{{- if and (eq .Values.database.type "mysql") (not .Values.mariadb.enabled) (not .Values.externalMysql.existingSecret) }} apiVersion: v1 kind: Secret metadata: @@ -19,9 +19,19 @@ metadata: type: Opaque data: mariadb-root-password: {{ required "externalMysql.password is required if not mariadb.enabled and not externalMysql.existingSecret" .Values.externalMysql.password | b64enc | quote }} +--- {{- end }} +{{- if and (not .Values.postgresql.enabled) (eq .Values.database.type "postgresql") (not .Values.externalPostgresql.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "oncall.fullname" . }}-postgresql-external +type: Opaque +data: + postgres-password: {{ required "externalPostgresql.password is required if not postgresql.enabled and not externalPostgresql.existingSecret" .Values.externalPostgresql.password | b64enc | quote }} --- -{{ if and (eq .Values.broker.type "rabbitmq") (not .Values.rabbitmq.enabled) (not .Values.externalRabbitmq.existingSecret) -}} +{{- end }} +{{- if and (eq .Values.broker.type "rabbitmq") (not .Values.rabbitmq.enabled) (not .Values.externalRabbitmq.existingSecret) }} apiVersion: v1 kind: Secret metadata: @@ -29,9 +39,9 @@ metadata: type: Opaque data: rabbitmq-password: {{ required "externalRabbitmq.password is required if not rabbitmq.enabled and not externalRabbitmq.existingSecret" .Values.externalRabbitmq.password | b64enc | quote }} -{{- end }} --- -{{ if and (not .Values.redis.enabled) (not .Values.externalRedis.existingSecret) -}} +{{- end }} +{{- if and (not .Values.redis.enabled) (not .Values.externalRedis.existingSecret) }} apiVersion: v1 kind: Secret metadata: @@ -39,9 +49,9 @@ metadata: type: Opaque data: redis-password: {{ required "externalRedis.password is required if not redis.enabled and not externalRedis.existingSecret" .Values.externalRedis.password | b64enc | quote }} -{{- end }} --- -{{ if and .Values.oncall.smtp.enabled .Values.oncall.smtp.password -}} +{{- end }} +{{- if and .Values.oncall.smtp.enabled .Values.oncall.smtp.password }} apiVersion: v1 kind: Secret metadata: @@ -49,9 +59,9 @@ metadata: type: Opaque data: smtp-password: {{ .Values.oncall.smtp.password | b64enc | quote }} -{{- end }} --- -{{ if and .Values.oncall.exporter.enabled .Values.oncall.exporter.authToken -}} +{{- end }} +{{- if and .Values.oncall.exporter.enabled .Values.oncall.exporter.authToken }} apiVersion: v1 kind: Secret metadata: @@ -59,14 +69,5 @@ metadata: type: Opaque data: exporter-secret: {{ .Values.oncall.exporter.authToken | b64enc | quote }} -{{- end }} --- -{{ if and (not .Values.postgresql.enabled) (eq .Values.database.type "postgresql") (not .Values.externalPostgresql.existingSecret) -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "oncall.fullname" . }}-postgresql-external -type: Opaque -data: - postgres-password: {{ required "externalPostgresql.password is required if not postgresql.enabled and not externalPostgresql.existingSecret" .Values.externalPostgresql.password | b64enc | quote }} {{- end }} diff --git a/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap b/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap index 76d8cacea9..7d764bdef1 100644 --- a/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap +++ b/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap @@ -181,7 +181,7 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: - name: DATABASE_TYPE value: postgresql - name: DATABASE_HOST - value: oncall-postgresql + value: some-postgresql-host - name: DATABASE_PORT value: "5432" - name: DATABASE_NAME @@ -192,7 +192,7 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: valueFrom: secretKeyRef: key: postgres-password - name: oncall-postgresql + name: oncall-postgresql-external - name: RABBITMQ_USERNAME value: user - name: RABBITMQ_PASSWORD @@ -256,7 +256,7 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: - name: DATABASE_TYPE value: postgresql - name: DATABASE_HOST - value: oncall-postgresql + value: some-postgresql-host - name: DATABASE_PORT value: "5432" - name: DATABASE_NAME @@ -267,7 +267,7 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: valueFrom: secretKeyRef: key: postgres-password - name: oncall-postgresql + name: oncall-postgresql-external - name: RABBITMQ_USERNAME value: user - name: RABBITMQ_PASSWORD diff --git a/helm/oncall/tests/extra_env_test.yaml b/helm/oncall/tests/extra_env_test.yaml index 3c6e19d0e9..53c61c2570 100644 --- a/helm/oncall/tests/extra_env_test.yaml +++ b/helm/oncall/tests/extra_env_test.yaml @@ -76,6 +76,7 @@ tests: - celery/deployment-celery.yaml set: database.type: postgresql + postgresql.enabled: true env: SOME_VAR: some_value another_var: "another_value" @@ -97,6 +98,7 @@ tests: - celery/deployment-celery.yaml set: database.type: postgresql + postgresql.enabled: true env: - name: SOME_VAR value: some_value diff --git a/helm/oncall/tests/postgres_env_test.yaml b/helm/oncall/tests/postgres_env_test.yaml index bbacbe6eab..fc2a9ce2ec 100644 --- a/helm/oncall/tests/postgres_env_test.yaml +++ b/helm/oncall/tests/postgres_env_test.yaml @@ -10,6 +10,7 @@ tests: set: database.type: postgresql postgresql.enabled: false + externalPostgresql.host: custom-postgres-host asserts: - contains: path: spec.template.spec.containers[0].env @@ -35,7 +36,7 @@ tests: path: spec.template.spec.containers[0].env content: name: DATABASE_HOST - value: oncall-postgresql + value: custom-postgres-host - it: externalPostgresql -> should use external PostgreSQL custom settings set: diff --git a/helm/oncall/tests/postgres_password_env_test.yaml b/helm/oncall/tests/postgres_password_env_test.yaml index 997e6984d7..e35b146532 100644 --- a/helm/oncall/tests/postgres_password_env_test.yaml +++ b/helm/oncall/tests/postgres_password_env_test.yaml @@ -11,6 +11,7 @@ tests: set: database.type: postgresql postgresql.enabled: false + externalPostgresql.host: some-postgres-host asserts: - failedTemplate: errorMessage: externalPostgresql.password is required if not postgresql.enabled and not externalPostgresql.existingSecret @@ -26,6 +27,7 @@ tests: postgresql.enabled: false externalPostgresql: password: abcd123 + host: some-postgres-host asserts: - contains: path: spec.template.spec.containers[0].env @@ -57,6 +59,8 @@ tests: postgresql.enabled: false externalPostgresql: existingSecret: some-postgres-secret + host: some-postgres-host + passwordKey: postgres-password-key asserts: - contains: path: spec.template.spec.containers[0].env @@ -65,7 +69,7 @@ tests: valueFrom: secretKeyRef: name: some-postgres-secret - key: postgres-password + key: postgres-password-key - it: externalPostgresql.passwordKey -> should be used for existing secret templates: @@ -76,6 +80,7 @@ tests: database.type: postgresql postgresql.enabled: false externalPostgresql: + host: some-postgres-host existingSecret: some-postgres-secret passwordKey: postgres.key asserts: diff --git a/helm/oncall/tests/rabbitmq_env_test.yaml b/helm/oncall/tests/rabbitmq_env_test.yaml index a969ccd48e..9fdc6dc660 100644 --- a/helm/oncall/tests/rabbitmq_env_test.yaml +++ b/helm/oncall/tests/rabbitmq_env_test.yaml @@ -200,6 +200,7 @@ tests: broker.type: rabbitmq rabbitmq.enabled: false externalRabbitmq: + host: some-rabbitmq-host existingSecret: existing-secret passwordKey: password-key asserts: @@ -236,7 +237,7 @@ tests: path: spec.template.spec.containers[0].env content: name: RABBITMQ_HOST - value: oncall-rabbitmq + value: some-rabbitmq-host - contains: path: spec.template.spec.containers[0].env content: @@ -251,4 +252,19 @@ tests: path: spec.template.spec.containers[0].env content: name: RABBITMQ_VHOST - value: "" \ No newline at end of file + value: "" + - it: rabbitmq.enabled=false -> should fail if host is missing + templates: + - engine/deployment.yaml + - engine/job-migrate.yaml + - celery/deployment-celery.yaml + set: + broker.type: rabbitmq + rabbitmq.enabled: false + externalRabbitmq: + existingSecret: existing-secret + passwordKey: password-key + asserts: + - failedTemplate: + errorMessage: externalRabbitmq.host is required if not rabbitmq.enabled + template: engine/job-migrate.yaml diff --git a/helm/oncall/tests/redis_env_test.yaml b/helm/oncall/tests/redis_env_test.yaml index b1bc487131..5fc3739fb7 100644 --- a/helm/oncall/tests/redis_env_test.yaml +++ b/helm/oncall/tests/redis_env_test.yaml @@ -77,6 +77,16 @@ tests: key: redis-password name: oncall-redis + - it: redis.enabled=false -> should fail if host not set + set: + redis.enabled: false + externalRedis: + existingSecret: some-redis-secret + asserts: + - failedTemplate: + errorMessage: externalRedis.host is required if not redis.enabled + template: engine/job-migrate.yaml + - it: redis.enabled=false -> should fail if not externalRabbitmq.existingSecret or not externalRabbitmq.password templates: - engine/deployment.yaml diff --git a/helm/oncall/tests/redis_password_env_test.yaml b/helm/oncall/tests/redis_password_env_test.yaml index c5eff6a5d9..de8c8eeb0f 100644 --- a/helm/oncall/tests/redis_password_env_test.yaml +++ b/helm/oncall/tests/redis_password_env_test.yaml @@ -10,6 +10,7 @@ tests: - it: secrets -> should fail if externalRedis.password not set set: redis.enabled: false + externalRedis.host: some-redis-host asserts: - failedTemplate: errorMessage: externalRedis.password is required if not redis.enabled and not externalRedis.existingSecret @@ -23,6 +24,7 @@ tests: set: redis.enabled: false externalRedis: + host: some-redis-host password: abcd123 asserts: - contains: @@ -53,7 +55,9 @@ tests: set: redis.enabled: false externalRedis: + host: some-redis-host existingSecret: some-redis-secret + passwordKey: redis-password-key asserts: - contains: path: spec.template.spec.containers[0].env @@ -62,7 +66,7 @@ tests: valueFrom: secretKeyRef: name: some-redis-secret - key: redis-password + key: redis-password-key - it: externalRedis.passwordKey -> should be used for existing secret templates: @@ -72,6 +76,7 @@ tests: set: redis.enabled: false externalRedis: + host: some-redis-host existingSecret: some-redis-secret passwordKey: redis.key asserts: diff --git a/helm/oncall/tests/wait_for_db_test.yaml b/helm/oncall/tests/wait_for_db_test.yaml index a744962e0d..e43b1ef8cb 100644 --- a/helm/oncall/tests/wait_for_db_test.yaml +++ b/helm/oncall/tests/wait_for_db_test.yaml @@ -25,6 +25,7 @@ tests: - it: database.type=postgresql -> should create initContainer for PostgreSQL database set: database.type: postgresql + externalPostgresql.host: some-postgresql-host asserts: - contains: path: spec.template.spec.initContainers diff --git a/helm/oncall/values.yaml b/helm/oncall/values.yaml index 9c974780cc..bfaac90f3d 100644 --- a/helm/oncall/values.yaml +++ b/helm/oncall/values.yaml @@ -94,15 +94,15 @@ oncall: secrets: # Use existing secret. (secretKey and mirageSecretKey is required) existingSecret: "" - # the key in the secret containing secret key + # The key in the secret containing secret key secretKey: "" - # the key in the secret containing mirage secret key + # The key in the secret containing mirage secret key mirageSecretKey: "" - # slack configures the Grafana Oncall Slack ChatOps integration. + # Slack configures the Grafana Oncall Slack ChatOps integration. slack: - # enabled enable the Slack ChatOps integration for the Oncall Engine. + # Enable the Slack ChatOps integration for the Oncall Engine. enabled: false - # commandName sets the Slack bot slash-command + # Sets the Slack bot slash-command commandName: oncall # clientId configures the Slack app OAuth2 client ID. # api.slack.com/apps/ -> Basic Information -> App Credentials -> Client ID @@ -110,18 +110,18 @@ oncall: # clientSecret configures the Slack app OAuth2 client secret. # api.slack.com/apps/ -> Basic Information -> App Credentials -> Client Secret clientSecret: ~ - # signingSecret configures the Slack app signature secret used to sign + # signingSecret - configures the Slack app signature secret used to sign # requests comming from Slack. # api.slack.com/apps/ -> Basic Information -> App Credentials -> Signing Secret signingSecret: ~ # Use existing secret for clientId, clientSecret and signingSecret. # clientIdKey, clientSecretKey and signingSecretKey are required existingSecret: "" - # the key in the secret containing OAuth2 client ID + # The key in the secret containing OAuth2 client ID clientIdKey: "" - # the key in the secret containing OAuth2 client secret + # The key in the secret containing OAuth2 client secret clientSecretKey: "" - # the key in the secret containing the Slack app signature secret + # The key in the secret containing the Slack app signature secret signingSecretKey: "" # OnCall external URL redirectHost: ~ @@ -129,9 +129,9 @@ oncall: enabled: false token: ~ webhookUrl: ~ - # Use exsting secret. (tokenKey is required) + # Use existing secret. (tokenKey is required) existingSecret: "" - # the key in the secret containing Telegram token + # The key in the secret containing Telegram token tokenKey: "" smtp: enabled: false @@ -161,16 +161,19 @@ oncall: # Use existing secret for authToken, phoneNumber, verifySid, apiKeySid and apiKeySecret. existingSecret: "" # Twilio password to allow OnCall to send SMSes and make calls - # the key in the secret containing the auth token + # The key in the secret containing the auth token authTokenKey: "" - # the key in the secret containing the phone number + # The key in the secret containing the phone number phoneNumberKey: "" - # the key in the secret containing verify service sid + # The key in the secret containing verify service sid verifySidKey: "" - # the key in the secret containing api key sid + # The key in the secret containing api key sid apiKeySidKey: "" - # the key in the secret containing the api key secret + # The key in the secret containing the api key secret apiKeySecretKey: "" + # Phone notifications limit (the only non-secret value). + # TODO: rename to phoneNotificationLimit + limitPhone: # Whether to run django database migrations automatically migrate: @@ -252,6 +255,7 @@ mariadb: enabled: true auth: database: oncall + existingSecret: primary: extraEnvVars: - name: MARIADB_COLLATE @@ -273,11 +277,11 @@ externalMysql: db_name: user: password: - # use an existing secret for the mysql password - existingSecret: "" - # the key in the secret containing the mysql username + # Use an existing secret for the mysql password. + existingSecret: + # The key in the secret containing the mysql username usernameKey: - # the key in the secret containing the mysql password + # The key in the secret containing the mysql password passwordKey: # PostgreSQL is included into this release for the convenience. @@ -287,6 +291,7 @@ postgresql: enabled: false auth: database: oncall + existingSecret: # Make sure to create the database with the following parameters: # CREATE DATABASE oncall WITH ENCODING UTF8; @@ -296,9 +301,9 @@ externalPostgresql: db_name: user: password: - # use an existing secret for the database password - existingSecret: "" - # the key in the secret containing the database password + # Use an existing secret for the database password + existingSecret: + # The key in the secret containing the database password passwordKey: # RabbitMQ is included into this release for the convenience. @@ -306,6 +311,8 @@ externalPostgresql: # Set rabbitmq.enabled = false and configure externalRabbitmq rabbitmq: enabled: true + auth: + existingPasswordSecret: broker: type: rabbitmq @@ -317,24 +324,26 @@ externalRabbitmq: password: protocol: vhost: - # use an existing secret for the rabbitmq password - existingSecret: "" - # the key in the secret containing the rabbitmq password + # Use an existing secret for the rabbitmq password + existingSecret: + # The key in the secret containing the rabbitmq password passwordKey: "" - # the key in the secret containing the rabbitmq username + # The key in the secret containing the rabbitmq username usernameKey: username # Redis is included into this release for the convenience. # It is recommended to host it separately from this release redis: enabled: true + auth: + existingSecret: externalRedis: host: password: - # use an existing secret for the redis password - existingSecret: "" - # the key in the secret containing the redis password + # Use an existing secret for the redis password + existingSecret: + # The key in the secret containing the redis password passwordKey: # Grafana is included into this release for the convenience. @@ -355,6 +364,7 @@ grafana: - grafana-oncall-app externalGrafana: + # Example: https://grafana.mydomain.com url: nameOverride: ""