如果 Ansible 中有条件,如何在使用 jinja2 时删除多余的大括号

How to remove the extra curly bracket while using jinja2 if condition in Ansible

我正在使用 jinja2 模板和 json(base.json) 文件创建一个新的 JSON 列表。在迭代 json 文件时输出有额外的大括号,该文件不满足在 json 文件中包含 hubs 数组的条件。

强文本

[
    {
        "ansible_loop_var": "item",
        "item": {
            "subnet": "192.168.127.0/24",
            "useVpn": false
        },
        "json": {
            "mode": "none"
        },
        "msg": "OK (unknown bytes)"
    
    },
    {
        "ansible_loop_var": "item",
        "item": {
            
            "subnet": "192.168.128.0/24",
            "useVpn": false
        },
        "json": {
            "mode": "none"
        },
        "msg": "OK (unknown bytes)",
        "pragma": "no-cache",
        "redirected": false,
        "server": "nginx/1.21.4",
        "status": 200
    },
    {
        "ansible_loop_var": "item",
        "invocation": {
            "module_args": {
                
                "status_code": [
                    200
                ],
                
                "validate_certs": false
            }
        },
        "item": {
            "name": "MGMT",
            "networkId": "987654321",
            "subnet": "1.1.1.1/28",
            "useVpn": false
        },
        "json": {
            "hubs": [
                {
                    "hubId": "123456789",
                    "useDefaultRoute": false
                }
            ],
            "mode": "spoke",
            "subnets": [
                {
                    "localSubnet": "1.1.1.1/28",
                    "useVpn": false
                }
            ]
        },
        "msg": "OK (unknown bytes)"
    }
]

Jinja 模板

[
    {% for dict_item in base %}
    {% if dict_item['json']['hubs'] is defined %}
    {
    "netid": "{{ dict_item['item']['networkId'] }}",
    "mgmt-subnet": "{{ dict_item['item']['subnet'] }}",
    "mode": "{{ dict_item['json']['mode'] }}",
    {% if dict_item['json']['hubs'] is defined %}
    "hubs": [
            {% for item in dict_item['json']['hubs'] %}
            {
            "hubId": "{{ item['hubId'] }}",
            "useDefaultRoute": {{ item['useDefaultRoute'] | lower}}
            }{% if not loop.last %},
            {% endif %}
            {% endfor %}
            ],
    {% endif %}
    {% if dict_item['json']['subnets'] is defined %}
    "subnets": [
            {% for item in dict_item['json']['subnets'] %}
            {
            "localSubnet": "{{ item['localSubnet'] }}",
            "useVpn": {{ item['useVpn'] | lower}}
            }{% if not loop.last %},
            {% endif %}
            {% endfor %}
            ]
    {% endif %}
    {% endif %}
    }{% if not loop.last %},
    {% endif %}
    {% endfor %}
]

当前输出JSON

[
},
    },
    {
"netid": "987654321",
"mgmt-subnet": "10.28.64.128/28",
"mode": "spoke",
"hubs": [
            {
"hubId": "123456789",
"useDefaultRoute": false
}                        ],
"subnets": [
            {
"localSubnet": "1.1.1.1/28",
"useVpn": false
}                       ]
}    ]

预期输出JSON 在迭代 base.json 时需要删除最初的额外大括号,它不包含数组 hubs

[
    {
"netid": "987654321",
"mgmt-subnet": "10.28.64.128/28",
"mode": "spoke",
"hubs": [
            {
"hubId": "123456789",
"useDefaultRoute": false
}                        ],
"subnets": [
            {
"localSubnet": "1.1.1.1/28",
"useVpn": false
}                       ]
}    ]

你可以写这个 jinja2 模板:你只循环 if dict_item['json']['hubs'] is defined

[
    {% for dict_item in base if dict_item['json']['hubs'] is defined %}
    {
    "netid": "{{ dict_item['item']['networkId'] }}",
    "mgmt-subnet": "{{ dict_item['item']['subnet'] }}",
    "mode": "{{ dict_item['json']['mode'] }}",
    "hubs": [
            {%      for item in dict_item['json']['hubs'] %}
            {
            "hubId": "{{ item['hubId'] }}",
            "useDefaultRoute": {{ item['useDefaultRoute'] | lower}}
            }{% if not loop.last %},
             {%  endif %}          
            {%      endfor %}
            ],
    {%          if dict_item['json']['subnets'] is defined %}
    "subnets": [
            {%      for item in dict_item['json']['subnets'] %}
            {
            "localSubnet": "{{ item['localSubnet'] }}",
            "useVpn": {{ item['useVpn'] | lower}}
            }{% if not loop.last %},
             {% endif %}
            {%      endfor %}
            ]
    {%          endif %}
    }{% if not loop.last %},
     {% endif %}
    {% endfor %}
]

结果:

[
        {
    "netid": "987654321",
    "mgmt-subnet": "1.1.1.1/28",
    "mode": "spoke",
    "hubs": [
                        {
            "hubId": "123456789",
            "useDefaultRoute": false
            }          
                        ],
        "subnets": [
                        {
            "localSubnet": "1.1.1.1/28",
            "useVpn": false
            }                        ]
        }    ]