Merge "Add node lessee"

This commit is contained in:
Zuul 2020-04-08 10:01:41 +00:00 committed by Gerrit Code Review
commit a904ef5f37
7 changed files with 124 additions and 7 deletions

View File

@ -37,7 +37,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 = 61
LAST_KNOWN_API_VERSION = 65
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
LOG = logging.getLogger(__name__)

View File

@ -452,6 +452,10 @@ class CreateBaremetalNode(command.ShowOne):
'--owner',
metavar='<owner>',
help=_('Owner of the node.'))
parser.add_argument(
'--lessee',
metavar='<lessee>',
help=_('Lessee of the node.'))
parser.add_argument(
'--description',
metavar='<description>',
@ -466,7 +470,7 @@ class CreateBaremetalNode(command.ShowOne):
field_list = ['automated_clean', 'chassis_uuid', 'driver',
'driver_info', 'properties', 'extra', 'uuid', 'name',
'conductor_group', 'owner', 'description',
'conductor_group', 'owner', 'description', 'lessee',
'resource_class'] + ['%s_interface' % iface
for iface in SUPPORTED_INTERFACES]
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
@ -656,6 +660,11 @@ class ListBaremetalNode(command.Lister):
metavar='<owner>',
help=_("Limit list to nodes with owner "
"<owner>"))
parser.add_argument(
'--lessee',
metavar='<lessee>',
help=_("Limit list to nodes with lessee "
"<lessee>"))
parser.add_argument(
'--description-contains',
metavar='<description_contains>',
@ -702,7 +711,7 @@ class ListBaremetalNode(command.Lister):
if getattr(parsed_args, field) is not None:
params[field] = getattr(parsed_args, field)
for field in ['provision_state', 'driver', 'resource_class',
'chassis', 'conductor', 'owner',
'chassis', 'conductor', 'owner', 'lessee',
'description_contains']:
if getattr(parsed_args, field):
params[field] = getattr(parsed_args, field)
@ -1225,6 +1234,10 @@ class SetBaremetalNode(command.Command):
"--owner",
metavar='<owner>',
help=_('Set the owner for the node')),
parser.add_argument(
"--lessee",
metavar='<lessee>',
help=_('Set the lessee for the node')),
parser.add_argument(
"--description",
metavar='<description>',
@ -1252,7 +1265,8 @@ class SetBaremetalNode(command.Command):
for field in ['automated_clean', 'instance_uuid', 'name',
'chassis_uuid', 'driver', 'resource_class',
'conductor_group', 'protected', 'protected_reason',
'retired', 'retired_reason', 'owner', 'description']:
'retired', 'retired_reason', 'owner', 'lessee',
'description']:
value = getattr(parsed_args, field)
if value:
properties.extend(utils.args_array_to_patch(
@ -1541,6 +1555,11 @@ class UnsetBaremetalNode(command.Command):
action="store_true",
help=_('Unset the owner field of the node'),
)
parser.add_argument(
"--lessee",
action="store_true",
help=_('Unset the lessee field of the node'),
)
parser.add_argument(
"--description",
action="store_true",
@ -1569,7 +1588,7 @@ class UnsetBaremetalNode(command.Command):
'power_interface', 'raid_interface', 'rescue_interface',
'storage_interface', 'vendor_interface',
'protected', 'protected_reason', 'retired',
'retired_reason', 'owner', 'description']:
'retired_reason', 'owner', 'lessee', 'description']:
if getattr(parsed_args, field):
properties.extend(utils.args_array_to_patch('remove', [field]))

View File

