7

我正在尝试在 Ansible 中过滤从 boto3 到达的结果。

当我对没有“[?starts_with(...)]”的结果使用json查询时,它运行良好,但是当添加starts_with语法时:

"state_machines[?starts_with(name,'hello')].state_machine_arn"

为了过滤结果:

{u'boto3': u'1.4.4', u'state_machines': 
[{u'state_machine_arn': u'<state machine arn 1>', u'name': u'hello_world_sfn', u'creation_date': u'2017-05-16 14:26:39.088000+00:00'}, 
{u'state_machine_arn': u'<state machine arn 2>', u'name': u'my_private_sfn', u'creation_date': u'2017-06-08 07:25:49.931000+00:00'}, 
{u'state_machine_arn': u'<state machine arn 3>', u'name': u'alex_sfn', u'creation_date': u'2017-06-14 08:35:07.123000+00:00'}], 
u'changed': True}" }

我希望得到第一个 state_machine_arn 值:“state machine arn 1”

但相反,我得到了例外:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: JMESPathTypeError: In function contains(), invalid type for value: <lamdba_name>, expected one of: ['array', 'string'], received: "unknown" fatal: [localhost]: FAILED!
=> {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}

可能是什么问题?

4

2 回答 2

12

问题是 json_query 过滤器期望得到一个带有 ascii 字符串的字典,但是你提供的是 unicode 字符串(注意u'blabla'你的输入)。

这是 json_query 的一个问题,显然是在 Ansible 2.2.1 中引入的(虽然这不是很清楚),这里有更多细节: https ://github.com/ansible/ansible/issues/20379#issuecomment-284034650

我希望这在未来的版本中得到修复,但现在这是一个对我们有用的解决方法:

"{{ results | to_json | from_json | json_query(jmespath_query) }}"

Wherejmespath_query是一个包含starts_with查询的变量。这种往返 json 的技巧将 unicode 字符串转换为 ASCII 字符串 :)

于 2017-06-14T14:14:33.767 回答
0

作为| to_json | from_json | json_query(…)到处编写的替代方法,您可以json_query通过创建以下filter_plugins/json_bug_workaround.py文件来猴子修补 Ansible 的过滤器:

import json
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.filter.json_query import json_query 

class FilterModule(object):
    def filters(self):
        return {
            # Workaround for Unicode bug https://stackoverflow.com/a/44547305
            'json_query': lambda data, query: json_query(
                json.loads(json.dumps(data, cls=AnsibleJSONEncoder)),
                query
            ),
        }

然后你就可以| json_query(…)自然使用了。该垫片相当于呼叫| to_json | from_json您。

您可以将它放在您的角色 ( ) 中或Ansible 的插件搜索路径中的任何位置。roles/role_name/filter_plugins/json_bug_workaround.py

于 2019-06-14T00:05:03.410 回答