diff --git a/plugins/inventory/kubevirt.py b/plugins/inventory/kubevirt.py index 9ff5df1..aa2e5bc 100644 --- a/plugins/inventory/kubevirt.py +++ b/plugins/inventory/kubevirt.py @@ -141,7 +141,7 @@ from typing import ( # Set HAS_K8S_MODULE_HELPER and k8s_import exception accordingly to # potentially print a warning to the user if the client is missing. try: - from kubernetes.dynamic.exceptions import DynamicApiError + from kubernetes.dynamic.exceptions import DynamicApiError, ResourceNotFoundError HAS_K8S_MODULE_HELPER = True K8S_IMPORT_EXCEPTION = None @@ -152,6 +152,11 @@ except ImportError as e: Dummy class, mainly used for ansible-test sanity. """ + class ResourceNotFoundError(Exception): + """ + Dummy class, mainly used for ansible-test sanity. + """ + HAS_K8S_MODULE_HELPER = False K8S_IMPORT_EXCEPTION = e @@ -575,9 +580,18 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): _get_available_namespaces lists all namespaces accessible with the configured credentials and returns them. """ + + namespaces = [] + try: + namespaces = self._get_resources( + client, "project.openshift.io/v1", "Project" + ) + except ResourceNotFoundError: + namespaces = self._get_resources(client, "v1", "Namespace") + return [ namespace["metadata"]["name"] - for namespace in self._get_resources(client, "v1", "Namespace") + for namespace in namespaces if "metadata" in namespace and "name" in namespace["metadata"] ] diff --git a/tests/unit/plugins/inventory/conftest.py b/tests/unit/plugins/inventory/conftest.py index 3f133e4..5a5602c 100644 --- a/tests/unit/plugins/inventory/conftest.py +++ b/tests/unit/plugins/inventory/conftest.py @@ -8,6 +8,7 @@ __metaclass__ = type import pytest +from kubernetes.dynamic.exceptions import ResourceNotFoundError from kubernetes.dynamic.resource import ResourceField from ansible.template import Templar @@ -113,6 +114,9 @@ def client(mocker, request): dns_obj = ResourceField({"spec": {"baseDomain": base_domain}}) dns.items = [dns_obj] + projects = mocker.Mock() + projects.items = [ResourceField(item) for item in param.get("projects", [])] + namespace_client = mocker.Mock() namespace_client.get = mocker.Mock(return_value=namespaces) vm_client = mocker.Mock() @@ -130,6 +134,14 @@ def client(mocker, request): dns_client = mocker.Mock() dns_client.get = dns_client_get + def project_client_get(): + if not projects.items: + raise ResourceNotFoundError + return projects + + project_client = mocker.Mock() + project_client.get = project_client_get + def resources_get(api_version="", kind=""): if api_version.lower() == "v1": if kind.lower() == "namespace": @@ -138,6 +150,11 @@ def client(mocker, request): return service_client elif api_version.lower() == "config.openshift.io/v1" and kind.lower() == "dns": return dns_client + elif ( + api_version.lower() == "project.openshift.io/v1" + and kind.lower() == "project" + ): + return project_client elif "kubevirt.io/" in api_version.lower(): if kind.lower() == "virtualmachine": return vm_client diff --git a/tests/unit/plugins/inventory/test_kubevirt_get_resources.py b/tests/unit/plugins/inventory/test_kubevirt_get_resources.py index 9b71f59..aaf8ceb 100644 --- a/tests/unit/plugins/inventory/test_kubevirt_get_resources.py +++ b/tests/unit/plugins/inventory/test_kubevirt_get_resources.py @@ -63,6 +63,27 @@ def test_get_resources(inventory, client): }, [DEFAULT_NAMESPACE, "test"], ), + ( + { + "projects": [ + {"metadata": {"name": DEFAULT_NAMESPACE}}, + {"metadata": {"name": "testproject"}}, + ] + }, + [DEFAULT_NAMESPACE, "testproject"], + ), + ( + { + "namespaces": [ + {"metadata": {"name": DEFAULT_NAMESPACE}}, + {"metadata": {"name": "test"}}, + ], + "projects": [ + {"metadata": {"name": "testproject"}}, + ], + }, + ["testproject"], + ), ], indirect=["client"], )