1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Add test plugin which allows to query whether a module or action plugin is available (#3628)

* Add test which allows to query whether an action is available.

* Add documentation.

* Fix FreeBSD / macOS compatibility.

* Rename an_action -> a_module.

* Forgot one place.
This commit is contained in:
Felix Fontein 2021-11-01 19:00:24 +01:00 committed by GitHub
parent 9eb638f651
commit c69810bf04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 183 additions and 0 deletions

3
.github/BOTMETA.yml vendored
View file

@ -1169,6 +1169,8 @@ files:
maintainers: inetfuture mattupstate
$modules/web_infrastructure/taiga_issue.py:
maintainers: lekum
$tests/a_module.py:
maintainers: felixfontein
#########################
tests/:
labels: tests
@ -1195,6 +1197,7 @@ macros:
module_utils: plugins/module_utils
modules: plugins/modules
terminals: plugins/terminal
tests: plugins/test
team_ansible_core:
team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross
team_bsd: JoergFiedler MacLemon bcoca dch jasperla mekanix opoplawski overhacked tuxillo

View file

@ -0,0 +1,3 @@
add plugin.test:
- name: a_module
description: Check whether the given string refers to an available module or action plugin

View file

@ -3,3 +3,4 @@ sections:
- title: Guides
toctree:
- filter_guide
- test_guide

View file

@ -0,0 +1,28 @@
.. _ansible_collections.community.general.docsite.test_guide:
community.general Test (Plugin) Guide
=====================================
The :ref:`community.general collection <plugins_in_community.general>` offers currently one test plugin.
.. contents:: Topics
Feature Tests
-------------
The ``a_module`` test allows to check whether a given string refers to an existing module or action plugin. This can be useful in roles, which can use this to ensure that required modules are present ahead of time.
.. code-block:: yaml+jinja
- name: Make sure that community.aws.route53 is available
assert:
that:
- >
'community.aws.route53' is community.general.a_module
- name: Make sure that community.general.does_not_exist is not a module or action plugin
assert:
that:
- "'community.general.does_not_exist' is not community.general.a_module"
.. versionadded:: 4.0.0

33
plugins/test/a_module.py Normal file
View file

@ -0,0 +1,33 @@
# (c) 2021, Felix Fontein <felix@fontein.de>
# 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
from ansible.plugins.loader import action_loader, module_loader
def a_module(term):
"""
Example:
- 'community.general.ufw' is community.general.a_module
- 'community.general.does_not_exist' is not community.general.a_module
"""
for loader in (action_loader, module_loader):
data = loader.find_plugin(term)
# Ansible 2.9 returns a tuple
if isinstance(data, tuple):
data = data[0]
if data is not None:
return True
return False
class TestModule(object):
''' Ansible jinja2 tests '''
def tests(self):
return {
'a_module': a_module,
}

View file

@ -0,0 +1 @@
shippable/posix/group3

View file

@ -0,0 +1,7 @@
namespace: testns
name: testcoll
version: 0.0.1
authors:
- Ansible (https://github.com/ansible)
description: null
tags: [community]

View file

@ -0,0 +1,32 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2021, Felix Fontein <felix@fontein.de>
# 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
DOCUMENTATION = '''
---
module: collection_module
short_description: Test collection module
description:
- This is a test module in a local collection.
author: "Felix Fontein (@felixfontein)"
options: {}
'''
EXAMPLES = ''' # '''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
def main():
AnsibleModule(argument_spec={}).exit_json()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,32 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2021, Felix Fontein <felix@fontein.de>
# 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
DOCUMENTATION = '''
---
module: local_module
short_description: Test local module
description:
- This is a test module locally next to a playbook.
author: "Felix Fontein (@felixfontein)"
options: {}
'''
EXAMPLES = ''' # '''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
def main():
AnsibleModule(argument_spec={}).exit_json()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -eux
export ANSIBLE_TEST_PREFER_VENV=1 # see https://github.com/ansible/ansible/pull/73000#issuecomment-757012395; can be removed once Ansible 2.9 and ansible-base 2.10 support has been dropped
source virtualenv.sh
# The collection loader ignores paths which have more than one ansible_collections in it.
# That's why we have to copy this directory to a temporary place and run the test there.
# Create temporary folder
TEMPDIR=$(mktemp -d)
trap '{ rm -rf ${TEMPDIR}; }' EXIT
cp -r . "${TEMPDIR}"
cd "${TEMPDIR}"
ansible-playbook runme.yml "$@"

View file

@ -0,0 +1,25 @@
- hosts: localhost
tasks:
- name: Test a_module
assert:
that:
# Modules/actions that do not exist
- "'foo_bar' is not community.general.a_module"
- "'foo.bar.baz' is not community.general.a_module"
# Short name and FQCN for builtin and other collections
- "'file' is community.general.a_module"
- "'set_fact' is community.general.a_module"
- "'ansible.builtin.file' is community.general.a_module"
- "'ansible.builtin.set_fact' is community.general.a_module"
- "'ansible.builtin.foo_bar' is not community.general.a_module"
- "'community.crypto.acme_certificate' is community.general.a_module"
- "'community.crypto.openssl_privatekey_pipe' is community.general.a_module"
- "'community.crypto.foo_bar' is not community.general.a_module"
# Modules from this collection (that exist or not)
- "'community.general.ufw' is community.general.a_module"
- "'community.general.foooo_really_does_not_exist' is not community.general.a_module"
# Local module
- "'local_module' is community.general.a_module"
# Local collection module (that exist or not)
- "'testns.testcoll.collection_module' is community.general.a_module"
- "'testns.testcoll.foobar' is not community.general.a_module"