Ансибельный фильтр/Анализ вывода в json

#python #regex #ansible #jmespath

Вопрос:

Я пытаюсь отфильтровать вывод ansible-playbook до допустимого вывода json, чтобы я мог с ним работать. Вывод, который я получаю, таков:

 ok: [r-sw01] => {
    "configlets | selectattr("name", "eq", "r-sw01")": [
        {
            "config": "hostname r-sw01nninterface Management1n   ip address 10.10.24.10/24nninterface Port-Channel20n   description USRn   switchport mode trunknninterface Ethernet99-100n   description  USR_Po20n   speed forced 25gfulln",
            "containerCount": 0,
            "containers": [],
            "dateTimeInLongFormat": 1615984781483,
            "devices": [
                "r-sw01"
            ],
            "editable": true,
            "isAutoBuilder": "",
            "isDefault": "no",
            "isDraft": false,
            "key": "configlet_71ef71",
            "name": "r-sw01",
            "netElementCount": 0,
            "note": "",
            "reconciled": false,
            "sslConfig": false,
            "type": "Static",
            "typeStudioConfiglet": false,
            "user": "chal",
            "visible": true
        }
    ]
}
 

Из этого сборника пьес:

 ---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  tasks:
    - name: "Gather CVP facts from {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          configlets
    - debug:
        var: configlets | selectattr("name", "eq", "{{ tag }}")
 

Пробовали фильтровать его с помощью python :

 configlet_settings = subprocess.Popen(["ansible-playbook", "configlets.yml", "-e", tag ,"-i", "inventory.ini"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = configlet_settings.communicate()
out = out.decode()
out = out.split('n')
r = re.search(r"configlets.*[(.*?)]", str(out))
r = r.group(1)
my_lst = re.findall(r"w ", r)
 

Но я только получаю
(['r', 'sw01'],)

Или «Нет», когда я пытаюсь изменить регулярное выражение, как я могу получить допустимый json этого вывода ? мне не нужно | selectattr("name", "eq", "r-sw01")" единственное, что будет потом

РЕДАКТИРОВАТЬ — Попытка перенаправить вывод в файл :

   ---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  vars:
    var: var
    vars_files:
            - vars.yml
  tasks:
    - name: "Gather CVP facts from {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          configlets
    - debug:
        var: configlets | selectattr("name", "eq", "{{ tag }}")

    - name: write JSON to a file
      copy:
         content: "{{ var|to_nice_json }}"
         dest: somefile.json
 

Произошла ошибка:

 FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var' is undefined
 

Комментарии:

1. Попытка проанализировать вывод из Ansible кажется пустой тратой времени. Если вы хотите получить вывод JSON из Ansible, просто запишите JSON в файл с помощью template copy задачи или, а затем просто прочитайте файл в свой код. Ручной анализ не требуется. В Ansible есть фильтры для сериализации данных в JSON/YAML/и т.д.

2. как мне перенаправить var? Я добавил это после отладки - local_action: copy content=var dest=somelog.log , попробовав также с content={{var}}

Ответ №1:

Если вы хотите записать сериализацию JSON переменной Ansible в файл, вы можете сделать что-то вроде этого:

 - name: write JSON to a file
  copy:
    content: "{{ var|to_nice_json }}"
    dest: somelog.json
 

Затем просто импортируйте это в свой код Python:

 import json

with open('somelog.json') as fd:
  data = json.load(fd)
 

Комментарии:

1. Playbook возвращает ошибку : FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var' is undefined — отредактированный вопрос с изменениями в playbook

2. Вы определили переменную с именем var ? Если нет, используйте имя переменной, которую вы пытаетесь сбросить.

3. где мне нужно его определить ? полный план игры здесь, в вопросе, пожалуйста, дайте мне знать, что я должен делать

4. На самом деле это требует, чтобы вы знали, что вы пытаетесь сделать. Каково имя переменной, которую вы хотите сбросить в JSON? Так ли это configlets ? Что бы это ни было, замените var в этом content выражении имя переменной.

5. var создан для фильтрации выходных данных configlets и предоставляет мне только соответствующую информацию по имени, так как в конфигурациях много информации, после ее фильтрации мне нужен только json, который она фильтрует . если я помещу содержимое конфигураций вместо var, я получу полную информацию, если нет способа поместить отфильтрованную информацию в var файл журнала, этого достаточно 🙂