我从 REST API 调用的输出中捕获了一个 dict/json 类型的对象,假设它位于一个名为ouput的变量/寄存器中。数据如下所示。为了完整起见,我分享了整个对象并做了一些基本的清理。请只关注我接下来要讨论的那一行 ;-)
{
"_create_time": 1724823837185,
"_create_user": "system",
"_last_modified_time": 1736218001919,
"_last_modified_user": "nsx_policy",
"_protection": "NOT_PROTECTED",
"_revision": 1,
"_system_owned": false,
"display_name": "w1-vc1-c4n17.example.com",
"host_switch_spec": {
"host_switches": [
{
"cpu_config": [],
"ecmp_mode": "L3",
"host_switch_id": "50 01 cb 21 be 19 cb 38-78 bd 67 bc b3 0e 91 f1",
"host_switch_mode": "STANDARD",
"host_switch_name": "w1-vc1-c4-dvs",
"host_switch_profile_ids": [
{
"key": "UplinkHostSwitchProfile",
"value": "/infra/host-switch-profiles/6d7a0ed8-c86a-4190-9121-ce6f863226ae"
},
{
"key": "VtepHAHostSwitchProfile",
"value": "/infra/host-switch-profiles/0de8282e-7385-4e8e-a905-0c11960db728"
}
],
"host_switch_type": "VDS",
"ip_assignment_spec": {
"ip_pool_id": "/infra/ip-pools/w1-nsx1-esxi-teps",
"resource_type": "StaticIpPoolSpec"
},
"is_migrate_pnics": false,
"not_ready": false,
"portgroup_transport_zone_id": "/infra/sites/default/enforcement-points/default/transport-zones/77166711-1f83-407f-8c27-a4e1b8b4e1e5",
"transport_zone_endpoints": [
{
"transport_zone_id": "/infra/sites/default/enforcement-points/default/transport-zones/4b367ddf-d4ac-460b-a884-24846ff4edf6",
"transport_zone_profile_ids": [
{
"profile_id": "/infra/transport-zone-profiles/52035bb3-ab02-4a08-9884-18631312e50a",
"resource_type": "BfdHealthMonitoringProfile"
}
]
},
{
"transport_zone_id": "/infra/sites/default/enforcement-points/default/transport-zones/bc19b340-f0b5-46d8-9454-6d94d3288821",
"transport_zone_profile_ids": [
{
"profile_id": "/infra/transport-zone-profiles/52035bb3-ab02-4a08-9884-18631312e50a",
"resource_type": "BfdHealthMonitoringProfile"
}
]
}
],
"uplinks": [
{
"uplink_name": "uplink-2",
"vds_uplink_name": "uplink2"
},
{
"uplink_name": "uplink-1",
"vds_uplink_name": "uplink1"
}
]
}
],
"resource_type": "StandardHostSwitchSpec"
},
"id": "w1-vc1-c4n17-6adb838f-669c-48ca-b76f-e1238984ef93host-2171",
"is_overridden": false,
"maintenance_mode": "DISABLED",
"marked_for_delete": false,
"node_deployment_info": {
"compute_collection_id": "6adb838f-669c-48ca-b76f-e1238984ef93:domain-c2147",
"discovered_ip_addresses": [
"x.x.x.x",
"x.x.x.x"
],
"discovered_node_id": "6adb838f-669c-48ca-b76f-e1238984ef93:host-2171",
"fqdn": "w1-vc1-c4n17.example.com",
"ip_addresses": [
"10.x.x.x"
],
"managed_by_server": "10.x.x.x",
"os_type": "ESXI",
"os_version": "x.x.x"
},
"overridden": false,
"owner_id": "1ae23909-d587-4683-a515-4c2001940803",
"parent_path": "/infra/sites/default/enforcement-points/default",
"path": "/infra/sites/default/enforcement-points/default/host-transport-nodes/w1-vc1-c4n17-6adb838f-669c-48ca-b76f-e1238984ef93host-2171",
"realization_id": "c2c69a21-698a-4586-869a-7c0b0a651601",
"relative_path": "w1-vc1-c4n17-6adb838f-669c-48ca-b76f-e1238984ef93host-2171",
"remote_path": "",
"resource_type": "HostTransportNode",
"unique_id": "c2c69a21-698a-4586-869a-7c0b0a651601"
}
我想通过更改以下行来更新该对象:
"host_switch_mode": "STANDARD",
到:
"host_switch_mode": "LEGACY",
我会将结果 JSON 作为消息体传递给 POST API 调用。我尝试过 anislbe 的组合过滤器,但没有得到预期的结果。例如:
- Name: example post/put API call
uri:
url: "https://{{ nsx }}/policy/api/v1/infra/host-transport-node-profiles/{{ id }}"
force_basic_auth: yes
validate_certs: no
headers:
Accept: "application/json"
Content-Type: "application/json"
user: "{{ username }}"
password: "{{ password }}"
method: PUT
body: "{{ ouput | combine( {'host_switch_spec': {'host_switches': [ {'host_switch_mode': "LEGACY"},],}, }, recursive=true) }}"
status_code: "200"
body_format: json
使用组合过滤器,我看到的是,整个 host_switch_spec 部分被替换(因此丢失了其他属性,如 host_switch_name、host_switch_id 等),而不是仅仅合并相关行,这不是我想要的:
"host_switch_spec": {
"host_switches": [
{
"host_switch_mode": "STANDARD"
}
],
"resource_type": "StandardHostSwitchSpec"
},
我做错了什么?我查看了组合过滤器的手册页,并尝试了所有list_merge选项,但都无济于事。
更新:
为了简单起见,我在上一篇文章中没有提到的一个复杂问题是,我有一个包含这些“输出”数据对象的列表,我需要像下面这样循环处理它们。假设这个列表在变量“tn”中:
# Modify the transport node json data on the fly and feed it to the API as message body
- debug:
msg:
- "{{ item }}"
- "{{ item | combine( {'host_switch_spec': {'host_switches': [ {'host_switch_mode': mode}, ], }, },) }}"
with_items: "{{ tn }}"
loop_control:
label: "{{ item.display_name }}"
概括:
感谢大家的帮助和指导。我还没有完成端到端测试,但以下是我根据 Vladimir Botka 提供的精彩示例得出的结论:
# how to modify the transport node json data on the fly and feed it to the API as message body
- name: Testing switch mode update on the fly
debug:
msg:
#- "hs: {{ (item.host_switch_spec.host_switches + [ hs_update ]) | combine }}"
#- "update: {{ {'host_switch_spec': {'host_switches': [ (item.host_switch_spec.host_switches + [ hs_update ]) | combine ]}} }}"
#- "result: {{ item | combine({'host_switch_spec': {'host_switches': [ (item.host_switch_spec.host_switches + [ hs_update ]) | combine ]}}) }}"
- "{{ item | combine({'host_switch_spec': {'host_switches': [ (item.host_switch_spec.host_switches + [ hs_update ]) | combine ]}}) }}"
loop: "{{ tn }}"
loop_control:
label: "{{ item.display_name }}"
index_var: counter
vars:
hs_update:
host_switch_mode: "LEGACY"
结果看起来很有希望(显示最后一个-#24,并且仅显示部分以避免混乱):
ok: [localhost] => (item=w11-vc1-c1n24.example.com) => {
"msg": [
"24':' STANDARD",
{
"_create_time": 1743198123451,
"_create_user": "system",
"_last_modified_time": 1743445520238,
"_last_modified_user": "system",
"_protection": "NOT_PROTECTED",
"_revision": 2,
"_system_owned": false,
"display_name": "w11-vc1-c1n24.example.com",
"host_switch_spec": {
"host_switches": [
{
"cpu_config": [],
"ecmp_mode": "L3",
"host_switch_id": "50 1e 66 c9 c5 fb da b3-5e 1f 45 fc 2a 42 99 50",
"host_switch_mode": "LEGACY",
"host_switch_name": "w11-vc1-dvs",
"host_switch_profile_ids": [
{
"key": "UplinkHostSwitchProfile",
"value": "/infra/host-switch-profiles/ace9be64-9728-4340-968e-a62dae6a3d00"
},
{
"key": "VtepHAHostSwitchProfile",
"value": "/infra/host-switch-profiles/0de8282e-7385-4e8e-a905-0c11960db728"
}
],
"host_switch_type": "VDS",
output.host_switch_spec.host_switches
是包含一个项目的列表将要更新的内容输入字典中。例如:
合并词典
给出
注意:如果有更多项目,您必须创建一个产品并映射组合功能。
创建字典更新
并合并结果
给出
完整测试剧本示例
问:** “‘host_switch_spec’ 同时具有‘host_switches’ 和‘resource_type’ ”
A:递归地合并字典
给出
问:“这些‘输出’数据对象的列表。”
A:如果项目较多,例如:
更新所有项目
给出
然后,合并词典
给出