Ensure openstacksdk compatibility in inventory plugin

Story: 2010337
Task: 46470

Change-Id: Ieb624b76627b5127d7a6c4d95233bbd5c2f16182
(cherry picked from commit e8bba38e2e)
This commit is contained in:
Jakob Meng
2022-09-29 20:43:18 +02:00
parent 40d913d2a6
commit 6ab3d76696
2 changed files with 58 additions and 54 deletions

View File

@@ -136,6 +136,9 @@ import logging
from ansible.errors import AnsibleParserError from ansible.errors import AnsibleParserError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
ensure_compatibility
)
display = Display() display = Display()
os_logger = logging.getLogger("openstack") os_logger = logging.getLogger("openstack")
@@ -177,6 +180,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
elif not HAS_SDK: elif not HAS_SDK:
msg = "openstacksdk is required for the OpenStack inventory plugin. OpenStack inventory sources will be skipped." 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: if msg:
display.vvvv(msg) display.vvvv(msg)
raise AnsibleParserError(msg) raise AnsibleParserError(msg)

View File

@@ -55,6 +55,39 @@ MINIMUM_SDK_VERSION = '0.101.0'
MAXIMUM_SDK_VERSION = None 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(): def openstack_argument_spec():
# DEPRECATED: This argument spec is only used for the deprecated old # DEPRECATED: This argument spec is only used for the deprecated old
# OpenStack modules. It turns out that modern OpenStack auth is WAY # 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: try:
# Due to the name shadowing we should import other way # Due to the name shadowing we should import other way
sdk = importlib.import_module('openstack') sdk = importlib.import_module('openstack')
sdk_version = importlib.import_module('openstack.version')
except ImportError: except ImportError:
module.fail_json(msg='openstacksdk is required for this module') module.fail_json(msg='openstacksdk is required for this module')
if min_version and MINIMUM_SDK_VERSION: try:
min_version = max(StrictVersion(MINIMUM_SDK_VERSION), ensure_compatibility(sdk.version.__version__,
StrictVersion(min_version)) min_version, max_version)
elif MINIMUM_SDK_VERSION: except ImportError as e:
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:
module.fail_json( module.fail_json(
msg="To utilize this module, the installed version of " msg="Incompatible openstacksdk library found: {error}."
"the openstacksdk library MUST be >={min_version}.".format( .format(error=str(e)))
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))
cloud_config = module.params.pop('cloud', None) cloud_config = module.params.pop('cloud', None)
try: try:
@@ -298,40 +314,18 @@ class OpenStackModule:
try: try:
# Due to the name shadowing we should import other way # Due to the name shadowing we should import other way
sdk = importlib.import_module('openstack') sdk = importlib.import_module('openstack')
sdk_version_lib = importlib.import_module('openstack.version') self.sdk_version = sdk.version.__version__
self.sdk_version = sdk_version_lib.__version__
except ImportError: except ImportError:
self.fail_json(msg='openstacksdk is required for this module') self.fail_json(msg='openstacksdk is required for this module')
# Fail if the available SDK version doesn't meet the minimum try:
# and maximum version requirements ensure_compatibility(self.sdk_version,
if self.module_min_sdk_version and MINIMUM_SDK_VERSION: self.module_min_sdk_version,
min_version = max(StrictVersion(MINIMUM_SDK_VERSION), self.module_max_sdk_version)
StrictVersion(self.module_min_sdk_version)) except ImportError as e:
elif MINIMUM_SDK_VERSION: self.fail_json(
min_version = StrictVersion(MINIMUM_SDK_VERSION) msg="Incompatible openstacksdk library found: {error}."
else: .format(error=str(e)))
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))
# Fail if there are set unsupported for this version parameters # Fail if there are set unsupported for this version parameters
# New parameters should NOT use 'default' but rely on SDK defaults # New parameters should NOT use 'default' but rely on SDK defaults