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

问题描述 投票:1回答:1

摘要

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

所需的值是cicontent.data字段内的json.data字段(参见下面的输出)。

重现步骤

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还是Dict?

- 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 }}一样?

json ansible yaml jinja2
1个回答
0
投票

虽然jsondata是他们的resp对象的关键,但ci只是一个更大的字符串的一部分(碰巧看起来像一个JSON对象)

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

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

然后你可以期待使用"{{ output.json.data.ci }}",但不是当.ci部分只是字符串的正常部分。

© www.soinside.com 2019 - 2024. All rights reserved.