Ansible pull data из ответа API - PullRequest
       30

Ansible pull data из ответа API

0 голосов
/ 19 декабря 2018

Я пытаюсь использовать ответ JSON от API для поиска UUID виртуальной машины, для которой я пытаюсь выполнить резервное копирование с использованием имени хоста.API возвращает список хэшей, которые включают имена хостов и UUID этого имени хоста.Я хотел бы, чтобы Ansible возвращал UUID компьютера, когда я передаю ему имя хоста.

Вот пример ответа от API, который я храню в networker_vms

    {
        "networker_vms.json.vms": [
            {
                "hostname": ""
            },
            {
                "hostname": ""
            },
            {
                "hostname": "server1.company.com",
                "uuid": "1ef92350-a5e3-8df3-6106-208a88aad352"
            },
            {
                "hostname": "server2.company.com",
                "uuid": "5003006d-23f4-a515-3722-181238489896"
            },
            {
                "hostname": "server3.company.com",
                "uuid": "50640076-07ae-571d-5e69-2183db42d2ee"
            },
            {
                "hostname": "server4.company.com",
                "uuid": "500410b1-505a-7539-5efd-89131d671b0a"
            },
            {
                "hostname": "server5.company.com",
                "uuid": "5024014b-e788-12a9-bcf6-5475ae50bf7c"
            },
            {
                "hostname": "server6.company.com",
                "uuid": "51462200-1abf-1c09-5007-fa72f76854fc"
            }
      ],
}

Я могу получить UUID, который совпадает с именем хоста со следующим фрагментом Ansible, однако я не могу заставить код работать при переключении переменной mynames на что-то вроде {{ansible_hostname}} - я получаю ошибку "неожиданный сбой во время выполнения модуля ".Я предполагаю, что это связано со сложением фигурных скобок, но я не уверен ....

- name: debug my_uuid
  debug:
    msg: "{{ mynames | map('extract', dict(networker_vms.json | json_query('vms[].[hostname,uuid]'))) }}"
  vars:
    mynames:
      - server2.company.com

Каков наилучший способ поиска результатов вызова API дляконкретное имя хоста и получить Ansible, чтобы поместить соответствующий uuid в факт или переменную для меня?

Спасибо!

1 Ответ

0 голосов
/ 19 декабря 2018

Звучит так, как будто вы хотите извлечь UUID для текущего хоста, как указано в переменной ansible_hostname.Вы можете сделать это следующим образом:

- name: debug using ansible_hostname
  debug:
    msg: >-
      {{ [ansible_hostname] |
      map('extract', dict(networker_vms.json |
      json_query('vms[].[hostname,uuid]'))) | first }}

Это просто заменит mynames в вашем примере, который является списком, на [ansible_hostname], который также является списком (состоящим из одного значения, содержимогоansible_hostname).Это обеспечивает контекст списка, необходимый для фильтра map.

Однако, если у вас есть одно значение, вам не нужно использовать фильтр map;вместо этого вы можете просто сделать это:

- name: debug using ansible_hostname
  debug:
    msg: >-
      {{ (networker_vms.json.vms |
      selectattr('hostname', 'eq', ansible_hostname)|first).uuid }}

Обновление

Если у вас есть сочетание квалифицированных и неквалифицированных имен хостов, вы можете сделать что-то вроде этого:

- name: get my uuid
  set_fact:
    my_uuid: "{{ host_to_addr[item] }}"
  when: my_uuid is not defined and item in host_to_addr
  vars:
    host_to_addr: "{{ dict(networker_vms.json | json_query('vms[].[hostname,uuid]')) }}"
  loop:
    - "{{ ansible_hostname }}"
    - "{{ ansible_fqdn }}"

- debug:
    var: my_uuid

Это зацикливает список имен хостов и устанавливает факт my_uuid в зависимости от того, какой из них совпадает первым.

Вы также можете написать более сложное выражение для фильтра json_query:

- name: get my uuid
  debug:
    msg: >-
      {{ networker_vms.json.vms |
      json_query('[?hostname == `%s` || hostname == `%s`].[uuid]|[]' % (
      ansible_hostname, ansible_fqdn))|
      first}}
...