Ansible 读取嵌套的 json 值和匹配变量
Ansible reading nested json values and matching variable
我在 Ansible 剧本中使用它:
- name: Gather info from Vcenter
vmware_vm_info:
hostname: "{{ result_item.vcenter }}"
username: "{{ ansible_username }}"
password: "{{ ansible_password }}"
validate_certs: no
register: vminfo
loop: "{{ result.list }}"
loop_control:
loop_var: result_item
我循环遍历一个 csv,其中包含 VM 及其 Vcenter 的列表。 Ansible 任务的 json 输出是这样的:
{
"results": [
{
"changed": false,
"virtual_machines": [
{
"guest_name": "Server1",
"guest_fullname": "SUSE Linux Enterprise 11 (64-bit)",
"power_state": "poweredOn",
},
{
"guest_name": "Server2",
"guest_fullname": "FreeBSD Pre-11 versions (64-bit)",
"power_state": "poweredOn",
},
现在我需要在我的 csv 中查询此输出以获取 VM(guest_name 匹配 vmname)并使用 set_fact 指示 csv 中的 VM 是关闭电源还是打开电源。接下来,我可以将其用作根据当前状态是否关闭 VM 的条件。
将 csv 中的 VM 名称与 json 输出匹配,然后获取相应的电源状态时,我似乎无法让 json_query 工作。有什么想法吗?
CSV 文件:
vmname vcenter
Server1 Vcenter1
Server2 Vcenter1
我想,根据您的示例,您确实有一个 TSV,因此制表符分隔值而不是 CSV,CSV 代表 逗号 分隔值。
基于此,read_csv
模块以及 dialect: excel-tab
将帮助您读取 TSV。
然后,您需要使用 filter projection 根据您的 TSV 文件中的数据查询 JSON。
您可能还需要 flatten the projection 删除由 results
和 virtual_machines
.
中的列表创建的双打列表
生成的 JMESPath 查询示例,Server1
最终为:
results[].virtual_machines[?
guest_name == `Server1`
]|[]|[0].power_state
然后将所有这些都写在剧本中,我们最终会得到:
- hosts: localhost
gather_facts: no
tasks:
- read_csv:
path: servers.csv
dialect: excel-tab
register: servers
- debug:
msg: >-
For {{ item.vmname }}, the state is {{
vminfo |
json_query(
'results[].virtual_machines[?
guest_name == `' ~ item.vmname ~ '`
]|[]|[0].power_state'
)
}}
loop: "{{ servers.list }}"
loop_control:
label: "{{ item.vmname }}"
vars:
vminfo:
results:
- changed: false
virtual_machines:
- guest_name: Server1
guest_fullname: SUSE Linux Enterprise 11 (64-bit)
power_state: poweredOn
- guest_name: Server2
guest_fullname: FreeBSD Pre-11 versions (64-bit)
power_state: poweredOn
其中产生了回顾:
PLAY [localhost] **************************************************************************************************
TASK [read_csv] ***************************************************************************************************
ok: [localhost]
TASK [debug] ******************************************************************************************************
ok: [localhost] => (item=Server1) =>
msg: For Server1, the state is poweredOn
ok: [localhost] => (item=Server2) =>
msg: For Server2, the state is poweredOn
PLAY RECAP ********************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
问:"set_fact表示CSV中的虚拟机是关机还是开机。"
答:例如
- read_csv:
path: servers.csv
dialect: excel-tab
register: result
- set_fact:
servers: "{{ result.list|map(attribute='vmname')|list }}"
- set_fact:
virtual_machines: "{{ virtual_machines|default([]) +
[dict(_servers|zip(_values))] }}"
loop: "{{ vminfo.results }}"
vars:
_servers: "{{ servers|intersect(_dict.keys()|list) }}"
_values: "{{ _servers|map('extract',_dict)|list }}"
_dict: "{{ item.virtual_machines|
items2dict(key_name='guest_name', value_name='power_state') }}"
- debug:
var: virtual_machines
给予
virtual_machines:
- Server1: poweredOn
Server2: poweredOn
vminfo.results 中缺少的服务器将被静默忽略。
问:"作为是否关闭虚拟机的条件。"
A:比如第一台主机中的Server1
- debug:
msg: "Host={{ _host }} VM={{ _vm }} is poweredOn"
when: virtual_machines[_host][_vm] == 'poweredOn'
vars:
_host: 0
_vm: Server1
给予
msg: Host=0 VM=Server1 is poweredOn
我在 Ansible 剧本中使用它:
- name: Gather info from Vcenter
vmware_vm_info:
hostname: "{{ result_item.vcenter }}"
username: "{{ ansible_username }}"
password: "{{ ansible_password }}"
validate_certs: no
register: vminfo
loop: "{{ result.list }}"
loop_control:
loop_var: result_item
我循环遍历一个 csv,其中包含 VM 及其 Vcenter 的列表。 Ansible 任务的 json 输出是这样的:
{
"results": [
{
"changed": false,
"virtual_machines": [
{
"guest_name": "Server1",
"guest_fullname": "SUSE Linux Enterprise 11 (64-bit)",
"power_state": "poweredOn",
},
{
"guest_name": "Server2",
"guest_fullname": "FreeBSD Pre-11 versions (64-bit)",
"power_state": "poweredOn",
},
现在我需要在我的 csv 中查询此输出以获取 VM(guest_name 匹配 vmname)并使用 set_fact 指示 csv 中的 VM 是关闭电源还是打开电源。接下来,我可以将其用作根据当前状态是否关闭 VM 的条件。
将 csv 中的 VM 名称与 json 输出匹配,然后获取相应的电源状态时,我似乎无法让 json_query 工作。有什么想法吗?
CSV 文件:
vmname vcenter
Server1 Vcenter1
Server2 Vcenter1
我想,根据您的示例,您确实有一个 TSV,因此制表符分隔值而不是 CSV,CSV 代表 逗号 分隔值。
基于此,read_csv
模块以及 dialect: excel-tab
将帮助您读取 TSV。
然后,您需要使用 filter projection 根据您的 TSV 文件中的数据查询 JSON。
您可能还需要 flatten the projection 删除由 results
和 virtual_machines
.
生成的 JMESPath 查询示例,Server1
最终为:
results[].virtual_machines[?
guest_name == `Server1`
]|[]|[0].power_state
然后将所有这些都写在剧本中,我们最终会得到:
- hosts: localhost
gather_facts: no
tasks:
- read_csv:
path: servers.csv
dialect: excel-tab
register: servers
- debug:
msg: >-
For {{ item.vmname }}, the state is {{
vminfo |
json_query(
'results[].virtual_machines[?
guest_name == `' ~ item.vmname ~ '`
]|[]|[0].power_state'
)
}}
loop: "{{ servers.list }}"
loop_control:
label: "{{ item.vmname }}"
vars:
vminfo:
results:
- changed: false
virtual_machines:
- guest_name: Server1
guest_fullname: SUSE Linux Enterprise 11 (64-bit)
power_state: poweredOn
- guest_name: Server2
guest_fullname: FreeBSD Pre-11 versions (64-bit)
power_state: poweredOn
其中产生了回顾:
PLAY [localhost] **************************************************************************************************
TASK [read_csv] ***************************************************************************************************
ok: [localhost]
TASK [debug] ******************************************************************************************************
ok: [localhost] => (item=Server1) =>
msg: For Server1, the state is poweredOn
ok: [localhost] => (item=Server2) =>
msg: For Server2, the state is poweredOn
PLAY RECAP ********************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
问:"set_fact表示CSV中的虚拟机是关机还是开机。"
答:例如
- read_csv:
path: servers.csv
dialect: excel-tab
register: result
- set_fact:
servers: "{{ result.list|map(attribute='vmname')|list }}"
- set_fact:
virtual_machines: "{{ virtual_machines|default([]) +
[dict(_servers|zip(_values))] }}"
loop: "{{ vminfo.results }}"
vars:
_servers: "{{ servers|intersect(_dict.keys()|list) }}"
_values: "{{ _servers|map('extract',_dict)|list }}"
_dict: "{{ item.virtual_machines|
items2dict(key_name='guest_name', value_name='power_state') }}"
- debug:
var: virtual_machines
给予
virtual_machines:
- Server1: poweredOn
Server2: poweredOn
vminfo.results 中缺少的服务器将被静默忽略。
问:"作为是否关闭虚拟机的条件。"
A:比如第一台主机中的Server1
- debug:
msg: "Host={{ _host }} VM={{ _vm }} is poweredOn"
when: virtual_machines[_host][_vm] == 'poweredOn'
vars:
_host: 0
_vm: Server1
给予
msg: Host=0 VM=Server1 is poweredOn