Заменить значение в динамическом списке словаря, загруженного из alertmanager yml?

Этот вопрос довольно специфичен, я успешно сделал то, что хочу, но он очень специфичен для моего варианта использования и, вероятно, уродлив для эксперта по Python, поэтому мне любопытно, может ли он быть более общим и/или умным.

Мне нужно отредактировать маршрутизацию prometheus alertmanager, хранящуюся в файле yml (документация здесь)

В моем случае использования моя маршрутизация (извлечение):

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

Мне нужно отредактировать приемник "sms_voidandnany" (получатель зависит от календаря Google).

Вот мой первый черновик:

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 цикла даже у меня, не эксперта по python и не разработчика на полную ставку, я думаю, что это уродливо.

Видите ли вы лучший способ, более питонистский способ добиться этого?

Вишенка на торте, как вы думаете, существует ли «простой» способ замены дженерика? Структура маршрутизации динамическая, мы можем сделать маршрутизацию-сопоставление-маршрутизацию-сопоставление и так далее... Рекурсивная функция?


person voidAndAny    schedule 28.05.2020    source источник
comment
Решение этого связанного вопроса реализует API для добавления значений, вы можете адаптировать его, чтобы также иметь возможность заменять значения.   -  person flyx    schedule 28.05.2020


Ответы (1)


Ваши запросы кажутся здесь более конкретными, поэтому мы не сможем много переписывать. Но вот моя попытка

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)

person Karthik Radhakrishnan    schedule 28.05.2020