mirror of
https://github.com/kubevirt/kubevirt.core.git
synced 2026-03-26 19:03:16 +00:00
fix: Ensure compatibility with ansible-core >= 2.19
ansible-core 2.19 changes the way templates are trusted and provides a new way of patching module args in unit tests. With this commit the following changes are made to ensure compatibility with ansible-core >= 2.19: - Mark inputs to composable as trusted to align with the new template trust model. - Utilize the updated method for patching module arguments in unit tests if available. - Replace direct access to the self._cache attribute with the inventory's cache property. Signed-off-by: Felix Matouschek <fmatouschek@redhat.com>
This commit is contained in:
@@ -157,6 +157,14 @@ except ImportError as e:
|
||||
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
|
||||
# Handle import errors of trust_as_template.
|
||||
# It is only available on ansible-core >=2.19.
|
||||
try:
|
||||
from ansible.template import trust_as_template
|
||||
except ImportError:
|
||||
trust_as_template = None
|
||||
|
||||
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
||||
get_api_client,
|
||||
K8SClient,
|
||||
@@ -445,13 +453,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
results = {}
|
||||
if attempt_to_read_cache:
|
||||
try:
|
||||
results = self._cache[cache_key]
|
||||
results = self.cache[cache_key]
|
||||
except KeyError:
|
||||
cache_needs_update = True
|
||||
if not attempt_to_read_cache or cache_needs_update:
|
||||
results = self._fetch_objects(get_api_client(**config_data), opts)
|
||||
if cache_needs_update:
|
||||
self._cache[cache_key] = results
|
||||
self.cache[cache_key] = results
|
||||
|
||||
self._populate_inventory(results, opts)
|
||||
|
||||
@@ -883,12 +891,32 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
"""
|
||||
hostvars = self.inventory.get_host(hostname).get_vars()
|
||||
strict = self.get_option("strict")
|
||||
|
||||
def trust_compose_groups(data: Dict) -> Dict:
|
||||
if trust_as_template is not None:
|
||||
return {k: trust_as_template(v) for k, v in data.items()}
|
||||
return data
|
||||
|
||||
def trust_keyed_groups(data: List) -> List:
|
||||
if trust_as_template is not None:
|
||||
return [{**d, "key": trust_as_template(d["key"])} for d in data]
|
||||
return data
|
||||
|
||||
self._set_composite_vars(
|
||||
self.get_option("compose"), hostvars, hostname, strict=True
|
||||
trust_compose_groups(self.get_option("compose")),
|
||||
hostvars,
|
||||
hostname,
|
||||
strict=True,
|
||||
)
|
||||
self._add_host_to_composed_groups(
|
||||
self.get_option("groups"), hostvars, hostname, strict=strict
|
||||
trust_compose_groups(self.get_option("groups")),
|
||||
hostvars,
|
||||
hostname,
|
||||
strict=strict,
|
||||
)
|
||||
self._add_host_to_keyed_groups(
|
||||
self.get_option("keyed_groups"), hostvars, hostname, strict=strict
|
||||
trust_keyed_groups(self.get_option("keyed_groups")),
|
||||
hostvars,
|
||||
hostname,
|
||||
strict=strict,
|
||||
)
|
||||
|
||||
@@ -17,6 +17,8 @@ from ansible_collections.kubevirt.core.plugins.inventory.kubevirt import (
|
||||
KubeVirtInventoryException,
|
||||
)
|
||||
|
||||
from ansible.plugins.inventory import Cacheable
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config_data,expected",
|
||||
@@ -96,9 +98,8 @@ from ansible_collections.kubevirt.core.plugins.inventory.kubevirt import (
|
||||
],
|
||||
)
|
||||
def test_config_data_to_opts(mocker, inventory, config_data, expected):
|
||||
read_config_data = mocker.patch.object(
|
||||
inventory, "_read_config_data", return_value=config_data
|
||||
)
|
||||
mocker.patch.object(Cacheable, "cache", new_callable=mocker.PropertyMock)
|
||||
mocker.patch.object(inventory, "_read_config_data", return_value=config_data)
|
||||
mocker.patch.object(inventory, "get_cache_key")
|
||||
mocker.patch.object(inventory, "get_option")
|
||||
mocker.patch.object(kubevirt, "get_api_client")
|
||||
@@ -129,7 +130,9 @@ def test_use_of_cache(
|
||||
path = "/testpath"
|
||||
config_data = {"host_format": "test-format"}
|
||||
|
||||
mocker.patch.dict(inventory._cache, cache_data)
|
||||
mocker.patch.object(
|
||||
Cacheable, "cache", new_callable=mocker.PropertyMock, return_value=cache_data
|
||||
)
|
||||
|
||||
read_config_data = mocker.patch.object(
|
||||
inventory, "_read_config_data", return_value=config_data
|
||||
@@ -168,6 +171,7 @@ def test_use_of_cache(
|
||||
],
|
||||
)
|
||||
def test_k8s_client_missing(mocker, inventory, present):
|
||||
mocker.patch.object(Cacheable, "cache", new_callable=mocker.PropertyMock)
|
||||
mocker.patch.object(kubevirt, "HAS_K8S_MODULE_HELPER", present)
|
||||
mocker.patch.object(kubevirt, "get_api_client")
|
||||
mocker.patch.object(inventory, "_read_config_data", return_value={})
|
||||
|
||||
@@ -16,14 +16,21 @@ from ansible_collections.kubevirt.core.tests.unit.utils.ansible_module_mock impo
|
||||
AnsibleExitJson,
|
||||
exit_json,
|
||||
fail_json,
|
||||
set_module_args,
|
||||
)
|
||||
|
||||
# Handle import errors of patch_module_args.
|
||||
# It is only available on ansible-core >=2.19.
|
||||
try:
|
||||
from ansible.module_utils.testing import patch_module_args
|
||||
except ImportError as e:
|
||||
from ansible_collections.kubevirt.core.tests.unit.utils.ansible_module_mock import (
|
||||
patch_module_args,
|
||||
)
|
||||
|
||||
|
||||
def test_module_fails_when_required_args_missing(mocker):
|
||||
mocker.patch.object(AnsibleModule, "fail_json", fail_json)
|
||||
with pytest.raises(AnsibleFailJson):
|
||||
set_module_args({})
|
||||
with pytest.raises(AnsibleFailJson), patch_module_args({}):
|
||||
kubevirt_vm.main()
|
||||
|
||||
|
||||
@@ -290,8 +297,7 @@ def test_module(mocker, module_params, k8s_module_params, vm_definition, method)
|
||||
},
|
||||
)
|
||||
|
||||
with pytest.raises(AnsibleExitJson):
|
||||
set_module_args(module_params)
|
||||
with pytest.raises(AnsibleExitJson), patch_module_args(module_params):
|
||||
kubevirt_vm.main()
|
||||
|
||||
perform_action.assert_called_once_with(
|
||||
|
||||
@@ -23,14 +23,21 @@ from ansible_collections.kubevirt.core.tests.unit.utils.ansible_module_mock impo
|
||||
AnsibleFailJson,
|
||||
exit_json,
|
||||
fail_json,
|
||||
set_module_args,
|
||||
)
|
||||
|
||||
# Handle import errors of patch_module_args.
|
||||
# It is only available on ansible-core >=2.19.
|
||||
try:
|
||||
from ansible.module_utils.testing import patch_module_args
|
||||
except ImportError as e:
|
||||
from ansible_collections.kubevirt.core.tests.unit.utils.ansible_module_mock import (
|
||||
patch_module_args,
|
||||
)
|
||||
|
||||
|
||||
def test_module_fails_when_required_args_missing(mocker):
|
||||
mocker.patch.object(AnsibleModule, "fail_json", fail_json)
|
||||
with pytest.raises(AnsibleFailJson):
|
||||
set_module_args({"running": False})
|
||||
with pytest.raises(AnsibleFailJson), patch_module_args({"running": False}):
|
||||
kubevirt_vm_info.main()
|
||||
|
||||
|
||||
@@ -96,8 +103,7 @@ def test_module(mocker, module_args, find_args):
|
||||
},
|
||||
)
|
||||
|
||||
with pytest.raises(AnsibleExitJson):
|
||||
set_module_args(module_args)
|
||||
with pytest.raises(AnsibleExitJson), patch_module_args(module_args):
|
||||
kubevirt_vm_info.main()
|
||||
|
||||
find.assert_called_once_with(**find_args)
|
||||
|
||||
@@ -21,9 +21,17 @@ from ansible_collections.kubevirt.core.plugins.module_utils import (
|
||||
from ansible_collections.kubevirt.core.tests.unit.utils.ansible_module_mock import (
|
||||
AnsibleExitJson,
|
||||
exit_json,
|
||||
set_module_args,
|
||||
)
|
||||
|
||||
# Handle import errors of patch_module_args.
|
||||
# It is only available on ansible-core >=2.19.
|
||||
try:
|
||||
from ansible.module_utils.testing import patch_module_args
|
||||
except ImportError as e:
|
||||
from ansible_collections.kubevirt.core.tests.unit.utils.ansible_module_mock import (
|
||||
patch_module_args,
|
||||
)
|
||||
|
||||
FIND_ARGS_DEFAULT = {
|
||||
"kind": "VirtualMachineInstance",
|
||||
"api_version": "kubevirt.io/v1",
|
||||
@@ -74,8 +82,7 @@ def test_module(mocker, module_args, find_args):
|
||||
},
|
||||
)
|
||||
|
||||
with pytest.raises(AnsibleExitJson):
|
||||
set_module_args(module_args)
|
||||
with pytest.raises(AnsibleExitJson), patch_module_args(module_args):
|
||||
kubevirt_vmi_info.main()
|
||||
|
||||
find.assert_called_once_with(**find_args)
|
||||
|
||||
@@ -10,16 +10,24 @@ from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import json
|
||||
from contextlib import contextmanager
|
||||
from json import dumps
|
||||
from typing import (
|
||||
Any,
|
||||
Dict,
|
||||
)
|
||||
from unittest import mock
|
||||
|
||||
from ansible.module_utils import basic
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
|
||||
|
||||
def set_module_args(args):
|
||||
@contextmanager
|
||||
def patch_module_args(args: Dict[str, Any] | None = None):
|
||||
"""prepare arguments so that they will be picked up during module creation"""
|
||||
args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
|
||||
basic._ANSIBLE_ARGS = to_bytes(args)
|
||||
args = dumps({"ANSIBLE_MODULE_ARGS": args})
|
||||
with mock.patch.object(basic, "_ANSIBLE_ARGS", to_bytes(args)):
|
||||
yield
|
||||
|
||||
|
||||
class AnsibleExitJson(Exception):
|
||||
|
||||
Reference in New Issue
Block a user