Skip to content

Commit

Permalink
Enable access to available plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
ssbarnea committed May 23, 2023
1 parent 34c1459 commit 8414f6b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
64 changes: 62 additions & 2 deletions src/ansible_compat/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import tempfile
import warnings
from collections import OrderedDict
from dataclasses import dataclass
from dataclasses import dataclass, field
from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
from typing import TYPE_CHECKING, Any, Callable, Optional, Union, no_type_check

import subprocess_tee
from packaging.version import Version
Expand Down Expand Up @@ -73,6 +73,64 @@ def __init__(self, version: str) -> None:
super().__init__(version)


@dataclass
class Plugins: # pylint: disable=too-many-instance-attributes
"""Dataclass to access installed Ansible plugins, uses ansible-doc to retrieve them."""

runtime: "Runtime"
become: dict[str, str] = field(init=False)
cache: dict[str, str] = field(init=False)
callback: dict[str, str] = field(init=False)
cliconf: dict[str, str] = field(init=False)
connection: dict[str, str] = field(init=False)
httpapi: dict[str, str] = field(init=False)
inventory: dict[str, str] = field(init=False)
lookup: dict[str, str] = field(init=False)
netconf: dict[str, str] = field(init=False)
shell: dict[str, str] = field(init=False)
vars: dict[str, str] = field(init=False) # noqa: A003
module: dict[str, str] = field(init=False)
strategy: dict[str, str] = field(init=False)
test: dict[str, str] = field(init=False)
filter: dict[str, str] = field(init=False) # noqa: A003
role: dict[str, str] = field(init=False)
keyword: dict[str, str] = field(init=False)

@no_type_check
def __getattribute__(self, attr: str): # noqa: ANN204
"""Get attribute."""
result = super().__getattribute__(attr)
if result is None and attr in {
"become",
"cache",
"callback",
"cliconf",
"connection",
"httpapi",
"inventory",
"lookup",
"netconf",
"shell",
"vars",
"module",
"strategy",
"test",
"filter",
"role",
"keyword",
}:
proc = self.runtime.run(
["ansible-doc", "--json", "-l", "-t", attr],
)
data = json.loads(proc.stdout)
if not isinstance(data, dict):
msg = "Unexpected output from ansible-doc"
raise AnsibleCompatError(msg)
result = data

return result


# pylint: disable=too-many-instance-attributes
class Runtime:
"""Ansible Runtime manager."""
Expand All @@ -83,6 +141,7 @@ class Runtime:
# Used to track if we have already initialized the Ansible runtime as attempts
# to do it multiple tilmes will cause runtime warnings from within ansible-core
initialized: bool = False
plugins: Plugins

def __init__(
self,
Expand Down Expand Up @@ -119,6 +178,7 @@ def __init__(
self.isolated = isolated
self.max_retries = max_retries
self.environ = environ or os.environ.copy()
self.plugins = Plugins(runtime=self)
# Reduce noise from paramiko, unless user already defined PYTHONWARNINGS
# paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated
# https://github.com/paramiko/paramiko/issues/2038
Expand Down
21 changes: 21 additions & 0 deletions test/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,3 +747,24 @@ def test_runtime_exec_env(runtime: Runtime) -> None:
runtime.environ["FOO"] = "bar"
result = runtime.run(["printenv", "FOO"])
assert result.stdout.rstrip() == "bar"


def test_runtime_plugins(runtime: Runtime) -> None:
"""Tests ability to access detected plugins."""
assert "ansible.builtin.sudo" in runtime.plugins.become
assert "ansible.builtin.memory" in runtime.plugins.cache
assert "ansible.builtin.default" in runtime.plugins.callback
assert len(runtime.plugins.cliconf) == 0
assert "ansible.builtin.local" in runtime.plugins.connection
assert "ansible.netcommon.restconf" in runtime.plugins.httpapi
assert "ansible.builtin.ini" in runtime.plugins.inventory
assert "ansible.builtin.env" in runtime.plugins.lookup
assert "ansible.netcommon.default" in runtime.plugins.netconf
assert "ansible.builtin.sh" in runtime.plugins.shell
assert "ansible.builtin.host_group_vars" in runtime.plugins.vars
assert "ansible.builtin.file" in runtime.plugins.module
assert "ansible.builtin.free" in runtime.plugins.strategy
assert "ansible.builtin.is_abs" in runtime.plugins.test
assert "ansible.builtin.bool" in runtime.plugins.filter
assert isinstance(runtime.plugins.role, dict)
assert "become" in runtime.plugins.keyword
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ setenv =
PIP_DISABLE_PIP_VERSION_CHECK = 1
PIP_CONSTRAINT = {toxinidir}/requirements.txt
PRE_COMMIT_COLOR = always
PYTEST_REQPASS = 81
PYTEST_REQPASS = 82
FORCE_COLOR = 1
allowlist_externals =
ansible
Expand Down

0 comments on commit 8414f6b

Please sign in to comment.