# Copyright (c) 2021, Felix Fontein # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later from __future__ import annotations DOCUMENTATION = """ name: a_module short_description: Test whether a given string refers to an existing module or action plugin version_added: 4.0.0 author: Felix Fontein (@felixfontein) description: - Test 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. options: _input: description: A string denoting a fully qualified collection name (FQCN) of a module or action plugin. type: string required: true """ EXAMPLES = """ - name: Make sure that community.aws.route53 is available ansible.builtin.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 ansible.builtin.assert: that: - "'community.general.does_not_exist' is not community.general.a_module" """ RETURN = """ _value: description: Whether the module or action plugin denoted by the input exists. type: boolean """ import typing as t from collections.abc import Callable from ansible.plugins.loader import action_loader, module_loader from ansible.errors import AnsibleFilterError try: from ansible.errors import AnsiblePluginRemovedError except ImportError: AnsiblePluginRemovedError = Exception # type: ignore def a_module(term: t.Any) -> bool: """ Example: - 'community.general.ufw' is community.general.a_module - 'community.general.does_not_exist' is not community.general.a_module """ if not isinstance(term, str): raise AnsibleFilterError(f"Parameter must be a string, got {term!r} of type {type(term)}") try: for loader in (action_loader, module_loader): data = loader.find_plugin(term) if data is not None: return True return False except AnsiblePluginRemovedError: return False class TestModule: """Ansible jinja2 tests""" def tests(self) -> dict[str, Callable]: return { "a_module": a_module, }