diff --git a/doc/source/deploy/cleaning.rst b/doc/source/deploy/cleaning.rst index 0c99affd5d..4f9bcdc983 100644 --- a/doc/source/deploy/cleaning.rst +++ b/doc/source/deploy/cleaning.rst @@ -71,6 +71,9 @@ cleaning steps. See `How do I change the priority of a cleaning step?`_ for more information. + +.. _manual_cleaning: + Manual cleaning =============== diff --git a/doc/source/drivers/ilo.rst b/doc/source/drivers/ilo.rst index 0b2047bc4e..d646facaa9 100644 --- a/doc/source/drivers/ilo.rst +++ b/doc/source/drivers/ilo.rst @@ -713,16 +713,18 @@ The following iLO drivers support node cleaning - * ``iscsi_ilo`` * ``agent_ilo`` -Supported Cleaning Operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For more information on node cleaning, see :ref:`cleaning` -* The cleaning operations supported are: +Supported **Automated** Cleaning Operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* The automated cleaning operations supported are: -``reset_ilo``: Resets the iLO. By default, enabled with priority 1. -``reset_bios_to_default``: - Resets system ROM sttings to default. By default, enabled with priority 10. - This clean step is supported only on Gen9 and above servers. + Resets system ROM settings to default. By default, enabled with priority + 10. This clean step is supported only on Gen9 and above servers. -``reset_secure_boot_keys_to_default``: Resets secure boot keys to manufacturer's defaults. This step is supported only on Gen9 and above servers. By default, enabled with priority 20 . @@ -736,15 +738,16 @@ Supported Cleaning Operations * For in-band cleaning operations supported by ``agent_ilo`` driver, see :ref:`InbandvsOutOfBandCleaning`. -* All the cleaning steps have an explicit configuration option for priority. - In order to disable or change the priority of the clean steps, respective - configuration option for priority should be updated in ironic.conf. +* All the automated cleaning steps have an explicit configuration option for + priority. In order to disable or change the priority of the automated clean + steps, respective configuration option for priority should be updated in + ironic.conf. * Updating clean step priority to 0, will disable that particular clean step - and will not run during cleaning. + and will not run during automated cleaning. -* Configuration Options for the clean steps are listed under ``[ilo]`` section in - ironic.conf :: +* Configuration Options for the automated clean steps are listed under + ``[ilo]`` section in ironic.conf :: - clean_priority_reset_ilo=1 - clean_priority_reset_bios_to_default=10 @@ -753,7 +756,31 @@ Supported Cleaning Operations - clean_priority_reset_ilo_credential=30 - clean_priority_erase_devices=10 -For more information on node cleaning, see :ref:`cleaning` +For more information on node automated cleaning, see :ref:`automated_cleaning` + +Supported **Manual** Cleaning Operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* The manual cleaning operations supported are: + + -``activate_license``: + Activates the iLO Advanced license. This is an out-of-band manual cleaning + step associated with ``management`` interface. See + `Activating iLO Advanced license as manual clean step`_ for user guidance + on usage. Please note that this operation cannot be performed using virtual + media based drivers like ``iscsi_ilo`` and ``agent_ilo`` as they need this + type of advanced license already active to use virtual media to boot into + to start cleaning operation. Virtual media is an advanced feature. If an + advanced license is already active and the user wants to overwrite the + current license key, for example in case of a multi-server activation key + delivered with a flexible-quantity kit or after completing an Activation + Key Agreement (AKA), then these drivers can still be used for executing + this cleaning step. + +* iLO with firmware version 1.5 is minimally required to support all the + operations. + +For more information on node manual cleaning, see :ref:`manual_cleaning` Hardware Inspection Support ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1206,3 +1233,33 @@ Localboot in standalone ironic Conductor -> Baremetal [label = "Power on the node"]; Baremetal -> Baremetal [label = "Boot user image from disk"]; } + +Activating iLO Advanced license as manual clean step +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +iLO drivers can activate the iLO Advanced license key as a manual cleaning +step. Any manual cleaning step can only be initiated when a node is in the +``manageable`` state. Once the manual cleaning is finished, the node will be +put in the ``manageable`` state again. User can follow steps from +:ref:`manual_cleaning` to initiate manual cleaning operation on a node. + +An example of a manual clean step to activate license as the only clean step +could be:: + + 'clean_steps': [{ + 'interface': 'management', + 'step': 'activate_license', + 'args': { + 'ilo_license_key': 'ABC12-XXXXX-XXXXX-XXXXX-YZ345' + } + }] + +The different attributes of ``activate_license`` clean step are as follows: + + .. csv-table:: + :header: "Attribute", "Description" + :widths: 30, 120 + + "``interface``", "Interface of clean step, here ``management``" + "``step``", "Name of clean step, here ``activate_license``" + "``args``", "Keyword-argument entry (: ) being passed to clean step" + "``args.ilo_license_key``", "The HPE iLO Advanced license key to activate enterprise features. This is mandatory." diff --git a/ironic/drivers/modules/ilo/management.py b/ironic/drivers/modules/ilo/management.py index 993d7ee375..0c74af10b4 100644 --- a/ironic/drivers/modules/ilo/management.py +++ b/ironic/drivers/modules/ilo/management.py @@ -18,12 +18,11 @@ iLO Management Interface from oslo_config import cfg from oslo_log import log as logging from oslo_utils import importutils +import six from ironic.common import boot_devices from ironic.common import exception -from ironic.common.i18n import _ -from ironic.common.i18n import _LI -from ironic.common.i18n import _LW +from ironic.common.i18n import _, _LI, _LW from ironic.conductor import task_manager from ironic.drivers import base from ironic.drivers.modules.ilo import common as ilo_common @@ -301,3 +300,36 @@ class IloManagement(base.ManagementInterface): :raises: NodeCleaningFailure, on failure to execute step. """ return _execute_ilo_clean_step(task.node, 'clear_secure_boot_keys') + + @base.clean_step(priority=0, abortable=False, argsinfo={ + 'ilo_license_key': { + 'description': ( + 'The HPE iLO Advanced license key to activate enterprise ' + 'features.' + ), + 'required': True + } + }) + def activate_license(self, task, **kwargs): + """Activates iLO Advanced license. + + :param task: a TaskManager object. + :raises: InvalidParameterValue, if any of the arguments are invalid. + :raises: NodeCleaningFailure, on failure to execute clean step. + """ + ilo_license_key = kwargs.get('ilo_license_key') + node = task.node + + if not isinstance(ilo_license_key, six.string_types): + msg = (_("Value of 'ilo_license_key' must be a string instead of " + "'%(value)s'. Step 'activate_license' is not executed " + "for %(node)s.") + % {'value': ilo_license_key, 'node': node.uuid}) + LOG.error(msg) + raise exception.InvalidParameterValue(msg) + + LOG.debug("Activating iLO license for node %(node)s ...", + {'node': node.uuid}) + _execute_ilo_clean_step(node, 'activate_license', ilo_license_key) + LOG.info(_LI("iLO license activated for node %(node)s."), + {'node': node.uuid}) diff --git a/ironic/tests/unit/drivers/modules/ilo/test_management.py b/ironic/tests/unit/drivers/modules/ilo/test_management.py index f34b32aadf..17cafa53d5 100644 --- a/ironic/tests/unit/drivers/modules/ilo/test_management.py +++ b/ironic/tests/unit/drivers/modules/ilo/test_management.py @@ -296,3 +296,30 @@ class IloManagementTestCase(db_base.DbTestCase): task.driver.management.clear_secure_boot_keys(task) clean_step_mock.assert_called_once_with(task.node, 'clear_secure_boot_keys') + + @mock.patch.object(ilo_management, '_execute_ilo_clean_step', + spec_set=True, autospec=True) + def test_activate_license(self, clean_step_mock): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + activate_license_args = { + 'ilo_license_key': 'XXXXX-YYYYY-ZZZZZ-XYZZZ-XXYYZ'} + task.driver.management.activate_license(task, + **activate_license_args) + clean_step_mock.assert_called_once_with( + task.node, 'activate_license', 'XXXXX-YYYYY-ZZZZZ-XYZZZ-XXYYZ') + + @mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True) + @mock.patch.object(ilo_management, '_execute_ilo_clean_step', + spec_set=True, autospec=True) + def test_activate_license_no_or_invalid_format_license_key( + self, clean_step_mock, log_mock): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + for license_key_value in (None, [], {}): + activate_license_args = {'ilo_license_key': license_key_value} + self.assertRaises(exception.InvalidParameterValue, + task.driver.management.activate_license, + task, + **activate_license_args) + self.assertFalse(clean_step_mock.called) diff --git a/releasenotes/notes/ilo-license-activate-manual-clean-step-84d335998d708b49.yaml b/releasenotes/notes/ilo-license-activate-manual-clean-step-84d335998d708b49.yaml new file mode 100644 index 0000000000..98a22a59ed --- /dev/null +++ b/releasenotes/notes/ilo-license-activate-manual-clean-step-84d335998d708b49.yaml @@ -0,0 +1,4 @@ +--- +features: + - Support for activation of iLO Advanced license as a + manual cleaning step in iLO drivers.