Ansible:如何从剧本打印警告?

问题描述 投票:0回答:5

我可以从 Ansible 打印警告消息吗?就像 Ansible 对内部警告所做的那样:

[WARNING]: Ignoring invalid attribute: xx

目标用途是警告,这不是错误,因此它们不应该结束 playbook 执行,但它们应该清晰可见(采用标准 Ansible 紫色)。

使用示例:

  1. 我有一些最新版本的硬编码 URL。
  2. 剧本下载最新的可用 URL。
  3. 如果 URL 不同,则打印警告。
  4. 由于来源不可信,下载的URL只能用于比较,不能直接使用。
ansible
5个回答
22
投票

这是一个简单的过滤器插件,它将发出警告消息:

from ansible.utils.display import Display


class FilterModule(object):
    def filters(self): return {'warn_me': self.warn_filter}

    def warn_filter(self, message, **kwargs):
        Display().warning(message)
        return message

将以上内容放入文件中,例如

[playbook_dir]/filter_plugins/warn_me.py

调用此过滤器的设计示例剧本可能如下所示:

---
- name: Demonstrate warn_me filter plugin
  gather_facts: no
  hosts: all

  tasks:
    - meta: end_play 
      when: ('file XYZ cannot be processed' | warn_me())
      delegate_to: localhost
      run_once: yes

运行此剧本可能会产生以下输出:

$ ansible-playbook test_warnme.yml -l forwards
 __________________________________________ 
< PLAY [Demonstrate warn_me filter plugin] >
 ------------------------------------------ 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

 [WARNING]: file XYZ cannot be processed

 ____________ 
< PLAY RECAP >
 ------------ 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||



14
投票

可以使用

fail:
+
when:
+
ignore_errors:
来混淆警告。

例如

- name: Check hostname matches entry in ansible/hosts
  fail:
    msg: "Warning: Expected hostname to be '{{ inventory_hostname }}' but was '{{ ansible_facts.fqdn}}'"
  when: ansible_facts.fqdn != inventory_hostname
  ignore_errors: True

警告显示为致命错误,后跟

...skipping
,并且在
PLAY RECAP
中显示的警告数量为
ignored=N

例如

TASK [mytask: Check hostname matches entry in ansible/hosts] ***************
fatal: [myhost]: FAILED! => {"changed": false, "msg": "Warning: Expected hostname to be 'myhost' but was 'myhost.my.example.com'"}
...ignoring

PLAY RECAP *************************************************************************************
myhost   ok=0    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    **ignored=1**

信用:https://medium.com/opsops/how-to-print-warning-from-a-task-3286ebb39f40


9
投票

根据您的问题,如果您不信任提供的 URL,但要回答有关生成的问题,您似乎可能想让剧本失败

[WARNING]: <supplied text>

messages 据我所知,执行此操作的唯一方法是通过您自己的 ansible 模块或插件。

您的模块或插件将进行您描述的 URL 比较并发出适当的消息。

在 ansible 模块中,您创建的

module
对象有一个
warn
函数,您可以这样调用:
module.warn('your text')

在插件中,您的代码将生成一个

Display
对象,并且该对象将具有您可以调用的
warning
函数,如下所示:
display.warning('your text')

如果您的目标只是获得一个 ansible 紫色警告消息,而不是通过

debug
模块生成的消息,这似乎需要大量工作。


1
投票

我已经成功做到了这一点,@daniel-ashton 的答案对我帮助很大。

您必须在剧本文件夹或角色文件夹中拥有/创建

library
filter_plugins
文件夹。

创建

library/noop.py

#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.module_utils.basic import AnsibleModule

def run_module():
    module_args = dict(
        noop=dict(type='list', required=True)
    )
    result = dict(
        changed=False
    )
    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )
    module.exit_json(**result)


def main():
    run_module()


if __name__ == '__main__':
    main()

并创建

filter_plugins/warn_me.py
:

#!/usr/bin/python
from ansible.utils.display import Display

class FilterModule(object):
    def filters(self): return {'warn_me': self.warn_filter}

    def warn_filter(self, message, **kwargs):
        Display().warning(message)
        return message

设置一个名为eg的var或fact。

bypass_folder_warn
,如:
bypass_folder_warn: Folder check bypass enabled, make sure you know what you are doing

然后在您的剧本或角色任务文件中添加一个任务,如下所示:

- noop:
    noop: '{{ bypass_folder_warn | warn_me()}}'
  delegate_to: localhost
  when: bypass_folder_check

结果是:

TASK [myrole : noop] ********************************************************
[WARNING]: Folder check bypass enabled, make sure you know what you are doing
ok: [localhost]

警告消息根据需要以标准 Ansible 紫色打印。


0
投票

这是一个名为

warning
的动作插件:

from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
    def run(self, tmp=None, task_vars=None):
        result = super(ActionModule, self).run(tmp, task_vars)
        result["warnings"] = [self._task.args["msg"]]
        return result

如果你这样称呼它:

- name: play
  hosts: localhost
  gather_facts: false
  tasks:
    - name: print warning
      my_namespace.my_collection.warning:
        msg: hello, world!

并获得如下输出:

PLAY [play] *****************************************************************************************************************

TASK [warning] **************************************************************************************************************
[WARNING]: hello, world!
ok: [localhost]

PLAY RECAP ******************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
© www.soinside.com 2019 - 2024. All rights reserved.