我正在try 修改JSON文件中的几个值.要做到这一点,最有效的方法似乎是使用UPDATE_FACT模块,它需要输出到寄存器.我遇到的问题是,我需要运行一个JSON查询来找到我需要修改的数据.

当我try 使用UPDATE_FACT修改json文件时,我希望在单个UPDATE_FACT块中使用json_Query,这样我就不需要在末尾go 掉递归寄存器名称,但每次try 时,Ansible都会告诉我 msg: 'template error while templating string: unexpected char ''?'' at 40. String: {{ jsondata.stigs[0].rules| json_query([?group_id==V-256376].comments)}}'

有没有更好的方法来做到这一点,而不必try 和打破JSON文件完全分开,修改每个部分,并try 把它放回一起.这样做的最终目标是修改一堆vule并将其输出到文件中.

我的 playbook

  tasks:
    - name: Read file directly into fact
      set_fact:
        jsondata: "{{ lookup('file', './files/U_VMW_vSphere_7-0_ESXi_V1R2_Manual_STIG.cklb') | from_json}}"
    - debug:
        msg: "{{ test.stigs[0].rules|json_query(query)}}"
      vars:
        groupid: 'V-256376'
        query: "[?group_id=='{{ groupid }}'].discussion"
      register: v256376

    - name: update IP address
      ansible.utils.update_fact:
        updates:
          - path:  jsondata.target_data.ip_address
            value: "10.10.10.10"
          - path:  jsondata.target_data.host_name
            value: "{{ esxserver }}"
          - path: "{{ jsondata.stigs[0].rules| json_query([?group_id==V-256376].comments)}}"
            value: "this worked" 
      register:  jsondata 

Edit adding mre for follow up question 判断表json文件精简为2个示例

    {
      "stigs": [
        {
          "rules": [
            {
              "group_id": "V-256375",
              "status": "not_reviewed",
              "comments": "",
              "finding_details": ""
            },
            {
              "group_id": "V-256375",
              "status": "not_reviewed",
              "comments": "",
              "finding_details": ""
            }
        }   
      }

对于每个group_id,我需要进行一个API调用来判断,然后将状态字段更改为OPEN或NOT_A_FINDING,然后使用API调用的输出填充COMMENTS/FINDING_DETAILS.

推荐答案

给出mre个用于测试的YAML数据(格式不重要)

shell> cat files/stig.yml
target_data:
  ip_address: 10.10.10.99
  host_name: server
  stigs:
    - rules:
        - group_id: V-256376
          comments: comments for gid V-256376
        - group_id: V-256377
          comments: comments for gid V-256377

读一读文件

    - set_fact:
        jsondata: "{{ lookup('file', 'files/stig.yml')|from_yaml }}"

赠送

  jsondata:
    target_data:
      host_name: server
      ip_address: 10.10.10.99
      stigs:
      - rules:
        - comments: comments for gid V-256376
          group_id: V-256376
        - comments: comments for gid V-256377
          group_id: V-256377

问:100

从您的查询(如下)可以看出,您希望将group_idcomments更新为等于stigs中第一项的第rules项中的V-256376

- path: "{{ jsondata.stigs[0].rules|
            json_query([?group_id==V-256376].comments) }}"
  value: this worked

答:这是不可能的.参数path表示:

它应该是一个有效的Jinja参考.

您的json_query的结果不是有效的进士推荐信.相反,您可以使用更新创建 struct (S).例如,一本词典

  gid_comments:
    V-256376: this worked

并用它来更新事实.创建要更新的列表

  stigs_0_rules: |
    [{% for i in jsondata.target_data.stigs.0.rules %}
    {{ i|combine({'comments': gid_comments[i.group_id]|d(i.comments)}) }},
    {% endfor %}]

赠送

  stigs_0_rules:
  - comments: this worked
    group_id: V-256376
  - comments: comments for gid V-256377
    group_id: V-256377

现在,使用列表stigs_0_rules来更新事实

    - ansible.utils.update_fact:
        updates:
          - path:  jsondata.target_data.ip_address
            value: 10.10.10.10
          - path:  jsondata.target_data.host_name
            value: esx-server
          - path: jsondata.target_data.stigs.0.rules
            value: "{{ stigs_0_rules }}"
      register: update

赠送 what you want

  update.jsondata:
    target_data:
      host_name: esx-server
      ip_address: 10.10.10.10
      stigs:
      - rules:
        - comments: this worked
          group_id: V-256376
        - comments: comments for gid V-256377
          group_id: V-256377

完整的测试攻略示例

- hosts: all

  vars:

    gid_comments:
      V-256376: this worked

    stigs_0_rules: |
      [{% for i in jsondata.target_data.stigs.0.rules %}
      {{ i|combine({'comments': gid_comments[i.group_id]|d(i.comments)}) }},
      {% endfor %}]

  tasks:

    - set_fact:
        jsondata: "{{ lookup('file', 'files/stig.yml')|from_yaml }}"
    - debug:
        var: jsondata

    - debug:
        var: stigs_0_rules

    - ansible.utils.update_fact:
        updates:
          - path:  jsondata.target_data.ip_address
            value: 10.10.10.10
          - path:  jsondata.target_data.host_name
            value: esx-server
          - path: jsondata.target_data.stigs.0.rules
            value: "{{ stigs_0_rules }}"
      register: update

    - debug:
        var: update.jsondata

Json相关问答推荐

JOLT拉平数组

kotlinx-serialization:如何将具有不同类型对象的JsonArray转换为同一个Class

遍历 JSON,检索父值

Jolt 变换 - 如何用字段值重命名字段?

如何在 Django 的模板语言中获取 json 键和值?

序列化特定类型时如何使 JSON.Net 序列化程序调用 ToString()?

没有很多类的 GSON 解析

Java JSON 序列化 - 最佳实践

十六进制格式可以与 JSON 文件一起使用吗?如果是这样,怎么做?

如何使用 LWP 发出 JSON POST 请求?

JSON.parse 返回字符串而不是对象

在 React 中访问子级的父级状态

使用适用于 Python 的 Google API - 我从哪里获取 client_secrets.json 文件?

在 Java 中比较两个 JSON 文件的最佳方法

java.lang.BootstrapMethodError:调用站点#4 bootstrap 方法的异常,初始化 retrofit 时

如何对 jq 中的 map 数组中的值求和?

雅虎财经全币种报价 API 文档

如何在 React js 中解析本地 JSON 文件?

从动态 json 数据更新力有向图上的链接

无法解析 JSON 文件中的 TAB