我正在从前一个任务的 json 结果列表中提取数据,以获取基于子网的 VLAN 号。
使用这个我需要一个包含两个 vlan 的列表,格式为:
“nic1”:[“100”],“nic1”:[“200”]
我将使用它来调用另一个 api 来配置虚拟机,我必须在其中提供 vlan 信息列表,如下所示:
"network": {
"nic0": [
"100"
],
"nic1": [
"200"
]
},
我尝试过展平和组合,但显然我做得不正确。
非常感谢任何帮助。
这是我尝试过的:
首先从我们的API获取网络信息,使用子网作为搜索条件并设置一个事实'net_info'
"item": "10.20.0.0",
"json": {
"data": {
"attributes": {
"az": "a",
"env": "test",
},
"subnet": "10.20.0.0"
"vlanNumber": 100
}
},
"item": "10.20.1.0",
"json": {
"data": {
"attributes": {
"az": "a",
"env": "test",
},
"subnet": "10.20.1.0"
"vlanNumber": 200
}
}
接下来,我使用 net_info.results 仅提取 VLAN 编号作为列表。
- name: Set nic number and vlan facts for provision payload
set_fact:
Network: "{{ Network | default([]) + [{ 'nic' + nicnum|string: [item.json.data.vlanNumber | string] }] }}"
loop: "{{ net_info.results }}"
loop_control:
index_var: nicnum
这给出:
ok: [localhost] => {
"Network": [
{
"nic0": [
"100"
]
},
{
"nic1": [
"200"
]
}
]
}
理想情况下,上一步会给出所需的最终结果,但没有。 我尝试将网络展平,但没有效果,看起来与之前的输出相同。
我想在这一点上合并,但没有共同元素,所以我创建了第二个列表,以 nics 作为共同点:
- name: set new list with nics and items from Network
set_fact:
Network2: "{{ Network2 | default([]) + [{ 'nics': [item] | join() }] }}"
loop: "{{ Network }}"
gives:
ok: [localhost] => {
"Network2": [
{
"nics": "{'nic0': ['2309']}"
},
{
"nics": "{'nic1': ['2308']}"
}
]
}
我尝试了一个简单的映射,虽然很接近,但它在列表的每个元素上都包含额外的大括号和引号。
- name: Try mapping
debug:
msg: "{{ Network2 | map(attribute='nics') }}"
gives:
TASK [provisionvms : Try mapping] *******************************************************************************************************************
ok: [localhost] => {
"msg": [
"{'nic0': ['2309']}",
"{'nic1': ['2308']}"
]
}
最后我尝试合并(看起来与之前的任务相同),然后我尝试合并但它抱怨:
- name: show network2 merged and then combined
debug:
#msg: "{{ Network2 | community.general.lists_mergeby('nics') }}"
msg: "{{ Network2 | ansible.builtin.combine('nics') }}"
-----
TASK [provisionvms : show network2 combined] ********************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "failed to combine variables, expected dicts but got a 'dict' and a 'str': \n{\"nics\": \"{'nic1': ['2308']}\"}\n\"nics\""}
我确实看到了 zip 过滤器,并认为这看起来很有希望,但不确定“values_list”是什么。
- name: Try zippig Network two based on nics
debug:
msg: "{{ Network2(nics | zip<unsure of this>)) }}"
我觉得这应该很简单,我只是不明白。
提前致谢。
问:“给出迭代结果
net_info.results:
- item: 10.20.0.0
json:
data:
attributes: {az: a, env: test}
subnet: 10.20.0.0
vlanNumber: ['100']
- item: 10.20.1.0
json:
data:
attributes: {az: a, env: test}
subnet: 10.20.1.0
vlanNumber: ['200']
创建字典
network:
{
"nic1": [
"100"
],
"nic2": [
"200"
]
}
A:获取属性列表vlanNumber
vns: "{{ net_info.results | map(attribute='json.data.vlanNumber') }}"
给予
vns:
- ['100']
- ['200']
创建索引列表
idx: "{{ range(1, vns|length +1) }}"
给予
idx:
- 1
- 2
创建字典键列表
nic: "{{ ['nic'] | product(idx) | map('join') }}"
给予
nic:
- nic1
- nic2
创建字典
network: "{{ dict(nic|zip(vns)) }}"
在 YAML 中提供您想要的内容
network:
nic1: ['100']
nic2: ['200']
,或 JSON
network:
{
"nic1": [
"100"
],
"nic2": [
"200"
]
}
用于测试的完整剧本示例
- hosts: localhost
vars:
net_info:
results:
- item: 10.20.0.0
json:
data:
attributes: {az: a, env: test}
subnet: 10.20.0.0
vlanNumber: ["100"]
- item: 10.20.1.0
json:
data:
attributes: {az: a, env: test}
subnet: 10.20.1.0
vlanNumber: ["200"]
vns: "{{ net_info.results | map(attribute='json.data.vlanNumber') }}"
idx: "{{ range(1, vns|length +1) }}"
nic: "{{ ['nic'] | product(idx) | map('join') }}"
network: "{{ dict(nic|zip(vns)) }}"
tasks:
- debug:
var: net_info.results | to_yaml
- debug:
var: vns | to_yaml
- debug:
var: idx
- debug:
var: nic
- debug:
var: network | to_yaml
- debug:
var: network | to_nice_json