Placement client: ensure_resource_provider
All other API resources (ie. traits, resource_provider_traits and resource_provider_inventories) we need to report on for minimum guaranteed bandwidth have update methods that can be called in one go, either because they have update-or-create or update-overrides-all semantics. Here we add the 'ensure_resource_provider' method so resource providers also have a similarly simple way of being kept in sync. We also add 'update_resource_provider' as a pre-requisite. On the side we also fix a little, silent unit test type error. Change-Id: Ib615ceeb323970d179ffb3dee14e52cb40e73ae7 Partial-Bug: #1578989 See-Also: https://review.openstack.org/502306 (nova spec) See-Also: https://review.openstack.org/508149 (neutron spec)
This commit is contained in:
parent
5aa2847367
commit
203f4f0696
@ -128,13 +128,56 @@ class PlacementAPIClient(object):
|
||||
def create_resource_provider(self, resource_provider):
|
||||
"""Create a resource provider.
|
||||
|
||||
:param resource_provider: The resource provider. A dict with the name
|
||||
(required) and the uuid (required).
|
||||
:param resource_provider: The resource provider. A dict with
|
||||
the uuid (required),
|
||||
the name (required) and
|
||||
the parent_provider_uuid (optional).
|
||||
:returns: The resource provider created.
|
||||
"""
|
||||
url = '/resource_providers'
|
||||
return self._post(url, resource_provider).json()
|
||||
|
||||
@_check_placement_api_available
|
||||
def update_resource_provider(self, resource_provider):
|
||||
"""Update the resource provider identified by uuid.
|
||||
|
||||
:param resource_provider: The resource provider. A dict with
|
||||
the uuid (required),
|
||||
the name (required) and
|
||||
the parent_provider_uuid (optional).
|
||||
:returns: The updated resource provider.
|
||||
"""
|
||||
url = '/resource_providers/%s' % resource_provider['uuid']
|
||||
# update does not tolerate if the uuid is repeated in the body
|
||||
update_body = resource_provider.copy()
|
||||
update_body.pop('uuid')
|
||||
try:
|
||||
return self._put(url, update_body).json()
|
||||
except ks_exc.NotFound:
|
||||
raise n_exc.PlacementResourceProviderNotFound(
|
||||
resource_provider=resource_provider['uuid'])
|
||||
except ks_exc.Conflict:
|
||||
raise n_exc.PlacementResourceProviderNameNotUnique(
|
||||
name=resource_provider['name'])
|
||||
|
||||
@_check_placement_api_available
|
||||
def ensure_resource_provider(self, resource_provider):
|
||||
"""Ensure a resource provider exists by updating or creating it.
|
||||
|
||||
:param resource_provider: The resource provider. A dict with
|
||||
the uuid (required),
|
||||
the name (required) and
|
||||
the parent_provider_uuid (optional).
|
||||
:returns: The Resource Provider updated or created.
|
||||
|
||||
Beware, this is not an atomic operation of the API.
|
||||
"""
|
||||
try:
|
||||
return self.update_resource_provider(
|
||||
resource_provider=resource_provider)
|
||||
except n_exc.PlacementResourceProviderNotFound:
|
||||
return self.create_resource_provider(resource_provider)
|
||||
|
||||
@_check_placement_api_available
|
||||
def delete_resource_provider(self, resource_provider_uuid):
|
||||
"""Delete a resource provider.
|
||||
|
@ -60,3 +60,8 @@ class PlacementResourceClassNotFound(exceptions.NotFound):
|
||||
class PlacementAPIVersionIncorrect(exceptions.NotFound):
|
||||
message = _("Placement API version %(current_version)s, do not meet the"
|
||||
"needed version %(needed_version)s.")
|
||||
|
||||
|
||||
class PlacementResourceProviderNameNotUnique(exceptions.Conflict):
|
||||
message = _("Another resource provider exists with the provided name: "
|
||||
"%(name)s.")
|
||||
|
@ -24,6 +24,11 @@ from neutron_lib.tests import _base as base
|
||||
|
||||
|
||||
RESOURCE_PROVIDER_UUID = uuidutils.generate_uuid()
|
||||
RESOURCE_PROVIDER_NAME = 'resource_provider_name'
|
||||
RESOURCE_PROVIDER = {
|
||||
'uuid': RESOURCE_PROVIDER_UUID,
|
||||
'name': RESOURCE_PROVIDER_NAME,
|
||||
}
|
||||
RESOURCE_PROVIDER_GENERATION = 1
|
||||
RESOURCE_CLASS_NAME = 'resource_class_name'
|
||||
TRAIT_NAME = 'trait_name'
|
||||
@ -49,10 +54,38 @@ class TestPlacementAPIClient(base.BaseTestCase):
|
||||
|
||||
def test_create_resource_provider(self):
|
||||
self.placement_api_client.create_resource_provider(
|
||||
RESOURCE_PROVIDER_UUID)
|
||||
RESOURCE_PROVIDER)
|
||||
self.placement_fixture.mock_post.assert_called_once_with(
|
||||
'/resource_providers',
|
||||
RESOURCE_PROVIDER_UUID
|
||||
RESOURCE_PROVIDER
|
||||
)
|
||||
|
||||
def test_update_resource_provider(self):
|
||||
self.placement_api_client.update_resource_provider(
|
||||
RESOURCE_PROVIDER)
|
||||
self.placement_fixture.mock_put.assert_called_once_with(
|
||||
'/resource_providers/%s' % RESOURCE_PROVIDER_UUID,
|
||||
{'name': RESOURCE_PROVIDER_NAME}
|
||||
)
|
||||
|
||||
def test_ensure_update_resource_provider(self):
|
||||
self.placement_api_client.ensure_resource_provider(
|
||||
RESOURCE_PROVIDER)
|
||||
self.placement_fixture.mock_put.assert_called_once_with(
|
||||
'/resource_providers/%s' % RESOURCE_PROVIDER_UUID,
|
||||
{'name': RESOURCE_PROVIDER_NAME}
|
||||
)
|
||||
self.placement_fixture.mock_post.assert_not_called()
|
||||
|
||||
def test_ensure_create_resource_provider(self):
|
||||
self.placement_fixture.mock_put.side_effect = \
|
||||
n_exc.PlacementResourceProviderNotFound(
|
||||
resource_provider=RESOURCE_PROVIDER_UUID)
|
||||
self.placement_api_client.ensure_resource_provider(
|
||||
RESOURCE_PROVIDER)
|
||||
self.placement_fixture.mock_post.assert_called_once_with(
|
||||
'/resource_providers',
|
||||
RESOURCE_PROVIDER
|
||||
)
|
||||
|
||||
def test_delete_resource_provider(self):
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
New methods available in Placement client:
|
||||
``update_resource_provider`` and ``ensure_resource_provider``.
|
Loading…
Reference in New Issue
Block a user