使用默认值处理 from_json 过滤器失败的优雅方法 [英] Elegant way to handle from_json filter failure with default value
问题描述
我正在寻求您的想法,以便在 from_json
过滤器失败发生时优雅地处理它.
我在 ansible 角色中有一个通用任务,我用来在 sonatype nexus 存储库管理器中调用不同的 groovy 脚本(完整角色是 在 github 上可用)
- name: 调用 Groovy 脚本 {{ script_name }}里:url: "{{ nexus_api_scheme }}://{{ nexus_api_hostname }}:{{ nexus_api_port }}\{{ nexus_api_context_path }}{{ nexus_rest_api_endpoint }}/{{ script_name }}/run"用户:'管理员'密码:{{ current_nexus_admin_password }}"标题:内容类型:文本/纯文本"方法:POSTforce_basic_auth: 是validate_certs: "{{ nexus_api_validate_certs }}"正文:{{ args | to_json }}"注册:script_run
我调用的脚本都返回一个json映射
<代码>{"name": "脚本名称""result": "任何用作常规返回语句的内容"}
注意:没有办法从groovy向这张地图添加任何其他内容,我只能在result
现在,我想使用 result
进一步详细说明我的脚本调用是否导致 ansible 中的错误、更改或 ok 状态.一些 groovy 脚本是完全ansible 感知"的,并且会在 result
中返回一个转义的 json 字符串,我可以用它来检查错误/更改.但是(暂时......)其他一些脚本不是可感知的"(或者我无法自己更改它们)并且将在 result
中返回一个简单的字符串(在大多数情况下没有任何可用信息).
现在我真正的问题是:如果我得到一个 json 结果,我想用它来检查失败或更改.如果它不是 json 结果,我将仅依靠 http 200 获得成功(直到可以修复脚本).
我几乎完成了以下任务:
failed_when: >-script_run.status != 200或者(script_run.json.result | from_json | default({})).error |默认(假)|布尔值changed_when: >-(script_run.json.result | from_json | default({})).changed |默认(假)|布尔值
不幸的是,当 result
是一个简单的字符串时,from_json
会触发一个错误(Expecting value: line 1 column 1 (char 0)
) 之前可以应用默认值,我的剧本就到此为止.
我目前的解决方法是在尝试读取 json 之前添加另一个条件来检查 result
是否以 {
开头,但我对此并不满意(因为json 字符串可能仍然损坏并仍然导致错误)
如果你们有关于如何使用默认值优雅地处理这个 json 解码错误或很好地检查字符串是否可以在 ansible 中解码为 json 的经验/想法,我会接受所有建议.
我发现在 failed_when
/changed_when
中编写复杂的东西很容易失控.您是否尝试过创建过滤器然后执行类似 failed_when: script_run | 的操作?my_role_failed
?
https://gist.github.com/tuxfight3r/37048ba5365781d275365784d27596581d69426 过滤器位于您的 ansible 角色中,位于 I'm seeking for your ideas to elegantly handle a 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) The scripts I call all return a json map Note: there is no way to add anything else to this map from groovy, I can only push data back to ansible in the Now, I want to use 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: Unfortunatelly, when My current workaround is to add another condition to check if 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. I found out that writing complex stuff in https://gist.github.com/tuxfight3r/37048ba536575277f5f4d26813d69489 filters live inside your ansible role, under 这篇关于使用默认值处理 from_json 过滤器失败的优雅方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!filter_plugins/
下,因此分发不应该成为问题.您可以创建仅定义过滤器的空 ansible 角色,然后将它们包含在其他角色中(通过 meta/main.yml
)以在那里使用.from_json
filter failure when it happens.- 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
{
"name": "name of the script"
"result": "whatever was used as a groovy return statement"
}
result
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). 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
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.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)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
? 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.