mirror of https://github.com/ansible/ansible.git
expand ansible-doc coverage (#74963)
* Expand ansible-doc to tests/filters and fix existing issues enable filter/test docs if in single file or companion yaml add docs for several filters/tests plugins allow .yml companion for docs for other plugins, must be colocated verify plugins are valid (not modules, cannot) fix 'per collection' filtering limit old style deprecation (_ prefix) to builtin/legacy start move to pathlib for saner path handling moved some funcitons, kept backwards compat shims with deprecation notice Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com> Co-authored-by: Felix Fontein <felix@fontein.de> Co-authored-by: Sandra McCann <samccann@redhat.com>pull/77665/head
parent
a65fbfad5b
commit
b439e41a91
@ -0,0 +1,44 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: ternary
|
||||||
|
author: Brian Coca (@bcoca)
|
||||||
|
version_added: '1.9'
|
||||||
|
short_description: Ternary operation filter
|
||||||
|
description:
|
||||||
|
- Return the first value if the input is C(True), the second if C(False).
|
||||||
|
positional: true_val, false_val
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: A boolean expression, must evaluate to C(True) or C(False).
|
||||||
|
type: bool
|
||||||
|
required: true
|
||||||
|
true_val:
|
||||||
|
description: Value to return if the input is C(True).
|
||||||
|
type: any
|
||||||
|
required: true
|
||||||
|
false_val:
|
||||||
|
description: Value to return if the input is C(False).
|
||||||
|
type: any
|
||||||
|
none_val:
|
||||||
|
description: Value to return if the input is C(None). If not set, C(None) will be treated as C(False).
|
||||||
|
type: any
|
||||||
|
version_added: '2.8'
|
||||||
|
notes:
|
||||||
|
- vars as values are evaluated even if not returned. This is due to them being evaluated before being passed into the filter.
|
||||||
|
|
||||||
|
EXAMPLES: |
|
||||||
|
# set first 10 volumes rw, rest as dp
|
||||||
|
volume_mode: "{{ (item|int < 11)|ternary('rw', 'dp') }}"
|
||||||
|
|
||||||
|
# choose correct vpc subnet id, note that vars as values are evaluated even if not returned
|
||||||
|
vpc_subnet_id: "{{ (ec2_subnet_type == 'public') | ternary(ec2_vpc_public_subnet_id, ec2_vpc_private_subnet_id) }}"
|
||||||
|
|
||||||
|
- name: service-foo, use systemd module unless upstart is present, then use old service module
|
||||||
|
service:
|
||||||
|
state: restarted
|
||||||
|
enabled: yes
|
||||||
|
use: "{{ (ansible_service_mgr == 'upstart') | ternary('service', 'systemd') }}"
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: The value indicated by the input.
|
||||||
|
type: any
|
@ -0,0 +1,69 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: to_json
|
||||||
|
author: core team
|
||||||
|
version_added: 'historical'
|
||||||
|
short_description: Convert variable to JSON string
|
||||||
|
description:
|
||||||
|
- Converts an Ansible variable into a JSON string representation.
|
||||||
|
- This filter functions as a wrapper to the Python ``json.dumps()`` function.
|
||||||
|
- Ansible internally auto-converts JSON strings into variable structures so this plugin is used to force it into a JSON string.
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: A variable or expression that returns a data structure.
|
||||||
|
type: raw
|
||||||
|
required: true
|
||||||
|
vault_to_text:
|
||||||
|
description: Toggle to either unvault a vault or create the JSON version of a vaulted object
|
||||||
|
type: bool
|
||||||
|
default: True
|
||||||
|
version_added: '2.9'
|
||||||
|
preprocess_unsafe:
|
||||||
|
description: Toggle to represent unsafe values directly in JSON or create a unsafe object in JSON
|
||||||
|
type: bool
|
||||||
|
default: True
|
||||||
|
version_added: '2.9'
|
||||||
|
allow_nan:
|
||||||
|
description: When off, strict adherence to float value limits of the JSON spec, so C(nan), C(inf) and C(-inf) values will produce errors
|
||||||
|
If on, JavaScript equivalents will be used (C(NaN), C(Infinity), C(-Infinity))
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
|
check_circular:
|
||||||
|
description: Controls the usage of the internal circular reference detection, if off can result in overflow errors.
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
|
ensure_ascii:
|
||||||
|
description: Escapes all non ASCII characters
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
|
indent:
|
||||||
|
description: Number of spaces to indent python structures, mainly used for display to humans
|
||||||
|
default: 0
|
||||||
|
type: integer
|
||||||
|
separators:
|
||||||
|
description: The C(item) and C(key) separator to be used in the serialized output,
|
||||||
|
default may change depending on I(indent) and Python version
|
||||||
|
default: "(', ', ': ')"
|
||||||
|
type: tuple
|
||||||
|
skipkeys:
|
||||||
|
description: If C(True), keys that are not basic Python types will be skipped
|
||||||
|
default: False
|
||||||
|
type: bool
|
||||||
|
sort_keys:
|
||||||
|
description: Affects sorting of dictionary keys
|
||||||
|
default: False
|
||||||
|
type: bool
|
||||||
|
notes:
|
||||||
|
- Both I(vault_to_text) and I(preprocess_unsafe) defaulted to C(False) between Ansible 2.9 and 2.12
|
||||||
|
- 'These parameters to ``json.dumps()`` will be ignored, as they are overriden internally: I(cls), I(default)'
|
||||||
|
|
||||||
|
EXAMPLES: |
|
||||||
|
# dump variable in a template to create a JSON document
|
||||||
|
{{ docker_config|to_json }}
|
||||||
|
|
||||||
|
# same as above but 'prettier' (equivalent to to_nice_json filter)
|
||||||
|
{{ docker_config|to_json(indent=4, sort_keys=True) }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: The JSON serialized string representing the variable structure inputted
|
||||||
|
type: string
|
@ -0,0 +1,54 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: to_nice_json
|
||||||
|
author: core team
|
||||||
|
version_added: 'historical'
|
||||||
|
short_description: Convert variable to 'nicely formatted' JSON string
|
||||||
|
description:
|
||||||
|
- Converts an Ansible variable into a 'nicely formatted' JSON string representation
|
||||||
|
- This filter functions as a wrapper to the Python ``json.dumps()`` function
|
||||||
|
- Ansible internally auto-converts JSON strings into variable structures so this plugin is used to force it into a JSON string
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: A variable or expression that returns a data structure
|
||||||
|
type: raw
|
||||||
|
required: true
|
||||||
|
vault_to_text:
|
||||||
|
description: Toggle to either unvault a vault or create the JSON version of a vaulted object
|
||||||
|
type: bool
|
||||||
|
default: True
|
||||||
|
version_added: '2.9'
|
||||||
|
preprocess_unsafe:
|
||||||
|
description: Toggle to represent unsafe values directly in JSON or create a unsafe object in JSON
|
||||||
|
type: bool
|
||||||
|
default: True
|
||||||
|
version_added: '2.9'
|
||||||
|
allow_nan:
|
||||||
|
description: When off, strict adherence to float value limits of the JSON spec, so C(nan), C(inf) and C(-inf) values will produce errors
|
||||||
|
If on, JavaScript equivalents will be used (C(NaN), C(Infinity), C(-Infinity)).
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
|
check_circular:
|
||||||
|
description: Controls the usage of the internal circular reference detection, if off can result in overflow errors.
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
|
ensure_ascii:
|
||||||
|
description: Escapes all non ASCII characters
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
|
skipkeys:
|
||||||
|
description: If C(True), keys that are not basic Python types will be skipped.
|
||||||
|
default: False
|
||||||
|
type: bool
|
||||||
|
notes:
|
||||||
|
- Both I(vault_to_text) and I(preprocess_unsafe) defaulted to C(False) between Ansible 2.9 and 2.12
|
||||||
|
- 'These parameters to ``json.dumps()`` will be ignored, they are overriden for internal use: I(cls), I(default), I(indent), I(separators), I(sort_keys).'
|
||||||
|
|
||||||
|
EXAMPLES: |
|
||||||
|
# dump variable in a template to create a nicely formatted JSON document
|
||||||
|
{{ docker_config|to_nice_json }}
|
||||||
|
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: The 'nicely formatted' JSON serialized string representing the variable structure inputted
|
||||||
|
type: string
|
@ -0,0 +1,20 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: type_debug
|
||||||
|
author: Adrian Likins (@alikins)
|
||||||
|
version_added: "2.3"
|
||||||
|
short_description: show input data type
|
||||||
|
description:
|
||||||
|
- Returns the equivalent of Python's ``type()`` function
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: Variable or expression of which you want to determine type.
|
||||||
|
type: any
|
||||||
|
required: true
|
||||||
|
EXAMPLES: |
|
||||||
|
# get type of 'myvar'
|
||||||
|
{{ myvar | type_debug }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: The Python 'type' of the I(_input) provided.
|
||||||
|
type: string
|
@ -0,0 +1,36 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: unvault
|
||||||
|
author: Brian Coca (@bcoca)
|
||||||
|
version_added: "2.12"
|
||||||
|
short_description: Open an Ansible Vault
|
||||||
|
description:
|
||||||
|
- Retrieve your information from an encrypted Ansible Vault
|
||||||
|
positional: secret
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: Vault string, or an C(AnsibleVaultEncryptedUnicode) string object.
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
secret:
|
||||||
|
description: Vault secret, the key that lets you open the vault
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
vault_id:
|
||||||
|
description: Secret identifier, used internally to try to best match a secret when multiple are provided
|
||||||
|
type: string
|
||||||
|
default: 'filter_default'
|
||||||
|
|
||||||
|
EXAMPLES: |
|
||||||
|
# simply decrypt my key from a vault
|
||||||
|
vars:
|
||||||
|
mykey: "{{ myvaultedkey|unvault(passphrase) }} "
|
||||||
|
|
||||||
|
- name: save templated unvaulted data
|
||||||
|
template: src=dump_template_data.j2 dest=/some/key/clear.txt
|
||||||
|
vars:
|
||||||
|
template_data: '{{ secretdata|uvault(vaultsecret) }}'
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: The string that was contained in the vault.
|
||||||
|
type: string
|
@ -0,0 +1,48 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: vault
|
||||||
|
author: Brian Coca (@bcoca)
|
||||||
|
version_added: "2.12"
|
||||||
|
short_description: vault your secrets
|
||||||
|
description:
|
||||||
|
- Put your information into an encrypted Ansible Vault
|
||||||
|
positional: secret
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: data to vault
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
secret:
|
||||||
|
description: Vault secret, the key that lets you open the vault
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
salt:
|
||||||
|
description:
|
||||||
|
- Encryption salt, will be random if not provided
|
||||||
|
- While providing one makes the resulting encrypted string reproducible, it can lower the security of the vault
|
||||||
|
type: string
|
||||||
|
vault_id:
|
||||||
|
description: Secret identifier, used internally to try to best match a secret when multiple are provided
|
||||||
|
type: string
|
||||||
|
default: 'filter_default'
|
||||||
|
wrap_object:
|
||||||
|
description:
|
||||||
|
- This toggle can force the return of an C(AnsibleVaultEncryptedUnicode) string object, when C(False), you get a simple string
|
||||||
|
- Mostly useful when combining with the C(to_yaml) filter to output the 'inline vault' format.
|
||||||
|
type: bool
|
||||||
|
default: False
|
||||||
|
|
||||||
|
EXAMPLES: |
|
||||||
|
# simply encrypt my key in a vault
|
||||||
|
vars:
|
||||||
|
myvaultedkey: "{{ keyrawdata|vault(passphrase) }} "
|
||||||
|
|
||||||
|
- name: save templated vaulted data
|
||||||
|
template: src=dump_template_data.j2 dest=/some/key/vault.txt
|
||||||
|
vars:
|
||||||
|
mysalt: '{{2**256|random(seed=inventory_hostname)}}'
|
||||||
|
template_data: '{{ secretdata|vault(vaultsecret, salt=mysalt) }}'
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: The vault string that contains the secret data (or AnsibleVaultEncryptedUnicode string object)
|
||||||
|
type: string
|
@ -0,0 +1,233 @@
|
|||||||
|
# (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
from ansible import constants as C
|
||||||
|
from ansible.collections.list import list_collections
|
||||||
|
from ansible.errors import AnsibleError
|
||||||
|
from ansible.module_utils._text import to_native, to_bytes
|
||||||
|
from ansible.plugins import loader
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
from ansible.utils.path import is_subpath
|
||||||
|
from ansible.utils.collection_loader._collection_finder import _get_collection_path
|
||||||
|
|
||||||
|
display = Display()
|
||||||
|
|
||||||
|
# not real plugins
|
||||||
|
IGNORE = {
|
||||||
|
# ptype: names
|
||||||
|
'module': ('async_wrapper', ),
|
||||||
|
'cache': ('base', ),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _list_plugins_from_paths(ptype, dirs, collection, depth=0):
|
||||||
|
|
||||||
|
plugins = {}
|
||||||
|
|
||||||
|
for path in dirs:
|
||||||
|
display.debug("Searching '{0}'s '{1}' for {2} plugins".format(collection, path, ptype))
|
||||||
|
b_path = to_bytes(path)
|
||||||
|
|
||||||
|
if os.path.basename(b_path).startswith((b'.', b'__')):
|
||||||
|
# skip hidden/special dirs
|
||||||
|
continue
|
||||||
|
|
||||||
|
if os.path.exists(b_path):
|
||||||
|
if os.path.isdir(b_path):
|
||||||
|
bkey = ptype.lower()
|
||||||
|
for plugin_file in os.listdir(b_path):
|
||||||
|
|
||||||
|
if plugin_file.startswith((b'.', b'__')):
|
||||||
|
# hidden or python internal file/dir
|
||||||
|
continue
|
||||||
|
|
||||||
|
display.debug("Found possible plugin: '{0}'".format(plugin_file))
|
||||||
|
b_plugin, ext = os.path.splitext(plugin_file)
|
||||||
|
plugin = to_native(b_plugin)
|
||||||
|
full_path = os.path.join(b_path, plugin_file)
|
||||||
|
|
||||||
|
if os.path.isdir(full_path):
|
||||||
|
# its a dir, recurse
|
||||||
|
if collection in C.SYNTHETIC_COLLECTIONS:
|
||||||
|
if not os.path.exists(os.path.join(full_path, b'__init__.py')):
|
||||||
|
# dont recurse for synthetic unless init.py present
|
||||||
|
continue
|
||||||
|
|
||||||
|
# actually recurse dirs
|
||||||
|
plugins.update(_list_plugins_from_paths(ptype, [to_native(full_path)], collection, depth=depth + 1))
|
||||||
|
else:
|
||||||
|
if any([
|
||||||
|
plugin in C.IGNORE_FILES, # general files to ignore
|
||||||
|
ext in C.REJECT_EXTS, # general extensions to ignore
|
||||||
|
plugin in IGNORE.get(bkey, ()), # plugin in reject list
|
||||||
|
]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ptype in ('test', 'filter'):
|
||||||
|
ploader = getattr(loader, '{0}_loader'.format(ptype))
|
||||||
|
|
||||||
|
if ptype == 'filter':
|
||||||
|
method_name = 'filters'
|
||||||
|
elif ptype == 'test':
|
||||||
|
method_name = 'tests'
|
||||||
|
else:
|
||||||
|
raise AnsibleError('how did you get here?')
|
||||||
|
|
||||||
|
try:
|
||||||
|
added = False
|
||||||
|
if path not in ploader._extra_dirs:
|
||||||
|
ploader.add_directory(path)
|
||||||
|
added = True
|
||||||
|
for plugin_map in ploader.all():
|
||||||
|
if not is_subpath(plugin_map._original_path, path, real=True):
|
||||||
|
# loader will not restrict to collection so we need to do it here
|
||||||
|
# requires both to be 'real' since loader solves symlinks
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
# uses the jinja2 method tests/filters to get 'name -> function' map
|
||||||
|
method_map = getattr(plugin_map, method_name)
|
||||||
|
jplugins = method_map()
|
||||||
|
seen = set()
|
||||||
|
# skip aliases, names that reference same function
|
||||||
|
for candidate in jplugins:
|
||||||
|
if jplugins[candidate] not in seen:
|
||||||
|
# use names and associate to actual file instead of 'function'
|
||||||
|
composite = [collection]
|
||||||
|
if depth:
|
||||||
|
composite.extend(plugin_map._original_path.split(os.path.sep)[depth * -1:])
|
||||||
|
composite.append(to_native(candidate))
|
||||||
|
fqcn = '.'.join(composite)
|
||||||
|
plugins[fqcn] = plugin_map._original_path
|
||||||
|
seen.add(jplugins[candidate])
|
||||||
|
except Exception as e:
|
||||||
|
display.warning("Skipping plugin file %s as it seems to be invalid: %r" % (to_native(plugin_map._original_path), e))
|
||||||
|
finally:
|
||||||
|
if added:
|
||||||
|
ploader._extra_dirs.remove(os.path.realpath(path))
|
||||||
|
ploader._clear_caches()
|
||||||
|
else:
|
||||||
|
# collectionize name
|
||||||
|
composite = [collection]
|
||||||
|
if depth:
|
||||||
|
composite.extend(path.split(os.path.sep)[depth * -1:])
|
||||||
|
composite.append(to_native(plugin))
|
||||||
|
plugin = '.'.join(composite)
|
||||||
|
|
||||||
|
if not os.path.islink(full_path):
|
||||||
|
# skip aliases, author should document in 'aliaes' field
|
||||||
|
plugins[plugin] = full_path
|
||||||
|
else:
|
||||||
|
display.debug("Skip listing plugins in '{0}' as it is not a directory".format(path))
|
||||||
|
else:
|
||||||
|
display.debug("Skip listing plugins in '{0}' as it does not exist".format(path))
|
||||||
|
|
||||||
|
return plugins
|
||||||
|
|
||||||
|
|
||||||
|
def list_collection_plugins(ptype, collections, search_paths=None):
|
||||||
|
|
||||||
|
# starts at {plugin_name: filepath, ...}, but changes at the end
|
||||||
|
plugins = {}
|
||||||
|
dirs = []
|
||||||
|
try:
|
||||||
|
ploader = getattr(loader, '{0}_loader'.format(ptype))
|
||||||
|
except AttributeError:
|
||||||
|
raise AnsibleError('Cannot list plugins, incorrect plugin type supplied: {0}'.format(ptype))
|
||||||
|
|
||||||
|
# get plugins for each collection
|
||||||
|
for collection in collections.keys():
|
||||||
|
if collection == 'ansible.builtin':
|
||||||
|
# dirs from ansible install, but not configured paths
|
||||||
|
dirs.extend([d.path for d in ploader._get_paths_with_context() if d.path not in ploader.config])
|
||||||
|
elif collection == 'ansible.legacy':
|
||||||
|
# configured paths + search paths (should include basedirs/-M)
|
||||||
|
dirs = ploader.config
|
||||||
|
if search_paths is not None:
|
||||||
|
for d in search_paths:
|
||||||
|
if not d.endswith(ploader.subdir):
|
||||||
|
d = os.path.join([d, ploader.subdir])
|
||||||
|
dirs.append(d)
|
||||||
|
else:
|
||||||
|
# search path in this case is for locating collection itself
|
||||||
|
b_ptype = to_bytes(C.COLLECTION_PTYPE_COMPAT.get(ptype, ptype))
|
||||||
|
dirs = [to_native(os.path.join(collections[collection], b'plugins', b_ptype))]
|
||||||
|
|
||||||
|
plugins.update(_list_plugins_from_paths(ptype, dirs, collection))
|
||||||
|
|
||||||
|
# return plugin and it's class object, None for those not verifiable or failing
|
||||||
|
if ptype in ('module',):
|
||||||
|
# no 'invalid' tests for modules
|
||||||
|
for plugin in plugins.keys():
|
||||||
|
plugins[plugin] = (plugins[plugin], None)
|
||||||
|
else:
|
||||||
|
# detect invalid plugin candidates AND add loaded object to return data
|
||||||
|
for plugin in list(plugins.keys()):
|
||||||
|
pobj = None
|
||||||
|
try:
|
||||||
|
pobj = ploader.get(plugin, class_only=True)
|
||||||
|
except Exception as e:
|
||||||
|
display.vvv("The '{0}' {1} plugin could not be loaded from '{2}': {3}".format(plugin, ptype, plugins[plugin], to_native(e)))
|
||||||
|
|
||||||
|
# sets final {plugin_name: (filepath, class|NONE if not loaded), ...}
|
||||||
|
plugins[plugin] = (plugins[plugin], pobj)
|
||||||
|
|
||||||
|
# {plugin_name: (filepath, class), ...}
|
||||||
|
return plugins
|
||||||
|
|
||||||
|
|
||||||
|
def list_plugins(ptype, collection=None, search_paths=None):
|
||||||
|
|
||||||
|
# {plugin_name: (filepath, class), ...}
|
||||||
|
plugins = {}
|
||||||
|
do_legacy = False
|
||||||
|
collections = {}
|
||||||
|
if collection is None:
|
||||||
|
# list all collections
|
||||||
|
collections['ansible.builtin'] = b''
|
||||||
|
collections.update(list_collections(search_paths=search_paths, dedupe=True))
|
||||||
|
do_legacy = True
|
||||||
|
elif collection == 'ansilbe.builtin':
|
||||||
|
collections['ansible.builtin'] = b''
|
||||||
|
elif collection == 'ansible.legacy':
|
||||||
|
do_legacy = True
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
collections[collection] = to_bytes(_get_collection_path(collection))
|
||||||
|
except ValueError as e:
|
||||||
|
raise AnsibleError("Cannot use supplied collection {0}: {1}".format(collection, to_native(e)), orig_exc=e)
|
||||||
|
|
||||||
|
if collections:
|
||||||
|
plugins.update(list_collection_plugins(ptype, collections))
|
||||||
|
|
||||||
|
if do_legacy:
|
||||||
|
legacy = list_collection_plugins(ptype, {'ansible.legacy': search_paths})
|
||||||
|
for plugin in legacy.keys():
|
||||||
|
builtin = plugin.replace('ansible.legacy.', 'ansible.builtin.', 1)
|
||||||
|
if builtin in plugins and legacy[plugin][0] == plugins[builtin][0]:
|
||||||
|
# add only if no overlap or overlap but diff files
|
||||||
|
continue
|
||||||
|
plugins[plugin] = legacy[plugin]
|
||||||
|
|
||||||
|
return plugins
|
||||||
|
|
||||||
|
|
||||||
|
# wrappers
|
||||||
|
def list_plugin_names(ptype, collection=None):
|
||||||
|
return list_plugins(ptype, collection).keys()
|
||||||
|
|
||||||
|
|
||||||
|
def list_plugin_files(ptype, collection=None):
|
||||||
|
plugins = list_plugins(ptype, collection)
|
||||||
|
return [plugins[k][0] for k in plugins.keys()]
|
||||||
|
|
||||||
|
|
||||||
|
def list_plugin_classes(ptype, collection=None):
|
||||||
|
plugins = list_plugins(ptype, collection)
|
||||||
|
return [plugins[k][1] for k in plugins.keys()]
|
@ -0,0 +1 @@
|
|||||||
|
changed.yml
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: changed
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check if task required changes
|
||||||
|
description:
|
||||||
|
- Tests if task required changes to complete
|
||||||
|
- This test checks for the existance of a C(changed) key in the input dictionary and that it is C(True) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (taskresults is changed }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the task was required changes, C(False) otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: failed
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check if task failed
|
||||||
|
description:
|
||||||
|
- Tests if task finished in failure , opposite of C(success).
|
||||||
|
- This test checks for the existance of a C(failed) key in the input dictionary and that it is C(True) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (taskresults is failed }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(False) if the task was completed as a failure, C(True) if otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1 @@
|
|||||||
|
failed.yml
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: finished
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check if a task has finished
|
||||||
|
description:
|
||||||
|
- Used to test if an async task has finished, it will aslo work with normal tasks but will issue a warning.
|
||||||
|
- This test checks for the existance of a C(finished) key in the input dictionary and that it is C(1) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (asynctaskpoll is finished}}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the aysnc task has finished, C(False) otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: reachable
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check task didn't return that host was unreachable
|
||||||
|
description:
|
||||||
|
- Tests if task was able to reach the host for execution
|
||||||
|
- This test checks for the existance of a C(unreachable) key in the input dictionary and that it is C(False) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (taskresults is reachable }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the task did not flag the host as unreachable, C(False) otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1 @@
|
|||||||
|
skipped.yml
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: skipped
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check if task was skipped
|
||||||
|
description:
|
||||||
|
- Tests if task was skipped
|
||||||
|
- This test checks for the existance of a C(skipped) key in the input dictionary and that it is C(True) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (taskresults is skipped}}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the task was skipped, C(False) otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: started
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check if a task has started
|
||||||
|
description:
|
||||||
|
- Used to check if an async task has started, will also work with non async tasks but will issue a warning.
|
||||||
|
- This test checks for the existance of a C(started) key in the input dictionary and that it is C(1) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (asynctaskpoll is started}}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the task has started, C(False) otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1 @@
|
|||||||
|
success.yml
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: success
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check task success
|
||||||
|
description:
|
||||||
|
- Tests if task finished successfully, opposite of C(failed).
|
||||||
|
- This test checks for the existance of a C(failed) key in the input dictionary and that it is C(False) if present
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (taskresults is success }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the task was successfully completed, C(False) otherwise.
|
||||||
|
type: boolean
|
@ -0,0 +1 @@
|
|||||||
|
success.yml
|
@ -0,0 +1,21 @@
|
|||||||
|
DOCUMENTATION:
|
||||||
|
name: unreachable
|
||||||
|
author: Ansible Core
|
||||||
|
version_added: "1.9"
|
||||||
|
short_description: check task returned that the host was unreachable
|
||||||
|
description:
|
||||||
|
- Tests if task was not able to reach the host for execution
|
||||||
|
- This test checks for the existance of a C(unreachable) key in the input dictionary and that it's value is C(True)
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: registered result from an Ansible task
|
||||||
|
type: dictionary
|
||||||
|
required: True
|
||||||
|
EXAMPLES: |
|
||||||
|
# test 'status' to know how to respond
|
||||||
|
{{ (taskresults is unreachable }}
|
||||||
|
|
||||||
|
RETURN:
|
||||||
|
_value:
|
||||||
|
description: Returns C(True) if the task flagged the host as unreachable, C(False) otherwise.
|
||||||
|
type: boolean
|
Loading…
Reference in New Issue