def create_alert_rule_trigger( alert_rule, label, threshold_type, alert_threshold, resolve_threshold=None, excluded_projects=None, actions=None, ): """ Creates a new AlertRuleTrigger :param alert_rule: The alert rule to create the trigger for :param label: A description of the trigger :param threshold_type: An AlertRuleThresholdType :param alert_threshold: Value that the subscription needs to reach to trigger the alert rule :param resolve_threshold: Optional value that the subscription needs to reach to resolve the alert :param excluded_projects: A list of Projects that should be excluded from this trigger. These projects must be associate with the alert rule already :param actions: A list of alert rule trigger actions for this trigger :return: The created AlertRuleTrigger """ if AlertRuleTrigger.objects.filter(alert_rule=alert_rule, label=label).exists(): raise AlertRuleTriggerLabelAlreadyUsedError() excluded_subs = [] if excluded_projects: excluded_subs = get_subscriptions_from_alert_rule( alert_rule, excluded_projects) with transaction.atomic(): trigger = AlertRuleTrigger.objects.create( alert_rule=alert_rule, label=label, threshold_type=threshold_type.value, alert_threshold=alert_threshold, resolve_threshold=resolve_threshold, ) if excluded_subs: new_exclusions = [ AlertRuleTriggerExclusion(alert_rule_trigger=trigger, query_subscription=sub) for sub in excluded_subs ] AlertRuleTriggerExclusion.objects.bulk_create(new_exclusions) if actions: for action_data in actions: create_alert_rule_trigger_action(trigger=trigger, **action_data) return trigger
def update_alert_rule_trigger( trigger, label=None, threshold_type=None, alert_threshold=None, resolve_threshold=None, excluded_projects=None, ): """ :param trigger: The AlertRuleTrigger to update :param label: A description of the trigger :param threshold_type: An AlertRuleThresholdType :param alert_threshold: Value that the subscription needs to reach to trigger the alert rule :param resolve_threshold: Optional value that the subscription needs to reach to resolve the alert :param excluded_projects: A list of Projects that should be excluded from this trigger. These projects must be associate with the alert rule already :return: The updated AlertRuleTrigger """ if (AlertRuleTrigger.objects.filter( alert_rule=trigger.alert_rule, label=label).exclude(id=trigger.id).exists()): raise AlertRuleTriggerLabelAlreadyUsedError() updated_fields = {} if label is not None: updated_fields["label"] = label if threshold_type is not None: updated_fields["threshold_type"] = threshold_type.value if alert_threshold is not None: updated_fields["alert_threshold"] = alert_threshold # We set resolve_threshold to None as a 'reset', in case it was previously a value and we're removing it here. updated_fields["resolve_threshold"] = resolve_threshold deleted_exclusion_ids = [] new_subs = [] if excluded_projects: # We link projects to exclusions via QuerySubscriptions. Calculate which # exclusions need to be deleted, and which need to be created. excluded_subs = get_subscriptions_from_alert_rule( trigger.alert_rule, excluded_projects) existing_exclusions = AlertRuleTriggerExclusion.objects.filter( alert_rule_trigger=trigger) new_sub_ids = {sub.id for sub in excluded_subs} existing_sub_ids = { exclusion.query_subscription_id for exclusion in existing_exclusions } deleted_exclusion_ids = [ e.id for e in existing_exclusions if e.query_subscription_id not in new_sub_ids ] new_subs = [ sub for sub in excluded_subs if sub.id not in existing_sub_ids ] with transaction.atomic(): if updated_fields: trigger.update(**updated_fields) if deleted_exclusion_ids: AlertRuleTriggerExclusion.objects.filter( id__in=deleted_exclusion_ids).delete() if new_subs: new_exclusions = [ AlertRuleTriggerExclusion(alert_rule_trigger=trigger, query_subscription=sub) for sub in new_subs ] AlertRuleTriggerExclusion.objects.bulk_create(new_exclusions) return trigger
def update_alert_rule_trigger( trigger, label=None, threshold_type=None, alert_threshold=None, resolve_threshold=None, excluded_projects=None, actions=None, ): """ :param trigger: The AlertRuleTrigger to update :param label: A description of the trigger :param threshold_type: An AlertRuleThresholdType :param alert_threshold: Value that the subscription needs to reach to trigger the alert rule :param resolve_threshold: Optional value that the subscription needs to reach to resolve the alert :param excluded_projects: A list of Projects that should be excluded from this trigger. These projects must be associate with the alert rule already :param actions: A list of alert rule trigger actions for this trigger :return: The updated AlertRuleTrigger """ if (AlertRuleTrigger.objects.filter( alert_rule=trigger.alert_rule, label=label).exclude(id=trigger.id).exists()): raise AlertRuleTriggerLabelAlreadyUsedError() updated_fields = {} if label is not None: updated_fields["label"] = label if threshold_type is not None: updated_fields["threshold_type"] = threshold_type.value if alert_threshold is not None: updated_fields["alert_threshold"] = alert_threshold if resolve_threshold is not None: updated_fields["resolve_threshold"] = resolve_threshold deleted_exclusion_ids = [] new_subs = [] if excluded_projects: # We link projects to exclusions via QuerySubscriptions. Calculate which # exclusions need to be deleted, and which need to be created. excluded_subs = get_subscriptions_from_alert_rule( trigger.alert_rule, excluded_projects) existing_exclusions = AlertRuleTriggerExclusion.objects.filter( alert_rule_trigger=trigger) new_sub_ids = {sub.id for sub in excluded_subs} existing_sub_ids = { exclusion.query_subscription_id for exclusion in existing_exclusions } deleted_exclusion_ids = [ e.id for e in existing_exclusions if e.query_subscription_id not in new_sub_ids ] new_subs = [ sub for sub in excluded_subs if sub.id not in existing_sub_ids ] with transaction.atomic(): if updated_fields: trigger.update(**updated_fields) if deleted_exclusion_ids: AlertRuleTriggerExclusion.objects.filter( id__in=deleted_exclusion_ids).delete() if new_subs: new_exclusions = [ AlertRuleTriggerExclusion(alert_rule_trigger=trigger, query_subscription=sub) for sub in new_subs ] AlertRuleTriggerExclusion.objects.bulk_create(new_exclusions) if actions is not None: # Delete actions we don't have present in the updated data. action_ids = [x["id"] for x in actions if "id" in x] AlertRuleTriggerAction.objects.filter( alert_rule_trigger=trigger).exclude( id__in=action_ids).delete() for action_data in actions: if "id" in action_data: action_instance = AlertRuleTriggerAction.objects.get( alert_rule_trigger=trigger, id=action_data["id"]) action_data.pop("id") update_alert_rule_trigger_action(action_instance, **action_data) else: create_alert_rule_trigger_action(trigger=trigger, **action_data) return trigger