2022-06-03 08:09:47 -06:00
|
|
|
from django.conf import settings
|
|
|
|
|
from django.core.validators import MinLengthValidator
|
|
|
|
|
from django.db import models
|
|
|
|
|
from django.db.models import JSONField
|
fix a few flaky e2e tests + allow running project locally via k8s/helm (#2751)
# What this PR does
- updates the GitHub Actions workflow to move the e2e tests into a
"[reusable
workflow](https://docs.github.com/en/actions/using-workflows/reusing-workflows#creating-a-reusable-workflow)"
which are run in two scenarios:
- all tests _except_ those annotated as `@expensive` are run against
`grafana/grafana:latest` on all feature branches
- all tests _including_ `@expensive` tests are run on weekdays @ 07h00
UTC, against a matrix of 6 grafana versions. Results of these builds
will be posted to `#irm-amixr-flux` Slack channel.
- local development will now be:
```bash
make build-dev-images init-k8s start-k8s
```
- `build-dev-images` - builds the engine and UI docker images (only need
to run first time)
- `init-k8s` - creates a `kind` cluster and loads the two Docker images
onto the cluster nodes (only need to run first time)
- `start-k8s` - switches `kubectl` context to the created `kind`
cluster, and uses `helm` to deploy everything as defined in
`./dev/helm-local.yml` and `./dev/helm-local.dev.yml` (that latter file
is `.gitignored` and specific to how _you_ want your setup to look like.
Hot reloading works as before. This is the _start_ of #2381. (I've
marked these `make` commands as beta, because they've not yet been
thoroughly tested for local development).
- modifies the `helm` chart to add the concept of `oncall.devMode`,
`ui`, and ability to run oncall w/ sqlite
- `oncall.devMode` will essentially just add `volumes` and
`volumeMounts` to the various engine/migrate containers +
- `ui.enabled` + `ui.env` - create a ui container (which is needed for
hot reloading locally)
- `sqlite` - this was useful for the e2e test environments where Github
runner resources are scarce. Running `mariadb` eats up precious
resources, instead lets just use sqlite here
- fixes an issue that caused sporadic HTTP 502s from the grafana
plugin-proxy, which led to flaky tests. See [this
comment](https://github.com/grafana/oncall/pull/2751/files#diff-09040e8df192699b9c5742110ebbe8d9d5c3938cb156cc1cb99fa1c3fdee4fefR72-R77)
for more context + a link to a relevant Slack conversation. **tldr;**
there is a bug with the Grafana plugin proxy in Grafana >= v10.0.3.
Let's stop using the `latest`/`main` docker tags in our test and pin to
`10.0.2` for now
- ~~re-enables the e2e test which validates a phone number via SMS, and
asserts that we can receive an alert escalation via SMS (new Mailslurp
API Key has been added as a repo secret)~~ update: this is still blocked
by procurement, will be done in a future PR
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-08-22 19:03:29 +02:00
|
|
|
from django.db.utils import IntegrityError
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
from apps.base.utils import LiveSettingValidator
|
|
|
|
|
from common.public_primary_keys import generate_public_primary_key, increase_public_primary_key_length
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_public_primary_key_for_live_setting():
|
|
|
|
|
prefix = "L"
|
|
|
|
|
new_public_primary_key = generate_public_primary_key(prefix)
|
|
|
|
|
|
|
|
|
|
failure_counter = 0
|
|
|
|
|
while LiveSetting.objects.filter(public_primary_key=new_public_primary_key).exists():
|
|
|
|
|
new_public_primary_key = increase_public_primary_key_length(
|
|
|
|
|
failure_counter=failure_counter, prefix=prefix, model_name="LiveSetting"
|
|
|
|
|
)
|
|
|
|
|
failure_counter += 1
|
|
|
|
|
|
|
|
|
|
return new_public_primary_key
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LiveSetting(models.Model):
|
|
|
|
|
public_primary_key = models.CharField(
|
|
|
|
|
max_length=20,
|
|
|
|
|
validators=[MinLengthValidator(settings.PUBLIC_PRIMARY_KEY_MIN_LENGTH + 1)],
|
|
|
|
|
unique=True,
|
|
|
|
|
default=generate_public_primary_key_for_live_setting,
|
|
|
|
|
)
|
|
|
|
|
name = models.CharField(max_length=50, unique=True)
|
|
|
|
|
value = JSONField(null=True, default=None)
|
|
|
|
|
error = models.TextField(null=True, default=None)
|
|
|
|
|
|
|
|
|
|
AVAILABLE_NAMES = (
|
2022-10-19 12:32:56 +01:00
|
|
|
"EMAIL_HOST",
|
|
|
|
|
"EMAIL_PORT",
|
|
|
|
|
"EMAIL_HOST_USER",
|
|
|
|
|
"EMAIL_HOST_PASSWORD",
|
|
|
|
|
"EMAIL_USE_TLS",
|
2024-02-20 08:38:09 +00:00
|
|
|
"EMAIL_USE_SSL",
|
2022-11-03 16:18:37 +00:00
|
|
|
"EMAIL_FROM_ADDRESS",
|
2023-03-16 05:59:21 +00:00
|
|
|
"INBOUND_EMAIL_ESP",
|
|
|
|
|
"INBOUND_EMAIL_DOMAIN",
|
|
|
|
|
"INBOUND_EMAIL_WEBHOOK_SECRET",
|
2022-06-03 08:09:47 -06:00
|
|
|
"TWILIO_ACCOUNT_SID",
|
|
|
|
|
"TWILIO_AUTH_TOKEN",
|
2022-10-11 14:47:16 -06:00
|
|
|
"TWILIO_API_KEY_SID",
|
|
|
|
|
"TWILIO_API_KEY_SECRET",
|
2022-06-03 08:09:47 -06:00
|
|
|
"TWILIO_NUMBER",
|
|
|
|
|
"TWILIO_VERIFY_SERVICE_SID",
|
|
|
|
|
"TELEGRAM_TOKEN",
|
2022-06-13 16:39:58 -06:00
|
|
|
"TELEGRAM_WEBHOOK_HOST",
|
2022-06-03 08:09:47 -06:00
|
|
|
"SLACK_CLIENT_OAUTH_ID",
|
|
|
|
|
"SLACK_CLIENT_OAUTH_SECRET",
|
|
|
|
|
"SLACK_SIGNING_SECRET",
|
2022-06-13 15:33:56 +03:00
|
|
|
"SLACK_INSTALL_RETURN_REDIRECT_HOST",
|
2022-06-03 08:09:47 -06:00
|
|
|
"SEND_ANONYMOUS_USAGE_STATS",
|
|
|
|
|
"GRAFANA_CLOUD_ONCALL_TOKEN",
|
|
|
|
|
"GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED",
|
2022-06-03 14:59:43 -03:00
|
|
|
"GRAFANA_CLOUD_NOTIFICATIONS_ENABLED",
|
2022-08-02 14:20:18 +04:00
|
|
|
"DANGEROUS_WEBHOOKS_ENABLED",
|
2023-05-24 14:27:48 +08:00
|
|
|
"PHONE_PROVIDER",
|
2023-07-05 08:55:53 +03:00
|
|
|
"ZVONOK_API_KEY",
|
|
|
|
|
"ZVONOK_CAMPAIGN_ID",
|
|
|
|
|
"ZVONOK_AUDIO_ID",
|
|
|
|
|
"ZVONOK_SPEAKER_ID",
|
|
|
|
|
"ZVONOK_POSTBACK_CALL_ID",
|
|
|
|
|
"ZVONOK_POSTBACK_CAMPAIGN_ID",
|
|
|
|
|
"ZVONOK_POSTBACK_STATUS",
|
|
|
|
|
"ZVONOK_POSTBACK_USER_CHOICE",
|
|
|
|
|
"ZVONOK_POSTBACK_USER_CHOICE_ACK",
|
2024-06-04 08:34:57 +03:00
|
|
|
"ZVONOK_VERIFICATION_CAMPAIGN_ID",
|
2024-06-06 11:49:02 +05:30
|
|
|
"EXOTEL_ACCOUNT_SID",
|
|
|
|
|
"EXOTEL_API_KEY",
|
|
|
|
|
"EXOTEL_API_TOKEN",
|
|
|
|
|
"EXOTEL_APP_ID",
|
|
|
|
|
"EXOTEL_CALLER_ID",
|
|
|
|
|
"EXOTEL_SMS_SENDER_ID",
|
|
|
|
|
"EXOTEL_SMS_VERIFICATION_TEMPLATE",
|
|
|
|
|
"EXOTEL_SMS_DLT_ENTITY_ID",
|
2025-04-21 14:23:37 -03:00
|
|
|
"MATTERMOST_CLIENT_OAUTH_ID",
|
|
|
|
|
"MATTERMOST_CLIENT_OAUTH_SECRET",
|
|
|
|
|
"MATTERMOST_HOST",
|
|
|
|
|
"MATTERMOST_BOT_TOKEN",
|
|
|
|
|
"MATTERMOST_LOGIN_RETURN_REDIRECT_HOST",
|
|
|
|
|
"MATTERMOST_SIGNING_SECRET",
|
2022-06-03 08:09:47 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
DESCRIPTIONS = {
|
2022-10-19 12:32:56 +01:00
|
|
|
"EMAIL_HOST": "SMTP server host. This email server will be used to notify users via email.",
|
|
|
|
|
"EMAIL_PORT": "SMTP server port",
|
|
|
|
|
"EMAIL_HOST_USER": "SMTP server user",
|
|
|
|
|
"EMAIL_HOST_PASSWORD": "SMTP server password",
|
|
|
|
|
"EMAIL_USE_TLS": "SMTP enable/disable TLS",
|
2024-02-20 08:38:09 +00:00
|
|
|
"EMAIL_USE_SSL": "SMTP enable/disable SSL. Should be used mutually exclusively with EMAIL_USE_TLS.",
|
2022-11-03 16:18:37 +00:00
|
|
|
"EMAIL_FROM_ADDRESS": "Email address used to send emails. If not specified, EMAIL_HOST_USER will be used.",
|
2023-03-16 05:59:21 +00:00
|
|
|
"INBOUND_EMAIL_DOMAIN": "Inbound email domain",
|
|
|
|
|
"INBOUND_EMAIL_ESP": (
|
|
|
|
|
"Inbound email ESP name. "
|
|
|
|
|
"Available options: amazon_ses, mailgun, mailjet, mandrill, postal, postmark, sendgrid, sparkpost"
|
|
|
|
|
),
|
|
|
|
|
"INBOUND_EMAIL_WEBHOOK_SECRET": "Inbound email webhook secret",
|
2022-06-03 08:09:47 -06:00
|
|
|
"SLACK_SIGNING_SECRET": (
|
|
|
|
|
"Check <a href='"
|
2023-04-19 14:42:16 +05:30
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#slack-setup"
|
2022-08-11 17:29:11 +03:00
|
|
|
"' target='_blank'>instruction</a> for details how to set up Slack. "
|
2022-06-03 08:09:47 -06:00
|
|
|
"Slack secrets can't be verified on the backend, please try installing the Slack Bot "
|
2022-06-13 15:33:56 +03:00
|
|
|
"after you update them."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"SLACK_CLIENT_OAUTH_SECRET": (
|
|
|
|
|
"Check <a href='"
|
2023-04-19 14:42:16 +05:30
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#slack-setup"
|
2022-08-11 17:29:11 +03:00
|
|
|
"' target='_blank'>instruction</a> for details how to set up Slack. "
|
2022-06-03 08:09:47 -06:00
|
|
|
"Slack secrets can't be verified on the backend, please try installing the Slack Bot "
|
2022-06-13 15:33:56 +03:00
|
|
|
"after you update them."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"SLACK_CLIENT_OAUTH_ID": (
|
|
|
|
|
"Check <a href='"
|
2023-04-19 14:42:16 +05:30
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#slack-setup"
|
2022-08-11 17:29:11 +03:00
|
|
|
"' target='_blank'>instruction</a> for details how to set up Slack. "
|
2022-06-03 08:09:47 -06:00
|
|
|
"Slack secrets can't be verified on the backend, please try installing the Slack Bot "
|
2022-06-13 15:33:56 +03:00
|
|
|
"after you update them."
|
|
|
|
|
),
|
|
|
|
|
"SLACK_INSTALL_RETURN_REDIRECT_HOST": (
|
|
|
|
|
"Check <a href='"
|
2023-04-19 14:42:16 +05:30
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#slack-setup"
|
2022-08-11 17:29:11 +03:00
|
|
|
"' target='_blank'>instruction</a> for details how to set up Slack. "
|
2022-06-13 15:33:56 +03:00
|
|
|
"Slack secrets can't be verified on the backend, please try installing the Slack Bot "
|
|
|
|
|
"after you update them."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"TWILIO_ACCOUNT_SID": (
|
2022-10-12 11:01:17 +02:00
|
|
|
"Twilio account SID/username to allow OnCall to send SMSes and make phone calls, see "
|
2022-08-11 17:29:11 +03:00
|
|
|
"<a href='https://support.twilio.com/hc/en-us/articles/223136027-Auth-Tokens-and-How-to-Change-Them' target='_blank'>"
|
2022-10-12 11:01:17 +02:00
|
|
|
"here</a> for more info. Required."
|
2022-10-11 14:47:16 -06:00
|
|
|
),
|
|
|
|
|
"TWILIO_API_KEY_SID": (
|
2022-10-18 16:05:49 -06:00
|
|
|
"Twilio API key SID/username to allow OnCall to send SMSes and make phone calls, see "
|
2022-10-11 14:47:16 -06:00
|
|
|
"<a href='https://www.twilio.com/docs/iam/keys/api-key' target='_blank'>"
|
2022-10-12 11:01:17 +02:00
|
|
|
"here</a> for more info. Either (TWILIO_API_KEY_SID + TWILIO_API_KEY_SECRET) or TWILIO_AUTH_TOKEN is required."
|
2022-10-11 14:47:16 -06:00
|
|
|
),
|
|
|
|
|
"TWILIO_API_KEY_SECRET": (
|
2022-10-18 16:05:49 -06:00
|
|
|
"Twilio API key secret/password to allow OnCall to send SMSes and make phone calls, see "
|
2022-10-11 14:47:16 -06:00
|
|
|
"<a href='https://www.twilio.com/docs/iam/keys/api-key' target='_blank'>"
|
2022-10-12 11:01:17 +02:00
|
|
|
"here</a> for more info. Either (TWILIO_API_KEY_SID + TWILIO_API_KEY_SECRET) or TWILIO_AUTH_TOKEN is required."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"TWILIO_AUTH_TOKEN": (
|
2022-10-18 16:05:49 -06:00
|
|
|
"Twilio password to allow OnCall to send SMSes and make calls, see "
|
2022-08-11 17:29:11 +03:00
|
|
|
"<a href='https://support.twilio.com/hc/en-us/articles/223136027-Auth-Tokens-and-How-to-Change-Them' target='_blank'>"
|
2022-10-12 11:01:17 +02:00
|
|
|
"here</a> for more info. Either (TWILIO_API_KEY_SID + TWILIO_API_KEY_SECRET) or TWILIO_AUTH_TOKEN is required."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"TWILIO_NUMBER": (
|
2022-10-18 16:05:49 -06:00
|
|
|
"Number from which you will receive calls and SMSes, "
|
2022-08-11 17:29:11 +03:00
|
|
|
"<a href='https://www.twilio.com/docs/phone-numbers' target='_blank'>more info</a>."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"TWILIO_VERIFY_SERVICE_SID": (
|
|
|
|
|
"SID of Twilio service for number verification. "
|
|
|
|
|
"You can create a service in Twilio web interface. "
|
|
|
|
|
"twilio.com -> verify -> create new service."
|
|
|
|
|
),
|
|
|
|
|
"TELEGRAM_TOKEN": (
|
2022-08-11 17:29:11 +03:00
|
|
|
"Secret token for Telegram bot, you can get one via <a href='https://t.me/BotFather' target='_blank'>BotFather</a>."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
2022-06-13 16:39:58 -06:00
|
|
|
"TELEGRAM_WEBHOOK_HOST": (
|
2022-08-02 10:57:12 +01:00
|
|
|
"Externally available URL for Telegram to make requests. Must use https and ports 80, 88, 443, 8443."
|
2022-06-13 16:39:58 -06:00
|
|
|
),
|
2022-06-03 08:09:47 -06:00
|
|
|
"SEND_ANONYMOUS_USAGE_STATS": (
|
|
|
|
|
"Grafana OnCall will send anonymous, but uniquely-identifiable usage analytics to Grafana Labs."
|
2022-06-14 09:14:45 -06:00
|
|
|
" These statistics are sent to https://stats.grafana.org/. For more information on what's sent, look at the "
|
2022-08-11 17:29:11 +03:00
|
|
|
"<a href='https://github.com/grafana/oncall/blob/dev/engine/apps/oss_installation/usage_stats.py#L29' target='_blank'> source code</a>."
|
2022-06-03 08:09:47 -06:00
|
|
|
),
|
|
|
|
|
"GRAFANA_CLOUD_ONCALL_TOKEN": "Secret token for Grafana Cloud OnCall instance.",
|
2022-06-25 11:19:40 +02:00
|
|
|
"GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED": "Enable heartbeat integration with Grafana Cloud OnCall.",
|
2022-06-03 14:59:43 -03:00
|
|
|
"GRAFANA_CLOUD_NOTIFICATIONS_ENABLED": "Enable SMS/call notifications via Grafana Cloud OnCall",
|
2022-08-02 14:20:18 +04:00
|
|
|
"DANGEROUS_WEBHOOKS_ENABLED": "Enable outgoing webhooks to private networks",
|
2023-05-24 14:27:48 +08:00
|
|
|
"PHONE_PROVIDER": f"Phone provider name. Available options: {','.join(list(settings.PHONE_PROVIDERS.keys()))}",
|
2023-07-05 08:55:53 +03:00
|
|
|
"ZVONOK_API_KEY": "API public key. You can get it in Profile->Settings section.",
|
|
|
|
|
"ZVONOK_CAMPAIGN_ID": "Calls by API campaign ID. You can get it after campaign creation.",
|
|
|
|
|
"ZVONOK_AUDIO_ID": "Calls with specific audio. You can get it in Audioclips section.",
|
|
|
|
|
"ZVONOK_SPEAKER_ID": "Calls with speaker.",
|
|
|
|
|
"ZVONOK_POSTBACK_CALL_ID": "'Postback' call id (ct_call_id) query parameter name to validate a postback request.",
|
|
|
|
|
"ZVONOK_POSTBACK_CAMPAIGN_ID": "'Postback' company id (ct_campaign_id) query parameter name to validate a postback request.",
|
|
|
|
|
"ZVONOK_POSTBACK_STATUS": "'Postback' status (ct_status) query parameter name to validate a postback request.",
|
|
|
|
|
"ZVONOK_POSTBACK_USER_CHOICE": "'Postback' user choice (ct_user_choice) query parameter name (optional).",
|
|
|
|
|
"ZVONOK_POSTBACK_USER_CHOICE_ACK": "'Postback' user choice (ct_user_choice) query parameter value for acknowledge alert group (optional).",
|
2024-06-04 08:34:57 +03:00
|
|
|
"ZVONOK_VERIFICATION_CAMPAIGN_ID": "The phone number verification campaign ID. You can get it after verification campaign creation.",
|
2024-06-06 11:49:02 +05:30
|
|
|
"EXOTEL_ACCOUNT_SID": "Exotel account SID. You can get it in DEVELOPER SETTINGS -> API Settings",
|
|
|
|
|
"EXOTEL_API_KEY": "API Key (username)",
|
|
|
|
|
"EXOTEL_API_TOKEN": "API Token (password)",
|
|
|
|
|
"EXOTEL_APP_ID": "Identifier of the flow (or applet)",
|
|
|
|
|
"EXOTEL_CALLER_ID": "Exophone / Exotel virtual number",
|
|
|
|
|
"EXOTEL_SMS_SENDER_ID": "Exotel SMS Sender ID to use for verification SMS",
|
|
|
|
|
"EXOTEL_SMS_VERIFICATION_TEMPLATE": "SMS text template to be used for sending SMS, add $verification_code as a placeholder for the verification code",
|
|
|
|
|
"EXOTEL_SMS_DLT_ENTITY_ID": "DLT Entity ID registered with TRAI.",
|
2025-04-21 14:23:37 -03:00
|
|
|
"MATTERMOST_CLIENT_OAUTH_ID": (
|
|
|
|
|
"Check <a href='"
|
|
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#mattermost-setup"
|
|
|
|
|
"' target='_blank'>instruction</a> for details how to set up Mattermost. "
|
|
|
|
|
),
|
|
|
|
|
"MATTERMOST_CLIENT_OAUTH_SECRET": (
|
|
|
|
|
"Check <a href='"
|
|
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#mattermost-setup"
|
|
|
|
|
"' target='_blank'>instruction</a> for details how to set up Mattermost. "
|
|
|
|
|
),
|
|
|
|
|
"MATTERMOST_HOST": (
|
|
|
|
|
"Check <a href='"
|
|
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#mattermost-setup"
|
|
|
|
|
"' target='_blank'>instruction</a> for details how to set up Mattermost. "
|
|
|
|
|
),
|
|
|
|
|
"MATTERMOST_BOT_TOKEN": (
|
|
|
|
|
"Check <a href='"
|
|
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#mattermost-setup"
|
|
|
|
|
"' target='_blank'>instruction</a> for details how to set up Mattermost. "
|
|
|
|
|
),
|
|
|
|
|
"MATTERMOST_LOGIN_RETURN_REDIRECT_HOST": (
|
|
|
|
|
"Check <a href='"
|
|
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#mattermost-setup"
|
|
|
|
|
"' target='_blank'>instruction</a> for details how to set up Mattermost. "
|
|
|
|
|
),
|
|
|
|
|
"MATTERMOST_SIGNING_SECRET": (
|
|
|
|
|
"Check <a href='"
|
|
|
|
|
"https://grafana.com/docs/oncall/latest/open-source/#mattermost-setup"
|
|
|
|
|
"' target='_blank'>instruction</a> for details how to set up Mattermost. "
|
|
|
|
|
),
|
2022-06-03 08:09:47 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SECRET_SETTING_NAMES = (
|
2022-10-19 12:32:56 +01:00
|
|
|
"EMAIL_HOST_PASSWORD",
|
2023-03-16 05:59:21 +00:00
|
|
|
"INBOUND_EMAIL_WEBHOOK_SECRET",
|
2022-06-03 08:09:47 -06:00
|
|
|
"TWILIO_ACCOUNT_SID",
|
|
|
|
|
"TWILIO_AUTH_TOKEN",
|
2022-10-18 16:05:49 -06:00
|
|
|
"TWILIO_API_KEY_SID",
|
|
|
|
|
"TWILIO_API_KEY_SECRET",
|
2022-06-03 08:09:47 -06:00
|
|
|
"TWILIO_VERIFY_SERVICE_SID",
|
|
|
|
|
"SLACK_CLIENT_OAUTH_ID",
|
|
|
|
|
"SLACK_CLIENT_OAUTH_SECRET",
|
|
|
|
|
"SLACK_SIGNING_SECRET",
|
|
|
|
|
"TELEGRAM_TOKEN",
|
|
|
|
|
"GRAFANA_CLOUD_ONCALL_TOKEN",
|
2023-07-05 08:55:53 +03:00
|
|
|
"ZVONOK_API_KEY",
|
2024-06-06 11:49:02 +05:30
|
|
|
"EXOTEL_ACCOUNT_SID",
|
|
|
|
|
"EXOTEL_API_TOKEN",
|
2025-04-21 14:23:37 -03:00
|
|
|
"MATTERMOST_CLIENT_OAUTH_ID",
|
|
|
|
|
"MATTERMOST_CLIENT_OAUTH_SECRET",
|
|
|
|
|
"MATTERMOST_BOT_TOKEN",
|
2022-06-03 08:09:47 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def description(self):
|
|
|
|
|
return self.DESCRIPTIONS.get(self.name)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def default_value(self):
|
|
|
|
|
return self._get_setting_from_setting_file(self.name)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def is_secret(self):
|
|
|
|
|
return self.name in self.SECRET_SETTING_NAMES
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def get_setting(cls, setting_name):
|
|
|
|
|
if not settings.FEATURE_LIVE_SETTINGS_ENABLED:
|
|
|
|
|
return cls._get_setting_from_setting_file(setting_name)
|
|
|
|
|
|
|
|
|
|
if setting_name not in cls.AVAILABLE_NAMES:
|
|
|
|
|
raise ValueError(
|
|
|
|
|
f"Setting with name '{setting_name}' is not in list of available names {cls.AVAILABLE_NAMES}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
live_setting = cls.objects.filter(name=setting_name).first()
|
|
|
|
|
if live_setting is not None:
|
|
|
|
|
return live_setting.value
|
|
|
|
|
else:
|
|
|
|
|
return cls._get_setting_from_setting_file(setting_name)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def populate_settings_if_needed(cls):
|
|
|
|
|
settings_in_db = cls.objects.filter(name__in=cls.AVAILABLE_NAMES).values_list("name", flat=True)
|
|
|
|
|
setting_names_to_populate = set(cls.AVAILABLE_NAMES) - set(settings_in_db)
|
2022-10-20 10:11:36 -06:00
|
|
|
if len(setting_names_to_populate) == 0:
|
|
|
|
|
return
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
for setting_name in setting_names_to_populate:
|
fix a few flaky e2e tests + allow running project locally via k8s/helm (#2751)
# What this PR does
- updates the GitHub Actions workflow to move the e2e tests into a
"[reusable
workflow](https://docs.github.com/en/actions/using-workflows/reusing-workflows#creating-a-reusable-workflow)"
which are run in two scenarios:
- all tests _except_ those annotated as `@expensive` are run against
`grafana/grafana:latest` on all feature branches
- all tests _including_ `@expensive` tests are run on weekdays @ 07h00
UTC, against a matrix of 6 grafana versions. Results of these builds
will be posted to `#irm-amixr-flux` Slack channel.
- local development will now be:
```bash
make build-dev-images init-k8s start-k8s
```
- `build-dev-images` - builds the engine and UI docker images (only need
to run first time)
- `init-k8s` - creates a `kind` cluster and loads the two Docker images
onto the cluster nodes (only need to run first time)
- `start-k8s` - switches `kubectl` context to the created `kind`
cluster, and uses `helm` to deploy everything as defined in
`./dev/helm-local.yml` and `./dev/helm-local.dev.yml` (that latter file
is `.gitignored` and specific to how _you_ want your setup to look like.
Hot reloading works as before. This is the _start_ of #2381. (I've
marked these `make` commands as beta, because they've not yet been
thoroughly tested for local development).
- modifies the `helm` chart to add the concept of `oncall.devMode`,
`ui`, and ability to run oncall w/ sqlite
- `oncall.devMode` will essentially just add `volumes` and
`volumeMounts` to the various engine/migrate containers +
- `ui.enabled` + `ui.env` - create a ui container (which is needed for
hot reloading locally)
- `sqlite` - this was useful for the e2e test environments where Github
runner resources are scarce. Running `mariadb` eats up precious
resources, instead lets just use sqlite here
- fixes an issue that caused sporadic HTTP 502s from the grafana
plugin-proxy, which led to flaky tests. See [this
comment](https://github.com/grafana/oncall/pull/2751/files#diff-09040e8df192699b9c5742110ebbe8d9d5c3938cb156cc1cb99fa1c3fdee4fefR72-R77)
for more context + a link to a relevant Slack conversation. **tldr;**
there is a bug with the Grafana plugin proxy in Grafana >= v10.0.3.
Let's stop using the `latest`/`main` docker tags in our test and pin to
`10.0.2` for now
- ~~re-enables the e2e test which validates a phone number via SMS, and
asserts that we can receive an alert escalation via SMS (new Mailslurp
API Key has been added as a repo secret)~~ update: this is still blocked
by procurement, will be done in a future PR
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-08-22 19:03:29 +02:00
|
|
|
try:
|
|
|
|
|
cls.objects.create(name=setting_name, value=cls._get_setting_from_setting_file(setting_name))
|
|
|
|
|
except IntegrityError:
|
|
|
|
|
# prevent the rare case where concurrent requests try inserting the same live setting and lead to:
|
|
|
|
|
# django.db.utils.IntegrityError: duplicate key value violates unique constraint "base_livesetting_name_key"
|
|
|
|
|
# this infers that a setting with this name already exists, and we can safely skip this
|
|
|
|
|
continue
|
2022-10-18 16:05:49 -06:00
|
|
|
|
2022-11-01 18:24:44 -06:00
|
|
|
cls.validate_settings()
|
2022-10-18 16:05:49 -06:00
|
|
|
|
|
|
|
|
@classmethod
|
2022-11-01 18:24:44 -06:00
|
|
|
def validate_settings(cls):
|
2024-06-04 20:06:59 +01:00
|
|
|
settings_to_validate = cls.objects.filter(name__in=cls.AVAILABLE_NAMES)
|
2022-10-20 10:11:36 -06:00
|
|
|
for setting in settings_to_validate:
|
2023-06-06 16:18:12 +01:00
|
|
|
setting.error = LiveSettingValidator(live_setting=setting).get_error()
|
2022-10-18 16:05:49 -06:00
|
|
|
setting.save(update_fields=["error"])
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _get_setting_from_setting_file(setting_name):
|
|
|
|
|
return getattr(settings, setting_name)
|
|
|
|
|
|
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
|
if self.name not in self.AVAILABLE_NAMES:
|
|
|
|
|
raise ValueError(
|
|
|
|
|
f"Setting with name '{self.name}' is not in list of available names {self.AVAILABLE_NAMES}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
super().save(*args, **kwargs)
|