Merge "Add support for 1.19 microversion"

This commit is contained in:
Zuul 2019-04-12 15:46:59 +00:00 committed by Gerrit Code Review
commit 5417b38509
5 changed files with 137 additions and 4 deletions

View File

@ -11,6 +11,7 @@
# under the License.
from osc_lib.command import command
from osc_lib import exceptions
from osc_placement import version
@ -18,7 +19,7 @@ BASE_URL = '/resource_providers/{uuid}/aggregates'
FIELDS = ('uuid',)
class SetAggregate(command.Lister):
class SetAggregate(command.Lister, version.CheckerMixin):
"""Associate a list of aggregates with the resource provider.
@ -48,6 +49,17 @@ class SetAggregate(command.Lister):
default=[]
)
parser.add_argument(
'--generation',
metavar='<resource_provider_generation>',
type=int,
help='The generation of resource provider. Must match the server-'
'side generation of the resource provider or the operation '
'will fail.\n\n'
'This param requires at least '
'``--os-placement-api-version 1.19``.'
)
return parser
@version.check(version.ge('1.1'))
@ -55,7 +67,24 @@ class SetAggregate(command.Lister):
http = self.app.client_manager.placement
url = BASE_URL.format(uuid=parsed_args.uuid)
resp = http.request('PUT', url, json=parsed_args.aggregate).json()
aggregate = parsed_args.aggregate
generation = None
if 'generation' in parsed_args and parsed_args.generation is not None:
self.check_version(version.ge('1.19'))
generation = parsed_args.generation
if self.compare_version(version.lt('1.19')):
resp = http.request('PUT', url, json=aggregate).json()
# Microversion 1.19 and beyond a generation argument is
# required to write aggregates.
elif generation is not None:
data = {'aggregates': aggregate,
'resource_provider_generation': generation}
resp = http.request('PUT', url, json=data).json()
else:
raise exceptions.CommandError(
'A generation must be specified.')
return FIELDS, [[r] for r in resp['aggregates']]

View File

@ -220,10 +220,14 @@ class BaseTestCase(base.BaseTestCase):
return self.openstack('resource provider aggregate list ' + uuid,
use_json=True)
def resource_provider_aggregate_set(self, uuid, *aggregates):
def resource_provider_aggregate_set(self, uuid, *aggregates,
**kwargs):
generation = kwargs.get('generation')
cmd = 'resource provider aggregate set %s ' % uuid
cmd += ' '.join('--aggregate %s' % aggregate
for aggregate in aggregates)
if generation is not None:
cmd += ' --generation %s' % generation
return self.openstack(cmd, use_json=True)
def resource_class_list(self):

View File

@ -82,7 +82,98 @@ class TestAggregate(base.BaseTestCase):
def test_fail_if_incorrect_aggregate_uuid(self):
rp = self.resource_provider_create()
aggs = ['abc', 'efg']
self.assertCommandFailed(
"is not a 'uuid'",
self.resource_provider_aggregate_set,
rp['uuid'], 'abc', 'efg')
rp['uuid'], *aggs)
# In version 1.1 a generation is not allowed.
def test_fail_generation_arg_version_handling(self):
rp = self.resource_provider_create()
agg = str(uuid.uuid4())
self.assertCommandFailed(
"Operation or argument is not supported with version 1.1",
self.resource_provider_aggregate_set,
rp['uuid'], agg, generation=5)
class TestAggregate119(TestAggregate):
VERSION = '1.19'
def test_success_set_aggregate(self):
rp = self.resource_provider_create()
aggs = {str(uuid.uuid4()) for _ in range(2)}
rows = self.resource_provider_aggregate_set(
rp['uuid'], *aggs, generation=rp['generation'])
self.assertEqual(aggs, {r['uuid'] for r in rows})
rows = self.resource_provider_aggregate_list(rp['uuid'])
self.assertEqual(aggs, {r['uuid'] for r in rows})
self.resource_provider_aggregate_set(
rp['uuid'], *[], generation=rp['generation'] + 1)
rows = self.resource_provider_aggregate_list(rp['uuid'])
self.assertEqual([], rows)
def test_success_set_multiple_aggregates(self):
# each rp is associated with two aggregates
rps = [self.resource_provider_create() for _ in range(2)]
aggs = {str(uuid.uuid4()) for _ in range(2)}
for rp in rps:
rows = self.resource_provider_aggregate_set(
rp['uuid'], *aggs, generation=rp['generation'])
self.assertEqual(aggs, {r['uuid'] for r in rows})
# remove association for the first aggregate
rows = self.resource_provider_aggregate_set(
rps[0]['uuid'], *[], generation=rp['generation'] + 1)
self.assertEqual([], rows)
# second rp should be in aggregates
rows = self.resource_provider_aggregate_list(rps[1]['uuid'])
self.assertEqual(aggs, {r['uuid'] for r in rows})
# cleanup
rows = self.resource_provider_aggregate_set(
rps[1]['uuid'], *[], generation=rp['generation'] + 1)
self.assertEqual([], rows)
def test_success_set_large_number_aggregates(self):
rp = self.resource_provider_create()
aggs = {str(uuid.uuid4()) for _ in range(100)}
rows = self.resource_provider_aggregate_set(
rp['uuid'], *aggs, generation=rp['generation'])
self.assertEqual(aggs, {r['uuid'] for r in rows})
rows = self.resource_provider_aggregate_set(
rp['uuid'], *[], generation=rp['generation'] + 1)
self.assertEqual([], rows)
def test_fail_incorrect_generation(self):
rp = self.resource_provider_create()
agg = str(uuid.uuid4())
self.assertCommandFailed(
"Please update the generation and try again.",
self.resource_provider_aggregate_set,
rp['uuid'], agg, generation=99999)
def test_fail_generation_not_int(self):
rp = self.resource_provider_create()
agg = str(uuid.uuid4())
self.assertCommandFailed(
"invalid int value",
self.resource_provider_aggregate_set,
rp['uuid'], agg, generation='barney')
def test_fail_if_incorrect_aggregate_uuid(self):
rp = self.resource_provider_create()
aggs = ['abc', 'efg']
self.assertCommandFailed(
"is not a 'uuid'",
self.resource_provider_aggregate_set,
rp['uuid'], *aggs, generation=rp['generation'])
# In version 1.19 a generation is required.
def test_fail_generation_arg_version_handling(self):
rp = self.resource_provider_create()
agg = str(uuid.uuid4())
self.assertCommandFailed(
"A generation must be specified.",
self.resource_provider_aggregate_set,
rp['uuid'], agg)

View File

@ -34,6 +34,7 @@ SUPPORTED_VERSIONS = [
'1.16',
'1.17',
'1.18',
'1.19',
]

View File

@ -0,0 +1,8 @@
---
features:
- |
Support is added for the `1.19`_ placement API microversion by adding
the ``--generation`` option to the
``openstack resource provider aggregate set`` command.
.. _1.19: https://docs.openstack.org/placement/latest/placement-api-microversion-history.html#include-generation-and-conflict-detection-in-provider-aggregates-apis