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.
This commit is contained in:
parent
336b924a08
commit
fda05a6cc4
14 changed files with 33 additions and 133 deletions
|
|
@ -39,7 +39,7 @@ engine:
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
celery:
|
celery:
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
worker_beat_enabled: false
|
worker_beat_enabled: true
|
||||||
|
|
||||||
externalGrafana:
|
externalGrafana:
|
||||||
url: http://grafana:3000
|
url: http://grafana:3000
|
||||||
|
|
|
||||||
|
|
@ -525,29 +525,21 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def short_name_with_maintenance_status(self):
|
def created_name(self) -> str:
|
||||||
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):
|
|
||||||
return f"{self.get_integration_display()} {self.smile_code}"
|
return f"{self.get_integration_display()} {self.smile_code}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def web_link(self) -> str:
|
def web_link(self) -> str:
|
||||||
return UIURLBuilder(self.organization).integration_detail(self.public_primary_key)
|
return UIURLBuilder(self.organization).integration_detail(self.public_primary_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_maintenace_integration(self) -> bool:
|
||||||
|
return self.integration == AlertReceiveChannel.INTEGRATION_MAINTENANCE
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def integration_url(self) -> str | None:
|
def integration_url(self) -> str | None:
|
||||||
if self.integration in [
|
if self.integration in [
|
||||||
AlertReceiveChannel.INTEGRATION_MANUAL,
|
AlertReceiveChannel.INTEGRATION_MANUAL,
|
||||||
AlertReceiveChannel.INTEGRATION_SLACK_CHANNEL,
|
|
||||||
AlertReceiveChannel.INTEGRATION_INBOUND_EMAIL,
|
AlertReceiveChannel.INTEGRATION_INBOUND_EMAIL,
|
||||||
AlertReceiveChannel.INTEGRATION_MAINTENANCE,
|
AlertReceiveChannel.INTEGRATION_MAINTENANCE,
|
||||||
]:
|
]:
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -48,16 +48,6 @@ class IntegrationHeartBeat(models.Model):
|
||||||
Stores the latest received heartbeat signal time
|
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)
|
previous_alerted_state_was_life = models.BooleanField(default=True)
|
||||||
"""
|
"""
|
||||||
Last status of the heartbeat. Determines if integration was alive on latest checkup
|
Last status of the heartbeat. Determines if integration was alive on latest checkup
|
||||||
|
|
|
||||||
|
|
@ -105,12 +105,6 @@ def check_heartbeats() -> str:
|
||||||
return f"Found {expired_count} expired and {restored_count} restored heartbeats"
|
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()
|
@shared_dedicated_queue_retry_task()
|
||||||
def process_heartbeat_task(alert_receive_channel_pk):
|
def process_heartbeat_task(alert_receive_channel_pk):
|
||||||
IntegrationHeartBeat.objects.filter(
|
IntegrationHeartBeat.objects.filter(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,5 @@ from apps.heartbeat.models import IntegrationHeartBeat
|
||||||
|
|
||||||
|
|
||||||
class IntegrationHeartBeatFactory(factory.DjangoModelFactory):
|
class IntegrationHeartBeatFactory(factory.DjangoModelFactory):
|
||||||
actual_check_up_task_id = "none"
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IntegrationHeartBeat
|
model = IntegrationHeartBeat
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,7 @@ def create_alertmanager_alerts(alert_receive_channel_pk, alert, is_demo=False, r
|
||||||
from apps.alerts.models import Alert, AlertReceiveChannel
|
from apps.alerts.models import Alert, AlertReceiveChannel
|
||||||
|
|
||||||
alert_receive_channel = AlertReceiveChannel.objects_with_deleted.get(pk=alert_receive_channel_pk)
|
alert_receive_channel = AlertReceiveChannel.objects_with_deleted.get(pk=alert_receive_channel_pk)
|
||||||
if (
|
if alert_receive_channel.deleted_at is not None or alert_receive_channel.is_maintenace_integration:
|
||||||
alert_receive_channel.deleted_at is not None
|
|
||||||
or alert_receive_channel.integration == AlertReceiveChannel.INTEGRATION_MAINTENANCE
|
|
||||||
):
|
|
||||||
logger.info("AlertReceiveChannel alert ignored if deleted/maintenance")
|
logger.info("AlertReceiveChannel alert ignored if deleted/maintenance")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -903,7 +903,6 @@ def test_get_list_integrations_link_and_inbound_email(
|
||||||
|
|
||||||
if integration_type in [
|
if integration_type in [
|
||||||
AlertReceiveChannel.INTEGRATION_MANUAL,
|
AlertReceiveChannel.INTEGRATION_MANUAL,
|
||||||
AlertReceiveChannel.INTEGRATION_SLACK_CHANNEL,
|
|
||||||
AlertReceiveChannel.INTEGRATION_MAINTENANCE,
|
AlertReceiveChannel.INTEGRATION_MAINTENANCE,
|
||||||
]:
|
]:
|
||||||
assert integration_link is None
|
assert integration_link is None
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,8 @@ class AlertGroupSlackService:
|
||||||
self._slack_client = SlackClient(slack_team_identity)
|
self._slack_client = SlackClient(slack_team_identity)
|
||||||
|
|
||||||
def update_alert_group_slack_message(self, alert_group: "AlertGroup") -> None:
|
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}")
|
logger.info(f"Update message for alert_group {alert_group.pk}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._slack_client.chat_update(
|
self._slack_client.chat_update(
|
||||||
channel=alert_group.slack_message.channel_id,
|
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}")
|
logger.info(f"Message has been updated for alert_group {alert_group.pk}")
|
||||||
except SlackAPIRatelimitError as e:
|
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:
|
if not alert_group.channel.is_rate_limited_in_slack:
|
||||||
alert_group.channel.start_send_rate_limit_message_task(e.retry_after)
|
alert_group.channel.start_send_rate_limit_message_task(e.retry_after)
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -141,22 +141,6 @@ class AlertShootingStep(scenario_step.ScenarioStep):
|
||||||
channel_id=channel_id,
|
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
|
alert.delivered = True
|
||||||
except SlackAPITokenError:
|
except SlackAPITokenError:
|
||||||
alert_group.reason_to_skip_escalation = AlertGroup.ACCOUNT_INACTIVE
|
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.")
|
logger.info("Not delivering alert due to channel is archived.")
|
||||||
except SlackAPIRatelimitError as e:
|
except SlackAPIRatelimitError as e:
|
||||||
# don't rate limit maintenance alert
|
# 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.reason_to_skip_escalation = AlertGroup.RATE_LIMITED
|
||||||
alert_group.save(update_fields=["reason_to_skip_escalation"])
|
alert_group.save(update_fields=["reason_to_skip_escalation"])
|
||||||
alert_group.channel.start_send_rate_limit_message_task(e.retry_after)
|
alert_group.channel.start_send_rate_limit_message_task(e.retry_after)
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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 -%}
|
|
||||||
<a href="{{ source_link }}">#{{ grafana_oncall_incident_id }}</a> {{ 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
|
|
||||||
|
|
@ -878,11 +878,9 @@ INSTALLED_ONCALL_INTEGRATIONS = [
|
||||||
"config_integrations.formatted_webhook",
|
"config_integrations.formatted_webhook",
|
||||||
"config_integrations.kapacitor",
|
"config_integrations.kapacitor",
|
||||||
"config_integrations.elastalert",
|
"config_integrations.elastalert",
|
||||||
"config_integrations.heartbeat",
|
|
||||||
"config_integrations.inbound_email",
|
"config_integrations.inbound_email",
|
||||||
"config_integrations.maintenance",
|
"config_integrations.maintenance",
|
||||||
"config_integrations.manual",
|
"config_integrations.manual",
|
||||||
"config_integrations.slack_channel",
|
|
||||||
"config_integrations.zabbix",
|
"config_integrations.zabbix",
|
||||||
"config_integrations.direct_paging",
|
"config_integrations.direct_paging",
|
||||||
# Actually it's Grafana 8 integration.
|
# Actually it's Grafana 8 integration.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ CELERY_TASK_ROUTES = {
|
||||||
"common.oncall_gateway.tasks.delete_oncall_connector_async": {"queue": "default"},
|
"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.create_slack_connector_async_v2": {"queue": "default"},
|
||||||
"common.oncall_gateway.tasks.delete_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.heartbeat.tasks.process_heartbeat_task": {"queue": "default"},
|
||||||
"apps.labels.tasks.update_labels_cache": {"queue": "default"},
|
"apps.labels.tasks.update_labels_cache": {"queue": "default"},
|
||||||
"apps.labels.tasks.update_instances_labels_cache": {"queue": "default"},
|
"apps.labels.tasks.update_instances_labels_cache": {"queue": "default"},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue