Callback plugins enable adding new behaviors to Ansible when responding to events. By default they are in charge of most of the output you see when running the command line programs.
Ansible comes with a number of callback plugins that you can look at for examples. These can be found in `lib/ansible/plugins/callback <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/callback>`_.
You have a couple of ways to activate a custom callback. You can drop it in a callback_plugins directory adjacent to your play or inside a role. Also you can put it in one of the callback directory sources configured in `ansible.cfg`.
Plugins are loaded in alphanumeric order; for example, a plugin implemented in a file named `1_first.py` would run before a plugin file named `2_second.py`.
You can only have one plugin be the main manager of your console output. If you want to replace the default, you should define CALLBACK_TYPE = stdout in the subclass and then the stdout plugin needs to be configured in `ansible.cfg`. For example::
Callback plugins are created by creating a new class with the Base(Callbacks) class as the parent::
from ansible.plugins.callback import CallbackBase
from ansible import constants as C
class CallbackModule(CallbackBase):
From there, override the specific methods from the CallbackBase that you want to provide a callback for. For plugins intended for use with Ansible version 2.0 and later, you should only override methods that start with `v2`. For a complete list of methods that you can override, please see ``__init__.py`` in the `lib/ansible/plugins/callback <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/callback>`_ directory.
The following example shows how Ansible's timer plugin is implemented::
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from datetime import datetime
from ansible.plugins.callback import CallbackBase
class CallbackModule(CallbackBase):
"""
This callback module tells you how long your plays ran for.
By default, ansible ships with a 'paramiko' SSH, native ssh (just called 'ssh'), 'local' connection type, and there are also some minor players like 'chroot' and 'jail'. All of these can be used in playbooks and with /usr/bin/ansible to decide how you want to talk to remote machines. The basics of these connection types
are covered in the :doc:`intro_getting_started` section. Should you want to extend Ansible to support other transports (SNMP? Message bus?
Carrier Pigeon?) it's as simple as copying the format of one of the existing modules and dropping it into the connection plugins
directory. The value of 'smart' for a connection allows selection of paramiko or openssh based on system capabilities, and chooses
'ssh' if OpenSSH supports ControlPersist, in Ansible 1.2.1 and later. Previous versions did not support 'smart'.
More documentation on writing connection plugins is pending, though you can jump into `lib/ansible/plugins/connection <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/connection>`_ and figure things out pretty easily.
Lookup plugins are used to pull in data from external sources. They can be used within playbooks and templates to return values for variables or other expressions.
Also they are used for looping - playbook language constructs like "with_fileglob" and "with_items" are implemented via lookup plugins.
Errors encountered during execution should be returned by raising AnsibleError() with a message describing the error. Any strings returned by your lookup plugin implementation that could ever contain non-ASCII characters must be converted into Python's unicode type becasue the strings will be run through jinja2. To do this, you can use::
from ansible.module_utils._text import to_text
result_string = to_text(result_string)
For more example lookup plugins, check out the source code for the lookup plugins that are included with Ansible here: `lib/ansible/plugins/lookup <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/lookup>`_.
Playbook constructs like 'host_vars' and 'group_vars' work via 'vars' plugins. They inject additional variable
data into ansible runs that did not come from an inventory, playbook, or command line. Note that variables
can also be returned from inventory, so in most cases, you won't need to write or understand vars_plugins.
More documentation on writing vars plugins is pending, though you can jump into `lib/ansible/inventory/vars_plugins <https://github.com/ansible/ansible/tree/devel/lib/ansible/inventory/vars_plugins>`_ and figure
things out pretty easily.
If you find yourself wanting to write a vars_plugin, it's more likely you should write an inventory script instead.
These plugins are for manipulating data, they are a feature of Jinja2 and are also available in Jinja2 templates used by the `template` module. As all plugins, they can be easily extended, but instead of having a file for each one you can have several per file, most of those shipped with Ansible reside in a `core.py`.
Jump into `lib/ansible/plugins/filter <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/filter>`_ for details.
.._developing_test_plugins:
Test Plugins
------------
These plugins are for verifying data, they are a feature of Jinja2 and are also available in Jinja2 templates used by the `template` module. As all plugins, they can be easily extended, but instead of having a file for each one you can have several per file, most of those shipped with Ansible reside in a `core.py`. These are specially useful in conjunction with some filter plugins like `map` and `select`, they are also available for conditional directives (`when:`).