def test_wrapped_remove_none_b(): alert_group = AlertGroup.construct( common_labels={ "tim": "schwenke", "hans": "meier", }, alerts=[ Alert.construct( labels={ "tim": "schwenke", "hans": "meier", "ronald": "fritz", "ute": "schneider", }), Alert.construct(labels={ "tim": "schwenke", "hans": "meier", "furz": "ernst", }), ], ) a = None b = Remove(re_labels=[re.compile("^(tim|hans|ute|furz|soda)$")]) actions.wrapped_remove(a, b, alert_group) assert alert_group.common_labels == {} assert alert_group.alerts[0].labels == {"ronald": "fritz"} assert alert_group.alerts[1].labels == {}
def test_remove_re(): target = "labels" keys = [re.compile("^(tim|hans|ute|furz|soda)$")] alert_group = AlertGroup.construct( **{ f"common_{target}": { "tim": "schwenke", "hans": "meier", }, "alerts": [ Alert.construct( **{ target: { "tim": "schwenke", "hans": "meier", "ronald": "fritz", "ute": "schneider", } }), Alert.construct( **{ target: { "tim": "schwenke", "hans": "meier", "furz": "ernst", } }), ], }) actions._remove_re(target, keys, alert_group) assert alert_group.__dict__[f"common_{target}"] == {} assert alert_group.alerts[0].__dict__[target] == {"ronald": "fritz"} assert alert_group.alerts[1].__dict__[target] == {}
def test_add_specific_annotations(): alert_group = AlertGroup.construct( common_labels={ "alertname": "JustATestAlert", "namespace": "whatever/promstack", "severity": "info", }, common_annotations={ "investigate_link": "https://domain.com/grafanMz/container-intra", "summary": "Ratio(Max(Working Set, RSS) / Reservation) [5m Avg] \\u003c 40 %", "title": "Memory: Relativ memory usage low", }, alerts=[ Alert.construct( labels={ "alertname": "JustATestAlert", "name": "grafana", "namespace": "whatever/promstack", "severity": "info", }, annotations={ "description": "Lorem ipsum dolor sit", "investigate_link": "https://domain.com/grafanainer-intra", "summary": "Ratio(Max(Working Set, RSS) / Reserg] \\u003c 40 %", "title": "Memory: Relativ memory usage low", "specific": "specific", "very_specific": "very_specific", }, ), Alert.construct( labels={ "alertname": "JustATestAlert", "name": "grafana", "namespace": "whatever/promstack", "severity": "info", }, annotations={ "description": "Lorem ipsum dolor sit amete value 2.", "investigate_link": "https://domain.com/graontainer-intra", "summary": "Ratio(Max(Workition) [5m Avg] \\u003c 40 %", "title": "Memory: Relativ memory usage low", }, ), ], ) utils.add_specific(alert_group) assert alert_group.alerts[0].specific_annotations["specific"] == "specific" assert alert_group.alerts[0].specific_annotations[ "very_specific"] == "very_specific" assert alert_group.alerts[0].specific_annotations is not None assert alert_group.alerts[1].specific_annotations is not None assert alert_group.alerts[0].specific_labels is not None assert alert_group.alerts[1].specific_labels is not None
def test_create_alert_group_single_alert(helpers): base = AlertGroup.construct( **{ "blabla": "blabladfefef", "groupKeys": { "fefefe": "fefefwe", }, "group_labels": { "will": "do" }, }) alerts = [ Alert.construct( **{ "what": "ever", "annotations": { "a": "aa", "b": "bb", }, "labels": {}, }), Alert.construct( **{ "annotations": { "a": "aa", "b": "bb", }, "labels": { "c": "cc", "d": "dd", }, }), ] alert_group = splitting._create_alert_group(base, alerts) helpers.print_struct(alert_group, "data") assert alert_group.blabla == "blabladfefef" assert alert_group.groupKeys == {"fefefe": "fefefwe"} assert alert_group.common_annotations == { "a": "aa", "b": "bb", } assert alert_group.common_labels == {} assert alert_group.alerts[0] == { "what": "ever", "annotations": { "a": "aa", "b": "bb", }, "labels": {}, } assert alert_group.group_labels == {}
def test_create_data_dict_two_alerts(caplog, helpers): base = AlertGroup.construct( **{ "blabla": "blabladfefef", "groupKeys": { "fefefe": "fefefwe", }, "group_labels": { "hot": "hotv" }, }) alerts = [ Alert.construct( **{ "what": "ever", "annotations": { "red": "redv", "blue": "bluev", "anno": "foo", }, "labels": { "hot": "hotv", "cold": "coldv", }, }), Alert.construct( **{ "what": "ever", "annotations": { "orange": "orangev", "green": "greenv", "blue": "somethingelse", "red": "redv", "anno": "foo", }, "labels": { "c": "cc", "hot": "hotv", "d": "dd", }, }), ] alert_group = splitting._create_alert_group(base, alerts) helpers.print_struct(alert_group, "alert_group") assert alert_group.common_annotations == {"anno": "foo", "red": "redv"} assert alert_group.common_labels == {"hot": "hotv"} assert alert_group.group_labels == {"hot": "hotv"}
def _override( target: Literal["annotations", "labels"], items: dict[str, str], alert_group: AlertGroup, ) -> None: """Adds and overrides annotations / labels in-place from alert group. Args: target (Literal["annotations", "labels"]): What to target. items (dict[str, str]): Items to override and add. alert_group (AlertGroup): Alert group to work with. """ for name, value in items.items(): alert_group.__dict__[f"common_{target}"][name] = value for alert in alert_group.alerts: alert.__dict__[target][name] = value
def test_wrapped_remove_a_b(): alert_group = AlertGroup.construct( common_annotations={}, common_labels={ "tim": "schwenke", "hans": "meier", }, alerts=[ Alert.construct( annotations={}, labels={ "tim": "schwenke", "hans": "meier", "ronald": "fritz", "ute": "schneider", }, ), Alert.construct( annotations={}, labels={ "tim": "schwenke", "hans": "meier", "furz": "ernst", }, ), ], ) a = Remove( labels=["ute", "tim", "furz"], annotations=["ute", "tim", "furz"], ) b = Remove( re_annotations=[re.compile("^(tim|hans)$")], re_labels=[re.compile("^(tim|hans)$")], ) actions.wrapped_remove(a, b, alert_group) assert alert_group.common_annotations == {} assert alert_group.common_labels == {} assert alert_group.alerts[0].annotations == {} assert alert_group.alerts[0].labels == {"ronald": "fritz"} assert alert_group.alerts[1].annotations == {} assert alert_group.alerts[1].labels == {}
def test_wrapped_override_a_b(): alert_group = AlertGroup.construct( common_labels={ "tim": "schwenke", }, alerts=[ Alert.construct(labels={ "tim": "schwenke", "ute": "meier", "frank": "sohn", }), Alert.construct(labels={ "tim": "schwenke", }), ], ) a = Override(labels={ "tim": "schwonkel", "ute": "freier", }) b = Override(labels={ "ute": "freier", "frank": "sohn", }) actions.wrapped_override(a, b, alert_group) assert alert_group.common_labels == { "tim": "schwonkel", "ute": "freier", "frank": "sohn", } assert alert_group.alerts[0].labels == { "tim": "schwonkel", "ute": "freier", "frank": "sohn", } assert alert_group.alerts[1].labels == { "tim": "schwonkel", "ute": "freier", "frank": "sohn", }
def test_wrapped_remove_none_none(): alert_group = AlertGroup.construct( common_labels={ "tim": "schwenke", "hans": "meier", }, alerts=[ Alert.construct( labels={ "tim": "schwenke", "hans": "meier", "ronald": "fritz", "ute": "schneider", }), Alert.construct(labels={ "tim": "schwenke", "hans": "meier", "furz": "ernst", }), ], ) a = None b = None actions.wrapped_remove(a, b, alert_group) assert alert_group.common_labels == { "tim": "schwenke", "hans": "meier", } assert alert_group.alerts[0].labels == { "tim": "schwenke", "hans": "meier", "ronald": "fritz", "ute": "schneider", } assert alert_group.alerts[1].labels == { "tim": "schwenke", "hans": "meier", "furz": "ernst", }
def test_override(): alert_group = AlertGroup.construct( common_labels={ "tim": "schwenke", }, alerts=[ Alert.construct(labels={ "tim": "schwenke", "ute": "meier", "frank": "sohn", }), Alert.construct(labels={ "tim": "schwenke", }), ], ) actions._override( "labels", { "tim": "schwonkel", "ute": "freier", "frank": "sohn", }, alert_group, ) assert alert_group.common_labels == { "tim": "schwonkel", "ute": "freier", "frank": "sohn", } assert alert_group.alerts[0].labels == { "tim": "schwonkel", "ute": "freier", "frank": "sohn", } assert alert_group.alerts[1].labels == { "tim": "schwonkel", "ute": "freier", "frank": "sohn", }
def test_wrapped_add_a1_a2(): alert_group = AlertGroup.construct( common_labels={ "tim": "schwenke", }, alerts=[ Alert.construct(labels={ "tim": "schwenke", "ute": "meier", "frank": "sohn", }), Alert.construct(labels={ "tim": "schwenke", }), ], ) a1 = Add(labels={ "tim": "schwonkel", "ute": "freier", }) a2 = Add(labels={ "ute": "freier", "frank": "sohn", }) actions.wrapped_add(a1, a2, alert_group) assert alert_group.common_labels == { "tim": "schwenke", "frank": "sohn", } assert alert_group.alerts[0].labels == { "tim": "schwenke", "ute": "meier", "frank": "sohn", } assert alert_group.alerts[1].labels == { "tim": "schwenke", "ute": "freier", "frank": "sohn", }
def preprocess(routing: Routing, route: Route, alert_group: AlertGroup) -> list[EnhancedAlertGroup]: """Preprocess payload from Alertmanager. Args: routing (Routing): Routing related settings. route (Route): Route related settings. data (AlertGroup): Alertmanager payload. Returns: list[EnhancedAlertGroup]: List of one or more alert group. List will only contain more than one if the `split_by` feature is used. """ wrapped_remove(routing.remove, route.remove, alert_group) wrapped_add(routing.add, route.add, alert_group) wrapped_override(routing.override, route.override, alert_group) alert_groups = (split(route.split_by.target, route.split_by.value, alert_group) if route.split_by else [alert_group]) enhanced_alert_groups = [] for alert_group in alert_groups: add_specific(alert_group) enhanced_alerts = [ EnhancedAlert.construct(**alert.dict()) for alert in alert_group.alerts ] del alert_group.alerts enhanced_alert_group = EnhancedAlertGroup.construct( **alert_group.dict()) enhanced_alert_group.alerts = enhanced_alerts enhanced_alert_group.targets = [ target.copy() for target in route.targets ] enhanced_alert_groups.append(enhanced_alert_group) return enhanced_alert_groups
def _add( target: Literal["annotations", "labels"], items: dict[str, str], alert_group: AlertGroup, ) -> None: """Adds annotations / labels in-place from alert group without updating. Args: target (Literal["annotations", "labels"]): What to target. items (dict[str, str]): Items to add. alert_group (AlertGroup): Alert group to work with. """ for name, value in items.items(): unique_values = set() for alert in alert_group.alerts: elements = alert.__dict__[target] if name not in elements: elements[name] = value unique_values.add(value) else: unique_values.add(elements[name]) if len(unique_values) == 1 and value in unique_values: alert_group.__dict__[f"common_{target}"][name] = value
def _create_alert_group(base: AlertGroup, alerts: list[Alert]) -> AlertGroup: base = base.copy() base.alerts = alerts if len(alerts) > 1: list_of_sets_of_keys = [ set(alert.annotations.keys()) for alert in alerts ] common_keys = set.intersection(*list_of_sets_of_keys) for common_key in list(common_keys): values = {alert.annotations[common_key] for alert in alerts} if len(values) > 1: common_keys.remove(common_key) base.common_annotations = { key: alerts[0].annotations[key] for key in common_keys } else: base.common_annotations = alerts[0].annotations if len(alerts) > 1: list_of_sets_of_keys = [set(alert.labels.keys()) for alert in alerts] common_keys = set.intersection(*list_of_sets_of_keys) for common_key in list(common_keys): values = {alert.labels[common_key] for alert in alerts} if len(values) > 1: common_keys.remove(common_key) base.common_labels = { key: alerts[0].labels[key] for key in common_keys } else: base.common_labels = alerts[0].labels for key in list(base.group_labels.keys()): if key not in base.common_labels: del base.group_labels[key] return base
def test_split(caplog, helpers): alert_group = AlertGroup.construct( **{ "receiver": "cisco webex", "status": "firing", "group_labels": { "alertname": "JustATestAlert", "namespace": "whatever/promstack", }, "common_labels": { "alertname": "JustATestAlert", "namespace": "whatever/promstack", "severity": "info", }, "common_annotations": { "investigate_link": "https://domain.com/grafana/d/fdwTIxFMz/container-intra", "summary": "Ratio(Max(Working Set, RSS) / Reservation) [5m Avg] \\u003c 40 %", "title": "Memory: Relativ memory usage low", }, "alerts": [ Alert.construct(**{ "labels": {}, "annotations": { "common": "common", }, }), Alert.construct( **{ "labels": {}, "annotations": { "common": "common", "whatever": "fefe", }, }), Alert.construct(**{ "labels": { "very": "unique" }, "annotations": {}, }), ], }) alert_groups = splitting.split("annotation", "common", alert_group) helpers.print_struct(alert_groups, "alert_groups") assert alert_groups[0].receiver == "cisco webex" assert alert_groups[0].group_labels == {} assert alert_groups[0].alerts == [ Alert.construct(**{ "labels": { "very": "unique" }, "annotations": {}, }) ] assert alert_groups[1].common_annotations == {"common": "common"} assert alert_groups[0].common_annotations == {}
def test_preprocess(helpers): routing = Routing( remove=Remove( annotations=["vw", "audi"], labels=["heinz"], re_annotations=["^(mercedes)$", "^__.*$"], re_labels=["^__.*$"], ), add=Add( annotations={"bmw": "value"}, labels={"simon": "humben"}, ), override=Override( annotations={"yung": "hurn"}, labels={"old": "barn"}, ), ) route = Route( name="whatever", add=Add( annotations={"bmw": "value"}, labels={"simon": "klumpen"}, ), ) alert_group = AlertGroup.construct( group_labels={"alertname": "WhatEver"}, common_labels={ "heinz": "meier", "__meta": "x", "severity": "warning" }, common_annotations={ "vw": "x", }, alerts=[ Alert.construct( labels={ "heinz": "meier", "__meta": "x", "severity": "warning", "yung": "barn", }, annotations={ "vw": "x", "audi": "x", "yung": "barn", }, ), Alert.construct( labels={ "heinz": "meier", "simon": "fart", "__meta": "x", "severity": "warning", }, annotations={ "vw": "x", }, ), ], ) alertgroup = preprocess(routing, route, alert_group)[0] helpers.print_struct(alertgroup) assert alertgroup.common_labels == { "severity": "warning", "old": "barn", } assert alertgroup.common_annotations == { "bmw": "value", "yung": "hurn", } assert alertgroup.alerts[0].labels == { "severity": "warning", "yung": "barn", "old": "barn", "simon": "klumpen", } assert alertgroup.alerts[0].annotations == { "yung": "hurn", "bmw": "value", } assert alertgroup.alerts[1].labels == { "simon": "fart", "severity": "warning", "simon": "fart", "old": "barn", } assert alertgroup.alerts[1].annotations == { "bmw": "value", "yung": "hurn", }