diff --git a/plugins/module_utils/common/controller_version.py b/plugins/module_utils/common/controller_version.py index 38bf76912..a8d88fb78 100644 --- a/plugins/module_utils/common/controller_version.py +++ b/plugins/module_utils/common/controller_version.py @@ -54,6 +54,9 @@ class ControllerVersion: ``` ### Response + + #### ND 3.x + ```json { "version": "12.1.2e", @@ -62,10 +65,40 @@ class ControllerVersion: "dev": false, "isHaEnabled": false, "install": "EASYFABRIC", - "uuid": "f49e6088-ad4f-4406-bef6-2419de914ff1", + "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "is_upgrade_inprogress": false } ``` + + #### ND 4.1 EFT 138c + + ```json + { + "version": "12.4.1.225", + "mode": "", + "isMediaController": false, + "dev": false, + "isHaEnabled": false, + "install": "", + "uuid": "", + "is_upgrade_inprogress": false + } + ``` + + #### ND 4.1 EFT 156b + + ```json + { + "version": "12.4.1.245", + "mode": "", + "isMediaController": false, + "dev": false, + "isHaEnabled": false, + "install": "", + "uuid": "", + "is_upgrade_inprogress": false + } + """ def __init__(self): @@ -109,10 +142,50 @@ def refresh(self): msg += f"{self.rest_send.response_current}" raise ValueError(msg) + # Ensure response_data is a dictionary + if not isinstance(self._response_data, dict): + msg = f"{self.class_name}.refresh() failed: " + msg += f"Expected response data to be a dictionary, got {type(self._response_data).__name__}. " + msg += f"Data: {self._response_data}" + raise ValueError(msg) + def _get(self, item): - return self.conversion.make_none( - self.conversion.make_boolean(self.response_data.get(item)) - ) + """ + # Summary + + Return the parameter (item) from the response + + ## Notes + + - With ND 4, parameters like "mode", "uuid" are empty strings. + Return empty string in this case, rather than None. + - None indicates that the parameter is missing in the response (i.e. an error) + """ + value = self.response_data.get(item) + if value == "": + return "" + return self.conversion.make_none(self.conversion.make_boolean(value)) + + def _validate_and_split_version(self): + """ + Validate version format and return split version parts. + + Expected formats: + w.x.y (3 parts) or w.x.y.z (4 parts) + + Returns: + list: Version parts split by '.' + + Raises: + ValueError: If version format is unexpected + """ + version_parts = self.version.split(".") + if len(version_parts) not in [3, 4]: + msg = f"{self.class_name}._validate_and_split_version: " + msg += f"Unexpected version format '{self.version}'. " + msg += f"Expected 3 or 4 parts (w.x.y or w.x.y.z), got {len(version_parts)} parts" + raise ValueError(msg) + return version_parts @property def dev(self): @@ -193,14 +266,24 @@ def response_data(self): @property def mode(self): """ + # Summary + Return the controller mode, if it exists. Return None otherwise Possible values: LAN - None + "" + + ## Notes + + - mode will be "" for ND 4 """ - return self._get("mode") + value = self._get("mode") + if value is None: + msg = "Controller response is missing 'mode' parameter." + raise ValueError(msg) + return value @property def uuid(self): @@ -217,84 +300,116 @@ def uuid(self): @property def version(self): """ - Return the controller version, if it exists. - Return None otherwise + # Summary + + - Return the controller version, if it exists. + - Raise ValueError if version is not available. Possible values: - version, e.g. "12.1.2e" - None + version, e.g. "12.1.2e" or "12.4.1.245" """ - return self._get("version") + version = self._get("version") + if version is None: + msg = f"{self.class_name}.version: " + msg += "Version information not available in controller response" + raise ValueError(msg) + return version @property def version_major(self): """ - Return the controller major version as a string, if it exists. - Return None otherwise + Return the controller major version as a string. + Raise ValueError if version format is unexpected. We are assuming semantic versioning based on: https://semver.org + Expected formats: + w.x.y (3 parts) or w.x.y.z (4 parts) + Possible values: if version is 12.1.2e, return "12" - None + if version is 12.4.1.245, return "12" """ - if self.version is None: - return None - return (self._get("version").split("."))[0] + version_parts = self._validate_and_split_version() + return version_parts[0] @property def version_minor(self): """ - Return the controller minor version as a string, if it exists. - Return None otherwise + Return the controller minor version as a string. + Raise ValueError if version format is unexpected. We are assuming semantic versioning based on: https://semver.org + Expected formats: + w.x.y (3 parts) or w.x.y.z (4 parts) + Possible values: - if version is 12.1.2e, return 1 - None + if version is 12.1.2e, return "1" + if version is 12.4.1.245, return "4" """ - if self.version is None: - return None - return (self._get("version").split("."))[1] + version_parts = self._validate_and_split_version() + return version_parts[1] @property def version_patch(self): """ - Return the controller patch version as a string, if it exists. - Return None otherwise + Return the controller patch version as a string. + Raise ValueError if version format is unexpected. We are assuming semantic versioning based on: https://semver.org + Expected formats: + w.x.y (3 parts) or w.x.y.z (4 parts) + Possible values: - if version is 12.1.2e, return 2e - None + if version is 12.1.2e, return "2e" + if version is 12.4.1.245, return "1" """ - if self.version is None: - return None - return (self._get("version").split("."))[2] + version_parts = self._validate_and_split_version() + return version_parts[2] @property def is_controller_version_4x(self) -> bool: """ - ### Summary + # Summary - Return True if the controller version implies ND 4.0 or higher. - Return False otherwise. + + ## Raises + + - ValueError if unable to determine version """ method_name = inspect.stack()[0][3] result = None - if int(self.version_major) == 12 and int(self.version_minor) < 3: - result = False - else: - result = True + try: + major = self.version_major + minor = self.version_minor + + if major is None or minor is None: + # This should never happen due to early validation, but if it does, raise an error + msg = f"{self.class_name}.{method_name}: " + msg += f"Unexpected None values: major={major}, minor={minor}" + raise ValueError(msg) + + # version_minor is always numeric, so we can convert directly to int + if int(major) == 12 and int(minor) < 3: + result = False + else: + result = True + except (ValueError, TypeError) as e: + # If version parsing fails, re-raise as ValueError - do not assume version + msg = f"{self.class_name}.{method_name}: " + msg += f"Error parsing version {self.version}: {e}" + raise ValueError(msg) from e msg = f"{self.class_name}.{method_name}: " - msg = f"self.version: {self.version}, " + msg += f"self.version: {self.version}, " msg += f"Controller is version 4.x: {result}" self.log.debug(msg) diff --git a/tests/unit/module_utils/common/fixtures/responses_ep_version.json b/tests/unit/module_utils/common/fixtures/responses_ep_version.json index 426030b47..f4718cdb2 100644 --- a/tests/unit/module_utils/common/fixtures/responses_ep_version.json +++ b/tests/unit/module_utils/common/fixtures/responses_ep_version.json @@ -1,491 +1,580 @@ { "test_controller_version_00100a": { - "RETURN_CODE": 200, - "METHOD": "GET", - "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00100b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00100b": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "true", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00100c": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00100c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00110a": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00110a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00110b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00110b": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00120a": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00120a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "true", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "true", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00120b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00120b": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00120c": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00120c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00130a": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00130a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "true", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "true", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00130b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00130b": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00130c": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00130c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00140a": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00140a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "true", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "true" - } - }, - "test_controller_version_00140b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00140b": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00140c": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00140c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", - "uuid": "" - } - }, - "test_controller_version_00150a": { - "RETURN_CODE": 200, + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", + "uuid": "", + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00150a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } + "version": "12.1.3b" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 }, "test_controller_version_00160a": { - "RETURN_CODE": 200, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK" + "RETURN_CODE": 200 }, "test_controller_version_00170a": { - "RETURN_CODE": 200, - "METHOD": "GET", - "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } + "version": "12.1.3b" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 }, "test_controller_version_00180a": { - "RETURN_CODE": 404, + "DATA": {}, + "MESSAGE": "Not Found", "METHOD": "GET", "REQUEST_PATH": "https://foo/noop", - "MESSAGE": "Not Found", - "DATA": {} + "RETURN_CODE": 404 }, "test_controller_version_00190a": { - "RETURN_CODE": 500, + "DATA": {}, + "MESSAGE": "Internal Server Error", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "Internal Server Error", - "DATA": {} + "RETURN_CODE": 500 }, "test_controller_version_00200a": { - "RETURN_CODE": 200, - "METHOD": "GET", - "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "TEST_NOTES": [ + "mode key is populated. ND 3." + ], "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } + "version": "12.1.3b" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 }, "test_controller_version_00200b": { - "RETURN_CODE": 200, + "TEST_NOTES": [ + "mode key is empty. ND 4." + ], + "DATA": { + "dev": false, + "install": "", + "is_upgrade_inprogress": false, + "isHaEnabled": false, + "isMediaController": false, + "mode": "", + "uuid": "", + "version": "12.4.1.245" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00200c": { + "TEST_NOTES": [ + "mode key is missing. Negative test." + ], "DATA": { - "version": "12.1.3b", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00210a": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00210a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "foo-uuid", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00210b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00210b": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00220a": { - "RETURN_CODE": 200, + "isMediaController": "false", + "mode": "LAN", + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00220a": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00220b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00220b": { "DATA": { - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "install": "", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00230a": { - "RETURN_CODE": 200, + "version": "12.4.1.245" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00220c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", + "uuid": "" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 + }, + "test_controller_version_00230a": { + "DATA": { + "dev": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00230b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00230b": { "DATA": { - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "install": "", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00240a": { - "RETURN_CODE": 200, + "version": "12.4.1.245" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00230c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", + "uuid": "" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 + }, + "test_controller_version_00240a": { + "DATA": { + "dev": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00240b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00240b": { "DATA": { - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "install": "", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00250a": { - "RETURN_CODE": 200, + "version": "12.4.1.245" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00240c": { "DATA": { - "version": "12.1.3b", - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", + "uuid": "" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 + }, + "test_controller_version_00250a": { + "DATA": { + "dev": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00250b": { - "RETURN_CODE": 200, + "version": "12.1.3b" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00250b": { "DATA": { - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "install": "", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00300a": { - "TEST_NOTES": [ - "12.2.2.238 implies ND 3.x" - ], - "RETURN_CODE": 200, + "version": "12.4.1.245" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200 + }, + "test_controller_version_00250c": { "DATA": { - "version": "12.2.2.238", - "mode": "LAN", - "isMediaController": "false", "dev": "false", + "is_upgrade_inprogress": "false", "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", + "uuid": "" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200 + }, + "test_controller_version_00300a": { + "DATA": { + "dev": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } - }, - "test_controller_version_00300b": { - "TEST_NOTES": [ - "12.3.1.248 implies ND 4.x" - ], - "RETURN_CODE": 200, + "version": "12.2.2.238" + }, + "MESSAGE": "OK", "METHOD": "GET", "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", - "MESSAGE": "OK", + "RETURN_CODE": 200, + "TEST_NOTES": [ + "12.2.2.238 implies ND 3.x" + ] + }, + "test_controller_version_00300b": { "DATA": { - "version": "12.3.1.248", - "mode": "LAN", - "isMediaController": "false", "dev": "false", - "isHaEnabled": "false", "install": "EASYFABRIC", + "is_upgrade_inprogress": "false", + "isHaEnabled": "false", + "isMediaController": "false", + "mode": "LAN", "uuid": "", - "is_upgrade_inprogress": "false" - } + "version": "12.3.1.248" + }, + "MESSAGE": "OK", + "METHOD": "GET", + "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/fm/about/version", + "RETURN_CODE": 200, + "TEST_NOTES": [ + "12.3.1.248 implies ND 4.x" + ] } } \ No newline at end of file diff --git a/tests/unit/module_utils/common/test_controller_version.py b/tests/unit/module_utils/common/test_controller_version.py index c5b819ca3..70e813bbf 100644 --- a/tests/unit/module_utils/common/test_controller_version.py +++ b/tests/unit/module_utils/common/test_controller_version.py @@ -29,17 +29,18 @@ import inspect import pytest -from ansible_collections.cisco.dcnm.plugins.module_utils.common.exceptions import \ - ControllerResponseError -from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import \ - ResponseHandler -from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import \ - RestSend -from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import \ - Sender +from ansible_collections.cisco.dcnm.plugins.module_utils.common.exceptions import ControllerResponseError +from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import ResponseHandler +from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import RestSend +from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import Sender from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ( - MockAnsibleModule, ResponseGenerator, controller_version_fixture, - does_not_raise, params, responses_ep_version) + MockAnsibleModule, + ResponseGenerator, + controller_version_fixture, + does_not_raise, + params, + responses_ep_version, +) def test_controller_version_00000(controller_version) -> None: @@ -533,34 +534,38 @@ def responses(): @pytest.mark.parametrize( - "key, expected", + "key, expected, raises", [ - ("test_controller_version_00200a", "LAN"), - ("test_controller_version_00200b", None), + ("test_controller_version_00200a", "LAN", False), + ("test_controller_version_00200b", "", False), + ("test_controller_version_00200c", None, True), ], ) -def test_controller_version_00200(controller_version, key, expected) -> None: +def test_controller_version_00200(controller_version, key, expected, raises) -> None: """ ### Classes and Methods - - ``ControllerVersion()`` - - ``refresh`` - - ``mode`` + - `ControllerVersion()` + - `refresh` + - `mode` ### Test - - ``mode`` returns expected values. + - `mode` returns expected values. + - ValueError is raised if `mode` is missing in the response ### Description ``mode`` returns: - Its value, if the "mode" key is present in the controller response. - - None, if the "mode" key is absent from the controller response. + - For ND 4, mode will be an empty string (""). + - ValueError if the "mode" key is absent from the controller response. ### Expected results 1. test_controller_version_00200a == "LAN" - 2. test_controller_version_00200b is None + 2. test_controller_version_00200b == "" + 3. test_controller_version_00200c == None (ValueError) """ def responses(): @@ -579,7 +584,13 @@ def responses(): instance = controller_version instance.rest_send = rest_send instance.refresh() - assert instance.mode == expected + print(f"raises: {raises}") + if not raises: + assert instance.mode == expected + else: + match = "Controller response is missing 'mode' parameter." + with pytest.raises(ValueError, match=match): + instance.mode # pylint: disable=pointless-statement @pytest.mark.parametrize( @@ -634,13 +645,14 @@ def responses(): @pytest.mark.parametrize( - "key, expected", + "key, expected, raises", [ - ("test_controller_version_00220a", "12.1.3b"), - ("test_controller_version_00220b", None), + ("test_controller_version_00220a", "12.1.3b", False), + ("test_controller_version_00220b", "12.4.1.245", False), + ("test_controller_version_00220c", None, True), ], ) -def test_controller_version_00220(controller_version, key, expected) -> None: +def test_controller_version_00220(controller_version, key, expected, raises) -> None: """ ### Classes and Methods @@ -656,12 +668,13 @@ def test_controller_version_00220(controller_version, key, expected) -> None: ``version`` returns: - Its value, if the "version" key is present in the controller response. - - None, if the "version" key is absent from the controller response. + - ValueError, if the "version" key is absent from the controller response. ### Expected result - 1. test_controller_version_00220a == "12.1.3b" - 2. test_controller_version_00220b is None + 1. test_controller_version_00220a == "12.1.3b" (ND 3.x format) + 2. test_controller_version_00220b == "12.4.1.245" (ND 4.1 format) + 2. test_controller_version_00220b == None (raises ValueError) """ def responses(): @@ -680,17 +693,22 @@ def responses(): instance = controller_version instance.rest_send = rest_send instance.refresh() - assert instance.version == expected + if not raises: + assert instance.version == expected + else: + match = "ControllerVersion.version: Version information not available in controller response" + pytest.raises(ValueError, match=match) @pytest.mark.parametrize( - "key, expected", + "key, expected, raises", [ - ("test_controller_version_00230a", "12"), - ("test_controller_version_00230b", None), + ("test_controller_version_00230a", "12", False), + ("test_controller_version_00230b", "12", False), + ("test_controller_version_00230c", None, True), ], ) -def test_controller_version_00230(controller_version, key, expected) -> None: +def test_controller_version_00230(controller_version, key, expected, raises) -> None: """ ### Classes and Methods @@ -709,7 +727,8 @@ def test_controller_version_00230(controller_version, key, expected) -> None: ### Expected result 1. test_controller_version_00230a == "12" - 2. test_controller_version_00230b is None + 2. test_controller_version_00230b == "12" + 2. test_controller_version_00230c == None (raises ValueError) """ def responses(): @@ -728,17 +747,23 @@ def responses(): instance = controller_version instance.rest_send = rest_send instance.refresh() - assert instance.version_major == expected + if not raises: + assert instance.version_major == expected + else: + match = "ControllerVersion.version: Version information not available in controller response" + with pytest.raises(ValueError, match=match): + instance.version_major # pylint: disable=pointless-statement @pytest.mark.parametrize( - "key, expected", + "key, expected, raises", [ - ("test_controller_version_00240a", "1"), - ("test_controller_version_00240b", None), + ("test_controller_version_00240a", "1", False), + ("test_controller_version_00240b", "4", False), + ("test_controller_version_00240c", None, True), ], ) -def test_controller_version_00240(controller_version, key, expected) -> None: +def test_controller_version_00240(controller_version, key, expected, raises) -> None: """ ### Classes and Methods @@ -758,7 +783,8 @@ def test_controller_version_00240(controller_version, key, expected) -> None: ### Expected result 1. test_controller_version_00240a == "1" - 2. test_controller_version_00240b is None + 1. test_controller_version_00240b == "4" + 2. test_controller_version_00240c == None (raises ValueError) """ def responses(): @@ -777,17 +803,23 @@ def responses(): instance = controller_version instance.rest_send = rest_send instance.refresh() - assert instance.version_minor == expected + if not raises: + assert instance.version_minor == expected + else: + match = "ControllerVersion.version: Version information not available in controller response" + with pytest.raises(ValueError, match=match): + instance.version_minor # pylint: disable=pointless-statement @pytest.mark.parametrize( - "key, expected", + "key, expected, raises", [ - ("test_controller_version_00250a", "3b"), - ("test_controller_version_00250b", None), + ("test_controller_version_00250a", "3b", False), + ("test_controller_version_00250b", "1", False), + ("test_controller_version_00250c", None, True), ], ) -def test_controller_version_00250(controller_version, key, expected) -> None: +def test_controller_version_00250(controller_version, key, expected, raises) -> None: """ ### Classes and Methods @@ -807,7 +839,8 @@ def test_controller_version_00250(controller_version, key, expected) -> None: ### Expected result 1. test_controller_version_00250a == "3b" - 2. test_controller_version_00250b is None + 2. test_controller_version_00250b == "1" + 3. test_controller_version_00250c == None (raises ValueError) """ def responses(): @@ -826,7 +859,12 @@ def responses(): instance = controller_version instance.rest_send = rest_send instance.refresh() - assert instance.version_patch == expected + if not raises: + assert instance.version_patch == expected + else: + match = "ControllerVersion.version: Version information not available in controller response" + with pytest.raises(ValueError, match=match): + instance.version_patch # pylint: disable=pointless-statement @pytest.mark.parametrize(