Ansible 从 API 响应中提取数据
Ansible pull data from API response
我正在尝试使用来自 API 的 JSON 响应来查找我正在尝试使用主机名备份的 VM 的 UUID。 API return 是一个散列列表,其中包括主机名和该主机名的 UUID。当我向它提供主机名时,我想让 Ansible return 机器的 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"
}
],
}
我能够使用以下 Ansible 代码段获得与主机名一致的 UUID,但是当将 "mynames" 变量切换为类似 {{ ansible_hostname }} - 我收到错误 "unexpected failure during module execution"。我猜这与花括号的堆叠有关,但我不确定....
- 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 放入事实或变量中的最佳方法是什么?
谢谢!
听起来您想提取当前主机的 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}}
我正在尝试使用来自 API 的 JSON 响应来查找我正在尝试使用主机名备份的 VM 的 UUID。 API return 是一个散列列表,其中包括主机名和该主机名的 UUID。当我向它提供主机名时,我想让 Ansible return 机器的 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"
}
],
}
我能够使用以下 Ansible 代码段获得与主机名一致的 UUID,但是当将 "mynames" 变量切换为类似 {{ ansible_hostname }} - 我收到错误 "unexpected failure during module execution"。我猜这与花括号的堆叠有关,但我不确定....
- 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 放入事实或变量中的最佳方法是什么?
谢谢!
听起来您想提取当前主机的 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}}