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 <Ildar.iskhakov@grafana.com>
This commit is contained in:
Sergei Kuzmin 2023-06-22 22:43:05 -07:00 committed by GitHub
parent 3dfc30cf13
commit 370d7b9867
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 524 additions and 338 deletions

View file

@ -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))

View file

@ -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<Component>` 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 `<subchart>.auth.existingSecret` is non-empty, then this secret is used. Secret keys are pre-defined by chart.
- If subchart supports password files and `<subchart>.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 `<subchart>.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: `<release>-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: `<release>-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: `<release>-rabbitmq`
password: ""
erlangCookie: ""
externalRabbitmq:
user: ""
password: ""
existingSecret: ""
passwordKey: ""
usernameKey: ""
```
Redis:
```yaml
redis:
enabled: true
auth:
existingSecret: ""
existingSecretPasswordKey: ""
# Secret name: `<release>-redis`
password: ""
externalRedis:
password: ""
existingSecret: ""
passwordKey: ""
```
### Set up Slack and Telegram
You can set up Slack connection via following variables:

View file

@ -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 -}}
{{- 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 "oncall.twilio.authTokenKey is required if oncall.twilio.existingSecret is not empty" .authTokenKey | quote }}
- name: TWILIO_NUMBER
valueFrom:
secretKeyRef:
name: {{ .existingSecret }}
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 "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 "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 "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 .existingSecret }}
- name: TWILIO_AUTH_TOKEN
valueFrom:
secretKeyRef:
name: {{ .existingSecret }}
key: {{ required ".authTokenKey is required if .existingSecret is not empty" .authTokenKey }}
- name: TWILIO_NUMBER
valueFrom:
secretKeyRef:
name: {{ .existingSecret }}
key: {{ required ".phoneNumberKey is required if .existingSecret is not empty" .phoneNumberKey }}
- name: TWILIO_VERIFY_SERVICE_SID
valueFrom:
secretKeyRef:
name: {{ .existingSecret }}
key: {{ required ".verifySidKey is required if .existingSecret is not empty" .verifySidKey }}
- name: TWILIO_API_KEY_SID
valueFrom:
secretKeyRef:
name: {{ .existingSecret }}
key: {{ required ".apiKeySidKey is required if .existingSecret is not empty" .apiKeySidKey }}
- name: TWILIO_API_KEY_SECRET
valueFrom:
secretKeyRef:
name: {{ .existingSecret }}
key: {{ required ".apiKeySecretKey is required if .existingSecret is not empty" .apiKeySecretKey }}
{{- else }}
{{- 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 }}

View file

@ -75,4 +75,4 @@ spec:
{{- end }}
resources:
{{- toYaml .Values.celery.resources | nindent 12 }}
{{- end}}
{{- end}}

View file

@ -1 +1 @@
{{ include "template.oncall.celery.deployment" . }}
{{ include "template.oncall.celery.deployment" . }}

View file

@ -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,49 +19,9 @@ 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 (eq .Values.broker.type "rabbitmq") (not .Values.rabbitmq.enabled) (not .Values.externalRabbitmq.existingSecret) -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-rabbitmq-external
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) -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-redis-external
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 -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-smtp
type: Opaque
data:
smtp-password: {{ .Values.oncall.smtp.password | b64enc | quote }}
{{- end }}
---
{{ if and .Values.oncall.exporter.enabled .Values.oncall.exporter.authToken -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-exporter
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) -}}
{{- if and (not .Values.postgresql.enabled) (eq .Values.database.type "postgresql") (not .Values.externalPostgresql.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
@ -69,4 +29,45 @@ metadata:
type: Opaque
data:
postgres-password: {{ required "externalPostgresql.password is required if not postgresql.enabled and not externalPostgresql.existingSecret" .Values.externalPostgresql.password | b64enc | quote }}
---
{{- end }}
{{- if and (eq .Values.broker.type "rabbitmq") (not .Values.rabbitmq.enabled) (not .Values.externalRabbitmq.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-rabbitmq-external
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) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-redis-external
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 }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-smtp
type: Opaque
data:
smtp-password: {{ .Values.oncall.smtp.password | b64enc | quote }}
---
{{- end }}
{{- if and .Values.oncall.exporter.enabled .Values.oncall.exporter.authToken }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "oncall.fullname" . }}-exporter
type: Opaque
data:
exporter-secret: {{ .Values.oncall.exporter.authToken | b64enc | quote }}
---
{{- end }}

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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: ""
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

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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/<yourApp> -> Basic Information -> App Credentials -> Client ID
@ -110,18 +110,18 @@ oncall:
# clientSecret configures the Slack app OAuth2 client secret.
# api.slack.com/apps/<yourApp> -> 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/<yourApp> -> 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: ""