首页 > 解决方案 > 使用默认值处理 from_json 过滤器失败的优雅方法

问题描述

我正在寻求您的想法,以便在from_json过滤器故障发生时优雅地处理它。

我有一个 ansible 角色的通用任务,我用来在 sonatype nexus 存储库管理器中调用不同的 groovy 脚本(完整角色可在 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 映射

{
"name": "name of the script"
"result": "whatever was used as a groovy return statement"
}

注意:无法从 groovy 向此地图添加任何其他内容,我只能将数据推送回 ansible 中result

result现在,如果我的脚本调用导致 ansible 中的错误、更改或正常状态,我想使用更多详细信息。一些 groovy 脚本是完全“可感知的”,并将返回result一个转义的 json 字符串,我可以使用它来检查错误/更改。但是(暂时......)其他一些脚本不是“可感知的”(或者我自己无法更改它们)并将返回result一个简单的字符串(在大多数情况下没有任何可用信息)。

现在我真正的问题是:如果我得到一个 json 结果,我想用它来检查失败或更改。如果它不是 json 结果,我将仅依靠 http 200 成功(直到可以修复脚本)。

我几乎在那里,我的任务有以下选择:

  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会在应用默认值之前触发错误(Expecting value: line 1 column 1 (char 0)),我的剧本到此结束。

我目前的解决方法是在尝试读取 json 之前添加另一个条件来检查是否result以 a 开头,{但我对此并不满意(因为 json 字符串可能仍然被损坏并且仍然导致错误)

如果你们中的任何人有关于如何用默认值优雅地处理这个 json 解码错误或很好地检查字符串是否可以在 ansible 中解码为 json 的经验/想法,我会接受所有建议。

标签: ansible

解决方案


我发现在failed_when/中写复杂的东西changed_when很容易失控。您是否尝试过创建过滤器然后执行类似的操作failed_when: script_run | my_role_failed

https://gist.github.com/tuxfight3r/37048ba536575277f5f4d26813d69489

过滤器位于您的 ansible 角色中,在 下filter_plugins/,因此分发不应该是一个问题。您可以创建仅定义过滤器的空 ansible 角色,然后将它们包含在其他角色中(通过meta/main.yml)以在那里使用。


推荐阅读