使用 URI 和 XML 模块的 Ansible 变量分配
Ansible variable assignment using URI & XML modules
我是 Ansible/Jinja 的新手,所以这可能是一个基本问题。我正在使用核心 URI 模块对网络设备进行 REST API 调用,如下所示:
---
- name: Test PAN API
hosts: fw
connection: local
gather_facts: False
tasks:
- name: Calling API System Info
action: uri url=https://192.168.1.10/api/?type=op&cmd=<show><system><info></info></system></show>&key=thisismysecretkey return_content=yes validate_certs=no
register: result
- name: Set variable
set_fact: sysinfo="{{ result.content }}”
- name: Parsing XML response
action: xml xmlstring="{{ sysinfo }}" xpath=//system/* content=text
register: hn
- debug: var=hn.matches['hostname']
我想将每个 xml 节点解析为变量,例如主机名=PA-VM 等。响应如下所示:
TASK [debug var=sysinfo] *******************************************************
ok: [pan] => {
"changed": false,
"sysinfo": "<response status=\"success\"><result><system><hostname>PA-VM</hostname><ip-address>192.168.1.10</ip-address><netmask>255.255.255.0</netmask></system></result></response>"
}
TASK [Testing XML] *************************************************************
ok: [pan]
TASK [debug var=hn.matches] ****************************************************
ok: [pan] => {
"changed": false,
"hn.matches": [
{
"hostname": "PA-VM"
},
{
"ip-address": "192.168.1.10”
},
{
"netmask": "255.255.255.0"
}
]
}
我尝试过不同的 Jinja 过滤器,但我觉得好像缺少一些简单的东西。 hn.matches 似乎是一个列表,每个键值对都是一个字符串。例如,如果我...
- debug: var=hn.matches[0]
我明白了……
TASK [debug var=hn.matches[0]] *************************************************
ok: [pan] => {
"changed": false,
"hn.matches[0]": {
"hostname": "PA-VM"
}
}
真正棒的是...
set_fact: hn="{{ response.result.system.hostname }}"
只是寻找不使用正则表达式的最干净/最好的方法。
使用 map
和 select
过滤器的组合:
- debug: msg="{{ hn.matches | map(attribute='hostname') | select('defined') | first }}"
我刚刚在 uri 模块中添加了 XML 解析支持,因为我也需要它。
https://github.com/ansible/ansible/pull/53045
就像JSON支持一样,它将return一个'xml'键和一个由XML内容组成的字典,以方便访问中的数据有效负载。
您的示例如下所示:
- name: Calling API System Info
uri:
url: https://192.168.1.10/api/?type=op&cmd=<show><system><info></info></system></show>&key=thisismysecretkey
return_content=yes
validate_certs=no
register: result
- debug:
var: result.xml
result.xml 中的输出将是:
{
'response': {
'@status': 'success',
'result': {
'system': {
'hostname': 'PA-VM',
'ip-address': '192.168.1.10',
'netmask': '255.255.255.0'
}
}
}
}
如果有多个系统条目,它将 return 一个条目列表。
我是 Ansible/Jinja 的新手,所以这可能是一个基本问题。我正在使用核心 URI 模块对网络设备进行 REST API 调用,如下所示:
---
- name: Test PAN API
hosts: fw
connection: local
gather_facts: False
tasks:
- name: Calling API System Info
action: uri url=https://192.168.1.10/api/?type=op&cmd=<show><system><info></info></system></show>&key=thisismysecretkey return_content=yes validate_certs=no
register: result
- name: Set variable
set_fact: sysinfo="{{ result.content }}”
- name: Parsing XML response
action: xml xmlstring="{{ sysinfo }}" xpath=//system/* content=text
register: hn
- debug: var=hn.matches['hostname']
我想将每个 xml 节点解析为变量,例如主机名=PA-VM 等。响应如下所示:
TASK [debug var=sysinfo] *******************************************************
ok: [pan] => {
"changed": false,
"sysinfo": "<response status=\"success\"><result><system><hostname>PA-VM</hostname><ip-address>192.168.1.10</ip-address><netmask>255.255.255.0</netmask></system></result></response>"
}
TASK [Testing XML] *************************************************************
ok: [pan]
TASK [debug var=hn.matches] ****************************************************
ok: [pan] => {
"changed": false,
"hn.matches": [
{
"hostname": "PA-VM"
},
{
"ip-address": "192.168.1.10”
},
{
"netmask": "255.255.255.0"
}
]
}
我尝试过不同的 Jinja 过滤器,但我觉得好像缺少一些简单的东西。 hn.matches 似乎是一个列表,每个键值对都是一个字符串。例如,如果我...
- debug: var=hn.matches[0]
我明白了……
TASK [debug var=hn.matches[0]] *************************************************
ok: [pan] => {
"changed": false,
"hn.matches[0]": {
"hostname": "PA-VM"
}
}
真正棒的是...
set_fact: hn="{{ response.result.system.hostname }}"
只是寻找不使用正则表达式的最干净/最好的方法。
使用 map
和 select
过滤器的组合:
- debug: msg="{{ hn.matches | map(attribute='hostname') | select('defined') | first }}"
我刚刚在 uri 模块中添加了 XML 解析支持,因为我也需要它。 https://github.com/ansible/ansible/pull/53045
就像JSON支持一样,它将return一个'xml'键和一个由XML内容组成的字典,以方便访问中的数据有效负载。
您的示例如下所示:
- name: Calling API System Info
uri:
url: https://192.168.1.10/api/?type=op&cmd=<show><system><info></info></system></show>&key=thisismysecretkey
return_content=yes
validate_certs=no
register: result
- debug:
var: result.xml
result.xml 中的输出将是:
{
'response': {
'@status': 'success',
'result': {
'system': {
'hostname': 'PA-VM',
'ip-address': '192.168.1.10',
'netmask': '255.255.255.0'
}
}
}
}
如果有多个系统条目,它将 return 一个条目列表。