【问题标题】:Using parse_xml in an Ansible playbook在 Ansible 剧本中使用 parse_xml
【发布时间】:2021-07-09 12:51:27
【问题描述】:

我一直在尝试在 Ansible 中解析 XML 数据。我可以使用 xml 模块让它工作,但我认为使用 parse_xml 会更好地满足我的需求。

我似乎无法将 xml 中的任何数据与我的规格文件匹配。

这里是xml数据:

 <data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">
  <ntp xmlns=\"http://cisco.com/ns/yang/Cisco-IOS-XR-ip-ntp-oper\">
   <nodes>
    <node>
     <node>0/0/CPU0</node>
     <associations>
      <is-ntp-enabled>true</is-ntp-enabled>
      <sys-leap>ntp-leap-no-warning</sys-leap>
      <peer-summary-info>
       <peer-info-common>
        <host-mode>ntp-mode-client</host-mode>
        <is-configured>true</is-configured>
        <address>10.1.1.1</address>
        <reachability>0</reachability>
       </peer-info-common>
       <time-since>-1</time-since>
      </peer-summary-info>
      <peer-summary-info>
       <peer-info-common>
        <host-mode>ntp-mode-client</host-mode>
        <is-configured>true</is-configured>
        <address>172.16.252.29</address>
        <reachability>255</reachability>
       </peer-info-common>
       <time-since>991</time-since>
      </peer-summary-info>
     </associations>
    </node>
   </nodes>
  </ntp>
 </data>

这是规范文件的样子:

---
vars:
  ntp_peers:
    address: "{{ item.address }}"
    reachability: "{{ item.reachability}}"
keys:
  result:
    value: "{{ ntp_peers }}"
    top: data/ntp/nodes/node/associations
    items:
      address: peer-summary-info/peer-info-common/address
      reachability: peer-summary-info/peer-info-common/reachability

以及yaml文件中的任务:

  - name: parse ntp reply
    set_fact:
      parsed_ntp_data: "{{ NTP_STATUS.stdout | parse_xml('specs/iosxr_ntp.yaml') }}"

但是数据没有返回任何结果:

TASK [debug parsed_ntp_data] **************************************************************************************************************************************************************************
ok: [core-rtr01] => {
    "parsed_ntp_data": {
        "result": []
    }
}
ok: [dist-rtr01] => {
    "parsed_ntp_data": {
        "result": []
    }
}

【问题讨论】:

    标签: ansible xml-parsing


    【解决方案1】:

    我以前从未见过parse_xml,所以这是一次有趣的冒险

    似乎有两件事对您不利:top: 键是从根元素评估,并且您的 XML(与其他示例不同)使用 XML 命名空间(@987654326 @bit) 这意味着您的 XPath 必须以 Element.findall 方式编码

    对于第一部分,由于Element.findall&lt;data&gt; 元素上运行,这意味着不能在XPath 中引用data/...,因为这将适用于结构&lt;data&gt;&lt;data&gt;。我试图通过将 XPath 设为绝对 /data/... 来偷偷摸摸,但 Python 的 XPath 库在这种情况下会出现。所以,至少你的top: 键不需要以data 开头任何东西

    然后,您的 sn-p 中的 xmlns= 对我来说很突出,因为这意味着这些元素的名称实际上是每个元素的 NS+":"+localName,因此 ntp 的 XPath 与 ns0:ntp 不匹配,因为它们'重新考虑完全独立的名称(毕竟这是命名空间的点)。很有可能使用足够的//*[localname() = "ntp"] 愚蠢来避免一遍又一遍地指定命名空间,但我没有尝试过

    再次,作为对 Python 的 XPath 库的让步,它们将 xpath 中的完全限定名称编码为 {the-namespace}local-name,并且似乎没有任何办法可以修改 network.py 以传入命名空间:-(

    因此,我用来证实我的理论的“hello world”版本:

    vars:
      ntp_peers:
        address: "{{ item.address }}"
    keys:
      result:
        value: "{{ ntp_peers }}"
        top: '{http://cisco.com/ns/yang/Cisco-IOS-XR-ip-ntp-oper}ntp/{http://cisco.com/ns/yang/Cisco-IOS-XR-ip-ntp-oper}nodes/{http://cisco.com/ns/yang/Cisco-IOS-XR-ip-ntp-oper}node'
        items:
          address: '{http://cisco.com/ns/yang/Cisco-IOS-XR-ip-ntp-oper}node'
    

    制作愉快

    ok: [localhost] => {
        "msg": {
            "result": [
                {
                    "address": "0/0/CPU0"
                }
            ]
        }
    }
    

    【讨论】:

    • 谢谢,命名空间正是原因。我认为打开功能请求对我来说是明智的吗?
    • 我会建议,是的。如果有人要努力与他们的 repo 进行交互,最好礼貌地邀请他们 stop swallowing Exception, too,因为这会使任何调试工作变得更加困难
    • @mdaniel 这次我不会提交答案 ;) 这对我来说也是一次有趣的冒险。同时,这个过滤器看起来真的是半生不熟。我仍然会将我的“有点工作”场景作为外部链接提供:gist.github.com/zeitounator/8452c2a20860c0e924bd3ed9ff1af4e0
    猜你喜欢
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多