用默认值处理from_json过滤器失败的好方法 [英] Elegant way to handle from_json filter failure with default value
问题描述
我正在寻找您的想法,以巧妙地处理 from_json
过滤器故障.
I'm seeking for your ideas to elegantly handle a from_json
filter failure when it happens.
我在ansible角色中有一个通用任务,可用于在sonatype nexus存储库管理器中调用不同的groovy脚本(完整角色为可在github上找到)
I have a generic task in an ansible role that I use to call different groovy script in sonatype nexus repository manager (the full role is available on github)
- name: Calling Groovy script {{ script_name }}
uri:
url: "{{ nexus_api_scheme }}://{{ nexus_api_hostname }}:{{ nexus_api_port }}\
{{ nexus_api_context_path }}{{ nexus_rest_api_endpoint }}/{{ script_name }}/run"
user: 'admin'
password: "{{ current_nexus_admin_password }}"
headers:
Content-Type: "text/plain"
method: POST
force_basic_auth: yes
validate_certs: "{{ nexus_api_validate_certs }}"
body: "{{ args | to_json }}"
register: script_run
我所有的脚本都返回一个json映射
The scripts I call all return a json map
{
"name": "name of the script"
"result": "whatever was used as a groovy return statement"
}
注意:无法从groovy向此地图添加任何其他内容,我只能在 result
Note: there is no way to add anything else to this map from groovy, I can only push data back to ansible in the result
现在,我想使用 result
进一步详细说明我的脚本调用是否导致错误,更改或正常状态.一些常规脚本完全可感知",并且会在 result
中返回一个转义的json字符串,我可以使用该字符串检查错误/更改.但是(暂时而言)其他一些脚本不是可感知的"(或者我自己无法更改),并且会在 result
中返回一个简单的字符串(在大多数情况下,没有任何可用的信息)
Now, I want to use result
to further detail if my script call leads to an error, a change or an ok status in ansible. Some groovy scripts are fully "ansible aware" and will return in result
an escaped json string I can use to check for error/changes. But (for time being...) some other scripts are not "ansible aware" (or I cannot change them myself) and will return in result
a simple string (without any usable information in most cases).
现在是我真正的问题:如果我得到json结果,我想用它来检查失败或更改.如果不是json结果,我将仅依靠http 200获得成功(直到脚本可以修复).
Now my real problem: If I get a json result I want to use it to check for failure or change. If its not a json result, I'll just rely on the http 200 for a success (until the script can be fixed).
我几乎可以在任务中使用以下选项:
I was almost there with the following options to my task:
failed_when: >-
script_run.status != 200
or
(script_run.json.result | from_json | default({})).error | default(false) | bool
changed_when: >-
(script_run.json.result | from_json | default({})).changed | default(false) | bool
不幸的是,当 result
是一个简单的字符串时, from_json
会引发错误(期望值:第1行第1列(字符0)
),然后应用默认设置,然后我的剧本就结束了.
Unfortunatelly, when result
is a simple string, from_json
will fire an error (Expecting value: line 1 column 1 (char 0)
) before the default can be applied and my playbook ends there.
我当前的解决方法是添加另一个条件,以在尝试读取json之前检查 result
是否以 {
开头,但是我对此并不满意(因为json字符串可能仍然损坏,仍然会导致错误)
My current workaround is to add another condition to check if result
starts with a {
before trying to read json but I'm not really happy with this (as the json string might still be corrupted and still lead to an error)
如果您有任何经验/想法如何合理地使用默认值处理此json解码错误或很好地检查字符串是否可以在ansible中解码为json,我将接受所有建议.
If any of you have experience/idea on how to gracefully handle this json decode error with a default value or to nicelly check if a string can be decoded as json in ansible, I'll take all suggestions.
推荐答案
我发现,在 failed_when
/ changed_when
中编写复杂的内容很容易失控.您是否尝试过创建过滤器,然后执行以下操作,如 failed_when:script_run |my_role_failed
?
I found out that writing complex stuff in failed_when
/changed_when
can get easily out of hand. Have you tried creating a filter and then do something like failed_when: script_run | my_role_failed
?
https://gist.github.com/tuxfight3r/37048ba536575277f5f4d26813d69489
过滤器位于您的角色中,位于 filter_plugins/
下,因此分发不成问题.您甚至可以创建空的ansible角色,这些角色仅定义过滤器,然后将它们包含在其他角色中(通过 meta/main.yml
)以在其中使用.
filters live inside your ansible role, under filter_plugins/
, so distribution shouldnt be an issue. You can go as far as creating empty ansible roles that only define filters and then include them in other roles (through meta/main.yml
) to be used there.
这篇关于用默认值处理from_json过滤器失败的好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!