From a64370701e8acff6aa28da87ccebd72664a48d34 Mon Sep 17 00:00:00 2001 From: Tzu-Mainn Chen Date: Wed, 15 Jan 2020 19:01:57 +0000 Subject: [PATCH] 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 --- ironicclient/common/http.py | 2 +- ironicclient/osc/v1/baremetal_allocation.py | 12 ++++- ironicclient/tests/unit/osc/v1/fakes.py | 1 + .../unit/osc/v1/test_baremetal_allocation.py | 54 +++++++++++++++++++ ironicclient/tests/unit/v1/test_allocation.py | 23 ++++++++ ironicclient/v1/allocation.py | 9 ++-- ironicclient/v1/resource_fields.py | 1 + ...add-allocation-owner-0c6daad4ebfea5e6.yaml | 5 ++ 8 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/add-allocation-owner-0c6daad4ebfea5e6.yaml diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py index bf41d2f4d..a756961b6 100644 --- a/ironicclient/common/http.py +++ b/ironicclient/common/http.py @@ -40,7 +40,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 = 58 +LAST_KNOWN_API_VERSION = 60 LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION) LOG = logging.getLogger(__name__) diff --git a/ironicclient/osc/v1/baremetal_allocation.py b/ironicclient/osc/v1/baremetal_allocation.py index e23517fc0..5e1d37ff3 100644 --- a/ironicclient/osc/v1/baremetal_allocation.py +++ b/ironicclient/osc/v1/baremetal_allocation.py @@ -56,6 +56,10 @@ class CreateBaremetalAllocation(command.ShowOne): '--uuid', dest='uuid', help=_('UUID of the allocation.')) + parser.add_argument( + '--owner', + dest='owner', + help=_('Owner of the allocation.')) parser.add_argument( '--extra', metavar="", @@ -91,7 +95,7 @@ class CreateBaremetalAllocation(command.ShowOne): _('--resource-class is required except when --node is used')) 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() if k in field_list and v is not None) @@ -182,6 +186,10 @@ class ListBaremetalAllocation(command.Lister): '--state', metavar='', help=_("Only list allocations in this state.")) + parser.add_argument( + '--owner', + metavar='', + help=_("Only list allocations with this owner.")) # NOTE(dtantsur): the allocation API does not expose the 'detail' flag, # but some fields are inconvenient to display in a table, so we emulate @@ -216,7 +224,7 @@ class ListBaremetalAllocation(command.Lister): parsed_args.limit) params['limit'] = parsed_args.limit 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) if value is not None: params[field] = value diff --git a/ironicclient/tests/unit/osc/v1/fakes.py b/ironicclient/tests/unit/osc/v1/fakes.py index 419b7091b..b226c543f 100644 --- a/ironicclient/tests/unit/osc/v1/fakes.py +++ b/ironicclient/tests/unit/osc/v1/fakes.py @@ -34,6 +34,7 @@ BAREMETAL_CHASSIS = { baremetal_uuid = 'xxx-xxxxxx-xxxx' baremetal_name = 'fake name' +baremetal_owner = 'fake-owner' baremetal_instance_uuid = 'yyy-yyyyyy-yyyy' baremetal_power_state = None baremetal_provision_state = None diff --git a/ironicclient/tests/unit/osc/v1/test_baremetal_allocation.py b/ironicclient/tests/unit/osc/v1/test_baremetal_allocation.py index ef9990d54..56a3c7f4d 100644 --- a/ironicclient/tests/unit/osc/v1/test_baremetal_allocation.py +++ b/ironicclient/tests/unit/osc/v1/test_baremetal_allocation.py @@ -174,6 +174,28 @@ class TestCreateBaremetalAllocation(TestBaremetalAllocation): 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): arglist = [] verifylist = [] @@ -344,6 +366,36 @@ class TestBaremetalAllocationList(TestBaremetalAllocation): baremetal_fakes.baremetal_uuid),) 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): arglist = ['--state', baremetal_fakes.baremetal_allocation_state] verifylist = [('state', baremetal_fakes.baremetal_allocation_state)] @@ -388,6 +440,7 @@ class TestBaremetalAllocationList(TestBaremetalAllocation): collist = ('UUID', 'Name', 'State', + 'Owner', 'Node UUID', 'Last Error', 'Resource Class', @@ -401,6 +454,7 @@ class TestBaremetalAllocationList(TestBaremetalAllocation): datalist = ((baremetal_fakes.baremetal_uuid, baremetal_fakes.baremetal_name, baremetal_fakes.baremetal_allocation_state, + '', baremetal_fakes.baremetal_uuid, '', baremetal_fakes.baremetal_resource_class, diff --git a/ironicclient/tests/unit/v1/test_allocation.py b/ironicclient/tests/unit/v1/test_allocation.py index e1fa8b506..c80f2ad33 100644 --- a/ironicclient/tests/unit/v1/test_allocation.py +++ b/ironicclient/tests/unit/v1/test_allocation.py @@ -21,6 +21,7 @@ import ironicclient.v1.allocation ALLOCATION = {'uuid': '11111111-2222-3333-4444-555555555555', 'name': 'Allocation-name', + 'owner': None, 'state': 'active', 'node_uuid': '66666666-7777-8888-9999-000000000000', 'last_error': None, @@ -31,6 +32,7 @@ ALLOCATION = {'uuid': '11111111-2222-3333-4444-555555555555', ALLOCATION2 = {'uuid': '55555555-4444-3333-2222-111111111111', 'name': 'Allocation2-name', + 'owner': 'fake-owner', 'state': 'allocating', 'node_uuid': None, 'last_error': None, @@ -73,6 +75,13 @@ fake_responses = { {"allocations": [ALLOCATION]}, ), }, + '/v1/allocations/?owner=%s' % ALLOCATION2['owner']: + { + 'GET': ( + {}, + {"allocations": [ALLOCATION2]}, + ), + }, } fake_responses_pagination = { @@ -150,6 +159,19 @@ class AllocationManagerTest(testtools.TestCase): self.assertEqual(expected_resp, 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): allocation = self.mgr.get(ALLOCATION['uuid']) expect = [ @@ -158,6 +180,7 @@ class AllocationManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertEqual(ALLOCATION['uuid'], allocation.uuid) self.assertEqual(ALLOCATION['name'], allocation.name) + self.assertEqual(ALLOCATION['owner'], allocation.owner) self.assertEqual(ALLOCATION['node_uuid'], allocation.node_uuid) self.assertEqual(ALLOCATION['state'], allocation.state) self.assertEqual(ALLOCATION['resource_class'], diff --git a/ironicclient/v1/allocation.py b/ironicclient/v1/allocation.py index f835828d3..9a87e7d4f 100644 --- a/ironicclient/v1/allocation.py +++ b/ironicclient/v1/allocation.py @@ -30,10 +30,11 @@ class AllocationManager(base.CreateManager): resource_class = Allocation _resource_name = 'allocations' _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, - 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. :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 of the resource to be returned. + :param owner: Optional, project that owns the allocation. :returns: A list of allocations. :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, fields) for name, value in [('resource_class', resource_class), - ('state', state), ('node', node)]: + ('state', state), ('node', node), + ('owner', owner)]: if value is not None: filters.append('%s=%s' % (name, value)) diff --git a/ironicclient/v1/resource_fields.py b/ironicclient/v1/resource_fields.py index 38b6cc6c1..a555a457e 100644 --- a/ironicclient/v1/resource_fields.py +++ b/ironicclient/v1/resource_fields.py @@ -493,6 +493,7 @@ ALLOCATION_DETAILED_RESOURCE = Resource( ['uuid', 'name', 'state', + 'owner', 'node_uuid', 'last_error', 'resource_class', diff --git a/releasenotes/notes/add-allocation-owner-0c6daad4ebfea5e6.yaml b/releasenotes/notes/add-allocation-owner-0c6daad4ebfea5e6.yaml new file mode 100644 index 000000000..8b4164b0b --- /dev/null +++ b/releasenotes/notes/add-allocation-owner-0c6daad4ebfea5e6.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support to create an allocation with an ``owner``, + as well as display it. Introduced in API 1.60.