0

This question is quite specific, I successfully done want I want but it's very specific to my use case and probably ugly for Python expert so I'me curious if it can be more generic and/or clever.

I need to edit prometheus alertmanager routing stored in yml file (documentation here)

In my use case my routing is (extract):

route:
  routes:
    - match:
        product: my_product
        stage: prod
      routes:
        - continue: true
          match_re:
            severity: (info|warning|critical)
          receiver: mattermost
        - continue: true
          match_re:
            severity: (warning|critical)
          receiver: mail_infra
        - match:
            severity: critical
          receiver: sms_voidandnany

I need to edit receiver "sms_voidandnany" (the receiver depend on a google calendar).

Here is my first draft:

with open('alertmanager.yml') as f:
    data = yaml.safe_load(f)
    routes=data['route']['routes']

    for item in routes:
        if item.get('match').get('product') == 'my_product' and item.get('match').get('stage') == 'prod':
            for subitem in item.get('routes'):
                if 'match' in subitem:
                    if subitem.get('match').get('severity') == 'critical':
                        subitem['receiver'] = 'sms_another_user'

with open("alertmanager2.yaml", "w") as f:
    yaml.dump(data, f)

3 ifs, 2 loops even me, not a python expert neither full time developer I think it's ugly.

Do you see a better way, more Pythonistic way to achieve that?

Cherry on the cake, do you think there a "simple" way to make replacement generic? Routing structure is dynamic, we can make routing - matching - routing - matching and so on... Recursive function?

martineau
  • 119,623
  • 25
  • 170
  • 301
voidAndAny
  • 147
  • 1
  • 1
  • 9
  • 1
    The solution to [this related question](https://stackoverflow.com/q/49352692/347964) implements an API for appending values, you could adapt it to also be able to replace values. – flyx May 28 '20 at 13:18

1 Answers1

1

Your Queries seems to be more specific here, so we will not be able to rewrite much. But here is my try

import yaml
with open('alertmanager.yml') as f:
    data = yaml.safe_load(f)
    subitems = [subitem for item in data['route']['routes'] for subitem in item.get('routes') if item.get('match').get('product') == 'my_product' and item.get('match').get('stage') == 'prod']

    for subitem in subitems:
        if 'match' in subitem and subitem.get('match').get('severity') == 'critical':
            subitem['receiver'] = 'sms_another_user'

with open("alertmanager2.yaml", "w") as f:
    yaml.dump(data, f)