From fda05a6cc43b509b8aed651355a659e558a1aca9 Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 20 Nov 2024 11:17:04 -0500 Subject: [PATCH] chore: remove deprecated `slack_channel` and `heartbeat` integration types (#5270) # What this PR does See [Slack discussion](https://raintank-corp.slack.com/archives/C06K1MQ07GS/p1732110700877869) for more context ## 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] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes. --- dev/helm-local.yml | 2 +- .../alerts/models/alert_receive_channel.py | 18 +++----- ...rtbeat_actual_check_up_task_id_and_more.py | 23 ++++++++++ engine/apps/heartbeat/models.py | 10 ----- engine/apps/heartbeat/tasks.py | 6 --- engine/apps/heartbeat/tests/factories.py | 2 - engine/apps/integrations/tasks.py | 5 +-- .../public_api/tests/test_integrations.py | 1 - .../apps/slack/alert_group_slack_service.py | 5 +-- .../apps/slack/scenarios/distribute_alerts.py | 18 +------- engine/config_integrations/heartbeat.py | 29 ------------ engine/config_integrations/slack_channel.py | 44 ------------------- engine/settings/base.py | 2 - engine/settings/celery_task_routes.py | 1 - 14 files changed, 33 insertions(+), 133 deletions(-) create mode 100644 engine/apps/heartbeat/migrations/0003_remove_integrationheartbeat_actual_check_up_task_id_and_more.py delete mode 100644 engine/config_integrations/heartbeat.py delete mode 100644 engine/config_integrations/slack_channel.py diff --git a/dev/helm-local.yml b/dev/helm-local.yml index 8655df43..770a5dfb 100644 --- a/dev/helm-local.yml +++ b/dev/helm-local.yml @@ -39,7 +39,7 @@ engine: replicaCount: 1 celery: replicaCount: 1 - worker_beat_enabled: false + worker_beat_enabled: true externalGrafana: url: http://grafana:3000 diff --git a/engine/apps/alerts/models/alert_receive_channel.py b/engine/apps/alerts/models/alert_receive_channel.py index a8cb1494..7a351d2a 100644 --- a/engine/apps/alerts/models/alert_receive_channel.py +++ b/engine/apps/alerts/models/alert_receive_channel.py @@ -525,29 +525,21 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject): ) @property - def short_name_with_maintenance_status(self): - if self.maintenance_mode is not None: - return ( - self.short_name + f" *[ on " - f"{AlertReceiveChannel.MAINTENANCE_MODE_CHOICES[self.maintenance_mode][1]}" - f" :construction: ]*" - ) - else: - return self.short_name - - @property - def created_name(self): + def created_name(self) -> str: return f"{self.get_integration_display()} {self.smile_code}" @property def web_link(self) -> str: return UIURLBuilder(self.organization).integration_detail(self.public_primary_key) + @property + def is_maintenace_integration(self) -> bool: + return self.integration == AlertReceiveChannel.INTEGRATION_MAINTENANCE + @property def integration_url(self) -> str | None: if self.integration in [ AlertReceiveChannel.INTEGRATION_MANUAL, - AlertReceiveChannel.INTEGRATION_SLACK_CHANNEL, AlertReceiveChannel.INTEGRATION_INBOUND_EMAIL, AlertReceiveChannel.INTEGRATION_MAINTENANCE, ]: diff --git a/engine/apps/heartbeat/migrations/0003_remove_integrationheartbeat_actual_check_up_task_id_and_more.py b/engine/apps/heartbeat/migrations/0003_remove_integrationheartbeat_actual_check_up_task_id_and_more.py new file mode 100644 index 00000000..e50d915e --- /dev/null +++ b/engine/apps/heartbeat/migrations/0003_remove_integrationheartbeat_actual_check_up_task_id_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.16 on 2024-11-20 15:39 + +from django.db import migrations +import django_migration_linter as linter + + +class Migration(migrations.Migration): + + dependencies = [ + ('heartbeat', '0002_delete_heartbeat'), + ] + + operations = [ + linter.IgnoreMigration(), + migrations.RemoveField( + model_name='integrationheartbeat', + name='actual_check_up_task_id', + ), + migrations.RemoveField( + model_name='integrationheartbeat', + name='last_checkup_task_time', + ), + ] diff --git a/engine/apps/heartbeat/models.py b/engine/apps/heartbeat/models.py index 0c0084bd..4688cc71 100644 --- a/engine/apps/heartbeat/models.py +++ b/engine/apps/heartbeat/models.py @@ -48,16 +48,6 @@ class IntegrationHeartBeat(models.Model): Stores the latest received heartbeat signal time """ - last_checkup_task_time = models.DateTimeField(default=None, null=True) - """ - Deprecated. This field is not used. TODO: remove it - """ - - actual_check_up_task_id = models.CharField(max_length=100) - """ - Deprecated. Stored the latest scheduled `integration_heartbeat_checkup` task id. TODO: remove it - """ - previous_alerted_state_was_life = models.BooleanField(default=True) """ Last status of the heartbeat. Determines if integration was alive on latest checkup diff --git a/engine/apps/heartbeat/tasks.py b/engine/apps/heartbeat/tasks.py index 7939290e..e9d26c57 100644 --- a/engine/apps/heartbeat/tasks.py +++ b/engine/apps/heartbeat/tasks.py @@ -105,12 +105,6 @@ def check_heartbeats() -> str: return f"Found {expired_count} expired and {restored_count} restored heartbeats" -@shared_dedicated_queue_retry_task() -def integration_heartbeat_checkup(heartbeat_id: int) -> None: - """Deprecated. TODO: Remove this task after this task cleared from queue""" - pass - - @shared_dedicated_queue_retry_task() def process_heartbeat_task(alert_receive_channel_pk): IntegrationHeartBeat.objects.filter( diff --git a/engine/apps/heartbeat/tests/factories.py b/engine/apps/heartbeat/tests/factories.py index 5e69db9d..40011255 100644 --- a/engine/apps/heartbeat/tests/factories.py +++ b/engine/apps/heartbeat/tests/factories.py @@ -4,7 +4,5 @@ from apps.heartbeat.models import IntegrationHeartBeat class IntegrationHeartBeatFactory(factory.DjangoModelFactory): - actual_check_up_task_id = "none" - class Meta: model = IntegrationHeartBeat diff --git a/engine/apps/integrations/tasks.py b/engine/apps/integrations/tasks.py index 45f3e04f..91f6a7d4 100644 --- a/engine/apps/integrations/tasks.py +++ b/engine/apps/integrations/tasks.py @@ -31,10 +31,7 @@ def create_alertmanager_alerts(alert_receive_channel_pk, alert, is_demo=False, r from apps.alerts.models import Alert, AlertReceiveChannel alert_receive_channel = AlertReceiveChannel.objects_with_deleted.get(pk=alert_receive_channel_pk) - if ( - alert_receive_channel.deleted_at is not None - or alert_receive_channel.integration == AlertReceiveChannel.INTEGRATION_MAINTENANCE - ): + if alert_receive_channel.deleted_at is not None or alert_receive_channel.is_maintenace_integration: logger.info("AlertReceiveChannel alert ignored if deleted/maintenance") return diff --git a/engine/apps/public_api/tests/test_integrations.py b/engine/apps/public_api/tests/test_integrations.py index 796942eb..9a4e29c6 100644 --- a/engine/apps/public_api/tests/test_integrations.py +++ b/engine/apps/public_api/tests/test_integrations.py @@ -903,7 +903,6 @@ def test_get_list_integrations_link_and_inbound_email( if integration_type in [ AlertReceiveChannel.INTEGRATION_MANUAL, - AlertReceiveChannel.INTEGRATION_SLACK_CHANNEL, AlertReceiveChannel.INTEGRATION_MAINTENANCE, ]: assert integration_link is None diff --git a/engine/apps/slack/alert_group_slack_service.py b/engine/apps/slack/alert_group_slack_service.py index 9bb9510b..ed614305 100644 --- a/engine/apps/slack/alert_group_slack_service.py +++ b/engine/apps/slack/alert_group_slack_service.py @@ -35,9 +35,8 @@ class AlertGroupSlackService: self._slack_client = SlackClient(slack_team_identity) def update_alert_group_slack_message(self, alert_group: "AlertGroup") -> None: - from apps.alerts.models import AlertReceiveChannel - logger.info(f"Update message for alert_group {alert_group.pk}") + try: self._slack_client.chat_update( channel=alert_group.slack_message.channel_id, @@ -47,7 +46,7 @@ class AlertGroupSlackService: ) logger.info(f"Message has been updated for alert_group {alert_group.pk}") except SlackAPIRatelimitError as e: - if alert_group.channel.integration != AlertReceiveChannel.INTEGRATION_MAINTENANCE: + if not alert_group.channel.is_maintenace_integration: if not alert_group.channel.is_rate_limited_in_slack: alert_group.channel.start_send_rate_limit_message_task(e.retry_after) logger.info( diff --git a/engine/apps/slack/scenarios/distribute_alerts.py b/engine/apps/slack/scenarios/distribute_alerts.py index 3a7090e3..3d3c1a60 100644 --- a/engine/apps/slack/scenarios/distribute_alerts.py +++ b/engine/apps/slack/scenarios/distribute_alerts.py @@ -141,22 +141,6 @@ class AlertShootingStep(scenario_step.ScenarioStep): channel_id=channel_id, ) - # If alert was made out of a message: - if alert_group.channel.integration == AlertReceiveChannel.INTEGRATION_SLACK_CHANNEL: - channel = json.loads(alert.integration_unique_data)["channel"] - result = self._slack_client.chat_postMessage( - channel=channel, - thread_ts=json.loads(alert.integration_unique_data)["ts"], - text=":rocket: <{}|Incident registered!>".format(alert_group.slack_message.permalink), - team=slack_team_identity, - ) - alert_group.slack_messages.create( - slack_id=result["ts"], - organization=alert_group.channel.organization, - _slack_team_identity=self.slack_team_identity, - channel_id=channel, - ) - alert.delivered = True except SlackAPITokenError: alert_group.reason_to_skip_escalation = AlertGroup.ACCOUNT_INACTIVE @@ -172,7 +156,7 @@ class AlertShootingStep(scenario_step.ScenarioStep): logger.info("Not delivering alert due to channel is archived.") except SlackAPIRatelimitError as e: # don't rate limit maintenance alert - if alert_group.channel.integration != AlertReceiveChannel.INTEGRATION_MAINTENANCE: + if not alert_group.channel.is_maintenace_integration: alert_group.reason_to_skip_escalation = AlertGroup.RATE_LIMITED alert_group.save(update_fields=["reason_to_skip_escalation"]) alert_group.channel.start_send_rate_limit_message_task(e.retry_after) diff --git a/engine/config_integrations/heartbeat.py b/engine/config_integrations/heartbeat.py deleted file mode 100644 index 60699c45..00000000 --- a/engine/config_integrations/heartbeat.py +++ /dev/null @@ -1,29 +0,0 @@ -# Main -enabled = True -title = "Heartbeat" -slug = "heartbeat" -short_description = None -description = None -is_displayed_on_web = False -is_featured = False -is_able_to_autoresolve = True -is_demo_alert_enabled = False - -description = None - -# Default templates -slack_title = """\ -*<{{ grafana_oncall_link }}|#{{ grafana_oncall_incident_id }} {{ payload.get("title", "Title undefined (check Slack Title Template)") }}>* via {{ integration_name }} -{% if source_link %} - (*<{{ source_link }}|source>*) -{%- endif %}""" - -grouping_id = """\ -{{ payload.get("id", "") }}{{ payload.get("user_defined_id", "") }} -""" - -resolve_condition = '{{ payload.get("is_resolve", False) == True }}' - -acknowledge_condition = None - -example_payload = None diff --git a/engine/config_integrations/slack_channel.py b/engine/config_integrations/slack_channel.py deleted file mode 100644 index 05021935..00000000 --- a/engine/config_integrations/slack_channel.py +++ /dev/null @@ -1,44 +0,0 @@ -# Main -enabled = True -title = "Slack Channel" -slug = "slack_channel" -short_description = None -description = None -is_displayed_on_web = False -is_featured = False -is_able_to_autoresolve = False -is_demo_alert_enabled = False - -description = None - -# Default templates -slack_title = """\ -{% if source_link -%} -*<{{ source_link }}|<#{{ payload.get("channel", "") }}>>* -{%- else -%} -<#{{ payload.get("channel", "") }}> -{%- endif %}""" - -web_title = """\ -{% if source_link -%} -[#{{ grafana_oncall_incident_id }}]{{ source_link }}) <#{{ payload.get("channel", "") }}>>* -{%- else -%} -*#{{ grafana_oncall_incident_id }}* <#{{ payload.get("channel", "") }}> -{%- endif %}""" - -telegram_title = """\ -{% if source_link -%} -#{{ grafana_oncall_incident_id }} {{ payload.get("channel", "") }} -{%- else -%} -*#{{ grafana_oncall_incident_id }}* <#{{ payload.get("channel", "") }}> -{%- endif %}""" - -grouping_id = '{{ payload.get("ts", "") }}' - -resolve_condition = None - -acknowledge_condition = None - -source_link = '{{ payload.get("amixr_mixin", {}).get("permalink", "")}}' - -example_payload = None diff --git a/engine/settings/base.py b/engine/settings/base.py index 2b3cc971..0f73c8d5 100644 --- a/engine/settings/base.py +++ b/engine/settings/base.py @@ -878,11 +878,9 @@ INSTALLED_ONCALL_INTEGRATIONS = [ "config_integrations.formatted_webhook", "config_integrations.kapacitor", "config_integrations.elastalert", - "config_integrations.heartbeat", "config_integrations.inbound_email", "config_integrations.maintenance", "config_integrations.manual", - "config_integrations.slack_channel", "config_integrations.zabbix", "config_integrations.direct_paging", # Actually it's Grafana 8 integration. diff --git a/engine/settings/celery_task_routes.py b/engine/settings/celery_task_routes.py index 04a8ffa4..7ef62121 100644 --- a/engine/settings/celery_task_routes.py +++ b/engine/settings/celery_task_routes.py @@ -12,7 +12,6 @@ CELERY_TASK_ROUTES = { "common.oncall_gateway.tasks.delete_oncall_connector_async": {"queue": "default"}, "common.oncall_gateway.tasks.create_slack_connector_async_v2": {"queue": "default"}, "common.oncall_gateway.tasks.delete_slack_connector_async_v2": {"queue": "default"}, - "apps.heartbeat.tasks.integration_heartbeat_checkup": {"queue": "default"}, "apps.heartbeat.tasks.process_heartbeat_task": {"queue": "default"}, "apps.labels.tasks.update_labels_cache": {"queue": "default"}, "apps.labels.tasks.update_instances_labels_cache": {"queue": "default"},