placement: update client to set parent provider

In preparation for future commits which will add child resource
providers for SR-IOV physical functions, this patch updates the
scheduler report client to use the new 1.12 microversion of the
placement API and set/get the 'parent_provider_uuid' attribute of the
resource provider created during calls to '_create_resource_provider()'

Change-Id: I2f367b06e683ed7c815dd9e0536a46e5f0a27e6c
blueprint: nested-resource-providers
Co-Authored-By: Moshe Levi <moshele@mellanox.com>
Co-Authored-By: Stephen Finucane <sfinucan@redhat.com>
Grenade fix for placement restart:
Depends-On: I7f2158aeaef82a47e11c6e29675e542023fff4be
This commit is contained in:
Jay Pipes 2016-10-12 19:05:17 -04:00 committed by Eric Fried
parent 109f21f3c8
commit a0ff3e2936
2 changed files with 53 additions and 15 deletions

View File

@ -42,6 +42,7 @@ WARN_EVERY = 10
PLACEMENT_CLIENT_SEMAPHORE = 'placement_client'
# Number of seconds between attempts to update the aggregate map
AGGREGATE_REFRESH = 300
NESTED_PROVIDER_API_VERSION = '1.14'
def warn_limit(self, msg):
@ -400,7 +401,8 @@ class SchedulerReportClient(object):
such resource provider could be found.
:raise: ResourceProviderRetrievalFailed on error.
"""
resp = self.get("/resource_providers/%s" % uuid)
resp = self.get("/resource_providers/%s" % uuid,
version=NESTED_PROVIDER_API_VERSION)
if resp.status_code == 200:
data = resp.json()
return data
@ -421,11 +423,13 @@ class SchedulerReportClient(object):
raise exception.ResourceProviderRetrievalFailed(uuid=uuid)
@safe_connect
def _create_resource_provider(self, uuid, name):
def _create_resource_provider(self, uuid, name,
parent_provider_uuid=None):
"""Calls the placement API to create a new resource provider record.
:param uuid: UUID of the new resource provider
:param name: Name of the resource provider
:param parent_provider_uuid: Optional UUID of the immediate parent
:return: A dict of resource provider information object representing
the newly-created resource provider.
:raise: ResourceProviderCreationFailed or
@ -436,7 +440,10 @@ class SchedulerReportClient(object):
'uuid': uuid,
'name': name,
}
resp = self.post(url, payload)
if parent_provider_uuid is not None:
payload['parent_provider_uuid'] = parent_provider_uuid
resp = self.post(url, payload, version=NESTED_PROVIDER_API_VERSION)
placement_req_id = get_placement_request_id(resp)
if resp.status_code == 201:
msg = ("[%(placement_req_id)s] Created resource provider record "
@ -452,6 +459,7 @@ class SchedulerReportClient(object):
uuid=uuid,
name=name,
generation=0,
parent_provider_uuid=parent_provider_uuid,
)
# TODO(efried): Push error codes from placement, and use 'em.

View File

@ -1252,6 +1252,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
'uuid': uuid,
'name': uuid,
'generation': 42,
'parent_provider_uuid': None,
}
resp_mock.json.return_value = json_data
self.ks_adap_mock.get.return_value = resp_mock
@ -1262,10 +1263,11 @@ class TestProviderOperations(SchedulerReportClientTestCase):
uuid=uuid,
name=uuid,
generation=42,
parent_provider_uuid=None,
)
expected_url = '/resource_providers/' + uuid
self.ks_adap_mock.get.assert_called_once_with(
expected_url, raise_exc=False, microversion=None)
expected_url, raise_exc=False, microversion='1.14')
self.assertEqual(expected_provider_dict, result)
def test_get_resource_provider_not_found(self):
@ -1279,7 +1281,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
expected_url = '/resource_providers/' + uuid
self.ks_adap_mock.get.assert_called_once_with(
expected_url, raise_exc=False, microversion=None)
expected_url, raise_exc=False, microversion='1.14')
self.assertIsNone(result)
@mock.patch.object(report.LOG, 'error')
@ -1299,38 +1301,66 @@ class TestProviderOperations(SchedulerReportClientTestCase):
expected_url = '/resource_providers/' + uuid
self.ks_adap_mock.get.assert_called_once_with(
expected_url, raise_exc=False, microversion=None)
# A 503 Service Unavailable should trigger an error log
# that includes the placement request id and return None
expected_url, raise_exc=False, microversion='1.14')
# A 503 Service Unavailable should trigger an error log that
# includes the placement request id and return None
# from _get_resource_provider()
self.assertTrue(logging_mock.called)
self.assertEqual(uuids.request_id,
logging_mock.call_args[0][1]['placement_req_id'])
def test_create_resource_provider(self):
# Ensure _create_resource_provider() returns a dict of resource
# provider constructed after creating a resource provider record in the
# placement API
"""Test that _create_resource_provider() sends a dict of resource
provider information without a parent provider UUID.
"""
uuid = uuids.compute_node
name = 'computehost'
resp_mock = mock.Mock(status_code=201)
self.ks_adap_mock.post.return_value = resp_mock
result = self.client._create_resource_provider(uuid, name)
self.client._create_resource_provider(uuid, name)
expected_payload = {
'uuid': uuid,
'name': name,
}
expected_url = '/resource_providers'
self.ks_adap_mock.post.assert_called_once_with(
expected_url, json=expected_payload, raise_exc=False,
microversion='1.14')
def test_create_resource_provider_with_parent(self):
"""Test that when specifying a parent provider UUID, that the
parent_provider_uuid part of the payload is properly specified.
"""
parent_uuid = uuids.parent
uuid = uuids.compute_node
name = 'computehost'
resp_mock = mock.Mock(status_code=201)
self.ks_adap_mock.post.return_value = resp_mock
result = self.client._create_resource_provider(
uuid,
name,
parent_provider_uuid=parent_uuid,
)
expected_payload = {
'uuid': uuid,
'name': name,
'parent_provider_uuid': parent_uuid,
}
expected_provider_dict = dict(
uuid=uuid,
name=name,
generation=0,
parent_provider_uuid=parent_uuid,
)
expected_url = '/resource_providers'
self.ks_adap_mock.post.assert_called_once_with(
expected_url, json=expected_payload, raise_exc=False,
microversion=None)
microversion='1.14')
self.assertEqual(expected_provider_dict, result)
@mock.patch.object(report.LOG, 'info')
@ -1361,7 +1391,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
expected_url = '/resource_providers'
self.ks_adap_mock.post.assert_called_once_with(
expected_url, json=expected_payload, raise_exc=False,
microversion=None)
microversion='1.14')
self.assertEqual(mock.sentinel.get_rp, result)
# The 409 response will produce a message to the info log.
self.assertTrue(logging_mock.called)
@ -1403,7 +1433,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
expected_url = '/resource_providers'
self.ks_adap_mock.post.assert_called_once_with(
expected_url, json=expected_payload, raise_exc=False,
microversion=None)
microversion='1.14')
# A 503 Service Unavailable should log an error that
# includes the placement request id and
# _create_resource_provider() should return None