使用URI和XML模块进行Ansible变量赋值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用URI和XML模块进行Ansible变量赋值相关的知识,希望对你有一定的参考价值。

我是Ansible / Jinja的新手,所以这可能是一个基本问题。我使用Core 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节点解析为变量,例如hostname = 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 }}"

只是在不使用正则表达式的情况下寻找最干净/最好的方法。

答案

使用mapselect过滤器的组合:

- debug: msg="{{ hn.matches | map(attribute='hostname') | select('defined') | first }}"
另一答案

我刚刚在uri模块中添加了XML解析支持,因为我也需要它。 https://github.com/ansible/ansible/pull/53045

就像JSON支持一样,它将返回一个'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'
            }
        }
    }
}

如果有多个系统条目,它将返回一个条目列表。

以上是关于使用URI和XML模块进行Ansible变量赋值的主要内容,如果未能解决你的问题,请参考以下文章

使用loop_var Ansible循环多个变量

Ansible uri模块和双向TLS

xml Miva - 使用Sebenza模板模块进行URI管理

Ansible 变量赋值

Ansible 调试消息到变量

Nginx反代配置