我想使用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>中读取元素似乎很容易,但我不知道如何从<PropertySection>中读取特定的Property
- 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发布于 2019-04-08 18:06:34
我们可以使用这样的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发布于 2021-06-09 17:22:20
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 }}"https://stackoverflow.com/questions/55578830
复制相似问题