From c02ad76fef7528b4b26ad7cb78a5b87a0870847c Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Tue, 18 Jun 2024 16:18:42 -0700 Subject: [PATCH] Remove deprecated xclarity hardware type Change-Id: I93e0d947d0f790bd4dfaa73e2cd31fdd36262af2 --- devstack/lib/ironic | 12 - doc/source/admin/drivers.rst | 1 - doc/source/admin/drivers/xclarity.rst | 79 ------ driver-requirements.txt | 1 - ironic/common/exception.py | 4 - ironic/conf/__init__.py | 2 - ironic/conf/opts.py | 1 - ironic/conf/xclarity.py | 44 ---- ironic/drivers/modules/xclarity/common.py | 178 ------------- ironic/drivers/modules/xclarity/management.py | 248 ------------------ ironic/drivers/modules/xclarity/power.py | 134 ---------- ironic/drivers/xclarity.py | 35 --- ironic/tests/unit/db/utils.py | 18 -- .../drivers/modules/xclarity/test_common.py | 113 -------- .../modules/xclarity/test_management.py | 158 ----------- .../drivers/modules/xclarity/test_power.py | 146 ----------- ironic/tests/unit/drivers/test_xclarity.py | 46 ---- .../drivers/third_party_driver_mock_specs.py | 18 -- .../unit/drivers/third_party_driver_mocks.py | 19 -- ...larity-hardware-type-aa1a26bcbb5b9670.yaml | 4 + setup.cfg | 3 - 21 files changed, 4 insertions(+), 1260 deletions(-) delete mode 100644 doc/source/admin/drivers/xclarity.rst delete mode 100644 ironic/conf/xclarity.py delete mode 100644 ironic/drivers/modules/xclarity/common.py delete mode 100644 ironic/drivers/modules/xclarity/management.py delete mode 100644 ironic/drivers/modules/xclarity/power.py delete mode 100644 ironic/drivers/xclarity.py delete mode 100644 ironic/tests/unit/drivers/modules/xclarity/test_common.py delete mode 100644 ironic/tests/unit/drivers/modules/xclarity/test_management.py delete mode 100644 ironic/tests/unit/drivers/modules/xclarity/test_power.py delete mode 100644 ironic/tests/unit/drivers/test_xclarity.py create mode 100644 releasenotes/notes/remove-xclarity-hardware-type-aa1a26bcbb5b9670.yaml diff --git a/devstack/lib/ironic b/devstack/lib/ironic index 5d856227ae..cb1ef003e5 100644 --- a/devstack/lib/ironic +++ b/devstack/lib/ironic @@ -842,11 +842,6 @@ function is_deployed_by_irmc { return 1 } -function is_deployed_by_xclarity { - [[ "$IRONIC_DEPLOY_DRIVER" == xclarity ]] && return 0 - return 1 -} - function is_deployed_by_ibmc { [[ "$IRONIC_DEPLOY_DRIVER" == ibmc ]] && return 0 return 1 @@ -2603,13 +2598,6 @@ function enroll_nodes { if [[ -n "$IRONIC_DEPLOY_ISO_ID" ]]; then node_options+=" --driver-info deploy_iso=$IRONIC_DEPLOY_ISO_ID" fi - elif is_deployed_by_xclarity; then - local xclarity_hardware_id - xclarity_hardware_id=$(echo $hardware_info |awk '{print $5}') - node_options+=" --driver-info xclarity_manager_ip=$bmc_address \ - --driver-info xclarity_password=$bmc_passwd \ - --driver-info xclarity_username=$bmc_username \ - --driver-info xclarity_hardware_id=$xclarity_hardware_id" elif is_deployed_by_ibmc; then node_options+=" --driver-info ibmc_address=$bmc_address \ --driver-info ibmc_username=$bmc_username \ diff --git a/doc/source/admin/drivers.rst b/doc/source/admin/drivers.rst index f35cb2dfa8..988f1376a1 100644 --- a/doc/source/admin/drivers.rst +++ b/doc/source/admin/drivers.rst @@ -25,7 +25,6 @@ Hardware Types drivers/irmc drivers/redfish drivers/snmp - drivers/xclarity drivers/fake Changing Hardware Types and Interfaces diff --git a/doc/source/admin/drivers/xclarity.rst b/doc/source/admin/drivers/xclarity.rst deleted file mode 100644 index 36a774a57e..0000000000 --- a/doc/source/admin/drivers/xclarity.rst +++ /dev/null @@ -1,79 +0,0 @@ -=============== -XClarity driver -=============== - -Overview -======== - -.. warning:: - The ``xclarity`` driver has been deprecated and is anticipated to be removed - from Ironic at some point during or after the 2024.2 development cycle. - The anticipated forward management path is to migrate to the ``redfish`` - hardware type. - -The ``xclarity`` driver is targeted for IMM 2.0 and IMM 3.0 managed Lenovo -servers. The xclarity hardware type enables the user to take advantage of -`XClarity Manager`_ by using the `XClarity Python Client`_. - -Prerequisites -============= - -* The XClarity Client library should be installed on the ironic conductor - node(s). - - For example, it can be installed with ``pip``:: - - sudo pip install python-xclarityclient - -Enabling the XClarity driver -============================ - -#. Add ``xclarity`` to the list of ``enabled_hardware_types``, - ``enabled_power_interfaces`` and ``enabled_management_interfaces`` - in ``/etc/ironic/ironic.conf``. For example:: - - [DEFAULT] - ... - enabled_hardware_types = ipmi,xclarity - enabled_power_interfaces = ipmitool,xclarity - enabled_management_interfaces = ipmitool,xclarity - -#. Restart the ironic conductor service:: - - sudo service ironic-conductor restart - - # Or, for RDO: - sudo systemctl restart openstack-ironic-conductor - -Registering a node with the XClarity driver -=========================================== - -Nodes configured to use the driver should have the ``driver`` property -set to ``xclarity``. - -The following properties are specified in the node's ``driver_info`` -field and are required: - -- ``xclarity_manager_ip``: The IP address of the XClarity Controller. -- ``xclarity_username``: User account with admin/server-profile access - privilege to the XClarity Controller. -- ``xclarity_password``: User account password corresponding to the - xclarity_username to the XClarity Controller. -- ``xclarity_hardware_id``: The hardware ID of the XClarity managed server. - -The ``baremetal node create`` command can be used to enroll -a node with the ``xclarity`` driver. For example: - -.. code-block:: bash - - baremetal node create --driver xclarity \ - --driver-info xclarity_manager_ip=https://10.240.217.101 \ - --driver-info xclarity_username=admin \ - --driver-info xclarity_password=password \ - --driver-info xclarity_hardware_id=hardware_id - -For more information about enrolling nodes see :ref:`enrollment` -in the install guide. - -.. _`XClarity Manager`: http://www3.lenovo.com/us/en/data-center/software/systems-management/xclarity/ -.. _`XClarity Python Client`: http://pypi.org/project/python-xclarityclient/ diff --git a/driver-requirements.txt b/driver-requirements.txt index f72b45cd42..f02e65f4ef 100644 --- a/driver-requirements.txt +++ b/driver-requirements.txt @@ -10,7 +10,6 @@ pyasn1>=0.5.1 # BSD pyasn1-modules>=0.3.0 # BSD python-scciclient>=0.16.0,<0.17.0 python-dracclient>=5.1.0,<9.0.0 -python-xclarityclient>=0.1.6 # Ansible-deploy interface ansible>=2.7 diff --git a/ironic/common/exception.py b/ironic/common/exception.py index 59d60f3ba0..1b5f0f9ae4 100644 --- a/ironic/common/exception.py +++ b/ironic/common/exception.py @@ -651,10 +651,6 @@ class InstanceUnrescueFailure(IronicException): '%(node)s: %(reason)s') -class XClarityError(IronicException): - _msg_fmt = _("XClarity exception occurred. Error: %(error)s") - - class BIOSSettingAlreadyExists(Conflict): _msg_fmt = _('A BIOS setting %(name)s for node %(node)s already exists.') diff --git a/ironic/conf/__init__.py b/ironic/conf/__init__.py index 648395362a..44a04f5024 100644 --- a/ironic/conf/__init__.py +++ b/ironic/conf/__init__.py @@ -49,7 +49,6 @@ from ironic.conf import sensor_data from ironic.conf import service_catalog from ironic.conf import snmp from ironic.conf import swift -from ironic.conf import xclarity CONF = cfg.CONF @@ -87,4 +86,3 @@ sensor_data.register_opts(CONF) service_catalog.register_opts(CONF) snmp.register_opts(CONF) swift.register_opts(CONF) -xclarity.register_opts(CONF) diff --git a/ironic/conf/opts.py b/ironic/conf/opts.py index d04f9ddfcc..7edf31a5dd 100644 --- a/ironic/conf/opts.py +++ b/ironic/conf/opts.py @@ -47,7 +47,6 @@ _opts = [ ('service_catalog', ironic.conf.service_catalog.list_opts()), ('snmp', ironic.conf.snmp.opts), ('swift', ironic.conf.swift.list_opts()), - ('xclarity', ironic.conf.xclarity.opts), ] diff --git a/ironic/conf/xclarity.py b/ironic/conf/xclarity.py deleted file mode 100644 index a14901ce9d..0000000000 --- a/ironic/conf/xclarity.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2017 LENOVO Development Company, LP -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg - -from ironic.common.i18n import _ - -opts = [ - cfg.StrOpt('manager_ip', - help=_('IP address of the XClarity Controller. ' - 'Configuration here is deprecated and will be removed ' - 'in the Stein release. Please update the driver_info ' - 'field to use "xclarity_manager_ip" instead')), - cfg.StrOpt('username', - help=_('Username for the XClarity Controller. ' - 'Configuration here is deprecated and will be removed ' - 'in the Stein release. Please update the driver_info ' - 'field to use "xclarity_username" instead')), - cfg.StrOpt('password', - secret=True, - help=_('Password for XClarity Controller username. ' - 'Configuration here is deprecated and will be removed ' - 'in the Stein release. Please update the driver_info ' - 'field to use "xclarity_password" instead')), - cfg.PortOpt('port', - default=443, - help=_('Port to be used for XClarity Controller ' - 'connection.')), -] - - -def register_opts(conf): - conf.register_opts(opts, group='xclarity') diff --git a/ironic/drivers/modules/xclarity/common.py b/ironic/drivers/modules/xclarity/common.py deleted file mode 100644 index cca29bba39..0000000000 --- a/ironic/drivers/modules/xclarity/common.py +++ /dev/null @@ -1,178 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log as logging -from oslo_utils import importutils - -from ironic.common import exception -from ironic.common.i18n import _ -from ironic.common import states -from ironic.common import utils -from ironic.conf import CONF - -LOG = logging.getLogger(__name__) - -client = importutils.try_import('xclarity_client.client') -xclarity_client_constants = importutils.try_import('xclarity_client.constants') -xclarity_client_exceptions = importutils.try_import( - 'xclarity_client.exceptions') - -REQUIRED_ON_DRIVER_INFO = { - 'xclarity_manager_ip': _("IP address of the XClarity Controller."), - 'xclarity_username': _("Username for the XClarity Controller " - "with administrator privileges."), - 'xclarity_password': _("Password for xclarity_username."), - 'xclarity_hardware_id': _("Server Hardware ID managed by XClarity."), -} - -OPTIONAL_ON_DRIVER_INFO = { - 'xclarity_port': _("Port to be used for XClarity Controller connection. " - "Optional"), -} - -COMMON_PROPERTIES = {} -COMMON_PROPERTIES.update(REQUIRED_ON_DRIVER_INFO) -COMMON_PROPERTIES.update(OPTIONAL_ON_DRIVER_INFO) - - -def get_properties(): - return COMMON_PROPERTIES - - -def parse_driver_info(node): - """Parse a node's driver_info values. - - Parses the driver_info of the node, reads default values - and returns a dict containing the combination of both. - - :param node: an ironic node object to get information from. - :returns: a dict containing information parsed from driver_info. - :raises: InvalidParameterValue if some required information - is missing on the node or inputs is invalid. - """ - driver_info = node.driver_info - parsed_driver_info = {} - - error_msgs = [] - for param in REQUIRED_ON_DRIVER_INFO: - if param == "xclarity_hardware_id": - try: - parsed_driver_info[param] = str(driver_info[param]) - except KeyError: - error_msgs.append(_("'%s' not provided to XClarity.") % param) - except UnicodeEncodeError: - error_msgs.append(_("'%s' contains non-ASCII symbol.") % param) - else: - # corresponding config names don't have 'xclarity_' prefix - if param in driver_info: - parsed_driver_info[param] = str(driver_info[param]) - elif param not in driver_info and\ - CONF.xclarity.get(param[len('xclarity_'):]) is not None: - parsed_driver_info[param] = str( - CONF.xclarity.get(param[len('xclarity_'):])) - LOG.warning('The configuration [xclarity]/%(config)s ' - 'is deprecated and will be removed in the ' - 'Stein release. Please update the node ' - '%(node_uuid)s driver_info field to use ' - '"%(field)s" instead', - {'config': param[len('xclarity_'):], - 'node_uuid': node.uuid, 'field': param}) - else: - error_msgs.append(_("'%s' not provided to XClarity.") % param) - - port = driver_info.get('xclarity_port', CONF.xclarity.get('port')) - parsed_driver_info['xclarity_port'] = utils.validate_network_port( - port, 'xclarity_port') - - if error_msgs: - msg = (_('The following errors were encountered while parsing ' - 'driver_info:\n%s') % '\n'.join(error_msgs)) - raise exception.InvalidParameterValue(msg) - - return parsed_driver_info - - -def get_xclarity_client(node): - """Generates an instance of the XClarity client. - - Generates an instance of the XClarity client using the imported - xclarity_client library. - - :param node: an ironic node object. - :returns: an instance of the XClarity client - :raises: XClarityError if can't get to the XClarity client - """ - driver_info = parse_driver_info(node) - try: - xclarity_client = client.Client( - ip=driver_info.get('xclarity_manager_ip'), - username=driver_info.get('xclarity_username'), - password=driver_info.get('xclarity_password'), - port=driver_info.get('xclarity_port') - ) - except xclarity_client_exceptions.XClarityError as exc: - msg = (_("Error getting connection to XClarity address: %(ip)s. " - "Error: %(exc)s"), - {'ip': driver_info.get('xclarity_manager_ip'), 'exc': exc}) - raise exception.XClarityError(error=msg) - return xclarity_client - - -def get_server_hardware_id(node): - """Validates node configuration and returns xclarity hardware id. - - Validates whether node configuration is consistent with XClarity and - returns the XClarity Hardware ID for a specific node. - :param node: node object to get information from - :returns: the XClarity Hardware ID for a specific node - :raises: MissingParameterValue if unable to validate XClarity Hardware ID - - """ - xclarity_hardware_id = node.driver_info.get('xclarity_hardware_id') - if not xclarity_hardware_id: - msg = (_("Error validating node driver info, " - "server uuid: %s missing xclarity_hardware_id") % - node.uuid) - raise exception.MissingParameterValue(err=msg) - return xclarity_hardware_id - - -def translate_xclarity_power_state(power_state): - """Translates XClarity's power state strings to be consistent with Ironic. - - :param power_state: power state string to be translated - :returns: the translated power state - """ - power_states_map = { - xclarity_client_constants.STATE_POWER_ON: states.POWER_ON, - xclarity_client_constants.STATE_POWER_OFF: states.POWER_OFF, - } - - return power_states_map.get(power_state, states.ERROR) - - -def translate_xclarity_power_action(power_action): - """Translates ironic's power action strings to XClarity's format. - - :param power_action: power action string to be translated - :returns: the power action translated - """ - - power_action_map = { - states.POWER_ON: xclarity_client_constants.ACTION_POWER_ON, - states.POWER_OFF: xclarity_client_constants.ACTION_POWER_OFF, - states.REBOOT: xclarity_client_constants.ACTION_REBOOT - } - - return power_action_map[power_action] diff --git a/ironic/drivers/modules/xclarity/management.py b/ironic/drivers/modules/xclarity/management.py deleted file mode 100644 index c5ec724eae..0000000000 --- a/ironic/drivers/modules/xclarity/management.py +++ /dev/null @@ -1,248 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from ironic_lib import metrics_utils -from oslo_log import log as logging -from oslo_utils import importutils - -from ironic.common import boot_devices -from ironic.common import exception -from ironic.common.i18n import _ -from ironic.conductor import task_manager -from ironic.drivers import base -from ironic.drivers.modules.xclarity import common - -LOG = logging.getLogger(__name__) - -METRICS = metrics_utils.get_metrics_logger(__name__) - -xclarity_client_exceptions = importutils.try_import( - 'xclarity_client.exceptions') - -BOOT_DEVICE_MAPPING_TO_XCLARITY = { - boot_devices.PXE: 'PXE Network', - boot_devices.DISK: 'Hard Disk 0', - boot_devices.CDROM: 'CD/DVD Rom', - boot_devices.BIOS: 'Boot To F1' -} - -BOOT_DEVICE_MAPPING_FROM_XCLARITY = { - v: k for k, v in BOOT_DEVICE_MAPPING_TO_XCLARITY.items()} - -SUPPORTED_BOOT_DEVICES = [ - boot_devices.PXE, - boot_devices.DISK, - boot_devices.CDROM, - boot_devices.BIOS, -] - - -class XClarityManagement(base.ManagementInterface): - - # NOTE(TheJulia): Deprecating November 2023 in favor of Redfish - # and due to a lack of active driver maintenance. - supported = False - - def get_properties(self): - return common.COMMON_PROPERTIES - - @METRICS.timer('XClarityManagement.validate') - def validate(self, task): - """Validate the driver-specific info supplied. - - This method validates if the 'driver_info' property of the supplied - task's node contains the required information for this driver to - manage the node. - - :param task: a task from TaskManager. - """ - common.parse_driver_info(task.node) - - @METRICS.timer('XClarityManagement.get_supported_boot_devices') - def get_supported_boot_devices(self, task): - """Gets a list of the supported boot devices. - - :param task: a task from TaskManager. - :returns: A list with the supported boot devices defined - in :mod:`ironic.common.boot_devices`. - """ - - return SUPPORTED_BOOT_DEVICES - - def _validate_supported_boot_device(self, task, boot_device): - """It validates if the boot device is supported by XClarity. - - :param task: a task from TaskManager. - :param boot_device: the boot device in XClarity format, one of - ['PXE Network', 'Hard Disk 0', 'CD/DVD Rom', 'Boot To F1'] - :raises: InvalidParameterValue if the boot device is not supported. - """ - if boot_device not in BOOT_DEVICE_MAPPING_FROM_XCLARITY: - raise exception.InvalidParameterValue( - _("Unsupported boot device %(device)s for node: %(node)s ") - % {"device": boot_device, "node": task.node.uuid} - ) - - @METRICS.timer('XClarityManagement.get_boot_device') - def get_boot_device(self, task): - """Get the current boot device for the task's node. - - :param task: a task from TaskManager. - :returns: a dictionary containing: - :boot_device: the boot device, one of [PXE, DISK, CDROM, BIOS] - :persistent: Whether the boot device will persist or not - It returns None if boot device is unknown. - :raises: InvalidParameterValue if the boot device is unknown - :raises: XClarityError if the communication with XClarity fails - """ - node = task.node - client = common.get_xclarity_client(node) - server_hardware_id = common.get_server_hardware_id(node) - try: - boot_info = ( - client.get_node_all_boot_info( - server_hardware_id) - ) - except xclarity_client_exceptions.XClarityError as xclarity_exc: - LOG.error( - "Error getting boot device from XClarity for node %(node)s. " - "Error: %(error)s", {'node': node.uuid, - 'error': xclarity_exc}) - raise exception.XClarityError(error=xclarity_exc) - - persistent = False - primary = None - boot_order = boot_info['bootOrder']['bootOrderList'] - for item in boot_order: - current = item.get('currentBootOrderDevices') - if current is None: - LOG.warning( - 'Current boot order is None from XClarity for ' - 'node %(node)s. Please check the hardware and ' - 'XClarity connection', {'node': node.uuid, }) - return {'boot_device': None, 'persistent': None} - else: - primary = current[0] - boot_type = item.get('bootType') - if boot_type == "SingleUse": - persistent = False - if primary != 'None': - self._validate_supported_boot_device(task, primary) - boot_device = { - 'boot_device': - BOOT_DEVICE_MAPPING_FROM_XCLARITY.get(primary), - 'persistent': persistent - } - return boot_device - elif boot_type == "Permanent": - persistent = True - if primary != 'None': - self._validate_supported_boot_device(task, primary) - boot_device = { - 'boot_device': - BOOT_DEVICE_MAPPING_FROM_XCLARITY.get(primary), - 'persistent': persistent - } - return boot_device - else: - return {'boot_device': None, 'persistent': None} - - @METRICS.timer('XClarityManagement.set_boot_device') - @task_manager.require_exclusive_lock - def set_boot_device(self, task, device, persistent=False): - """Sets the boot device for a node. - - :param task: a task from TaskManager. - :param device: the boot device, one of the supported devices - listed in :mod:`ironic.common.boot_devices`. - :param persistent: Boolean value. True if the boot device will - persist to all future boots, False if not. - Default: False. - :raises: InvalidParameterValue if an invalid boot device is - specified. - :raises: XClarityError if the communication with XClarity fails - """ - node = task.node - xc_device = self._translate_ironic_to_xclarity(device) - - server_hardware_id = common.get_server_hardware_id(node) - LOG.debug("Setting boot device to %(device)s for node %(node)s", - {"device": device, "node": node.uuid}) - self._set_boot_device(task, server_hardware_id, xc_device, - singleuse=not persistent) - - @METRICS.timer('XClarityManagement.get_sensors_data') - def get_sensors_data(self, task): - """Get sensors data. - - :param task: a TaskManager instance. - :raises: NotImplementedError - - """ - raise NotImplementedError() - - def _translate_ironic_to_xclarity(self, boot_device): - """Translates Ironic boot options to Xclarity boot options. - - :param boot_device: Ironic boot_device - :returns: Translated XClarity boot_device. - - """ - return BOOT_DEVICE_MAPPING_TO_XCLARITY.get(boot_device) - - def _set_boot_device(self, task, server_hardware_id, - new_primary_boot_device, singleuse=False): - """Set the current boot device for xclarity - - :param server_hardware_id: the uri of the server hardware in XClarity - :param new_primary_boot_device: boot device to be set - :param task: a TaskManager instance. - :param singleuse: if this device will be used only once at next boot - """ - node = task.node - client = common.get_xclarity_client(node) - boot_info = client.get_node_all_boot_info( - server_hardware_id) - current = [] - LOG.debug( - ("Setting boot device to %(device)s for XClarity " - "node %(node)s"), - {'device': new_primary_boot_device, 'node': node.uuid} - ) - for item in boot_info['bootOrder']['bootOrderList']: - if singleuse and item['bootType'] == 'SingleUse': - item['currentBootOrderDevices'][0] = new_primary_boot_device - elif not singleuse and item['bootType'] == 'Permanent': - current = item['currentBootOrderDevices'] - if new_primary_boot_device == current[0]: - return - if new_primary_boot_device in current: - current.remove(new_primary_boot_device) - current.insert(0, new_primary_boot_device) - item['currentBootOrderDevices'] = current - - try: - client.set_node_boot_info(server_hardware_id, - boot_info, - new_primary_boot_device, - singleuse) - except xclarity_client_exceptions.XClarityError as xclarity_exc: - LOG.error( - ('Error setting boot device %(boot_device)s for the XClarity ' - 'node %(node)s. Error: %(error)s'), - {'boot_device': new_primary_boot_device, 'node': node.uuid, - 'error': xclarity_exc} - ) - raise exception.XClarityError(error=xclarity_exc) diff --git a/ironic/drivers/modules/xclarity/power.py b/ironic/drivers/modules/xclarity/power.py deleted file mode 100644 index 463de156db..0000000000 --- a/ironic/drivers/modules/xclarity/power.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from ironic_lib import metrics_utils -from oslo_log import log as logging -from oslo_utils import importutils - -from ironic.common import exception -from ironic.common import states -from ironic.conductor import task_manager -from ironic.drivers import base -from ironic.drivers.modules.xclarity import common - -LOG = logging.getLogger(__name__) - -METRICS = metrics_utils.get_metrics_logger(__name__) - -xclarity_client_exceptions = importutils.try_import( - 'xclarity_client.exceptions') - - -class XClarityPower(base.PowerInterface): - - # NOTE(TheJulia): Deprecating November 2023 in favor of Redfish - # and due to a lack of active driver maintenance. - supported = False - - def get_properties(self): - return common.get_properties() - - @METRICS.timer('XClarityPower.validate') - def validate(self, task): - """Validate the driver-specific info supplied. - - This method validates if the 'driver_info' property of the supplied - task's node contains the required information for this driver to - manage the power state of the node. - - :param task: a task from TaskManager. - """ - common.parse_driver_info(task.node) - - @METRICS.timer('XClarityPower.get_power_state') - def get_power_state(self, task): - """Gets the current power state. - - :param task: a TaskManager instance. - :returns: one of :mod:`ironic.common.states` POWER_OFF, - POWER_ON or ERROR. - :raises: XClarityError if fails to retrieve power state of XClarity - resource - """ - node = task.node - client = common.get_xclarity_client(node) - server_hardware_id = common.get_server_hardware_id(node) - try: - power_state = client.get_node_power_status(server_hardware_id) - except xclarity_client_exceptions.XClarityError as xclarity_exc: - LOG.error( - ("Error getting power state for node %(node)s. Error: " - "%(error)s"), - {'node': node.uuid, 'error': xclarity_exc} - ) - raise exception.XClarityError(error=xclarity_exc) - return common.translate_xclarity_power_state(power_state) - - @METRICS.timer('XClarityPower.set_power_state') - @task_manager.require_exclusive_lock - def set_power_state(self, task, power_state, timeout=None): - """Turn the current power state on or off. - - :param task: a TaskManager instance. - :param power_state: The desired power state POWER_ON, POWER_OFF or - REBOOT from :mod:`ironic.common.states`. - :param timeout: timeout (in seconds). Unsupported by this interface. - :raises: InvalidParameterValue if an invalid power state was specified. - :raises: XClarityError if XClarity fails setting the power state. - """ - # TODO(rloo): Support timeouts! - if timeout is not None: - LOG.warning( - "The 'xclarity' Power Interface's 'set_power_state' method " - "doesn't support the 'timeout' parameter. Ignoring " - "timeout=%(timeout)s", - {'timeout': timeout}) - - if power_state == states.REBOOT: - target_power_state = self.get_power_state(task) - if target_power_state == states.POWER_OFF: - power_state = states.POWER_ON - - node = task.node - client = common.get_xclarity_client(node) - server_hardware_id = common.get_server_hardware_id(node) - LOG.debug("Setting power state of node %(node_uuid)s to " - "%(power_state)s", - {'node_uuid': node.uuid, 'power_state': power_state}) - - try: - client.set_node_power_status(server_hardware_id, power_state) - except xclarity_client_exceptions.XClarityError as xclarity_exc: - LOG.error( - "Error setting power state of node %(node_uuid)s to " - "%(power_state)s", - {'node_uuid': task.node.uuid, 'power_state': power_state}) - raise exception.XClarityError(error=xclarity_exc) - - @METRICS.timer('XClarityPower.reboot') - @task_manager.require_exclusive_lock - def reboot(self, task, timeout=None): - """Soft reboot the node - - :param task: a TaskManager instance. - :param timeout: timeout (in seconds). Unsupported by this interface. - """ - # TODO(rloo): Support timeouts! - if timeout is not None: - LOG.warning("The 'xclarity' Power Interface's 'reboot' method " - "doesn't support the 'timeout' parameter. Ignoring " - "timeout=%(timeout)s", - {'timeout': timeout}) - - self.set_power_state(task, states.REBOOT) diff --git a/ironic/drivers/xclarity.py b/ironic/drivers/xclarity.py deleted file mode 100644 index 87b3569951..0000000000 --- a/ironic/drivers/xclarity.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -XClarity Driver and supporting meta-classes. -""" - -from ironic.drivers import generic -from ironic.drivers.modules.xclarity import management -from ironic.drivers.modules.xclarity import power - - -class XClarityHardware(generic.GenericHardware): - """XClarity hardware type. """ - - @property - def supported_management_interfaces(self): - """List of supported management interfaces.""" - return [management.XClarityManagement] - - @property - def supported_power_interfaces(self): - """List of supported power interfaces.""" - return [power.XClarityPower] diff --git a/ironic/tests/unit/db/utils.py b/ironic/tests/unit/db/utils.py index 609eee2919..e9f287c92c 100644 --- a/ironic/tests/unit/db/utils.py +++ b/ironic/tests/unit/db/utils.py @@ -514,24 +514,6 @@ def create_test_node_tag(**kw): return dbapi.add_node_tag(tag['node_id'], tag['tag']) -def get_test_xclarity_properties(): - return { - "cpu_arch": "x86_64", - "local_gb": "10", - "memory_mb": "4096", - } - - -def get_test_xclarity_driver_info(): - return { - 'xclarity_manager_ip': "1.2.3.4", - 'xclarity_username': "USERID", - 'xclarity_password': "fake", - 'xclarity_port': 443, - 'xclarity_hardware_id': 'fake_sh_id', - } - - def get_test_node_trait(**kw): return { 'version': kw.get('version', trait.Trait.VERSION), diff --git a/ironic/tests/unit/drivers/modules/xclarity/test_common.py b/ironic/tests/unit/drivers/modules/xclarity/test_common.py deleted file mode 100644 index 1b01c13ec4..0000000000 --- a/ironic/tests/unit/drivers/modules/xclarity/test_common.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from unittest import mock - -from oslo_utils import importutils - -from ironic.common import exception -from ironic.drivers.modules.xclarity import common -from ironic.tests.unit.db import base as db_base -from ironic.tests.unit.db import utils as db_utils -from ironic.tests.unit.objects import utils as obj_utils - -xclarity_client = importutils.try_import('xclarity_client.client') -xclarity_exceptions = importutils.try_import('xclarity_client.exceptions') -xclarity_constants = importutils.try_import('xclarity_client.constants') - -INFO_DICT = db_utils.get_test_xclarity_driver_info() - - -class XClarityCommonTestCase(db_base.DbTestCase): - - def setUp(self): - super(XClarityCommonTestCase, self).setUp() - self.config(enabled_hardware_types=['xclarity'], - enabled_power_interfaces=['xclarity'], - enabled_management_interfaces=['xclarity']) - self.node = obj_utils.create_test_node( - self.context, driver='xclarity', - properties=db_utils.get_test_xclarity_properties(), - driver_info=INFO_DICT) - - def test_parse_driver_info(self): - info = common.parse_driver_info(self.node) - self.assertEqual(INFO_DICT['xclarity_manager_ip'], - info['xclarity_manager_ip']) - self.assertEqual(INFO_DICT['xclarity_username'], - info['xclarity_username']) - self.assertEqual(INFO_DICT['xclarity_password'], - info['xclarity_password']) - self.assertEqual(INFO_DICT['xclarity_port'], info['xclarity_port']) - self.assertEqual(INFO_DICT['xclarity_hardware_id'], - info['xclarity_hardware_id']) - - def test_parse_driver_info_missing_hardware_id(self): - del self.node.driver_info['xclarity_hardware_id'] - self.assertRaises(exception.InvalidParameterValue, - common.parse_driver_info, self.node) - - def test_parse_driver_info_get_param_from_config(self): - del self.node.driver_info['xclarity_manager_ip'] - del self.node.driver_info['xclarity_username'] - del self.node.driver_info['xclarity_password'] - self.config(manager_ip='5.6.7.8', group='xclarity') - self.config(username='user', group='xclarity') - self.config(password='password', group='xclarity') - info = common.parse_driver_info(self.node) - self.assertEqual('5.6.7.8', info['xclarity_manager_ip']) - self.assertEqual('user', info['xclarity_username']) - self.assertEqual('password', info['xclarity_password']) - - def test_parse_driver_info_missing_driver_info_and_config(self): - del self.node.driver_info['xclarity_manager_ip'] - del self.node.driver_info['xclarity_username'] - del self.node.driver_info['xclarity_password'] - e = self.assertRaises(exception.InvalidParameterValue, - common.parse_driver_info, self.node) - self.assertIn('xclarity_manager_ip', str(e)) - self.assertIn('xclarity_username', str(e)) - self.assertIn('xclarity_password', str(e)) - - def test_parse_driver_info_invalid_port(self): - self.node.driver_info['xclarity_port'] = 'asd' - self.assertRaises(exception.InvalidParameterValue, - common.parse_driver_info, self.node) - self.node.driver_info['xclarity_port'] = '65536' - self.assertRaises(exception.InvalidParameterValue, - common.parse_driver_info, self.node) - self.node.driver_info['xclarity_port'] = 'invalid' - self.assertRaises(exception.InvalidParameterValue, - common.parse_driver_info, self.node) - self.node.driver_info['xclarity_port'] = '-1' - self.assertRaises(exception.InvalidParameterValue, - common.parse_driver_info, self.node) - - def test_get_xclarity_client(self): - if not mock._is_instance_mock(xclarity_client): - mock.patch.object(xclarity_client, 'Client', autospec=True).start() - mock_xclarityclient = xclarity_client.Client - expected_call = mock.call(ip='1.2.3.4', password='fake', port=443, - username='USERID') - common.get_xclarity_client(self.node) - - self.assertEqual(mock_xclarityclient.mock_calls, [expected_call]) - - def test_get_server_hardware_id(self): - driver_info = self.node.driver_info - driver_info['xclarity_hardware_id'] = 'test' - self.node.driver_info = driver_info - result = common.get_server_hardware_id(self.node) - self.assertEqual(result, 'test') diff --git a/ironic/tests/unit/drivers/modules/xclarity/test_management.py b/ironic/tests/unit/drivers/modules/xclarity/test_management.py deleted file mode 100644 index f63933c906..0000000000 --- a/ironic/tests/unit/drivers/modules/xclarity/test_management.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import importlib -import sys -from unittest import mock - -from oslo_utils import importutils - -from ironic.common import boot_devices -from ironic.common import exception -from ironic.conductor import task_manager -from ironic.drivers.modules.xclarity import common -from ironic.drivers.modules.xclarity import management -from ironic.tests.unit.db import base as db_base -from ironic.tests.unit.db import utils as db_utils -from ironic.tests.unit.objects import utils as obj_utils - - -xclarity_client_exceptions = importutils.try_import( - 'xclarity_client.exceptions') - - -@mock.patch.object(common, 'get_xclarity_client', spect_set=True, - autospec=True) -class XClarityManagementDriverTestCase(db_base.DbTestCase): - - def setUp(self): - super(XClarityManagementDriverTestCase, self).setUp() - self.config(enabled_hardware_types=['xclarity'], - enabled_power_interfaces=['xclarity'], - enabled_management_interfaces=['xclarity']) - self.node = obj_utils.create_test_node( - self.context, - driver='xclarity', - driver_info=db_utils.get_test_xclarity_driver_info()) - - @mock.patch.object(common, 'get_server_hardware_id', - spect_set=True, autospec=True) - def test_validate(self, mock_validate, mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.management.validate(task) - common.get_server_hardware_id(task.node) - mock_validate.assert_called_with(task.node) - - def test_get_properties(self, mock_get_xc_client): - expected = common.COMMON_PROPERTIES - driver = management.XClarityManagement() - self.assertEqual(expected, driver.get_properties()) - - @mock.patch.object(management.XClarityManagement, 'get_boot_device', - return_value='pxe', autospec=True) - def test_set_boot_device(self, mock_get_boot_device, - mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.management.set_boot_device(task, 'pxe') - result = task.driver.management.get_boot_device(task) - self.assertEqual(result, 'pxe') - - def test_set_boot_device_fail(self, mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - xclarity_client_exceptions.XClarityError = Exception - sys.modules['xclarity_client.exceptions'] = ( - xclarity_client_exceptions) - if 'ironic.drivers.modules.xclarity' in sys.modules: - importlib.reload( - sys.modules['ironic.drivers.modules.xclarity']) - ex = exception.XClarityError('E') - mock_get_xc_client.return_value.set_node_boot_info.side_effect = ex - self.assertRaises(exception.XClarityError, - task.driver.management.set_boot_device, - task, - "pxe") - - def test_get_supported_boot_devices(self, mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - expected = [boot_devices.PXE, boot_devices.BIOS, - boot_devices.DISK, boot_devices.CDROM] - self.assertCountEqual( - expected, - task.driver.management.get_supported_boot_devices(task)) - - @mock.patch.object( - management.XClarityManagement, - 'get_boot_device', - return_value={'boot_device': 'pxe', 'persistent': False}, - autospec=True) - def test_get_boot_device(self, mock_get_boot_device, mock_get_xc_client): - reference = {'boot_device': 'pxe', 'persistent': False} - with task_manager.acquire(self.context, self.node.uuid) as task: - expected_boot_device = task.driver.management.get_boot_device( - task=task) - - self.assertEqual(reference, expected_boot_device) - - def test_get_boot_device_fail(self, mock_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - xclarity_client_exceptions.XClarityError = Exception - sys.modules['xclarity_client.exceptions'] = ( - xclarity_client_exceptions) - if 'ironic.drivers.modules.xclarity' in sys.modules: - importlib.reload( - sys.modules['ironic.drivers.modules.xclarity']) - ex = exception.XClarityError('E') - mock_xc_client.return_value.get_node_all_boot_info.side_effect = ex - self.assertRaises( - exception.XClarityError, - task.driver.management.get_boot_device, - task) - - def test_get_boot_device_current_none(self, mock_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - reference = {'boot_device': None, 'persistent': None} - mock_xc_client.return_value.get_node_all_boot_info.return_value = \ - { - 'bootOrder': { - 'bootOrderList': [{ - 'fakeBootOrderDevices': [] - }] - } - } - expected_boot_device = task.driver.management.get_boot_device( - task=task) - self.assertEqual(reference, expected_boot_device) - - def test_get_boot_device_primary_none(self, mock_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - reference = {'boot_device': None, 'persistent': None} - mock_xc_client.return_value.get_node_all_boot_info.return_value = \ - { - 'bootOrder': { - 'bootOrderList': [ - { - 'bootType': 'SingleUse', - 'CurrentBootOrderDevices': [] - }, - { - 'bootType': 'Permanent', - 'CurrentBootOrderDevices': [] - }, - ] - } - } - expected_boot_device = task.driver.management.get_boot_device( - task=task) - self.assertEqual(reference, expected_boot_device) diff --git a/ironic/tests/unit/drivers/modules/xclarity/test_power.py b/ironic/tests/unit/drivers/modules/xclarity/test_power.py deleted file mode 100644 index e12ee837a8..0000000000 --- a/ironic/tests/unit/drivers/modules/xclarity/test_power.py +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import importlib -import sys -from unittest import mock - -from oslo_utils import importutils - -from ironic.common import exception -from ironic.common import states -from ironic.conductor import task_manager -from ironic.drivers.modules.xclarity import common -from ironic.drivers.modules.xclarity import power -from ironic.tests.unit.db import base as db_base -from ironic.tests.unit.db import utils as db_utils -from ironic.tests.unit.objects import utils as obj_utils - -STATE_POWER_ON = "power on" -STATE_POWER_OFF = "power off" -STATE_POWERING_ON = "power on" -STATE_POWERING_OFF = "power on" - -xclarity_constants = importutils.try_import('xclarity_client.constants') -xclarity_client_exceptions = importutils.try_import( - 'xclarity_client.exceptions') - - -@mock.patch.object(common, 'get_xclarity_client', - spect_set=True, autospec=True) -class XClarityPowerDriverTestCase(db_base.DbTestCase): - - def setUp(self): - super(XClarityPowerDriverTestCase, self).setUp() - self.config(enabled_hardware_types=['xclarity'], - enabled_power_interfaces=['xclarity'], - enabled_management_interfaces=['xclarity']) - self.node = obj_utils.create_test_node( - self.context, - driver='xclarity', - driver_info=db_utils.get_test_xclarity_driver_info()) - - def test_get_properties(self, mock_get_xc_client): - expected = common.COMMON_PROPERTIES - driver = power.XClarityPower() - self.assertEqual(expected, driver.get_properties()) - - @mock.patch.object(common, 'get_server_hardware_id', - spect_set=True, autospec=True) - def test_validate(self, mock_validate_driver_info, mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.power.validate(task) - common.get_server_hardware_id(task.node) - mock_validate_driver_info.assert_called_with(task.node) - - @mock.patch.object(power.XClarityPower, 'get_power_state', - return_value=STATE_POWER_ON, autospec=True) - def test_get_power_state(self, mock_get_power_state, mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - result = power.XClarityPower.get_power_state(self, task) - self.assertEqual(STATE_POWER_ON, result) - - @mock.patch.object(common, 'translate_xclarity_power_state', - spec_set=True, autospec=True) - def test_get_power_state_fail(self, mock_translate_state, mock_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - xclarity_client_exceptions.XClarityError = Exception - sys.modules['xclarity_client.exceptions'] = ( - xclarity_client_exceptions) - if 'ironic.drivers.modules.xclarity' in sys.modules: - importlib.reload( - sys.modules['ironic.drivers.modules.xclarity']) - ex = exception.XClarityError('E') - mock_xc_client.return_value.get_node_power_status.side_effect = ex - self.assertRaises(exception.XClarityError, - task.driver.power.get_power_state, - task) - self.assertFalse(mock_translate_state.called) - - @mock.patch.object(power.LOG, 'warning', autospec=True) - @mock.patch.object(power.XClarityPower, 'get_power_state', - return_value=states.POWER_ON, autospec=True) - def test_set_power(self, mock_set_power_state, mock_log, - mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.power.set_power_state(task, states.POWER_ON) - expected = task.driver.power.get_power_state(task) - self.assertEqual(expected, states.POWER_ON) - self.assertFalse(mock_log.called) - - @mock.patch.object(power.LOG, 'warning', autospec=True) - @mock.patch.object(power.XClarityPower, 'get_power_state', - return_value=states.POWER_ON, autospec=True) - def test_set_power_timeout(self, mock_set_power_state, mock_log, - mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.power.set_power_state(task, states.POWER_ON, - timeout=21) - expected = task.driver.power.get_power_state(task) - self.assertEqual(expected, states.POWER_ON) - self.assertTrue(mock_log.called) - - def test_set_power_fail(self, mock_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - xclarity_client_exceptions.XClarityError = Exception - sys.modules['xclarity_client.exceptions'] = ( - xclarity_client_exceptions) - if 'ironic.drivers.modules.xclarity' in sys.modules: - importlib.reload( - sys.modules['ironic.drivers.modules.xclarity']) - ex = exception.XClarityError('E') - mock_xc_client.return_value.set_node_power_status.side_effect = ex - self.assertRaises(exception.XClarityError, - task.driver.power.set_power_state, - task, states.POWER_OFF) - - @mock.patch.object(power.LOG, 'warning', autospec=True) - @mock.patch.object(power.XClarityPower, 'set_power_state', autospec=True) - def test_reboot(self, mock_set_power_state, mock_log, mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.power.reboot(task) - mock_set_power_state.assert_called_with( - mock.ANY, task, states.REBOOT) - self.assertFalse(mock_log.called) - - @mock.patch.object(power.LOG, 'warning', autospec=True) - @mock.patch.object(power.XClarityPower, 'set_power_state', autospec=True) - def test_reboot_timeout(self, mock_set_power_state, mock_log, - mock_get_xc_client): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.power.reboot(task, timeout=55) - mock_set_power_state.assert_called_with( - mock.ANY, task, states.REBOOT) - self.assertTrue(mock_log.called) diff --git a/ironic/tests/unit/drivers/test_xclarity.py b/ironic/tests/unit/drivers/test_xclarity.py deleted file mode 100644 index 9d7f9e207f..0000000000 --- a/ironic/tests/unit/drivers/test_xclarity.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2017 Lenovo, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Test class for XClarity Driver -""" - -from ironic.conductor import task_manager -from ironic.drivers.modules import agent -from ironic.drivers.modules import pxe -from ironic.drivers.xclarity import management as xc_management -from ironic.drivers.xclarity import power as xc_power -from ironic.tests.unit.db import base as db_base -from ironic.tests.unit.objects import utils as obj_utils - - -class XClarityHardwareTestCase(db_base.DbTestCase): - - def setUp(self): - super(XClarityHardwareTestCase, self).setUp() - self.config(enabled_hardware_types=['xclarity'], - enabled_power_interfaces=['xclarity'], - enabled_management_interfaces=['xclarity']) - - def test_default_interfaces(self): - node = obj_utils.create_test_node(self.context, driver='xclarity') - with task_manager.acquire(self.context, node.id) as task: - self.assertIsInstance(task.driver.boot, - pxe.PXEBoot) - self.assertIsInstance(task.driver.deploy, - agent.AgentDeploy) - self.assertIsInstance(task.driver.management, - xc_management.XClarityManagement) - self.assertIsInstance(task.driver.power, - xc_power.XClarityPower) diff --git a/ironic/tests/unit/drivers/third_party_driver_mock_specs.py b/ironic/tests/unit/drivers/third_party_driver_mock_specs.py index 78939c91af..8dedc2fe10 100644 --- a/ironic/tests/unit/drivers/third_party_driver_mock_specs.py +++ b/ironic/tests/unit/drivers/third_party_driver_mock_specs.py @@ -122,24 +122,6 @@ REDFISH_SPEC = ( 'redfish', ) -XCLARITY_SPEC = ( - 'client', - 'states', - 'exceptions', - 'models', - 'utils', -) - -XCLARITY_CLIENT_CLS_SPEC = ( -) - -XCLARITY_STATES_SPEC = ( - 'STATE_POWERING_OFF', - 'STATE_POWERING_ON', - 'STATE_POWER_OFF', - 'STATE_POWER_ON', -) - # python-ibmcclient IBMCCLIENT_SPEC = ( 'connect', diff --git a/ironic/tests/unit/drivers/third_party_driver_mocks.py b/ironic/tests/unit/drivers/third_party_driver_mocks.py index 2e7d5bc652..1d05f08e90 100644 --- a/ironic/tests/unit/drivers/third_party_driver_mocks.py +++ b/ironic/tests/unit/drivers/third_party_driver_mocks.py @@ -196,25 +196,6 @@ class MockKwargsException(Exception): self.kwargs = kwargs -xclarity_client = importutils.try_import('xclarity_client') -if not xclarity_client: - xclarity_client = mock.MagicMock(spec_set=mock_specs.XCLARITY_SPEC) - sys.modules['xclarity_client'] = xclarity_client - sys.modules['xclarity_client.client'] = xclarity_client.client - states = mock.MagicMock( - spec_set=mock_specs.XCLARITY_STATES_SPEC, - STATE_POWER_ON="power on", - STATE_POWER_OFF="power off", - STATE_POWERING_ON="powering_on", - STATE_POWERING_OFF="powering_off") - sys.modules['xclarity_client.states'] = states - sys.modules['xclarity_client.exceptions'] = xclarity_client.exceptions - sys.modules['xclarity_client.utils'] = xclarity_client.utils - xclarity_client.exceptions.XClarityException = type('XClarityException', - (Exception,), {}) - sys.modules['xclarity_client.models'] = xclarity_client.models - - # python-ibmcclient mocks for HUAWEI rack server driver ibmc_client = importutils.try_import('ibmc_client') if not ibmc_client: diff --git a/releasenotes/notes/remove-xclarity-hardware-type-aa1a26bcbb5b9670.yaml b/releasenotes/notes/remove-xclarity-hardware-type-aa1a26bcbb5b9670.yaml new file mode 100644 index 0000000000..05ecb156a8 --- /dev/null +++ b/releasenotes/notes/remove-xclarity-hardware-type-aa1a26bcbb5b9670.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + The deprecated ``xclarity`` hardware type has been removed from Ironic. diff --git a/setup.cfg b/setup.cfg index 66924b7846..90cb8fb213 100644 --- a/setup.cfg +++ b/setup.cfg @@ -130,7 +130,6 @@ ironic.hardware.interfaces.management = irmc = ironic.drivers.modules.irmc.management:IRMCManagement noop = ironic.drivers.modules.noop_mgmt:NoopManagement redfish = ironic.drivers.modules.redfish.management:RedfishManagement - xclarity = ironic.drivers.modules.xclarity.management:XClarityManagement ironic.hardware.interfaces.network = flat = ironic.drivers.modules.network.flat:FlatNetwork @@ -149,7 +148,6 @@ ironic.hardware.interfaces.power = irmc = ironic.drivers.modules.irmc.power:IRMCPower redfish = ironic.drivers.modules.redfish.power:RedfishPower snmp = ironic.drivers.modules.snmp:SNMPPower - xclarity = ironic.drivers.modules.xclarity.power:XClarityPower ironic.hardware.interfaces.raid = agent = ironic.drivers.modules.agent:AgentRAID @@ -198,7 +196,6 @@ ironic.hardware.types = manual-management = ironic.drivers.generic:ManualManagementHardware redfish = ironic.drivers.redfish:RedfishHardware snmp = ironic.drivers.snmp:SNMPHardware - xclarity = ironic.drivers.xclarity:XClarityHardware ironic.database.migration_backend = sqlalchemy = ironic.db.sqlalchemy.migration