Add support for microversion 1.38 consumer types
Story: 2005473 Task: 42878 Depends-On: https://review.opendev.org/c/openstack/placement/+/679486 Change-Id: I1b7d7095e62dc80191ff3e199959fb4d7df6f68e
This commit is contained in:
parent
b0a74d094d
commit
5e38a59317
|
@ -62,6 +62,11 @@ class SetAllocation(command.Lister, version.CheckerMixin):
|
|||
|
||||
Starting with ``--os-placement-api-version 1.28`` a consumer generation is
|
||||
used which facilitates safe concurrent modification of an allocation.
|
||||
|
||||
Starting with ``--os-placement-api-version 1.38`` it is required to specify
|
||||
``--consumer-type`` to set allocations. It is helpful to provide a
|
||||
``--consumer-type`` when setting allocations so that resource usages can be
|
||||
filtered on consumer types.
|
||||
"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
|
@ -97,6 +102,14 @@ class SetAllocation(command.Lister, version.CheckerMixin):
|
|||
'``--os-placement-api-version 1.8``.',
|
||||
required=self.compare_version(version.ge('1.8'))
|
||||
)
|
||||
parser.add_argument(
|
||||
'--consumer-type',
|
||||
metavar='consumer_type',
|
||||
help='The type of the consumer. '
|
||||
'This option is required starting from '
|
||||
'``--os-placement-api-version 1.38``.',
|
||||
required=self.compare_version(version.ge('1.38'))
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
@ -136,18 +149,28 @@ class SetAllocation(command.Lister, version.CheckerMixin):
|
|||
self.log.warning('--project-id and --user-id options do not '
|
||||
'affect allocation for '
|
||||
'--os-placement-api-version less than 1.8')
|
||||
if self.compare_version(version.ge('1.38')):
|
||||
payload['consumer_type'] = parsed_args.consumer_type
|
||||
elif parsed_args.consumer_type:
|
||||
self.log.warning('--consumer-type option does not affect '
|
||||
'allocation for --os-placement-api-version less '
|
||||
'than 1.38')
|
||||
http.request('PUT', url, json=payload)
|
||||
resp = http.request('GET', url).json()
|
||||
per_provider = resp['allocations'].items()
|
||||
props = {}
|
||||
|
||||
fields = ('resource_provider', 'generation', 'resources')
|
||||
allocs = [dict(resource_provider=k, **v) for k, v in per_provider]
|
||||
if self.compare_version(version.ge('1.12')):
|
||||
fields += ('project_id', 'user_id')
|
||||
[alloc.update(project_id=resp['project_id'],
|
||||
user_id=resp['user_id'])
|
||||
for alloc in allocs]
|
||||
props['project_id'] = resp['project_id']
|
||||
props['user_id'] = resp['user_id']
|
||||
if self.compare_version(version.ge('1.38')):
|
||||
fields += ('consumer_type',)
|
||||
props['consumer_type'] = resp['consumer_type']
|
||||
|
||||
allocs = [dict(resource_provider=k, **props, **v)
|
||||
for k, v in per_provider]
|
||||
rows = (utils.get_dict_properties(a, fields) for a in allocs)
|
||||
return fields, rows
|
||||
|
||||
|
@ -262,11 +285,16 @@ class UnsetAllocation(command.Lister, version.CheckerMixin):
|
|||
|
||||
resp = http.request('GET', url).json()
|
||||
per_provider = resp['allocations'].items()
|
||||
props = {}
|
||||
|
||||
fields = ('resource_provider', 'generation', 'resources',
|
||||
'project_id', 'user_id')
|
||||
if self.compare_version(version.ge('1.38')):
|
||||
fields += ('consumer_type',)
|
||||
props['consumer_type'] = resp['consumer_type']
|
||||
allocs = [dict(project_id=resp['project_id'], user_id=resp['user_id'],
|
||||
resource_provider=k, **v) for k, v in per_provider]
|
||||
resource_provider=k, **props, **v)
|
||||
for k, v in per_provider]
|
||||
rows = (utils.get_dict_properties(a, fields) for a in allocs)
|
||||
return fields, rows
|
||||
|
||||
|
@ -277,6 +305,9 @@ class ShowAllocation(command.Lister, version.CheckerMixin):
|
|||
Starting with ``--os-placement-api-version 1.12`` the API response contains
|
||||
the ``project_id`` and ``user_id`` of allocations which also appears in the
|
||||
CLI output.
|
||||
|
||||
Starting with ``--os-placement-api-version 1.38`` the API response contains
|
||||
the ``consumer_type`` of consumer which also appears in the CLI output.
|
||||
"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
|
@ -296,18 +327,19 @@ class ShowAllocation(command.Lister, version.CheckerMixin):
|
|||
url = BASE_URL + '/' + parsed_args.uuid
|
||||
resp = http.request('GET', url).json()
|
||||
per_provider = resp['allocations'].items()
|
||||
if self.compare_version(version.ge('1.12')):
|
||||
allocs = [dict(
|
||||
resource_provider=k,
|
||||
project_id=resp['project_id'],
|
||||
user_id=resp['user_id'],
|
||||
**v) for k, v in per_provider]
|
||||
else:
|
||||
allocs = [dict(resource_provider=k, **v) for k, v in per_provider]
|
||||
props = {}
|
||||
|
||||
fields = ('resource_provider', 'generation', 'resources')
|
||||
if self.compare_version(version.ge('1.12')):
|
||||
fields += ('project_id', 'user_id')
|
||||
props['project_id'] = resp['project_id']
|
||||
props['user_id'] = resp['user_id']
|
||||
if self.compare_version(version.ge('1.38')):
|
||||
fields += ('consumer_type',)
|
||||
props['consumer_type'] = resp['consumer_type']
|
||||
|
||||
allocs = [dict(resource_provider=k, **props, **v)
|
||||
for k, v in per_provider]
|
||||
|
||||
rows = (utils.get_dict_properties(a, fields) for a in allocs)
|
||||
return fields, rows
|
||||
|
|
|
@ -236,7 +236,8 @@ class BaseTestCase(base.BaseTestCase):
|
|||
|
||||
def resource_allocation_set(self, consumer_uuid, allocations,
|
||||
project_id=None, user_id=None,
|
||||
use_json=True, may_print_to_stderr=False):
|
||||
consumer_type=None, use_json=True,
|
||||
may_print_to_stderr=False):
|
||||
cmd = 'resource provider allocation set {allocs} {uuid}'.format(
|
||||
uuid=consumer_uuid,
|
||||
allocs=' '.join('--allocation {}'.format(a) for a in allocations)
|
||||
|
@ -245,6 +246,8 @@ class BaseTestCase(base.BaseTestCase):
|
|||
cmd += ' --project-id %s' % project_id
|
||||
if user_id:
|
||||
cmd += ' --user-id %s' % user_id
|
||||
if consumer_type:
|
||||
cmd += ' --consumer-type %s' % consumer_type
|
||||
result = self.openstack(
|
||||
cmd, use_json=use_json, may_print_to_stderr=may_print_to_stderr)
|
||||
|
||||
|
|
|
@ -67,6 +67,23 @@ class TestAllocation(base.BaseTestCase):
|
|||
'--project-id and --user-id options do not affect allocation for '
|
||||
'--os-placement-api-version less than 1.8', warning)
|
||||
|
||||
# Test that specifying --consumer-type before microversion 1.38 does
|
||||
# not result in an error but display a warning.
|
||||
output, warning = self.resource_allocation_set(
|
||||
consumer_uuid,
|
||||
['rp={},VCPU=2'.format(self.rp1['uuid']),
|
||||
'rp={},MEMORY_MB=512'.format(self.rp1['uuid'])],
|
||||
consumer_type='fake-type', may_print_to_stderr=True)
|
||||
expected = [
|
||||
{'resource_provider': self.rp1['uuid'],
|
||||
'generation': 4,
|
||||
'resources': {'VCPU': 2, 'MEMORY_MB': 512}}
|
||||
]
|
||||
self.assertEqual(expected, output)
|
||||
self.assertIn(
|
||||
'--consumer-type option does not affect allocation for '
|
||||
'--os-placement-api-version less than 1.38', warning)
|
||||
|
||||
def test_allocation_create_empty(self):
|
||||
consumer_uuid = str(uuid.uuid4())
|
||||
|
||||
|
@ -208,6 +225,54 @@ class TestAllocation128(TestAllocation112):
|
|||
self.assertEqual(expected, updated_alloc)
|
||||
|
||||
|
||||
class TestAllocation138(TestAllocation128):
|
||||
"""Tests allocation set command with --os-placement-api-version 1.38.
|
||||
|
||||
The 1.38 microversion adds the consumer_type parameter to the
|
||||
GET and PUT /allocations/{consumer_id} APIs
|
||||
"""
|
||||
VERSION = '1.38'
|
||||
|
||||
def test_allocation_update(self):
|
||||
consumer_uuid = str(uuid.uuid4())
|
||||
project_uuid = str(uuid.uuid4())
|
||||
user_uuid = str(uuid.uuid4())
|
||||
# First create the initial set of allocations using rp1.
|
||||
created_alloc = self.resource_allocation_set(
|
||||
consumer_uuid,
|
||||
['rp={},VCPU=2'.format(self.rp1['uuid']),
|
||||
'rp={},MEMORY_MB=512'.format(self.rp1['uuid'])],
|
||||
project_id=project_uuid, user_id=user_uuid,
|
||||
consumer_type='INSTANCE'
|
||||
)
|
||||
retrieved_alloc = self.resource_allocation_show(consumer_uuid)
|
||||
|
||||
expected = [
|
||||
{'resource_provider': self.rp1['uuid'],
|
||||
'generation': 2,
|
||||
'project_id': project_uuid,
|
||||
'user_id': user_uuid,
|
||||
'resources': {'VCPU': 2, 'MEMORY_MB': 512},
|
||||
'consumer_type': 'INSTANCE'}
|
||||
]
|
||||
self.assertEqual(expected, created_alloc)
|
||||
self.assertEqual(expected, retrieved_alloc)
|
||||
# Now update the allocations which should use the consumer generation.
|
||||
updated_alloc = self.resource_allocation_set(
|
||||
consumer_uuid,
|
||||
['rp={},VCPU=4'.format(self.rp1['uuid']),
|
||||
'rp={},MEMORY_MB=1024'.format(self.rp1['uuid'])],
|
||||
project_id=project_uuid, user_id=user_uuid,
|
||||
consumer_type='MIGRATION'
|
||||
)
|
||||
expected[0].update({
|
||||
'generation': expected[0]['generation'] + 1,
|
||||
'resources': {'VCPU': 4, 'MEMORY_MB': 1024},
|
||||
'consumer_type': 'MIGRATION'
|
||||
})
|
||||
self.assertEqual(expected, updated_alloc)
|
||||
|
||||
|
||||
class TestAllocationUnsetOldVersion(base.BaseTestCase):
|
||||
|
||||
def test_invalid_version(self):
|
||||
|
|
|
@ -49,6 +49,7 @@ SUPPORTED_MICROVERSIONS = [
|
|||
'1.28', # Added for provider allocation (un)set (Ussuri)
|
||||
'1.29',
|
||||
'1.37', # unused
|
||||
'1.38', # Added for consumer types (Xena)
|
||||
]
|
||||
SUPPORTED_VERSIONS = SUPPORTED_MICROVERSIONS + NEGOTIATE_VERSIONS
|
||||
# The max microversion lower than which are all supported by this client.
|
||||
|
|
Loading…
Reference in New Issue