mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Added a section wrt. hybrid plugins and provide an example for lookup plugins
This commit is contained in:
parent
064cdec6ff
commit
c1d90e3f2d
1 changed files with 124 additions and 0 deletions
|
@ -254,6 +254,130 @@ Connection plugins
|
||||||
* connection plugins
|
* connection plugins
|
||||||
|
|
||||||
|
|
||||||
|
Hybrid plugins
|
||||||
|
==============
|
||||||
|
In specific cases you may want a plugin that supports both ansible-1.9.x *and*
|
||||||
|
ansible-2.0. Much like porting plugins from v1 to v2, you need to understand
|
||||||
|
how plugins work in each version and support both requirements. It may mean
|
||||||
|
playing tricks on Ansible.
|
||||||
|
|
||||||
|
Since the ansible-2.0 plugin system is more advanced, it is easier to adapt
|
||||||
|
your plugin to provide similar pieces (subclasses, methods) for ansible-1.9.x
|
||||||
|
as ansible-2.0 expects. This way your code will look a lot cleaner.
|
||||||
|
|
||||||
|
You may find the following tips useful:
|
||||||
|
|
||||||
|
* Check whether the ansible-2.0 class(es) are available and if they are missing
|
||||||
|
(ansible-1.9.x) mimic them with the needed methods (e.g. `__init__`)
|
||||||
|
|
||||||
|
* When ansible-2.0 python modules are imported, and they fail (ansible-1.9.x),
|
||||||
|
catch the `ImportError` exception and perform the equivalent imports for
|
||||||
|
ansible-1.9.x. With possible translations (e.g. importing specific methods).
|
||||||
|
|
||||||
|
* Use the existence of these methods as a qualifier to what version of Ansible
|
||||||
|
you are running. So rather than using version checks, you can do capability
|
||||||
|
checks instead. (See examples below)
|
||||||
|
|
||||||
|
* Document for each if-then-else case for which specific version each block is
|
||||||
|
needed. This will help others to understand how they have to adapt their
|
||||||
|
plugins, but it will also help you to remove the older ansible-1.9.x support
|
||||||
|
when it is deprecated.
|
||||||
|
|
||||||
|
* When doing plugin development, it is very useful to have the `warning()`
|
||||||
|
method during development, but it is also important to emit warnings for
|
||||||
|
deadends (cases that you expect should never be triggered) or corner cases
|
||||||
|
(e.g. cases where you expect misconfigurations).
|
||||||
|
|
||||||
|
|
||||||
|
Lookup plugins
|
||||||
|
--------------
|
||||||
|
As a simple example we are going to make a hybrid `fileglob` lookup plugin.
|
||||||
|
The `fileglob` lookup plugin is pretty simple to understand::
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ansible-2.0
|
||||||
|
from ansible.plugins.lookup import LookupBase
|
||||||
|
except ImportError:
|
||||||
|
# ansible-1.9.x
|
||||||
|
|
||||||
|
class LookupBase(object):
|
||||||
|
def __init__(self, basedir=None, runner=None, **kwargs):
|
||||||
|
self.runner = runner
|
||||||
|
self.basedir = self.runner.basedir
|
||||||
|
|
||||||
|
def get_basedir(self, variables):
|
||||||
|
return self.basedir
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ansible-1.9.x
|
||||||
|
from ansible.utils import (listify_lookup_plugin_terms, path_dwim, warning)
|
||||||
|
except ImportError:
|
||||||
|
# ansible-2.0
|
||||||
|
from __main__ import display
|
||||||
|
warning = display.warning
|
||||||
|
|
||||||
|
class LookupModule(LookupBase):
|
||||||
|
|
||||||
|
# For ansible-1.9.x, we added inject=None as valid arguments
|
||||||
|
def run(self, terms, inject=None, variables=None, **kwargs):
|
||||||
|
|
||||||
|
# ansible-2.0, but we made this work for ansible-1.9.x too !
|
||||||
|
basedir = self.get_basedir(variables)
|
||||||
|
|
||||||
|
# ansible-1.9.x
|
||||||
|
if 'listify_lookup_plugin_terms' in globals():
|
||||||
|
terms = listify_lookup_plugin_terms(terms, basedir, inject)
|
||||||
|
|
||||||
|
ret = []
|
||||||
|
for term in terms:
|
||||||
|
term_file = os.path.basename(term)
|
||||||
|
|
||||||
|
# For ansible-1.9.x, we imported path_dwim() from ansible.utils
|
||||||
|
if 'path_dwim' in globals():
|
||||||
|
# ansible-1.9.x
|
||||||
|
dwimmed_path = path_dwim(basedir, os.path.dirname(term))
|
||||||
|
else:
|
||||||
|
# ansible-2.0
|
||||||
|
dwimmed_path = self._loader.path_dwim_relative(basedir, 'files', os.path.dirname(term))
|
||||||
|
|
||||||
|
globbed = glob.glob(os.path.join(dwimmed_path, term_file))
|
||||||
|
ret.extend(g for g in globbed if os.path.isfile(g))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
Note that in the above example we did not use the `warning()` method as we
|
||||||
|
had no direct use for it in the final version. However we left this code in
|
||||||
|
so people can use this part during development/porting/use.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Connection plugins
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* connection plugins
|
||||||
|
|
||||||
|
Action plugins
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* action plugins
|
||||||
|
|
||||||
|
Callback plugins
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* callback plugins
|
||||||
|
|
||||||
|
Connection plugins
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* connection plugins
|
||||||
|
|
||||||
|
|
||||||
Porting custom scripts
|
Porting custom scripts
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue