Ansible,行模块未将JSON数据正确保存到文件

Ansible,行模块未将JSON数据正确保存到文件,ansible,Ansible,我有一个设置变量“certData”的剧本,它是一个字典数组。 这就是“certData”的外观: ok: [localhost] => { "msg": [ { "cn": "node1.corp.com", "expires": "2020-11-05T15:20:18+00:00", &qu

我有一个设置变量“certData”的剧本,它是一个字典数组。 这就是“certData”的外观:

ok: [localhost] => {
    "msg": [
        {
            "cn": "node1.corp.com",
            "expires": "2020-11-05T15:20:18+00:00",
            "id": 705,
            "serial": "111"
        },
        {
            "cn": "node2.corp.com",
            "expires": "2020-11-05T15:20:28+00:00",
            "id": 728,
            "serial": "222"
        },
        {
            "cn": "node3.corp.com",
            "expires": "2020-10-28T19:37:29+00:00",
            "id": 670,
            "serial": "333"
        },
        {
            "cn": "node4.corp.com",
            "expires": "2021-04-04T09:55:08+00:00",
            "id": 1163,
            "serial": "444"
        },
        {
            "cn": "node5.corp.com",
            "expires": "2020-11-05T15:20:22+00:00",
            "id": 715,
            "serial": "555"
        }
    ]
}
我有一个剧本,从“certData”中获取数据并将其保存到一个名为cert_expiring.json的文件中,如下所示:

- name: Testing jinja
      lineinfile:
        dest: "./cert_expiring.json"
        line: |-
          {
          "devices": [{
              "items": {
          {%- for i in certData -%}
          {{ "" if loop.first else "," }}
                "{{ i.id }}": "{{ i.cn }}"
          {%- endfor %}
            
              }
          }]
          }
        state: present
        create: yes
playbook成功运行,但发出以下警告:

[WARNING]: The value {'devices': [{'items': {'705': 'node1.corp.com', '715': 'node5.corp.com', '670': 'node3.corp.com', '728': 'node2.corp.com', '1163':
'node4.corp.com'}}]} (type dict) in a string field was converted to u"{'devices': [{'items': {'705': 'node1.corp.com', '715': 'node5.corp.com', '670':
'node3.corp.com', '728': 'node2.corp.com', '1163': 'node4.corp.com'}}]}" (type string). If this does not look like what you expect, quote the entire value to ensure it does not
change.
警告中的数据正是以单引号打印到“cert_expiring.json”文件的方式

certs_expiring.json:

{'devices': [{'items': {'705': 'node1.corp.com', '715': 'node5.corp.com', '670': 'node3.corp.com', '728': 'node2.corp.com', '1163': 'node4.corp.com'}}]}
但是,当我将“cert_expiring.json”的内容加载回变量(expired_certs2)并打印它时,它会正确打印:

 - name: Store file contents into variable
   include_vars:
     file: cert_expiring.json
     name: expired_certs2
    
 - name: Print expired_certs2 variable.
   debug:
     msg: "{{ expired_certs2 | json_query('devices[*].items') }}"
我试着这样引用Jinja代码,但没有帮助:

- name: Testing jinja
      lineinfile:
        dest: "./cert_expiring.json"
        line: |-
          '{
          "devices": [{
              "items": {
          {%- for i in certData -%}
          {{ "" if loop.first else "," }}
                "{{ i.id }}": "{{ i.cn }}"
          {%- endfor %}
            
              }
          }]
          }'
        state: present
        create: yes
此外,尝试使用双引号没有运气

如何以正确的json格式将数据打印到“cert\u expiring.json”文件?

Q:如何以正确的json格式将数据打印到“cert\u expiring.json”文件?

答:使用过滤器来过滤json,例如

-包括变量:
文件:cert_expiring.json
姓名:过期的_证书2
-调试:
msg:{{expired_certs2}to_json}
给予

msg:'{“设备”:[{“项目”:{“705”:“node1.corp.com”,“728”:“node2.corp.com”,“670”:“node3.corp.com”,“1163”:“node4.corp.com”,“715”:“node5.corp.com”}
询问

-调试:
msg:{{expired_certs2.devices | json_query('[].item')| to_json}
给予

msg:'[{“705”:“node1.corp.com”,“728”:“node2.corp.com”,“670”:“node3.corp.com”,“1163”:“node4.corp.com”,“715”:“node5.corp.com”}]

可以简化内容,例如:

-设置事实:
设备:{{devices |默认值([])+
[{'item':certData | items2dict(key_name='id',value_name='cn')}]}”
-副本:
dest:cert\u expiring.json
内容:>
{“设备”:{{devices | to_json}}
给予

shell>cat cert\u expiring.json
{“设备”:[{“项目”:{“705”:“node1.corp.com”,“728”:“node2.corp.com”,“670”:“node3.corp.com”,“1163”:“node4.corp.com”,“715”:“node5.corp.com”}]

当我应用“to_json”过滤器并打印过期的证书2时,我的输出与您的一样打印,但所有的双引号都被删除(“msg”:“{”devices\”:[{”items\”:{“705\”:…)。当我尝试使用
json\查询('[].items')打印时|对于_json
,这将使用转义双引号打印相同的内容。当采用简化方法时,它会工作并使用正确的语法创建cert_expiring.json文件…顺便说一句,设备应该使用双引号是否正确?这取决于回调插件。请参阅
ansible doc-t callback-l
。我使用
yaml
回调插件。转义的引号可能是
json
回调插件的结果。回调插件负责打印数据。Jinja2模板不受回调插件的影响。你是对的。json标准要求双引号。我已经修复了答案。谢谢。
- name: Testing jinja
      lineinfile:
        dest: "./cert_expiring.json"
        line: |-
          '{
          "devices": [{
              "items": {
          {%- for i in certData -%}
          {{ "" if loop.first else "," }}
                "{{ i.id }}": "{{ i.cn }}"
          {%- endfor %}
            
              }
          }]
          }'
        state: present
        create: yes