Support for protected and protected_reason fields

Story: #2003869
Task: #27624
Depends-On: https://review.openstack.org/611662
Change-Id: Ib575ace38d1bedce54d0d21517d745ed3204d6f2
This commit is contained in:
Dmitry Tantsur 2018-10-24 16:08:40 +02:00
parent 9325743c0d
commit 1c941eefe5
6 changed files with 121 additions and 3 deletions

View File

@ -43,7 +43,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 = 47 LAST_KNOWN_API_VERSION = 48
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

@ -1116,6 +1116,16 @@ class SetBaremetalNode(command.Command):
action='store_true', action='store_true',
help=_('Enable automated cleaning for the node'), help=_('Enable automated cleaning for the node'),
) )
parser.add_argument(
'--protected',
action='store_true',
help=_('Mark the node as protected'),
)
parser.add_argument(
'--protected-reason',
metavar='<protected_reason>',
help=_('Set the reason of marking the node as protected'),
)
parser.add_argument( parser.add_argument(
'--target-raid-config', '--target-raid-config',
metavar='<target_raid_config>', metavar='<target_raid_config>',
@ -1174,7 +1184,7 @@ class SetBaremetalNode(command.Command):
properties = [] properties = []
for field in ['automated_clean', 'instance_uuid', 'name', for field in ['automated_clean', 'instance_uuid', 'name',
'chassis_uuid', 'driver', 'resource_class', 'chassis_uuid', 'driver', 'resource_class',
'conductor_group']: 'conductor_group', 'protected', 'protected_reason']:
value = getattr(parsed_args, field) value = getattr(parsed_args, field)
if value: if value:
properties.extend(utils.args_array_to_patch( properties.extend(utils.args_array_to_patch(
@ -1436,6 +1446,17 @@ class UnsetBaremetalNode(command.Command):
help=_('Unset automated clean option on this baremetal node ' help=_('Unset automated clean option on this baremetal node '
'(the value from configuration will be used)'), '(the value from configuration will be used)'),
) )
parser.add_argument(
"--protected",
action="store_true",
help=_('Unset the protected flag on the node'),
)
parser.add_argument(
"--protected-reason",
action="store_true",
help=_('Unset the protected reason (gets unset automatically when '
'protected is unset)'),
)
return parser return parser
@ -1457,7 +1478,8 @@ class UnsetBaremetalNode(command.Command):
'deploy_interface', 'inspect_interface', 'deploy_interface', 'inspect_interface',
'management_interface', 'network_interface', 'management_interface', 'network_interface',
'power_interface', 'raid_interface', 'rescue_interface', 'power_interface', 'raid_interface', 'rescue_interface',
'storage_interface', 'vendor_interface']: 'storage_interface', 'vendor_interface',
'protected', 'protected_reason']:
if getattr(parsed_args, field): if getattr(parsed_args, field):
properties.extend(utils.args_array_to_patch('remove', [field])) properties.extend(utils.args_array_to_patch('remove', [field]))

View File

@ -636,6 +636,8 @@ class TestBaremetalList(TestBaremetal):
'Power Interface', 'Power Interface',
'Power State', 'Power State',
'Properties', 'Properties',
'Protected',
'Protected Reason',
'Provision Updated At', 'Provision Updated At',
'Provisioning State', 'Provisioning State',
'RAID Interface', 'RAID Interface',
@ -2303,6 +2305,49 @@ class TestBaremetalSet(TestBaremetal):
reset_interfaces=None, reset_interfaces=None,
) )
def test_baremetal_set_protected(self):
arglist = [
'node_uuid',
'--protected'
]
verifylist = [
('node', 'node_uuid'),
('protected', 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': '/protected', 'value': 'True', 'op': 'add'}],
reset_interfaces=None,
)
def test_baremetal_set_protected_with_reason(self):
arglist = [
'node_uuid',
'--protected',
'--protected-reason', 'reason!'
]
verifylist = [
('node', 'node_uuid'),
('protected', True),
('protected_reason', 'reason!')
]
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': '/protected', 'value': 'True', 'op': 'add'},
{'path': '/protected_reason', 'value': 'reason!', 'op': 'add'}],
reset_interfaces=None,
)
def test_baremetal_set_extra(self): def test_baremetal_set_extra(self):
arglist = [ arglist = [
'node_uuid', 'node_uuid',
@ -2774,6 +2819,44 @@ class TestBaremetalUnset(TestBaremetal):
[{'path': '/automated_clean', 'op': 'remove'}] [{'path': '/automated_clean', 'op': 'remove'}]
) )
def test_baremetal_unset_protected(self):
arglist = [
'node_uuid',
'--protected',
]
verifylist = [
('node', 'node_uuid'),
('protected', 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': '/protected', 'op': 'remove'}]
)
def test_baremetal_unset_protected_reason(self):
arglist = [
'node_uuid',
'--protected-reason',
]
verifylist = [
('node', 'node_uuid'),
('protected_reason', 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': '/protected_reason', 'op': 'remove'}]
)
def test_baremetal_unset_extra(self): def test_baremetal_unset_extra(self):
arglist = [ arglist = [
'node_uuid', 'node_uuid',

View File

@ -65,6 +65,8 @@ class NodeShellTest(utils.BaseTestCase):
'vendor_interface', 'vendor_interface',
'power_state', 'power_state',
'properties', 'properties',
'protected',
'protected_reason',
'provision_state', 'provision_state',
'provision_updated_at', 'provision_updated_at',
'reservation', 'reservation',

View File

@ -89,6 +89,8 @@ class Resource(object):
'node_uuid': 'Node UUID', 'node_uuid': 'Node UUID',
'power_state': 'Power State', 'power_state': 'Power State',
'properties': 'Properties', 'properties': 'Properties',
'protected': 'Protected',
'protected_reason': 'Protected Reason',
'provision_state': 'Provisioning State', 'provision_state': 'Provisioning State',
'provision_updated_at': 'Provision Updated At', 'provision_updated_at': 'Provision Updated At',
'raid_config': 'Current RAID configuration', 'raid_config': 'Current RAID configuration',
@ -234,6 +236,8 @@ NODE_DETAILED_RESOURCE = Resource(
'power_interface', 'power_interface',
'power_state', 'power_state',
'properties', 'properties',
'protected',
'protected_reason',
'provision_updated_at', 'provision_updated_at',
'provision_state', 'provision_state',
'raid_interface', 'raid_interface',

View File

@ -0,0 +1,7 @@
---
features:
- |
Adds the ability to set and unset the ``protected`` and
``protected_reason`` fields introduced in API 1.48. Setting ``protected``
allows protecting a deployed node from undeploying, rebuilding and
deleting.