You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible:如何修改REST API返回的嵌套字典中的指定值?

问题描述

我在多个论坛(包括本论坛)搜索过,但都没找到合适的解决方案。在我的Ansible Playbook中,我使用uri模块调用REST API,并将结果注册为变量result。

result.json的结构如下:

{
"global_api_concurrency_limit": 199,
"client_api_rate_limit": 100,
"client_api_concurrency_limit": 40,
"connection_timeout": 30,
"redirect_host": "",
"protocol_versions": [
{"enabled": true, "name": "TLSv1.1"},
{"enabled": true, "name": "TLSv1.2"}
]
}

通过result.json | type_debug确认这是一个字典类型。我需要将其中name为TLSv1.1的元素的enabled属性修改为false(注意JSON中false无需加引号)。我尝试创建新字典或修改原字典,但不知道如何仅更新该指定值。

我尝试了以下任务,但未能成功:

- name: Call NSXT
    vars:
      api: "/api/v1/cluster/api-service"
    ansible.builtin.uri:
      url: "https://server01{{ api }}"
      user: user1
      password: pwd1
      method: GET
      force_basic_auth: true
      validate_certs: false
      headers:
        Content-Type: application/json
    register: result

  - set_fact:
      newdic: "{{ (newdic | d([])) | combine(new_item, recursive=True) }}"
    with_dict: "{{ result.json }}"
    vars:
      new_item: {'enabled': false}
    when: item.protocol_versions.name == 'TLSv1.1'

注:由于公司限制,我无法安装jmespath用于JSON查询。


解决方案

可以通过Jinja2模板遍历嵌套列表修改指定元素,再重新组合成完整字典,全程无需额外工具。具体步骤如下:

  1. 生成修改后的协议版本列表
    使用set_fact结合Jinja2循环,遍历原列表并修改目标元素的enabled值:
- set_fact:
    updated_protocols: >-
      {% set updated_list = [] %}
      {% for proto in result.json.protocol_versions %}
          {% if proto.name == 'TLSv1.1' %}
              {% do updated_list.append(proto | combine({'enabled': false})) %}
          {% else %}
              {% do updated_list.append(proto) %}
          {% endif %}
      {% endfor %}
      {{ updated_list }}
  1. 组合原字典与修改后的列表
    用combine方法替换原字典中的protocol_versions字段,生成最终的更新后字典:
- set_fact:
    updated_result: "{{ result.json | combine({'protocol_versions': updated_protocols}, recursive=True) }}"
  1. 完整Playbook示例
    整合后的完整Playbook如下:
- name: Fetch NSXT config and update TLSv1.1 setting
  hosts: localhost
  tasks:
    - name: Call NSXT API to get config
      vars:
        api: "/api/v1/cluster/api-service"
      ansible.builtin.uri:
        url: "https://server01{{ api }}"
        user: user1
        password: pwd1
        method: GET
        force_basic_auth: true
        validate_certs: false
        headers:
          Content-Type: application/json
      register: result

    - name: Update TLSv1.1 enabled status to false
      set_fact:
        updated_protocols: >-
          {% set updated_list = [] %}
          {% for proto in result.json.protocol_versions %}
              {% if proto.name == 'TLSv1.1' %}
                  {% do updated_list.append(proto | combine({'enabled': false})) %}
              {% else %}
                  {% do updated_list.append(proto) %}
              {% endif %}
          {% endfor %}
          {{ updated_list }}

    - name: Generate updated config dictionary
      set_fact:
        updated_result: "{{ result.json | combine({'protocol_versions': updated_protocols}, recursive=True) }}"

    # 可选:打印结果验证修改是否生效
    - name: Print updated config
      debug:
        var: updated_result

关键说明

  • 使用Jinja2的{% do %}语句向空列表添加元素,避免循环任务的冗余逻辑
  • combine方法配合recursive=True确保嵌套字典的字段正确替换
  • 全程仅依赖Ansible内置功能,无需安装额外工具

内容的提问来源于stack exchange,提问作者Kelvin Wong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:06:27