placement: add claim_resources() to report client

Adds a claim_resources() method to the scheduler report client that
takes an allocation request body as a JSON object, a consumer, user,
and project ID and creates allocations in the placement API for the
consumer.

Change-Id: Ic1390662f78b293e93a17f6b79dcf0c2f42941e3
blueprint: placement-claims
blueprint: placement-allocation-requests
This commit is contained in:
Jay Pipes 2017-07-10 20:13:09 -04:00
parent 48268c73e3
commit aa29fe7fcf
2 changed files with 95 additions and 0 deletions

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import functools
import math
import re
@ -886,6 +887,32 @@ class SchedulerReportClient(object):
LOG.info(_LI('Submitted allocation for instance'),
instance=instance)
def claim_resources(self, consumer_uuid, alloc_request, project_id,
user_id):
"""Creates allocation records for the supplied instance UUID against
the supplied resource providers.
:param consumer_uuid: The instance's UUID.
:param alloc_request: The JSON body of the request to make to the
placement's PUT /allocations API
:param project_id: The project_id associated with the allocations.
:param user_id: The user_id associated with the allocations.
:returns: True if the allocations were created, False otherwise.
"""
url = '/allocations/%s' % consumer_uuid
payload = copy.deepcopy(alloc_request)
payload['project_id'] = project_id
payload['user_id'] = user_id
r = self.put(url, payload, version='1.10')
if r.status_code != 204:
LOG.warning(
'Unable to submit allocation for instance '
'%(uuid)s (%(code)i %(text)s)',
{'uuid': consumer_uuid,
'code': r.status_code,
'text': r.text})
return r.status_code == 204
@safe_connect
def put_allocations(self, rp_uuid, consumer_uuid, alloc_data, project_id,
user_id):

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from keystoneauth1 import exceptions as ks_exc
import mock
import six
@ -233,6 +235,72 @@ class TestPutAllocations(SchedulerReportClientTestCase):
log_msg = mock_warn.call_args[0][0]
self.assertIn("Unable to submit allocation for instance", log_msg)
def test_claim_resources_success(self):
resp_mock = mock.Mock(status_code=204)
self.ks_sess_mock.put.return_value = resp_mock
consumer_uuid = uuids.consumer_uuid
alloc_req = {
'allocations': {
'resource_provider': {
'uuid': uuids.cn1,
},
'resources': {
'VCPU': 1,
'MEMORY_MB': 1024,
},
},
}
project_id = uuids.project_id
user_id = uuids.user_id
res = self.client.claim_resources(consumer_uuid, alloc_req, project_id,
user_id)
expected_url = "/allocations/%s" % consumer_uuid
expected_payload = copy.deepcopy(alloc_req)
expected_payload['project_id'] = project_id
expected_payload['user_id'] = user_id
self.ks_sess_mock.put.assert_called_once_with(
expected_url, endpoint_filter=mock.ANY,
headers={'OpenStack-API-Version': 'placement 1.10'},
json=expected_payload, raise_exc=False)
self.assertTrue(res)
@mock.patch.object(report.LOG, 'warning')
def test_claim_resources_failure(self, mock_log):
resp_mock = mock.Mock(status_code=409)
self.ks_sess_mock.put.return_value = resp_mock
consumer_uuid = uuids.consumer_uuid
alloc_req = {
'allocations': {
'resource_provider': {
'uuid': uuids.cn1,
},
'resources': {
'VCPU': 1,
'MEMORY_MB': 1024,
},
},
}
project_id = uuids.project_id
user_id = uuids.user_id
res = self.client.claim_resources(consumer_uuid, alloc_req, project_id,
user_id)
expected_url = "/allocations/%s" % consumer_uuid
expected_payload = copy.deepcopy(alloc_req)
expected_payload['project_id'] = project_id
expected_payload['user_id'] = user_id
self.ks_sess_mock.put.assert_called_once_with(
expected_url, endpoint_filter=mock.ANY,
headers={'OpenStack-API-Version': 'placement 1.10'},
json=expected_payload, raise_exc=False)
self.assertFalse(res)
self.assertTrue(mock_log.called)
class TestProviderOperations(SchedulerReportClientTestCase):
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'