我想使用ansible从以下文件中读取<PropertySection>
下的属性:
<?xml version='1.0' encoding='UTF-8'?>
<Environment xmlns="http://schemas.dmtf.org/ovf/environment/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oe="http://schemas.dmtf.org/ovf/environment/1" xmlns:ve="http://www.vmware.com/schema/ovfenv" oe:id="" ve:vCenterId="vm-6863">
<PlatformSection>
<Kind>VMware ESXi</Kind>
<Version>6.0.0</Version>
<Vendor>VMware, Inc.</Vendor>
<Locale>en</Locale>
</PlatformSection>
<PropertySection>
<Property oe:key="dns" oe:value="test.myeng.com"/>
<Property oe:key="dns-servers" oe:value="8.8.8.8"/>
<Property oe:key="gateway" oe:value="192.168.100.1"/>
<Property oe:key="mask" oe:value="255.255.255.0"/>
</PropertySection>
<ve:EthernetAdapterSection>
<ve:Adapter ve:mac="00:50:56:90:2d:a3" ve:network="VM Network" ve:unitNumber="7"/>
</ve:EthernetAdapterSection>
</Environment>
从<PlatformSection>
读取元素似乎很容易,但是我不知道如何从Property
读取特定的<PropertySection>
- hosts: localhost
tasks:
- name: Read XML
xml:
path: /tmp/input.xml
xpath: /a:Environment/a:PlatformSection/a:Version
content: text
namespaces:
a: http://schemas.dmtf.org/ovf/environment/1
register: xml_out
- debug: var=xml_out
答案 0 :(得分:2)
larsks 的解决方案似乎适合在 Ansible 中使用 VMware 的 vApp 属性的任何人。
但是,我认为该解决方案仅适用于在 python2 上运行 Ansible 时;使用 python3,不支持语法 item.values().0
。
下面的代码在 python3 上运行:
- ansible.builtin.set_fact:
properties: >-
{{ properties | default({}) |
combine({((item.values() | list)[0].values() | list)[0]:
((item.values() | list)[0].values() | list)[1]})
}}
loop: "{{ xml_out.matches }}"
答案 1 :(得分:1)
我们可以使用xpath表达式来返回所有属性值:
xpath: '/a:Environment/a:PropertySection/a:Property'
不幸的是,在这种情况下,xml
模块的返回值很难使用;我们得到这样的数据结构:
ok: [localhost] => { [53/7069]
"xml_out.matches": [
{
"{http://schemas.dmtf.org/ovf/environment/1}Property": {
"{http://schemas.dmtf.org/ovf/environment/1}key": "dns",
"{http://schemas.dmtf.org/ovf/environment/1}value": "test.myeng.com"
}
},
{
"{http://schemas.dmtf.org/ovf/environment/1}Property": {
"{http://schemas.dmtf.org/ovf/environment/1}key": "dns-servers",
"{http://schemas.dmtf.org/ovf/environment/1}value": "8.8.8.8"
}
},
{
"{http://schemas.dmtf.org/ovf/environment/1}Property": { "{http://schemas.dmtf.org/ovf/environment/1}key": "gateway",
"{http://schemas.dmtf.org/ovf/environment/1}value": "192.168.100.1" }
}, {
"{http://schemas.dmtf.org/ovf/environment/1}Property": { "{http://schemas.dmtf.org/ovf/environment/1}key": "mask",
"{http://schemas.dmtf.org/ovf/environment/1}value": "255.255.255.0"
}
}
]
}
好吧,对吧?但是,有了一点黑客,我们就可以将其按摩到更有用的结构中:
---
- hosts: localhost
gather_facts: false
tasks:
- xml:
path: ./data.xml
xpath: '/a:Environment/a:PropertySection/a:Property'
content: attribute
namespaces:
a: http://schemas.dmtf.org/ovf/environment/1
register: xml_out
- set_fact:
properties: >-
{{ properties|default({})|
combine({item.values().0['{http://schemas.dmtf.org/ovf/environment/1}key']:
item.values().0['{http://schemas.dmtf.org/ovf/environment/1}value']})
}}
loop: "{{ xml_out.matches }}"
- debug:
var: properties
从该剧本的输出中可以看到,我们现在有了一个简单的字典:
ok: [localhost] => {
"properties": {
"dns": "test.myeng.com",
"dns-servers": "8.8.8.8",
"gateway": "192.168.100.1",
"mask": "255.255.255.0"
}
}
因此我们可以像这样访问各个属性:
- debug:
msg: "The gateway address is {{ properties.gateway }}"
上面的set_fact
任务有点麻烦。我们利用default
和combine
过滤器来建立字典;一个简化的版本可能看起来像:
---
- hosts: localhost
gather_facts: false
vars:
example:
- [color, red]
- [name, alice]
- [size, medium]
tasks:
- set_fact:
properties: "{{ properties|default({})|combine({item.0: item.1}) }}"
loop: "{{ example }}"
- debug:
var: properties