17

Can I print a warning message from Ansible? Like as Ansible does for an internal warning:

[WARNING]: Ignoring invalid attribute: xx

The targeted use are warning, that are not an error, so they should not end the playbook execution, but they should be clearly visible (in standard Ansible purple color).

Example usage:

  1. I have some hardcoded URL of the latest release.
  2. The playbook downloads the latest avaiable URL.
  3. And print warning if the URLs differs.
  4. As the source is not trusted, the downloaded URL is should be used only for comparison, but not used directly.
U880D
  • 8,601
  • 6
  • 24
  • 40
mvorisek
  • 3,290
  • 2
  • 18
  • 53
  • Can you provide some context about why/when you want to issue the warning and *why* you want a warning vs just a standard debug msg? You can generate a purple [WARNING] message from an ansible callback easily but creating a callback just to produce a msg seems like overkill, unless the callback is doing somethign meaningful in the process of generating the message. – Rob H Dec 30 '17 at 12:53
  • I added my targetted use as an example. – mvorisek Dec 30 '17 at 13:06
  • 3
    I find the question quite valid and the currently accepted answer not really a solution as it does not allow user to create warnings. The entire idea was to raise warnings during runtime and be able to process them at the end of the playbook. – sorin Aug 09 '18 at 10:38
  • 2
    @sorin I just opened a feature request at Ansible: https://github.com/ansible/ansible/issues/67260 – mvorisek Feb 09 '20 at 23:34

4 Answers4

21

Here is a simple filter plugin that will emit a Warning message:

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

Place the above into a file in, for example, [playbook_dir]/filter_plugins/warn_me.py.

A contrived example playbook that calls this filter might look like this:

---
- 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

And running this playbook might produce this output:

$ 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 |
                ||     ||


Daniel Ashton
  • 1,388
  • 11
  • 23
12

Warnings can be sort of kludged by using fail: + when: + ignore_errors:.

e.g.

- 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

The warnings show up as fatal errors, followed by ...skipping, and a count of the number them will appear in the PLAY RECAP as ignored=N.

e.g.

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**

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

U880D
  • 8,601
  • 6
  • 24
  • 40
Ben Aveling
  • 842
  • 7
  • 13
9

Based on your question it seems like you may want to fail the playbook if you don't trust the supplied URL but to answer your question about generating

[WARNING]: <supplied text>

messages the only way I know of to do this is by either your own ansible module or by a plugin.

Your module or plugin would make the URL comparison you described and issue an appropriate message.

In an ansible module the module object that you create has a warn function that you call like: module.warn('your text')

In a plugin, your code will generate a Display object and that object will have a warning function that you call like: display.warning('your text').

If your goal is simply to have an ansible purple warning message vs what you can generate via the debug module this seems like a lot of work.

Rob H
  • 1,676
  • 10
  • 18
1

I have managed to accomplish this, the answers by @daniel-ashton helped me a lot.

You must have/create library and filter_plugins folders in your playbook folder or into the role folder.

Create 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()

and create 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

Set a var or fact named eg. bypass_folder_warn, such as: bypass_folder_warn: Folder check bypass enabled, make sure you know what you are doing.

Then add a task in you playbook or role task file like this:

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

Result is:

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

The WARNING message is printed in standard Ansible purple color as desired.

U880D
  • 8,601
  • 6
  • 24
  • 40