为什么Ansible无法将Unicode字符串读取为JSON?

时间:2019-04-18 18:17:09

标签: json ansible yaml jinja2

摘要

在Ansible中使用uri模块检索数据时,我无法将其一部分解析为JSON来检索嵌套值。

期望的值是cicontent.data字段内的json.data字段(请参见下面的 output )。

复制步骤

site.yml

--- 
- hosts: localhost 
  gather_facts: false 
  tasks: 
    - name: Get String 
      uri: 
        url: "http://localhost/get-data" 
        method: POST 
        body_format: json 
        body: "{ \"kong-jid\": \"run-sn-discovery\" }"
        return_content: yes 
      register: output 

    - set_fact:
        ci: "{{ output.json.data.ci }}"

    - debug:
        msg: "{{ ci }}"

{{output}}变量

{
  u'status': 200, 
  u'cookies': {}, 
  u'url': u'http://kong-demo:8000/get-data', 
  u'transfer_encoding': u'chunked', 
  u'changed': False, 
  u'connection': u'close', 
  u'server': u'kong/0.34-1-enterprise-edition', 
  u'content': 
  u'{"data":"\\"{u\'ci\': u\'3bb8d625dbac3700e4f07b6e0f96195b\'}\\""}', 
  'failed': False, 
  u'json': {u'data': u'"{u\'ci\': u\'3bb8d625dbac3700e4f07b6e0f96195b\'}"'}, 
  u'content_type': u'application/json', 
  u'date': u'Thu, 18 Apr 2019 15:50:25 GMT', 
  u'redirected': False, 
  u'msg': u'OK (unknown bytes)'
}

结果

[user@localhost]$ ansible-playbook site.yml
 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] ***************************************************************************************************************

TASK [Pass Redis data to next task as output] **********************************************************************************
ok: [localhost]

TASK [set_fact] ****************************************************************************************************************
fatal: [localhost]: FAILED! => {}

MSG:

The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'ci'

The error appears to have been in 'site.yml': line 19, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


    - set_fact:
      ^ here

exception type: <class 'ansible.errors.AnsibleUndefinedVariable'>
exception: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'ci'

重要的故障排除信息

看来,根本问题与所解释的Ansible类型有关。我希望在一项任务中从输出中解析ci

下面显示的两个任务的解决方案有效,但是这使我相信这应该在一行即可。

两任务解决方案

- set_fact:
    ci: "{{ output.json.data | from_json }}"

- debug:
    msg: "{{ ci['ci'] }}"

但是ci中的{{ output.json.data | from_json }}事实集报告的TYPE与内联类型不同...

Unicode还是字典?

- debug:
    msg: "{{ output.json.data | from_json | type_debug }}" # returns unicode

- set_fact:
    ci: "{{ output.json.data | from_json }}"

- debug:
    msg: "{{ ci | type_debug }}" # returns dict

为什么不是{{ output.json.data | from_json | type_debug }}
{{ ci | type_debug }}一样?

1 个答案:

答案 0 :(得分:0)

尽管jsondata是其res对象中的键,但是ci只是一个较大字符串的一部分(恰好看起来像JSON对象

如果数据结构中的相关行为:

u'json': {u'data': {'ci': u'3bb8d625dbac3700e4f07b6e0f96195b'}}, 

那么您可能希望使用"{{ output.json.data.ci }}",但是如果.ci部分只是字符串的普通部分,则不会使用。