From 016a168906c38c3f9e46a4b344b5c0f4f78ef781 Mon Sep 17 00:00:00 2001 From: Derek Higgins <derekh@redhat.com> Date: Mon, 11 Nov 2024 16:55:10 +0000 Subject: [PATCH] Add support to set 'disable_power_off' Add support to set 'disable_power_off' on node create and set/unset on node property set. Change-Id: Id70b4d2c9e3399e9944d5d3743b48b9889979fd4 --- ironicclient/common/http.py | 2 +- ironicclient/osc/v1/baremetal_node.py | 33 +++++++++++-- .../tests/unit/osc/v1/test_baremetal_node.py | 46 +++++++++++++++++++ ironicclient/v1/node.py | 14 +++--- ironicclient/v1/resource_fields.py | 4 +- ...isable_power_off_api-1d9efcb96c5ba37f.yaml | 4 ++ 6 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 releasenotes/notes/disable_power_off_api-1d9efcb96c5ba37f.yaml diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py index cb7d90c5e..a71a22a6f 100644 --- a/ironicclient/common/http.py +++ b/ironicclient/common/http.py @@ -36,7 +36,7 @@ from ironicclient import exc # http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html # noqa # for full details. DEFAULT_VER = '1.9' -LAST_KNOWN_API_VERSION = 92 +LAST_KNOWN_API_VERSION = 95 LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION) LOG = logging.getLogger(__name__) diff --git a/ironicclient/osc/v1/baremetal_node.py b/ironicclient/osc/v1/baremetal_node.py index 94b582db6..b32d66436 100755 --- a/ironicclient/osc/v1/baremetal_node.py +++ b/ironicclient/osc/v1/baremetal_node.py @@ -597,17 +597,22 @@ class CreateBaremetalNode(command.ShowOne): help=_('Firmware interface used by the node\'s driver. This is ' 'only applicable when the specified --driver is a ' 'hardware type.')) - + parser.add_argument( + '--disable-power-off', + action='store_true', + dest='disable_power_off', + default=None, + help=_('Explicitly disable power off actions on the node')) return parser def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) baremetal_client = self.app.client_manager.baremetal - field_list = ['automated_clean', 'chassis_uuid', 'driver', - 'driver_info', 'properties', 'extra', 'uuid', 'name', - 'conductor_group', 'owner', 'description', 'lessee', - 'shard', 'resource_class', 'parent_node', + field_list = ['automated_clean', 'chassis_uuid', 'disable_power_off', + 'driver', 'driver_info', 'properties', 'extra', 'uuid', + 'name', 'conductor_group', 'owner', 'description', + 'lessee', 'shard', 'resource_class', 'parent_node', ] + ['%s_interface' % iface for iface in SUPPORTED_INTERFACES] fields = dict((k, v) for (k, v) in vars(parsed_args).items() @@ -1530,6 +1535,19 @@ class SetBaremetalNode(command.Command): metavar='<parent_node>', help=_('Set the parent node for the node'), ) + power_off = parser.add_mutually_exclusive_group() + power_off.add_argument( + '--enable-power-off', + action='store_false', + dest='disable_power_off', + default=None, + help=_('Explicitly enable power off actions on nodes')) + power_off.add_argument( + '--disable-power-off', + action='store_true', + dest='disable_power_off', + default=None, + help=_('Explicitly disable power off actions on nodes')) return parser @@ -1570,6 +1588,11 @@ class SetBaremetalNode(command.Command): properties.extend(utils.args_array_to_patch( 'add', ["automated_clean=%s" % parsed_args.automated_clean])) + if parsed_args.disable_power_off is not None: + properties.extend(utils.args_array_to_patch( + 'add', ["disable_power_off=%s" % parsed_args.disable_power_off] + )) + if parsed_args.reset_interfaces and not parsed_args.driver: raise exc.CommandError( _("--reset-interfaces can only be specified with --driver")) diff --git a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py index 11a9e8d05..319491023 100644 --- a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py +++ b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py @@ -989,6 +989,11 @@ class TestBaremetalCreate(TestBaremetal): [('parent_node', 'nodex')], {'parent_node': 'nodex'}) + def test_baremetal_create_with_disable_power_off(self): + self.check_with_options(['--disable-power-off'], + [('disable_power_off', True)], + {'disable_power_off': True}) + class TestBaremetalDelete(TestBaremetal): def setUp(self): @@ -1150,6 +1155,7 @@ class TestBaremetalList(TestBaremetal): 'Deploy Interface', 'Deploy Step', 'Description', + 'Disable Power Off', 'Driver', 'Driver Info', 'Driver Internal Info', @@ -3620,6 +3626,46 @@ class TestBaremetalSet(TestBaremetal): reset_interfaces=None, ) + def test_baremetal_set_disable_power_off(self): + arglist = [ + 'node_uuid', + '--disable-power-off' + ] + verifylist = [ + ('nodes', ['node_uuid']), + ('disable_power_off', True) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.baremetal_mock.node.update.assert_called_once_with( + 'node_uuid', + [{'path': '/disable_power_off', 'value': 'True', 'op': 'add'}], + reset_interfaces=None, + ) + + def test_baremetal_set_enable_power_off(self): + arglist = [ + 'node_uuid', + '--enable-power-off' + ] + verifylist = [ + ('nodes', ['node_uuid']), + ('disable_power_off', False) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.baremetal_mock.node.update.assert_called_once_with( + 'node_uuid', + [{'path': '/disable_power_off', 'value': 'False', 'op': 'add'}], + reset_interfaces=None, + ) + class TestBaremetalShow(TestBaremetal): def setUp(self): diff --git a/ironicclient/v1/node.py b/ironicclient/v1/node.py index 5e2633b40..c36a27d64 100644 --- a/ironicclient/v1/node.py +++ b/ironicclient/v1/node.py @@ -48,13 +48,13 @@ class NodeManager(base.CreateManager): 'extra', 'uuid', 'properties', 'name', 'bios_interface', 'boot_interface', 'console_interface', 'deploy_interface', - 'inspect_interface', 'management_interface', - 'network_interface', 'power_interface', - 'raid_interface', 'rescue_interface', - 'storage_interface', 'vendor_interface', - 'firmware_interface', 'resource_class', - 'conductor_group', 'automated_clean', - 'network_data', 'parent_node', + 'disable_power_off', 'inspect_interface', + 'management_interface', 'network_interface', + 'power_interface', 'raid_interface', + 'rescue_interface', 'storage_interface', + 'vendor_interface', 'firmware_interface', + 'resource_class', 'conductor_group', + 'automated_clean', 'network_data', 'parent_node', 'owner', 'lessee', 'shard', 'description'] _resource_name = 'nodes' diff --git a/ironicclient/v1/resource_fields.py b/ironicclient/v1/resource_fields.py index b45c9a11f..af73cf8b4 100644 --- a/ironicclient/v1/resource_fields.py +++ b/ironicclient/v1/resource_fields.py @@ -157,7 +157,8 @@ class Resource(object): 'parent_node': 'Parent Node', 'children': 'Child Nodes', 'firmware_interface': 'Firmware Interface', - 'public': 'Public' + 'public': 'Public', + 'disable_power_off': 'Disable Power Off' } def __init__(self, field_ids, sort_excluded=None, override_labels=None): @@ -255,6 +256,7 @@ NODE_DETAILED_RESOURCE = Resource( 'deploy_interface', 'deploy_step', 'description', + 'disable_power_off', 'driver', 'driver_info', 'driver_internal_info', diff --git a/releasenotes/notes/disable_power_off_api-1d9efcb96c5ba37f.yaml b/releasenotes/notes/disable_power_off_api-1d9efcb96c5ba37f.yaml new file mode 100644 index 000000000..68c6cfa63 --- /dev/null +++ b/releasenotes/notes/disable_power_off_api-1d9efcb96c5ba37f.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Support added to set "disable power off" on nodes.