循环组 IP
Loop over group IP's
我有一个主机组,要用 GlusterFS 探测这些主机,我需要将该组变成 IP 列表。
我在这里和 Google 上进行了搜索,并尝试了很多方法来完成这项工作,其中一些包含大量代码,而另一些包含模板和正则表达式等等。
目前我还没有找到仅列出一组主机 IP 的单一解决方案。
这是我自己做的,它带组,把这个字典变成一个列表,然后在列表上循环,太棒了!但是当我遍历它时,结果是字符串(为什么?!)而且我无法再获取 IP。
- name: workit
vars:
main_nodes_ips: "{{ groups['glusterpeers'] | list }}"
loop: "{{ main_nodes_ips }}"
debug:
msg: "{{ item['hostvars'] }}"
我找到了这个
- debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
但是如何把它变成这个(例子不工作)
- debug: var=groups['glusterpeers']['ansible_default_ipv4']['address']
我不明白为什么主机列表会突然变成字符串列表,但也许我不应该将其视为对象。
我的结果
这就是我最终为 GlusterFS 探测所有对等点的结果。在 'when' 块中,我对第一个节点的主机名进行了硬编码,这不是很好。我仍然想知道是否有更优雅的方式来探测对等点,这一定是所有 GlusterFS 用户都会做的事情。
当此 IP 顺序更改时,使用第二个 IP 可能会带来麻烦,因此主机名可能更好。
- hosts: all
gather_facts: true
tasks:
- set_fact:
main_nodes_ips: "{{ groups.zicluster|
map('extract', hostvars, 'ansible_all_ipv4_addresses')|
map(attribute='1')|
list }}"
run_once: true
- debug:
var: main_nodes_ips[1:]
when: inventory_hostname == 'zi01'
- name: probe the peers
gluster.gluster.gluster_peer:
state: present
nodes: "{{ main_nodes_ips[1:] }}"
when: inventory_hostname == 'zi01'
例如,下面的剧本获取远程主机的第一个 IP 地址并创建列表
- hosts: glusterpeers
gather_facts: true
tasks:
- debug:
var: ansible_all_ipv4_addresses
- set_fact:
main_nodes_ips: "{{ groups.glusterpeers|
map('extract', hostvars, 'ansible_all_ipv4_addresses')|
map('first')|
list }}"
run_once: true
- debug:
var: main_nodes_ips
run_once: true
给予
PLAY [glusterpeers] ***************************************
TASK [Gathering Facts] ************************************
ok: [host02]
ok: [host01]
ok: [host03]
TASK [debug] **********************************************
ok: [host01] =>
ansible_all_ipv4_addresses:
- 10.1.0.61
ok: [host02] =>
ansible_all_ipv4_addresses:
- 10.1.0.62
ok: [host03] =>
ansible_all_ipv4_addresses:
- 10.1.0.63
TASK [set_fact] *******************************************
ok: [host01]
TASK [debug] **********************************************
ok: [host01] =>
main_nodes_ips:
- 10.1.0.61
- 10.1.0.62
- 10.1.0.63
备注
- 如果您想从列表 map 属性中获取任何其他索引。例如,要获得第二项,替换
map('first')|
来自
map(attribute='1')|
- 在您的代码中,您从特定主机的列表中删除了第一个 IP。这仅适用于第一台主机
- debug:
msg: "{{ main_nodes_ips[1:] }}"
when: inventory_hostname == 'host01'
如果要删除任何主机的 IP,请创建字典。例如
- set_fact:
main_nodes: "{{ dict(groups.glusterpeers|zip(main_nodes_ips)) }}"
run_once: true
给予
main_nodes:
host01: 10.1.0.61
host02: 10.1.0.62
host03: 10.1.0.63
然后,使用这个字典从列表中删除特定主机的 IP
- debug:
msg: "{{ main_nodes_ips|difference(main_nodes[inventory_hostname]) }}"
when: inventory_hostname == 'host01'
给予
TASK [debug] **************************************************
skipping: [host02]
skipping: [host03]
ok: [host01] =>
msg:
- 10.1.0.62
- 10.1.0.63
我有一个主机组,要用 GlusterFS 探测这些主机,我需要将该组变成 IP 列表。
我在这里和 Google 上进行了搜索,并尝试了很多方法来完成这项工作,其中一些包含大量代码,而另一些包含模板和正则表达式等等。
目前我还没有找到仅列出一组主机 IP 的单一解决方案。 这是我自己做的,它带组,把这个字典变成一个列表,然后在列表上循环,太棒了!但是当我遍历它时,结果是字符串(为什么?!)而且我无法再获取 IP。
- name: workit
vars:
main_nodes_ips: "{{ groups['glusterpeers'] | list }}"
loop: "{{ main_nodes_ips }}"
debug:
msg: "{{ item['hostvars'] }}"
我找到了这个
- debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
但是如何把它变成这个(例子不工作)
- debug: var=groups['glusterpeers']['ansible_default_ipv4']['address']
我不明白为什么主机列表会突然变成字符串列表,但也许我不应该将其视为对象。
我的结果
这就是我最终为 GlusterFS 探测所有对等点的结果。在 'when' 块中,我对第一个节点的主机名进行了硬编码,这不是很好。我仍然想知道是否有更优雅的方式来探测对等点,这一定是所有 GlusterFS 用户都会做的事情。
当此 IP 顺序更改时,使用第二个 IP 可能会带来麻烦,因此主机名可能更好。
- hosts: all
gather_facts: true
tasks:
- set_fact:
main_nodes_ips: "{{ groups.zicluster|
map('extract', hostvars, 'ansible_all_ipv4_addresses')|
map(attribute='1')|
list }}"
run_once: true
- debug:
var: main_nodes_ips[1:]
when: inventory_hostname == 'zi01'
- name: probe the peers
gluster.gluster.gluster_peer:
state: present
nodes: "{{ main_nodes_ips[1:] }}"
when: inventory_hostname == 'zi01'
例如,下面的剧本获取远程主机的第一个 IP 地址并创建列表
- hosts: glusterpeers
gather_facts: true
tasks:
- debug:
var: ansible_all_ipv4_addresses
- set_fact:
main_nodes_ips: "{{ groups.glusterpeers|
map('extract', hostvars, 'ansible_all_ipv4_addresses')|
map('first')|
list }}"
run_once: true
- debug:
var: main_nodes_ips
run_once: true
给予
PLAY [glusterpeers] ***************************************
TASK [Gathering Facts] ************************************
ok: [host02]
ok: [host01]
ok: [host03]
TASK [debug] **********************************************
ok: [host01] =>
ansible_all_ipv4_addresses:
- 10.1.0.61
ok: [host02] =>
ansible_all_ipv4_addresses:
- 10.1.0.62
ok: [host03] =>
ansible_all_ipv4_addresses:
- 10.1.0.63
TASK [set_fact] *******************************************
ok: [host01]
TASK [debug] **********************************************
ok: [host01] =>
main_nodes_ips:
- 10.1.0.61
- 10.1.0.62
- 10.1.0.63
备注
- 如果您想从列表 map 属性中获取任何其他索引。例如,要获得第二项,替换
map('first')|
来自
map(attribute='1')|
- 在您的代码中,您从特定主机的列表中删除了第一个 IP。这仅适用于第一台主机
- debug:
msg: "{{ main_nodes_ips[1:] }}"
when: inventory_hostname == 'host01'
如果要删除任何主机的 IP,请创建字典。例如
- set_fact:
main_nodes: "{{ dict(groups.glusterpeers|zip(main_nodes_ips)) }}"
run_once: true
给予
main_nodes:
host01: 10.1.0.61
host02: 10.1.0.62
host03: 10.1.0.63
然后,使用这个字典从列表中删除特定主机的 IP
- debug:
msg: "{{ main_nodes_ips|difference(main_nodes[inventory_hostname]) }}"
when: inventory_hostname == 'host01'
给予
TASK [debug] **************************************************
skipping: [host02]
skipping: [host03]
ok: [host01] =>
msg:
- 10.1.0.62
- 10.1.0.63