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
This commit is contained in:
Derek Higgins 2024-11-11 16:55:10 +00:00
parent 2caa47fdf0
commit 016a168906
6 changed files with 89 additions and 14 deletions

View File

@ -36,7 +36,7 @@ from ironicclient import exc
# http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html # noqa # http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html # noqa
# for full details. # for full details.
DEFAULT_VER = '1.9' DEFAULT_VER = '1.9'
LAST_KNOWN_API_VERSION = 92 LAST_KNOWN_API_VERSION = 95
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION) LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)

View File

@ -597,17 +597,22 @@ class CreateBaremetalNode(command.ShowOne):
help=_('Firmware interface used by the node\'s driver. This is ' help=_('Firmware interface used by the node\'s driver. This is '
'only applicable when the specified --driver is a ' 'only applicable when the specified --driver is a '
'hardware type.')) '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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args) self.log.debug("take_action(%s)", parsed_args)
baremetal_client = self.app.client_manager.baremetal baremetal_client = self.app.client_manager.baremetal
field_list = ['automated_clean', 'chassis_uuid', 'driver', field_list = ['automated_clean', 'chassis_uuid', 'disable_power_off',
'driver_info', 'properties', 'extra', 'uuid', 'name', 'driver', 'driver_info', 'properties', 'extra', 'uuid',
'conductor_group', 'owner', 'description', 'lessee', 'name', 'conductor_group', 'owner', 'description',
'shard', 'resource_class', 'parent_node', 'lessee', 'shard', 'resource_class', 'parent_node',
] + ['%s_interface' % iface ] + ['%s_interface' % iface
for iface in SUPPORTED_INTERFACES] for iface in SUPPORTED_INTERFACES]
fields = dict((k, v) for (k, v) in vars(parsed_args).items() fields = dict((k, v) for (k, v) in vars(parsed_args).items()
@ -1530,6 +1535,19 @@ class SetBaremetalNode(command.Command):
metavar='<parent_node>', metavar='<parent_node>',
help=_('Set the parent node for the 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 return parser
@ -1570,6 +1588,11 @@ class SetBaremetalNode(command.Command):
properties.extend(utils.args_array_to_patch( properties.extend(utils.args_array_to_patch(
'add', ["automated_clean=%s" % parsed_args.automated_clean])) '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: if parsed_args.reset_interfaces and not parsed_args.driver:
raise exc.CommandError( raise exc.CommandError(
_("--reset-interfaces can only be specified with --driver")) _("--reset-interfaces can only be specified with --driver"))

View File

@ -989,6 +989,11 @@ class TestBaremetalCreate(TestBaremetal):
[('parent_node', 'nodex')], [('parent_node', 'nodex')],
{'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): class TestBaremetalDelete(TestBaremetal):
def setUp(self): def setUp(self):
@ -1150,6 +1155,7 @@ class TestBaremetalList(TestBaremetal):
'Deploy Interface', 'Deploy Interface',
'Deploy Step', 'Deploy Step',
'Description', 'Description',
'Disable Power Off',
'Driver', 'Driver',
'Driver Info', 'Driver Info',
'Driver Internal Info', 'Driver Internal Info',
@ -3620,6 +3626,46 @@ class TestBaremetalSet(TestBaremetal):
reset_interfaces=None, 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): class TestBaremetalShow(TestBaremetal):
def setUp(self): def setUp(self):

View File

@ -48,13 +48,13 @@ class NodeManager(base.CreateManager):
'extra', 'uuid', 'properties', 'name', 'extra', 'uuid', 'properties', 'name',
'bios_interface', 'boot_interface', 'bios_interface', 'boot_interface',
'console_interface', 'deploy_interface', 'console_interface', 'deploy_interface',
'inspect_interface', 'management_interface', 'disable_power_off', 'inspect_interface',
'network_interface', 'power_interface', 'management_interface', 'network_interface',
'raid_interface', 'rescue_interface', 'power_interface', 'raid_interface',
'storage_interface', 'vendor_interface', 'rescue_interface', 'storage_interface',
'firmware_interface', 'resource_class', 'vendor_interface', 'firmware_interface',
'conductor_group', 'automated_clean', 'resource_class', 'conductor_group',
'network_data', 'parent_node', 'automated_clean', 'network_data', 'parent_node',
'owner', 'lessee', 'shard', 'description'] 'owner', 'lessee', 'shard', 'description']
_resource_name = 'nodes' _resource_name = 'nodes'

View File

@ -157,7 +157,8 @@ class Resource(object):
'parent_node': 'Parent Node', 'parent_node': 'Parent Node',
'children': 'Child Nodes', 'children': 'Child Nodes',
'firmware_interface': 'Firmware Interface', '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): def __init__(self, field_ids, sort_excluded=None, override_labels=None):
@ -255,6 +256,7 @@ NODE_DETAILED_RESOURCE = Resource(
'deploy_interface', 'deploy_interface',
'deploy_step', 'deploy_step',
'description', 'description',
'disable_power_off',
'driver', 'driver',
'driver_info', 'driver_info',
'driver_internal_info', 'driver_internal_info',

View File

@ -0,0 +1,4 @@
---
features:
- |
Support added to set "disable power off" on nodes.