Add allocation owner
Add support to create an allocation with an owner, and to display an allocation owner. Change-Id: I85d5c324b177a1e016e93e011f9ad22144ca9340 Story: #2006506 Task: #37540
This commit is contained in:
@@ -40,7 +40,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 = 58
|
LAST_KNOWN_API_VERSION = 60
|
||||||
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
|
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@@ -56,6 +56,10 @@ class CreateBaremetalAllocation(command.ShowOne):
|
|||||||
'--uuid',
|
'--uuid',
|
||||||
dest='uuid',
|
dest='uuid',
|
||||||
help=_('UUID of the allocation.'))
|
help=_('UUID of the allocation.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--owner',
|
||||||
|
dest='owner',
|
||||||
|
help=_('Owner of the allocation.'))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--extra',
|
'--extra',
|
||||||
metavar="<key=value>",
|
metavar="<key=value>",
|
||||||
@@ -91,7 +95,7 @@ class CreateBaremetalAllocation(command.ShowOne):
|
|||||||
_('--resource-class is required except when --node is used'))
|
_('--resource-class is required except when --node is used'))
|
||||||
|
|
||||||
field_list = ['name', 'uuid', 'extra', 'resource_class', 'traits',
|
field_list = ['name', 'uuid', 'extra', 'resource_class', 'traits',
|
||||||
'candidate_nodes', 'node']
|
'candidate_nodes', 'node', 'owner']
|
||||||
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
|
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
|
||||||
if k in field_list and v is not None)
|
if k in field_list and v is not None)
|
||||||
|
|
||||||
@@ -182,6 +186,10 @@ class ListBaremetalAllocation(command.Lister):
|
|||||||
'--state',
|
'--state',
|
||||||
metavar='<state>',
|
metavar='<state>',
|
||||||
help=_("Only list allocations in this state."))
|
help=_("Only list allocations in this state."))
|
||||||
|
parser.add_argument(
|
||||||
|
'--owner',
|
||||||
|
metavar='<owner>',
|
||||||
|
help=_("Only list allocations with this owner."))
|
||||||
|
|
||||||
# NOTE(dtantsur): the allocation API does not expose the 'detail' flag,
|
# NOTE(dtantsur): the allocation API does not expose the 'detail' flag,
|
||||||
# but some fields are inconvenient to display in a table, so we emulate
|
# but some fields are inconvenient to display in a table, so we emulate
|
||||||
@@ -216,7 +224,7 @@ class ListBaremetalAllocation(command.Lister):
|
|||||||
parsed_args.limit)
|
parsed_args.limit)
|
||||||
params['limit'] = parsed_args.limit
|
params['limit'] = parsed_args.limit
|
||||||
params['marker'] = parsed_args.marker
|
params['marker'] = parsed_args.marker
|
||||||
for field in ('node', 'resource_class', 'state'):
|
for field in ('node', 'resource_class', 'state', 'owner'):
|
||||||
value = getattr(parsed_args, field)
|
value = getattr(parsed_args, field)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
params[field] = value
|
params[field] = value
|
||||||
|
@@ -34,6 +34,7 @@ BAREMETAL_CHASSIS = {
|
|||||||
|
|
||||||
baremetal_uuid = 'xxx-xxxxxx-xxxx'
|
baremetal_uuid = 'xxx-xxxxxx-xxxx'
|
||||||
baremetal_name = 'fake name'
|
baremetal_name = 'fake name'
|
||||||
|
baremetal_owner = 'fake-owner'
|
||||||
baremetal_instance_uuid = 'yyy-yyyyyy-yyyy'
|
baremetal_instance_uuid = 'yyy-yyyyyy-yyyy'
|
||||||
baremetal_power_state = None
|
baremetal_power_state = None
|
||||||
baremetal_provision_state = None
|
baremetal_provision_state = None
|
||||||
|
@@ -174,6 +174,28 @@ class TestCreateBaremetalAllocation(TestBaremetalAllocation):
|
|||||||
|
|
||||||
self.baremetal_mock.allocation.create.assert_called_once_with(**args)
|
self.baremetal_mock.allocation.create.assert_called_once_with(**args)
|
||||||
|
|
||||||
|
def test_baremetal_allocation_create_owner(self):
|
||||||
|
arglist = [
|
||||||
|
'--resource-class', baremetal_fakes.baremetal_resource_class,
|
||||||
|
'--owner', baremetal_fakes.baremetal_owner,
|
||||||
|
]
|
||||||
|
|
||||||
|
verifylist = [
|
||||||
|
('resource_class', baremetal_fakes.baremetal_resource_class),
|
||||||
|
('owner', baremetal_fakes.baremetal_owner),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'resource_class': baremetal_fakes.baremetal_resource_class,
|
||||||
|
'owner': baremetal_fakes.baremetal_owner,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.baremetal_mock.allocation.create.assert_called_once_with(**args)
|
||||||
|
|
||||||
def test_baremetal_allocation_create_no_options(self):
|
def test_baremetal_allocation_create_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = []
|
verifylist = []
|
||||||
@@ -344,6 +366,36 @@ class TestBaremetalAllocationList(TestBaremetalAllocation):
|
|||||||
baremetal_fakes.baremetal_uuid),)
|
baremetal_fakes.baremetal_uuid),)
|
||||||
self.assertEqual(datalist, tuple(data))
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
def test_baremetal_allocation_list_owner(self):
|
||||||
|
arglist = ['--owner',
|
||||||
|
baremetal_fakes.baremetal_owner]
|
||||||
|
verifylist = [('owner',
|
||||||
|
baremetal_fakes.baremetal_owner)]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
'owner': baremetal_fakes.baremetal_owner,
|
||||||
|
'marker': None,
|
||||||
|
'limit': None}
|
||||||
|
self.baremetal_mock.allocation.list.assert_called_once_with(**kwargs)
|
||||||
|
|
||||||
|
collist = (
|
||||||
|
"UUID",
|
||||||
|
"Name",
|
||||||
|
"Resource Class",
|
||||||
|
"State",
|
||||||
|
"Node UUID")
|
||||||
|
self.assertEqual(collist, columns)
|
||||||
|
|
||||||
|
datalist = ((baremetal_fakes.baremetal_uuid,
|
||||||
|
baremetal_fakes.baremetal_name,
|
||||||
|
baremetal_fakes.baremetal_resource_class,
|
||||||
|
baremetal_fakes.baremetal_allocation_state,
|
||||||
|
baremetal_fakes.baremetal_uuid),)
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
def test_baremetal_allocation_list_state(self):
|
def test_baremetal_allocation_list_state(self):
|
||||||
arglist = ['--state', baremetal_fakes.baremetal_allocation_state]
|
arglist = ['--state', baremetal_fakes.baremetal_allocation_state]
|
||||||
verifylist = [('state', baremetal_fakes.baremetal_allocation_state)]
|
verifylist = [('state', baremetal_fakes.baremetal_allocation_state)]
|
||||||
@@ -388,6 +440,7 @@ class TestBaremetalAllocationList(TestBaremetalAllocation):
|
|||||||
collist = ('UUID',
|
collist = ('UUID',
|
||||||
'Name',
|
'Name',
|
||||||
'State',
|
'State',
|
||||||
|
'Owner',
|
||||||
'Node UUID',
|
'Node UUID',
|
||||||
'Last Error',
|
'Last Error',
|
||||||
'Resource Class',
|
'Resource Class',
|
||||||
@@ -401,6 +454,7 @@ class TestBaremetalAllocationList(TestBaremetalAllocation):
|
|||||||
datalist = ((baremetal_fakes.baremetal_uuid,
|
datalist = ((baremetal_fakes.baremetal_uuid,
|
||||||
baremetal_fakes.baremetal_name,
|
baremetal_fakes.baremetal_name,
|
||||||
baremetal_fakes.baremetal_allocation_state,
|
baremetal_fakes.baremetal_allocation_state,
|
||||||
|
'',
|
||||||
baremetal_fakes.baremetal_uuid,
|
baremetal_fakes.baremetal_uuid,
|
||||||
'',
|
'',
|
||||||
baremetal_fakes.baremetal_resource_class,
|
baremetal_fakes.baremetal_resource_class,
|
||||||
|
@@ -21,6 +21,7 @@ import ironicclient.v1.allocation
|
|||||||
|
|
||||||
ALLOCATION = {'uuid': '11111111-2222-3333-4444-555555555555',
|
ALLOCATION = {'uuid': '11111111-2222-3333-4444-555555555555',
|
||||||
'name': 'Allocation-name',
|
'name': 'Allocation-name',
|
||||||
|
'owner': None,
|
||||||
'state': 'active',
|
'state': 'active',
|
||||||
'node_uuid': '66666666-7777-8888-9999-000000000000',
|
'node_uuid': '66666666-7777-8888-9999-000000000000',
|
||||||
'last_error': None,
|
'last_error': None,
|
||||||
@@ -31,6 +32,7 @@ ALLOCATION = {'uuid': '11111111-2222-3333-4444-555555555555',
|
|||||||
|
|
||||||
ALLOCATION2 = {'uuid': '55555555-4444-3333-2222-111111111111',
|
ALLOCATION2 = {'uuid': '55555555-4444-3333-2222-111111111111',
|
||||||
'name': 'Allocation2-name',
|
'name': 'Allocation2-name',
|
||||||
|
'owner': 'fake-owner',
|
||||||
'state': 'allocating',
|
'state': 'allocating',
|
||||||
'node_uuid': None,
|
'node_uuid': None,
|
||||||
'last_error': None,
|
'last_error': None,
|
||||||
@@ -73,6 +75,13 @@ fake_responses = {
|
|||||||
{"allocations": [ALLOCATION]},
|
{"allocations": [ALLOCATION]},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
'/v1/allocations/?owner=%s' % ALLOCATION2['owner']:
|
||||||
|
{
|
||||||
|
'GET': (
|
||||||
|
{},
|
||||||
|
{"allocations": [ALLOCATION2]},
|
||||||
|
),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_responses_pagination = {
|
fake_responses_pagination = {
|
||||||
@@ -150,6 +159,19 @@ class AllocationManagerTest(testtools.TestCase):
|
|||||||
self.assertEqual(expected_resp,
|
self.assertEqual(expected_resp,
|
||||||
self.api.responses['/v1/allocations']['GET'])
|
self.api.responses['/v1/allocations']['GET'])
|
||||||
|
|
||||||
|
def test_allocations_list_by_owner(self):
|
||||||
|
allocations = self.mgr.list(owner=ALLOCATION2['owner'])
|
||||||
|
expect = [
|
||||||
|
('GET', '/v1/allocations/?owner=%s' % ALLOCATION2['owner'], {},
|
||||||
|
None),
|
||||||
|
]
|
||||||
|
self.assertEqual(expect, self.api.calls)
|
||||||
|
self.assertEqual(1, len(allocations))
|
||||||
|
|
||||||
|
expected_resp = ({}, {"allocations": [ALLOCATION, ALLOCATION2]},)
|
||||||
|
self.assertEqual(expected_resp,
|
||||||
|
self.api.responses['/v1/allocations']['GET'])
|
||||||
|
|
||||||
def test_allocations_show(self):
|
def test_allocations_show(self):
|
||||||
allocation = self.mgr.get(ALLOCATION['uuid'])
|
allocation = self.mgr.get(ALLOCATION['uuid'])
|
||||||
expect = [
|
expect = [
|
||||||
@@ -158,6 +180,7 @@ class AllocationManagerTest(testtools.TestCase):
|
|||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(ALLOCATION['uuid'], allocation.uuid)
|
self.assertEqual(ALLOCATION['uuid'], allocation.uuid)
|
||||||
self.assertEqual(ALLOCATION['name'], allocation.name)
|
self.assertEqual(ALLOCATION['name'], allocation.name)
|
||||||
|
self.assertEqual(ALLOCATION['owner'], allocation.owner)
|
||||||
self.assertEqual(ALLOCATION['node_uuid'], allocation.node_uuid)
|
self.assertEqual(ALLOCATION['node_uuid'], allocation.node_uuid)
|
||||||
self.assertEqual(ALLOCATION['state'], allocation.state)
|
self.assertEqual(ALLOCATION['state'], allocation.state)
|
||||||
self.assertEqual(ALLOCATION['resource_class'],
|
self.assertEqual(ALLOCATION['resource_class'],
|
||||||
|
@@ -30,10 +30,11 @@ class AllocationManager(base.CreateManager):
|
|||||||
resource_class = Allocation
|
resource_class = Allocation
|
||||||
_resource_name = 'allocations'
|
_resource_name = 'allocations'
|
||||||
_creation_attributes = ['extra', 'name', 'resource_class', 'uuid',
|
_creation_attributes = ['extra', 'name', 'resource_class', 'uuid',
|
||||||
'traits', 'candidate_nodes', 'node']
|
'traits', 'candidate_nodes', 'node', 'owner']
|
||||||
|
|
||||||
def list(self, resource_class=None, state=None, node=None, limit=None,
|
def list(self, resource_class=None, state=None, node=None, limit=None,
|
||||||
marker=None, sort_key=None, sort_dir=None, fields=None):
|
marker=None, sort_key=None, sort_dir=None, fields=None,
|
||||||
|
owner=None):
|
||||||
"""Retrieve a list of allocations.
|
"""Retrieve a list of allocations.
|
||||||
|
|
||||||
:param resource_class: Optional, get allocations with this resource
|
:param resource_class: Optional, get allocations with this resource
|
||||||
@@ -60,6 +61,7 @@ class AllocationManager(base.CreateManager):
|
|||||||
|
|
||||||
:param fields: Optional, a list with a specified set of fields
|
:param fields: Optional, a list with a specified set of fields
|
||||||
of the resource to be returned.
|
of the resource to be returned.
|
||||||
|
:param owner: Optional, project that owns the allocation.
|
||||||
|
|
||||||
:returns: A list of allocations.
|
:returns: A list of allocations.
|
||||||
:raises: InvalidAttribute if a subset of fields is requested with
|
:raises: InvalidAttribute if a subset of fields is requested with
|
||||||
@@ -72,7 +74,8 @@ class AllocationManager(base.CreateManager):
|
|||||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir,
|
filters = utils.common_filters(marker, limit, sort_key, sort_dir,
|
||||||
fields)
|
fields)
|
||||||
for name, value in [('resource_class', resource_class),
|
for name, value in [('resource_class', resource_class),
|
||||||
('state', state), ('node', node)]:
|
('state', state), ('node', node),
|
||||||
|
('owner', owner)]:
|
||||||
if value is not None:
|
if value is not None:
|
||||||
filters.append('%s=%s' % (name, value))
|
filters.append('%s=%s' % (name, value))
|
||||||
|
|
||||||
|
@@ -493,6 +493,7 @@ ALLOCATION_DETAILED_RESOURCE = Resource(
|
|||||||
['uuid',
|
['uuid',
|
||||||
'name',
|
'name',
|
||||||
'state',
|
'state',
|
||||||
|
'owner',
|
||||||
'node_uuid',
|
'node_uuid',
|
||||||
'last_error',
|
'last_error',
|
||||||
'resource_class',
|
'resource_class',
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds support to create an allocation with an ``owner``,
|
||||||
|
as well as display it. Introduced in API 1.60.
|
Reference in New Issue
Block a user