diff --git a/engine/apps/api/views/live_setting.py b/engine/apps/api/views/live_setting.py
index d2c77ab0..8040ee48 100644
--- a/engine/apps/api/views/live_setting.py
+++ b/engine/apps/api/views/live_setting.py
@@ -38,40 +38,40 @@ class LiveSettingViewSet(PublicPrimaryKeyMixin, viewsets.ModelViewSet):
return queryset
def perform_update(self, serializer):
+ name = serializer.instance.name
old_value = serializer.instance.value
new_value = serializer.validated_data["value"]
super().perform_update(serializer)
if new_value != old_value:
- self._post_update_hook(old_value)
+ self._post_update_hook(name, old_value)
def perform_destroy(self, instance):
+ name = instance.name
old_value = instance.value
new_value = instance.default_value
super().perform_destroy(instance)
if new_value != old_value:
- self._post_update_hook(old_value)
+ self._post_update_hook(name, old_value)
- def _post_update_hook(self, old_value):
- instance = self.get_object()
-
- if instance.name == "TELEGRAM_TOKEN":
+ def _post_update_hook(self, name, old_value):
+ if name == "TELEGRAM_TOKEN":
self._reset_telegram_integration(old_token=old_value)
register_telegram_webhook.delay()
- if instance.name == "TELEGRAM_WEBHOOK_HOST":
+ if name == "TELEGRAM_WEBHOOK_HOST":
register_telegram_webhook.delay()
- if instance.name in ["SLACK_CLIENT_OAUTH_ID", "SLACK_CLIENT_OAUTH_SECRET"]:
+ if name in ["SLACK_CLIENT_OAUTH_ID", "SLACK_CLIENT_OAUTH_SECRET"]:
organization = self.request.auth.organization
slack_team_identity = organization.slack_team_identity
if slack_team_identity is not None:
unpopulate_slack_user_identities.delay(organization_pk=organization.pk, force=True)
- if instance.name == "GRAFANA_CLOUD_ONCALL_TOKEN":
+ if name == "GRAFANA_CLOUD_ONCALL_TOKEN":
from apps.oss_installation.models import CloudConnector
CloudConnector.remove_sync()
diff --git a/engine/apps/base/models/live_setting.py b/engine/apps/base/models/live_setting.py
index 770e3eb4..f69c25a3 100644
--- a/engine/apps/base/models/live_setting.py
+++ b/engine/apps/base/models/live_setting.py
@@ -87,22 +87,22 @@ class LiveSetting(models.Model):
"here for more info. Required."
),
"TWILIO_API_KEY_SID": (
- "Twilio API key SID/username to allow OnCall to send SMSes and make phone calls, see"
+ "Twilio API key SID/username to allow OnCall to send SMSes and make phone calls, see "
""
"here for more info. Either (TWILIO_API_KEY_SID + TWILIO_API_KEY_SECRET) or TWILIO_AUTH_TOKEN is required."
),
"TWILIO_API_KEY_SECRET": (
- "Twilio API key secret/password to allow OnCall to send SMSes and make phone calls, see"
+ "Twilio API key secret/password to allow OnCall to send SMSes and make phone calls, see "
""
"here for more info. Either (TWILIO_API_KEY_SID + TWILIO_API_KEY_SECRET) or TWILIO_AUTH_TOKEN is required."
),
"TWILIO_AUTH_TOKEN": (
- "Twilio password to allow OnCall to send SMSes and make calls, "
+ "Twilio password to allow OnCall to send SMSes and make calls, see "
""
"here for more info. Either (TWILIO_API_KEY_SID + TWILIO_API_KEY_SECRET) or TWILIO_AUTH_TOKEN is required."
),
"TWILIO_NUMBER": (
- "Number from which you will receive calls and SMS, "
+ "Number from which you will receive calls and SMSes, "
"more info."
),
"TWILIO_VERIFY_SERVICE_SID": (
@@ -140,6 +140,8 @@ class LiveSetting(models.Model):
SECRET_SETTING_NAMES = (
"TWILIO_ACCOUNT_SID",
"TWILIO_AUTH_TOKEN",
+ "TWILIO_API_KEY_SID",
+ "TWILIO_API_KEY_SECRET",
"TWILIO_VERIFY_SERVICE_SID",
"SENDGRID_API_KEY",
"SENDGRID_SECRET_KEY",
@@ -186,8 +188,21 @@ class LiveSetting(models.Model):
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)
+ revalidate_twilio = False
for setting_name in setting_names_to_populate:
- cls.objects.create(name=setting_name, value=cls._get_setting_from_setting_file(setting_name))
+ setting = cls.objects.create(name=setting_name, value=cls._get_setting_from_setting_file(setting_name))
+ if setting.name.startswith("TWILIO"):
+ revalidate_twilio = True
+
+ if revalidate_twilio:
+ cls.revalidate_twilio()
+
+ @classmethod
+ def revalidate_twilio(cls):
+ twilio_settings = cls.objects.filter(name__startswith="TWILIO")
+ for setting in twilio_settings:
+ setting.error = LiveSettingValidator(live_setting=setting).get_error()
+ setting.save(update_fields=["error"])
@staticmethod
def _get_setting_from_setting_file(setting_name):
diff --git a/engine/apps/base/utils.py b/engine/apps/base/utils.py
index e57a78d7..377dd443 100644
--- a/engine/apps/base/utils.py
+++ b/engine/apps/base/utils.py
@@ -34,13 +34,20 @@ live_settings = LiveSettingProxy()
class LiveSettingValidator:
+
+ EMPTY_VALID_NAMES = (
+ "TWILIO_AUTH_TOKEN",
+ "TWILIO_API_KEY_SID",
+ "TWILIO_API_KEY_SECRET",
+ )
+
def __init__(self, live_setting):
self.live_setting = live_setting
def get_error(self):
check_fn_name = f"_check_{self.live_setting.name.lower()}"
- if self.live_setting.value is None:
+ if self.live_setting.value is None and self.live_setting.name not in self.EMPTY_VALID_NAMES:
return "Empty"
# skip validation if there's no handler for it