Ansible проверяет, существует ли переменная в списке атрибутов

Ansible проверяет, существует ли переменная в списке атрибутов

У меня есть переменная, содержащая сведения о хост-машинах в моей сети (называется «hostlist» — кажется, вы называете это словарем, но я не уверен в терминологии). Переменная определена в файле в group_vars/all, поэтому она доступна во всех плейбуках (не уверен, важно ли это).

У меня есть игра, которую я хотел бы запустить только в том случае, если ansible_hostname не найден в списке имен хостов в hostlist. Имена хостов в hostlist являются одним из атрибутов переменной, но я снова не уверен, что «атрибут» — правильный термин...

Список хостов определяется как:

hostlist:
  - { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
  - { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
  - { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }

Чтобы это заработало, я использую следующий прием:

- name: Conditional test
  debug:
    msg: "ansible_hostname not found in hostlist."
  when: ansible_hostname not in hostlist.name

Я не уверен в синтаксисе, требуемом в условии, и можно ли таким образом достичь того, чего я хочу?

решение1

Вероятно, есть более элегантные способы сделать это, но мне подходит что-то вроде этого:

Если ваш файл инвентаризации выглядит так

host1
host2
host3
host4

Тогда сценарий со следующим содержимым будет запущен только host4потому, что он не соответствует переменной hostlist:
$ cat test.yml

- hosts: all
  vars:
    hostlist:
      - { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
      - { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
      - { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }
  tasks:

    - name: Conditional test
      debug:
        msg: "ansible_hostname not found in hostlist."
      when: hostlist|selectattr("name", "equalto", ansible_hostname)|list|length == 0

при вызове таким образом:

ansible-playbook test.yml

означает, что только host4 запускает блок задач....

PLAY [all] *************************************************

TASK [Gathering Facts] *************************************
ok: [host1]
ok: [host2]
ok: [host3]
ok: [host4]

TASK [debug] ***********************************************
ok: [host4] => {
    "msg": "hostname not in hostlist name list"
}
skipping: [host1]
skipping: [host2]
skipping: [host3]

решение2

По желанию, это условие чище

    when: inventory_hostname not in hostlist|map(attribute="name")|list

Используйте inventory_hostnameвместо ansible_hostname, если вы хотите сравнить со списком псевдонимов инвентаря. СмотретьВ чем разница между inventory_hostname и ansible_hostname.

решение3

Альтернативным решением (как предложено в комментарии к вопросу) является рефакторинг списка хостов в инвентарь следующим образом:

[physical_workstation]
host1 ansible_host=192.168.2.31
host2 ansible_host=192.168.2.32

[virtual_machine]
host3 ansible_host=192.168.2.33

[all]
host4 ansible_host=192.168.2.34

Затем вы можете упростить схему игры, чтобы запускать игры против хостов, не входящих ни в одну группу, используя специальную ungroupedгруппу, которая выбирает хосты, allне входящие ни в одну другую группу:

- hosts: ungrouped
  tasks:
    - name: only ungrouped
      debug:
        msg: "host not found in any other group."

или запускать действия против этих конкретных хостов в группах...

- hosts: physical_workstation:virtual_machine
  tasks:
    - name: only in specified groups
      debug:
        msg: |
          This will run on machines that are in groups:
          physical_workstation or virtual_machine

выходы

PLAY [ungrouped] ***********************************************

TASK [only ungrouped] ******************************************
ok: [host4] => {
    "msg": "host not found in any other group."
}

PLAY [physical_workstation:virtual_machine] ********************

TASK [only in specified groups] ********************************
ok: [host1] => {
    "msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}
ok: [host2] => {
    "msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}
ok: [host3] => {
    "msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}

Связанный контент