From 6ab3d76696e6dda36aa5499859a1aea9e8ca0478 Mon Sep 17 00:00:00 2001 From: Jakob Meng <code@jakobmeng.de> Date: Thu, 29 Sep 2022 20:43:18 +0200 Subject: [PATCH] Ensure openstacksdk compatibility in inventory plugin Story: 2010337 Task: 46470 Change-Id: Ieb624b76627b5127d7a6c4d95233bbd5c2f16182 (cherry picked from commit e8bba38e2e78b0352f4ce5a93b8ebb43ce7714ed) --- plugins/inventory/openstack.py | 10 +++ plugins/module_utils/openstack.py | 102 ++++++++++++++---------------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/plugins/inventory/openstack.py b/plugins/inventory/openstack.py index b7f8920..86b271a 100644 --- a/plugins/inventory/openstack.py +++ b/plugins/inventory/openstack.py @@ -136,6 +136,9 @@ import logging from ansible.errors import AnsibleParserError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.utils.display import Display +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import ( + ensure_compatibility +) display = Display() os_logger = logging.getLogger("openstack") @@ -177,6 +180,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): elif not HAS_SDK: msg = "openstacksdk is required for the OpenStack inventory plugin. OpenStack inventory sources will be skipped." + if not msg: + try: + ensure_compatibility(sdk.version.__version__) + except ImportError as e: + msg = ("Incompatible openstacksdk library found: {error}." + .format(error=str(e))) + if msg: display.vvvv(msg) raise AnsibleParserError(msg) diff --git a/plugins/module_utils/openstack.py b/plugins/module_utils/openstack.py index f116ca4..c7b4cae 100644 --- a/plugins/module_utils/openstack.py +++ b/plugins/module_utils/openstack.py @@ -55,6 +55,39 @@ MINIMUM_SDK_VERSION = '0.101.0' MAXIMUM_SDK_VERSION = None +def ensure_compatibility(version, min_version=None, max_version=None): + """ Raises ImportError if the specified version does not + meet the minimum and maximum version requirements""" + + if min_version and MINIMUM_SDK_VERSION: + min_version = max(StrictVersion(MINIMUM_SDK_VERSION), + StrictVersion(min_version)) + elif MINIMUM_SDK_VERSION: + min_version = StrictVersion(MINIMUM_SDK_VERSION) + + if max_version and MAXIMUM_SDK_VERSION: + max_version = min(StrictVersion(MAXIMUM_SDK_VERSION), + StrictVersion(max_version)) + elif MAXIMUM_SDK_VERSION: + max_version = StrictVersion(MAXIMUM_SDK_VERSION) + + if min_version and StrictVersion(version) < min_version: + raise ImportError( + "Version MUST be >={min_version} and <={max_version}, but" + " {version} is smaller than minimum version {min_version}" + .format(version=version, + min_version=min_version, + max_version=max_version)) + + if max_version and StrictVersion(version) > max_version: + raise ImportError( + "Version MUST be >={min_version} and <={max_version}, but" + " {version} is larger than maximum version {max_version}" + .format(version=version, + min_version=min_version, + max_version=max_version)) + + def openstack_argument_spec(): # DEPRECATED: This argument spec is only used for the deprecated old # OpenStack modules. It turns out that modern OpenStack auth is WAY @@ -129,33 +162,16 @@ def openstack_cloud_from_module(module, min_version=None, max_version=None): try: # Due to the name shadowing we should import other way sdk = importlib.import_module('openstack') - sdk_version = importlib.import_module('openstack.version') except ImportError: module.fail_json(msg='openstacksdk is required for this module') - if min_version and MINIMUM_SDK_VERSION: - min_version = max(StrictVersion(MINIMUM_SDK_VERSION), - StrictVersion(min_version)) - elif MINIMUM_SDK_VERSION: - min_version = StrictVersion(MINIMUM_SDK_VERSION) - - if max_version and MAXIMUM_SDK_VERSION: - max_version = min(StrictVersion(MAXIMUM_SDK_VERSION), - StrictVersion(max_version)) - elif MAXIMUM_SDK_VERSION: - max_version = StrictVersion(MAXIMUM_SDK_VERSION) - - if min_version and StrictVersion(sdk_version.__version__) < min_version: + try: + ensure_compatibility(sdk.version.__version__, + min_version, max_version) + except ImportError as e: module.fail_json( - msg="To utilize this module, the installed version of " - "the openstacksdk library MUST be >={min_version}.".format( - min_version=min_version)) - - if max_version and StrictVersion(sdk_version.__version__) > max_version: - module.fail_json( - msg="To utilize this module, the installed version of " - "the openstacksdk library MUST be <={max_version}.".format( - max_version=max_version)) + msg="Incompatible openstacksdk library found: {error}." + .format(error=str(e))) cloud_config = module.params.pop('cloud', None) try: @@ -298,40 +314,18 @@ class OpenStackModule: try: # Due to the name shadowing we should import other way sdk = importlib.import_module('openstack') - sdk_version_lib = importlib.import_module('openstack.version') - self.sdk_version = sdk_version_lib.__version__ + self.sdk_version = sdk.version.__version__ except ImportError: self.fail_json(msg='openstacksdk is required for this module') - # Fail if the available SDK version doesn't meet the minimum - # and maximum version requirements - if self.module_min_sdk_version and MINIMUM_SDK_VERSION: - min_version = max(StrictVersion(MINIMUM_SDK_VERSION), - StrictVersion(self.module_min_sdk_version)) - elif MINIMUM_SDK_VERSION: - min_version = StrictVersion(MINIMUM_SDK_VERSION) - else: - min_version = None - - if self.module_max_sdk_version and MAXIMUM_SDK_VERSION: - max_version = min(StrictVersion(MAXIMUM_SDK_VERSION), - StrictVersion(self.module_max_sdk_version)) - elif MAXIMUM_SDK_VERSION: - max_version = StrictVersion(MAXIMUM_SDK_VERSION) - else: - max_version = None - - if min_version and StrictVersion(self.sdk_version) < min_version: - self.fail( - msg="To utilize this module, the installed version of " - "the openstacksdk library MUST be >={min_version}.".format( - min_version=min_version)) - - if max_version and StrictVersion(self.sdk_version) > max_version: - self.fail( - msg="To utilize this module, the installed version of " - "the openstacksdk library MUST be <={max_version}.".format( - max_version=max_version)) + try: + ensure_compatibility(self.sdk_version, + self.module_min_sdk_version, + self.module_max_sdk_version) + except ImportError as e: + self.fail_json( + msg="Incompatible openstacksdk library found: {error}." + .format(error=str(e))) # Fail if there are set unsupported for this version parameters # New parameters should NOT use 'default' but rely on SDK defaults -- GitLab