@ -470,6 +470,11 @@ class TestBaremetalCreate(TestBaremetal):
[('description', 'there is no spoon')],
{'description': 'there is no spoon'})
def test_baremetal_create_with_lessee(self):
self.check_with_options(['--lessee', 'lessee 1'],
[('lessee', 'lessee 1')],
{'lessee': 'lessee 1'})
class TestBaremetalDelete(TestBaremetal):
def setUp(self):
@ -641,6 +646,7 @@ class TestBaremetalList(TestBaremetal):
'Instance Info',
'Instance UUID',
'Last Error',
'Lessee',
'Maintenance',
'Maintenance Reason',
'Management Interface',
@ -1080,6 +1086,29 @@ class TestBaremetalList(TestBaremetal):
**kwargs
)
def test_baremetal_list_by_lessee(self):
lessee = 'lessee 1'
arglist = [
'--lessee', lessee,
]
verifylist = [
('lessee', lessee),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
kwargs = {
'marker': None,
'limit': None,
'lessee': lessee,
}
self.baremetal_mock.node.list.assert_called_with(
**kwargs
)
def test_baremetal_list_fields(self):
arglist = [
'--fields', 'uuid', 'name',
@ -2736,6 +2765,28 @@ class TestBaremetalSet(TestBaremetal):
reset_interfaces=None,
)
def test_baremetal_set_lessee(self):
arglist = [
'node_uuid',
'--lessee', 'lessee 1',
]
verifylist = [
('node', 'node_uuid'),
('lessee', 'lessee 1')
]
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': '/lessee',
'value': 'lessee 1',
'op': 'add'}],
reset_interfaces=None,
)
class TestBaremetalShow(TestBaremetal):
def setUp(self):
@ -3335,6 +3386,25 @@ class TestBaremetalUnset(TestBaremetal):
[{'path': '/description', 'op': 'remove'}]
)
def test_baremetal_unset_lessee(self):
arglist = [
'node_uuid',
'--lessee',
]
verifylist = [
('node', 'node_uuid'),
('lessee', 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': '/lessee', 'op': 'remove'}]
)
class TestValidate(TestBaremetal):
def setUp(self):

View File

@ -49,7 +49,8 @@ NODE2 = {'uuid': '66666666-7777-8888-9999-111111111111',
'resource_class': 'bar',
'extra': {},
'owner': '33333333-2222-1111-0000-111111111111',
'retired': True}
'retired': True,
'lessee': '77777777-8888-5555-2222-999999999999'}
PORT = {'uuid': '11111111-2222-3333-4444-555555555555',
'node_uuid': '66666666-7777-8888-9999-000000000000',
'address': 'AA:AA:AA:AA:AA:AA',
@ -213,6 +214,13 @@ fake_responses = {
{"nodes": [NODE2]},
)
},
'/v1/nodes/?lessee=%s' % NODE2['lessee']:
{
'GET': (
{},
{"nodes": [NODE2]},
)
},
'/v1/nodes/?driver=fake':
{
'GET': (
@ -857,6 +865,15 @@ class NodeManagerTest(testtools.TestCase):
self.assertThat(nodes, HasLength(1))
self.assertEqual(NODE2['owner'], getattr(nodes[0], 'owner'))
def test_node_list_lessee(self):
nodes = self.mgr.list(lessee=NODE2['lessee'])
expect = [
('GET', '/v1/nodes/?lessee=%s' % NODE2['lessee'], {}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertThat(nodes, HasLength(1))
self.assertEqual(NODE2['lessee'], getattr(nodes[0], 'lessee'))
def test_node_list_provision_state_fail(self):
self.assertRaises(KeyError, self.mgr.list,
provision_state="test")

View File

@ -61,7 +61,7 @@ class NodeManager(base.CreateManager):
fields=None, provision_state=None, driver=None,
resource_class=None, chassis=None, fault=None,
os_ironic_api_version=None, conductor_group=None,
conductor=None, owner=None, retired=None):
conductor=None, owner=None, retired=None, lessee=None):
"""Retrieve a list of nodes.
:param associated: Optional. Either a Boolean or a string
@ -122,6 +122,8 @@ class NodeManager(base.CreateManager):
mapped to the given conductor.
:param owner: Optional. String value to get only nodes
mapped to a specific owner.
:param lessee: Optional. String value to get only nodes
mapped to a specific lessee.
:returns: A list of nodes.
@ -157,6 +159,8 @@ class NodeManager(base.CreateManager):
filters.append('conductor=%s' % conductor)
if owner is not None:
filters.append('owner=%s' % owner)
if lessee is not None:
filters.append('lessee=%s' % lessee)
path = ''
if detail:

View File

@ -87,6 +87,7 @@ class Resource(object):
'instance_uuid': 'Instance UUID',
'internal_info': 'Internal Info',
'last_error': 'Last Error',
'lessee': 'Lessee',
'maintenance': 'Maintenance',
'maintenance_reason': 'Maintenance Reason',
'fault': 'Fault',
@ -243,6 +244,7 @@ NODE_DETAILED_RESOURCE = Resource(
'instance_info',
'instance_uuid',
'last_error',
'lessee',
'maintenance',
'maintenance_reason',
'management_interface',

View File

@ -0,0 +1,5 @@
---
features:
- |
Adds support to display and update the ``lessee`` field of nodes,
which is introduced in API 1.64.