ansible 修改嵌套字典中的删除值

ansible modify a delete value in nested dictonary

我想在嵌套字典中添加新值,旧值应该被删除。

这是我的 parse.json 文件。

{
    "class": "Service_HTTPS",
    "layer4": "tcp",
    "profileTCP": {
        "egress": {
            "use": "/Common/Shared/f5-tcp-wan"
        },
        "ingress": {
            "use": "/Common/Shared/f5-tcp-lan"
        }
    }
}

这是我的脚本,它会添加新值但也会保留旧值,我知道我正在使用 recursive=True 但没有这个命令我会丢失入口密钥。 这是我的脚本

- set_fact:
        json_file: "{{ lookup('file', 'parse.json')   }}"
    

    - set_fact:
        json_file: "{{ json_file | combine( egress_modify, recursive=True) }}"
      when: json_file['profileTCP']['egress'] is defined
      vars: 
        egress_modify: "{{ json_file  | combine({ 'profileTCP': { 'egress': { 'bigip': '/Common/' + json_file['profileTCP']['egress']['use'].split('/')[-1] } }}) }}" 
        

    - name: debug
      debug:
          msg: "{{ json_file }}"

错误的结果

ok: [localhost] => {
    "msg": {
        "class": "Service_HTTPS",
        "layer4": "tcp",
        "profileTCP": {
            "egress": {
                "bigip": "/Common/f5-tcp-wan",
                "use": "/Common/Shared/f5-tcp-wan"
            },
            "ingress": {
                "use": "/Common/Shared/f5-tcp-lan"
            }
        }
    }
}

但我想要这个结果

ok: [localhost] => {
    "msg": {
        "class": "Service_HTTPS",
        "layer4": "tcp",
        "profileTCP": {
            "egress": {
                "bigip": "/Common/f5-tcp-wan",
            },
            "ingress": {
                "use": "/Common/Shared/f5-tcp-lan"
            }
        }
    }
}


dicts 在 ansible 中是“实时”的,所以你可以继续做“set_fact:, loop:”业务,或者你可以一次完成所有操作:

    - set_fact:
        json_file: >-
          {%- set j = lookup('file', 'parse.json') | from_json -%}
          {%- set tcp_egress_use = j.profileTCP.egress.pop('use') -%}
          {%- set _ = j.profileTCP.egress.update({
                'bigip': '/Common/' + tcp_egress_use.split('/')[-1]
              }) -%}
          {{ j }}

生产

    "json_file": {
      "class": "Service_HTTPS",
      "layer4": "tcp",
      "profileTCP": {
        "egress": {
          "bigip": "/Common/f5-tcp-wan"
        },
        "ingress": {
          "use": "/Common/Shared/f5-tcp-lan"
        }
      }
    }