rewrite of the developer guide, part 1 (#45179)

* rewrite of the developer guide, part 1
This commit is contained in:
Alicia Cozine 2018-09-07 08:57:36 -05:00 committed by GitHub
parent 1325ddbb0b
commit 9a76441c02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1231 additions and 2882 deletions

View file

@ -1,8 +1,9 @@
.. _flow_modules:
.. _developing_program_flow_modules:
===========================
Ansible Module Architecture
===========================
***************************
Ansible module architecture
***************************
This in-depth dive helps you understand Ansible's program flow to execute
modules. It is written for people working on the portions of the Core Ansible
@ -10,9 +11,12 @@ Engine that execute a module. Those writing Ansible Modules may also find this
in-depth dive to be of interest, but individuals simply using Ansible Modules
will not likely find this to be helpful.
.. contents:: Topics
:local:
.. _flow_types_of_modules:
Types of Modules
Types of modules
================
Ansible supports several different types of modules in its code base. Some of
@ -20,7 +24,7 @@ these are for backwards compatibility and others are to enable flexibility.
.. _flow_action_plugins:
Action Plugins
Action plugins
--------------
Action Plugins look like modules to end users who are writing :term:`playbooks` but
@ -42,7 +46,7 @@ into its final location, sets file permissions, and so on.
.. _flow_new_style_modules:
New-style Modules
New-style modules
-----------------
All of the modules that ship with Ansible fall into this category.
@ -55,7 +59,7 @@ connections instead of only one.
.. _flow_python_modules:
Python
^^^^^^
------
New-style Python modules use the :ref:`Ansiballz` framework for constructing
modules. All official modules (shipped with Ansible) use either this or the
@ -73,7 +77,7 @@ values as :term:`JSON`, and various file operations.
.. _flow_powershell_modules:
Powershell
^^^^^^^^^^
----------
New-style powershell modules use the :ref:`module_replacer` framework for
constructing modules. These modules get a library of powershell code embedded
@ -82,7 +86,7 @@ in them before being sent to the managed node.
.. _flow_jsonargs_modules:
JSONARGS
^^^^^^^^
--------
Scripts can arrange for an argument string to be placed within them by placing
the string ``<<INCLUDE_ANSIBLE_MODULE_JSON_ARGS>>`` somewhere inside of the
@ -133,7 +137,7 @@ only modifies them to change a shebang line if present.
.. _flow_binary_modules:
Binary Modules
Binary modules
--------------
From Ansible 2.2 onwards, modules may also be small binary programs. Ansible
@ -152,7 +156,7 @@ way as :ref:`want JSON modules <flow_want_json_modules>`.
.. _flow_old_style_modules:
Old-style Modules
Old-style modules
-----------------
Old-style modules are similar to
@ -176,7 +180,7 @@ the remote machine.
.. _flow_executor_task_executor:
executor/task_executor
Executor/task_executor
----------------------
The TaskExecutor receives the module name and parameters that were parsed from
@ -189,10 +193,10 @@ to that Action Plugin for further processing.
.. _flow_normal_action_plugin:
Normal Action Plugin
Normal action plugin
--------------------
The ``normal`` Action Plugin executes the module on the remote host. It is
The ``normal`` action plugin executes the module on the remote host. It is
the primary coordinator of much of the work to actually execute the module on
the managed machine.
@ -223,7 +227,7 @@ which lives in :file:`plugins/action/__init__.py`. It makes use of
.. _flow_executor_module_common:
executor/module_common.py
Executor/module_common.py
-------------------------
Code in :file:`executor/module_common.py` takes care of assembling the module
@ -248,8 +252,8 @@ Next we'll go into some details of the two assembler frameworks.
.. _module_replacer:
Module Replacer
^^^^^^^^^^^^^^^
Module Replacer framework
^^^^^^^^^^^^^^^^^^^^^^^^^
The Module Replacer framework is the original framework implementing new-style
modules. It is essentially a preprocessor (like the C Preprocessor for those
@ -310,8 +314,8 @@ substitutions:
.. _Ansiballz:
Ansiballz
^^^^^^^^^
Ansiballz framework
^^^^^^^^^^^^^^^^^^^
Ansible 2.1 switched from the :ref:`module_replacer` framework to the
Ansiballz framework for assembling modules. The Ansiballz framework differs
@ -330,7 +334,7 @@ ansible module.
.. note::
Ansible wraps the zipfile in the Python script for two reasons:
* for compatibility with Python-2.6 which has a less
* for compatibility with Python 2.6 which has a less
functional version of Python's ``-m`` command line switch.
* so that pipelining will function properly. Pipelining needs to pipe the
Python module into the Python interpreter on the remote node. Python
@ -354,7 +358,7 @@ the zipfile as well.
.. _flow_passing_module_args:
Passing args
~~~~~~~~~~~~
------------
In :ref:`module_replacer`, module arguments are turned into a JSON-ified
string and substituted into the combined module file. In :ref:`Ansiballz`,
@ -379,7 +383,7 @@ other code.
.. _flow_internal_arguments:
Internal arguments
^^^^^^^^^^^^^^^^^^
------------------
Both :ref:`module_replacer` and :ref:`Ansiballz` send additional arguments to
the module beyond those which the user specified in the playbook. These
@ -389,7 +393,7 @@ the features are implemented in :py:mod:`ansible.module_utils.basic` but certain
features need support from the module so it's good to know about them.
_ansible_no_log
~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^
This is a boolean. If it's True then the playbook specified ``no_log`` (in
a task's parameters or as a play parameter). This automatically affects calls
@ -402,7 +406,7 @@ to instantiate an `AnsibleModule` and then check the value of
``no_log`` specified in a module's argument_spec are handled by a different mechanism.
_ansible_debug
~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^
This is a boolean that turns on more verbose logging. If a module uses
:py:meth:`AnsibleModule.debug` rather than :py:meth:`AnsibleModule.log` then
@ -414,7 +418,7 @@ should do so by instantiating an `AnsibleModule` and accessing
:attr:`AnsibleModule._debug`.
_ansible_diff
~~~~~~~~~~~~~
^^^^^^^^^^^^^^^
This boolean is turned on via the ``--diff`` command line option. If a module
supports it, it will tell the module to show a unified diff of changes to be
@ -423,13 +427,13 @@ instantiating an `AnsibleModule` and accessing
:attr:`AnsibleModule._diff`.
_ansible_verbosity
~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^
This value could be used for finer grained control over logging. However, it
is currently unused.
_ansible_selinux_special_fs
~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is a list of names of filesystems which should have a special selinux
context. They are used by the `AnsibleModule` methods which operate on
@ -452,7 +456,7 @@ filesystem names. Under Ansiballz it's an actual list.
.. versionadded:: 2.1
_ansible_syslog_facility
~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^
This parameter controls which syslog facility ansible module logs to. It may
be set by changing the ``syslog_facility`` value in :file:`ansible.cfg`. Most
@ -477,7 +481,7 @@ than it did under :ref:`module_replacer` due to how hacky the old way was
.. versionadded:: 2.1
_ansible_version
~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^
This parameter passes the version of ansible that runs the module. To access
it, a module should instantiate an `AnsibleModule` and then retrieve it
@ -489,7 +493,7 @@ from :attr:`AnsibleModule.ansible_version`. This replaces
.. _flow_special_considerations:
Special Considerations
Special considerations
----------------------
.. _flow_pipelining:
@ -528,14 +532,14 @@ Passing arguments via stdin was chosen for the following reasons:
truncation of the parameters if we hit that limit.
.. _ansiblemodule:
.. _flow_ansiblemodule:
AnsibleModule
-------------
.. _argument_spec:
Argument Spec
Argument spec
^^^^^^^^^^^^^
The ``argument_spec`` provided to ``AnsibleModule`` defines the supported arguments for a module, as well as their type, defaults and more.
@ -556,10 +560,10 @@ Example ``argument_spec``:
)
))
This section will discss the behavioral attributes for arguments
This section will discuss the behavioral attributes for arguments:
type
~~~~
""""
``type`` allows you to define the type of the value accepted for the argument. The default value for ``type`` is ``str``. Possible values are:
@ -579,17 +583,17 @@ type
The ``raw`` type, performs no type validation or type casing, and maintains the type of the passed value.
elements
~~~~~~~~
""""""""
``elements`` works in combination with ``type`` when ``type='list'``. ``elements`` can then be defined as ``elements='int'`` or any other type, indicating that each element of the specified list should be of that type.
default
~~~~~~~
"""""""
The ``default`` option allows sets a default value for the argument for the scenario when the argument is not provided to the module. When not specified, the default value is ``None``.
fallback
~~~~~~~~
""""""""
``fallback`` accepts a ``tuple`` where the first argument is a callable (function) that will be used to perform the lookup, based on the second argument. The second argument is a list of values to be accepted by the callable.
@ -600,38 +604,38 @@ Example::
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME']))
choices
~~~~~~~
"""""""
``choices`` accepts a list of choices that the argument will accept. The types of ``choices`` should match the ``type``.
required
~~~~~~~~
""""""""
``required`` accepts a boolean, either ``True`` or ``False`` that indicates that the argument is required. This should not be used in combination with ``default``.
no_log
~~~~~~
""""""
``no_log`` indicates that the value of the argument should not be logged or displayed.
aliases
~~~~~~~
"""""""
``aliases`` accepts a list of alternative argument names for the argument, such as the case where the argument is ``name`` but the module accepts ``aliases=['pkg']`` to allow ``pkg`` to be interchangably with ``name``
options
~~~~~~~
"""""""
``options`` implements the ability to create a sub-argument_spec, where the sub options of the top level argument are also validated using the attributes discussed in this section. The example at the top of this section demonstrates use of ``options``. ``type`` or ``elements`` should be ``dict`` is this case.
apply_defaults
~~~~~~~~~~~~~~
""""""""""""""
``apply_defaults`` works alongside ``options`` and allows the ``default`` of the sub-options to be applied even when the top-level argument is not supplied.
In the example of the ``argument_spec`` at the top of this section, it would allow ``module.params['top_level']['second_level']`` to be defined, even if the user does not provide ``top_level`` when calling the module.
removed_in_version
~~~~~~~~~~~~~~~~~~
""""""""""""""""""
``removed_in_version`` indicates which version of Ansible a deprecated argument will be removed in.