oncall-engine/engine/apps/labels/utils.py
Innokentii Konstantinov acd0c44c33
Support prescribed labels (#3848)
# What this PR does

**Cleanup label typing:**
1. LabelParam -> two separate types LabekKey and LabelValue 
2. LabelData -> renamed to LabelPair. 
3. LabelKeyData -> renamed to LabelOption
Data is not giving any info about what this type represents. 
4. Remove LabelsData and LabelsKeysData types. They are just list of
types listed above and with new naming it feels obsolete.
5. ValueData removed. LabelPair is used instead.
6. Rework AlertGroupCustomLabel to use LabelKey type for key to make
type system more consistent. Name model type AlertGroupCustomLabel**DB**
and api type AlertGroupCustomLabel**API** to clearly distinguish them.

**Split update_labels_cache into two tasks** update_label_option_cache
and update_label_pairs_cache.
Original task was expecting array of LabelsData (now it's LabelPair) OR
one LabelKeyData ( now it's LabelOption). I believe having one function
with two sp different argument types makes it more complicated for
understanding.


**Make OnCall backend support prescribed labels**. OnCall will sync and
store "prescribed" field for key and values, so Label dropdown able to
disable editing for certain labels.

## Which issue(s) this PR fixes

## Checklist

- [x] Unit, integration, and e2e (if applicable) tests updated
- [ ] 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)

---------

Co-authored-by: Maxim Mordasov <maxim.mordasov@grafana.com>
Co-authored-by: Yulya Artyukhina <Ferril.darkdiver@gmail.com>
2024-02-20 14:42:51 +08:00

45 lines
1.7 KiB
Python

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
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"
def get_associating_label_model(obj_model_name: str) -> typing.Type["AssociatedLabel"]:
associating_label_model_name = obj_model_name + ASSOCIATED_MODEL_NAME
label_model = apps.get_model("labels", associating_label_model_name)
return label_model
def is_labels_feature_enabled(organization: "Organization") -> bool:
"""
is_labels_feature_enabled checks if env with labels feature is enabled and plugin is provisioned.
"""
env_enabled = settings.FEATURE_LABELS_ENABLED_FOR_ALL or organization.id in settings.FEATURE_LABELS_ENABLED_PER_ORG
return organization.is_grafana_labels_enabled and env_enabled
def get_labels_dict(labelable) -> dict[str, str]:
"""
get_labels_dict returns dict of labels' key and values names for the given object
"""
return {label.key.name: label.value.name for label in labelable.labels.all().select_related("key", "value")}
def get_alert_group_labels_dict(alert_group: "AlertGroup") -> dict[str, str]:
"""
get_alert_group_labels_dict returns dict of labels' key and values names for the given alert group.
It's different from get_labels_dict, because AlertGroupAssociated labels store key/value_name, not key/value_id
"""
return {label.key_name: label.value_name for label in alert_group.labels.all()}