diff --git a/engine/apps/alerts/models/alert.py b/engine/apps/alerts/models/alert.py index 060c961b..afb4a9e4 100644 --- a/engine/apps/alerts/models/alert.py +++ b/engine/apps/alerts/models/alert.py @@ -12,6 +12,7 @@ from django.db.models import JSONField from apps.alerts import tasks from apps.alerts.constants import TASK_DELAY_SECONDS from apps.alerts.incident_appearance.templaters import TemplateLoader +from apps.labels.utils import assign_labels from common.jinja_templater import apply_jinja_template from common.jinja_templater.apply_jinja_template import JinjaTemplateError, JinjaTemplateWarning from common.public_primary_keys import generate_public_primary_key, increase_public_primary_key_length @@ -107,6 +108,7 @@ class Alert(models.Model): ) if group_created: + assign_labels(group, alert_receive_channel) group.log_records.create(type=AlertGroupLogRecord.TYPE_REGISTERED) group.log_records.create(type=AlertGroupLogRecord.TYPE_ROUTE_ASSIGNED) diff --git a/engine/apps/labels/tests/test_alert_group.py b/engine/apps/labels/tests/test_alert_group.py new file mode 100644 index 00000000..d022926c --- /dev/null +++ b/engine/apps/labels/tests/test_alert_group.py @@ -0,0 +1,48 @@ +from unittest import mock + +import pytest + +from apps.alerts.models import Alert + + +@mock.patch("apps.labels.utils.is_labels_feature_enabled", return_value=False) +@pytest.mark.django_db +def test_assign_labels_feature_flag_disabled( + _, make_organization, make_alert_receive_channel, make_integration_label_association +): + organization = make_organization() + alert_receive_channel = make_alert_receive_channel(organization) + make_integration_label_association(organization, alert_receive_channel) + + alert = Alert.create( + title="the title", + message="the message", + alert_receive_channel=alert_receive_channel, + raw_request_data={}, + integration_unique_data={}, + image_url=None, + link_to_upstream_details=None, + ) + + assert not alert.group.labels.exists() + + +@pytest.mark.django_db +def test_assign_labels(make_organization, make_alert_receive_channel, make_integration_label_association): + organization = make_organization() + alert_receive_channel = make_alert_receive_channel(organization) + label = make_integration_label_association(organization, alert_receive_channel) + + alert = Alert.create( + title="the title", + message="the message", + alert_receive_channel=alert_receive_channel, + raw_request_data={}, + integration_unique_data={}, + image_url=None, + link_to_upstream_details=None, + ) + + assert alert.group.labels.count() == 1 + assert alert.group.labels.first().key_name == label.key.name + assert alert.group.labels.first().value_name == label.value.name diff --git a/engine/apps/labels/utils.py b/engine/apps/labels/utils.py index 56b0a1ad..b26e6c63 100644 --- a/engine/apps/labels/utils.py +++ b/engine/apps/labels/utils.py @@ -1,13 +1,13 @@ -import logging import typing from django.apps import apps # noqa: I251 from django.conf import settings if typing.TYPE_CHECKING: + from apps.alerts.models import AlertGroup, AlertReceiveChannel from apps.labels.models import AssociatedLabel + from apps.user_management.models import Organization -logger = logging.getLogger(__name__) LABEL_OUTDATED_TIMEOUT_MINUTES = 30 ASSOCIATED_MODEL_NAME = "AssociatedLabel" @@ -42,19 +42,28 @@ def get_associating_label_model(obj_model_name: str) -> typing.Type["AssociatedL return label_model -def is_labels_feature_enabled(organization) -> bool: - """ - Checks if labels feature enabled for all organizations (FEATURE_LABELS_ENABLED_FOR_ALL). - If not, checks if current organization's grafana org_id is in the list of organizations labels feature enabled for - (FEATURE_LABELS_ENABLED_FOR_GRAFANA_ORGS) - """ - logger.info( - "is_labels_feature_enabled: " - f"FEATURE_LABELS_ENABLED_FOR_ALL={settings.FEATURE_LABELS_ENABLED_FOR_ALL}, " - f"organization in FEATURE_LABELS_ENABLED_FOR_GRAFANA_ORGS=" - f"{organization.id in settings.FEATURE_LABELS_ENABLED_FOR_GRAFANA_ORGS}, " - f"organization={organization.id}" +def is_labels_feature_enabled(organization: "Organization") -> bool: + return ( + settings.FEATURE_LABELS_ENABLED_FOR_ALL + or organization.org_id in settings.FEATURE_LABELS_ENABLED_FOR_GRAFANA_ORGS # Grafana org ID, not OnCall org ID ) - if not settings.FEATURE_LABELS_ENABLED_FOR_ALL: - return organization.org_id in settings.FEATURE_LABELS_ENABLED_FOR_GRAFANA_ORGS - return settings.FEATURE_LABELS_ENABLED_FOR_ALL + + +def assign_labels(alert_group: "AlertGroup", alert_receive_channel: "AlertReceiveChannel") -> None: + from apps.labels.models import AlertGroupAssociatedLabel + + if not is_labels_feature_enabled(alert_receive_channel.organization): + return + + # inherit all labels from the integration + # FIXME: this is a temporary solution before we have a UI for configuring inherited labels + alert_group_labels = [ + AlertGroupAssociatedLabel( + alert_group=alert_group, + organization=alert_receive_channel.organization, + key_name=label.key.name, + value_name=label.value.name, + ) + for label in alert_receive_channel.labels.all().select_related("key", "value") + ] + AlertGroupAssociatedLabel.objects.bulk_create(alert_group_labels) diff --git a/engine/common/utils.py b/engine/common/utils.py index c8287f6d..b169188d 100644 --- a/engine/common/utils.py +++ b/engine/common/utils.py @@ -8,6 +8,7 @@ import time from functools import reduce import factory +import faker import markdown2 from bs4 import BeautifulSoup from celery.utils.log import get_task_logger @@ -21,7 +22,7 @@ logger = get_task_logger(__name__) class UniqueFaker(factory.Faker): @classmethod def _get_faker(cls, locale=None): - return super()._get_faker(locale).unique + return faker.Faker(locale=locale).unique # Context manager for tasks that are intended to retry