Add support for 1.22 microversion
The 1.22 microversion of placement adds support for excluding resource providers and allocation candidates with specified traits. A forbidden trait may be specified with --forbidden option. Change-Id: I4760fe6119e29d80f63ec7bd6c4a5f2395a9291e
This commit is contained in:
parent
4c95f7caff
commit
e52fa969f9
@ -86,6 +86,16 @@ class ListAllocationCandidate(command.Lister, version.CheckerMixin):
|
||||
'This option requires at least '
|
||||
'``--os-placement-api-version 1.17``.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--forbidden',
|
||||
metavar='<forbidden>',
|
||||
action='append',
|
||||
default=[],
|
||||
help='A forbidden trait. May be repeated. Returned allocation '
|
||||
'candidates must not contain any of the specified traits. '
|
||||
'This option requires at least '
|
||||
'``--os-placement-api-version 1.22``.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--aggregate-uuid',
|
||||
default=[],
|
||||
@ -126,6 +136,14 @@ class ListAllocationCandidate(command.Lister, version.CheckerMixin):
|
||||
# Fail if --required but not high enough microversion.
|
||||
self.check_version(version.ge('1.17'))
|
||||
params['required'] = ','.join(parsed_args.required)
|
||||
if 'forbidden' in parsed_args and parsed_args.forbidden:
|
||||
self.check_version(version.ge('1.22'))
|
||||
forbidden_traits = ','.join(
|
||||
['!' + f for f in parsed_args.forbidden])
|
||||
if 'required' in params:
|
||||
params['required'] += ',' + forbidden_traits
|
||||
else:
|
||||
params['required'] = forbidden_traits
|
||||
if 'aggregate_uuid' in parsed_args and parsed_args.aggregate_uuid:
|
||||
# Fail if --aggregate_uuid but not high enough microversion.
|
||||
self.check_version(version.ge('1.21'))
|
||||
|
@ -128,6 +128,16 @@ class ListResourceProvider(command.Lister, version.CheckerMixin):
|
||||
'This option requires at least '
|
||||
'``--os-placement-api-version 1.18``.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--forbidden',
|
||||
metavar='<forbidden>',
|
||||
action='append',
|
||||
default=[],
|
||||
help='A forbidden trait. May be repeated. Returned resource '
|
||||
'providers must not contain any of the specified traits. '
|
||||
'This option requires at least '
|
||||
'``--os-placement-api-version 1.22``.'
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
@ -153,6 +163,14 @@ class ListResourceProvider(command.Lister, version.CheckerMixin):
|
||||
if 'required' in parsed_args and parsed_args.required:
|
||||
self.check_version(version.ge('1.18'))
|
||||
filters['required'] = ','.join(parsed_args.required)
|
||||
if 'forbidden' in parsed_args and parsed_args.forbidden:
|
||||
self.check_version(version.ge('1.22'))
|
||||
forbidden_traits = ','.join(
|
||||
['!' + f for f in parsed_args.forbidden])
|
||||
if 'required' in filters:
|
||||
filters['required'] += ',' + forbidden_traits
|
||||
else:
|
||||
filters['required'] = forbidden_traits
|
||||
|
||||
url = common.url_with_filters(BASE_URL, filters)
|
||||
resources = http.request('GET', url).json()['resource_providers']
|
||||
|
@ -189,7 +189,7 @@ class BaseTestCase(base.BaseTestCase):
|
||||
|
||||
def resource_provider_list(self, uuid=None, name=None,
|
||||
aggregate_uuids=None, resources=None,
|
||||
in_tree=None, required=None):
|
||||
in_tree=None, required=None, forbidden=None):
|
||||
to_exec = 'resource provider list'
|
||||
if uuid:
|
||||
to_exec += ' --uuid ' + uuid
|
||||
@ -204,6 +204,8 @@ class BaseTestCase(base.BaseTestCase):
|
||||
to_exec += ' --in-tree ' + in_tree
|
||||
if required:
|
||||
to_exec += ' ' + ' '.join('--required %s' % t for t in required)
|
||||
if forbidden:
|
||||
to_exec += ' ' + ' '.join('--forbidden %s' % f for f in forbidden)
|
||||
|
||||
return self.openstack(to_exec, use_json=True)
|
||||
|
||||
@ -354,12 +356,15 @@ class BaseTestCase(base.BaseTestCase):
|
||||
cmd = 'resource provider trait delete %s ' % uuid
|
||||
self.openstack(cmd)
|
||||
|
||||
def allocation_candidate_list(self, resources, required=None, limit=None,
|
||||
def allocation_candidate_list(self, resources, required=None,
|
||||
forbidden=None, limit=None,
|
||||
aggregate_uuids=None):
|
||||
cmd = 'allocation candidate list ' + ' '.join(
|
||||
'--resource %s' % resource for resource in resources)
|
||||
if required is not None:
|
||||
cmd += ''.join([' --required %s' % t for t in required])
|
||||
if forbidden:
|
||||
cmd += ' ' + ' '.join('--forbidden %s' % f for f in forbidden)
|
||||
if limit is not None:
|
||||
cmd += ' --limit %d' % limit
|
||||
if aggregate_uuids:
|
||||
|
@ -188,3 +188,52 @@ class TestAllocationCandidate121(base.BaseTestCase):
|
||||
self.assertEqual(1, len(candidate_dict))
|
||||
self.assertIn(rp2['uuid'], candidate_dict)
|
||||
self.assertNotIn(rp1['uuid'], candidate_dict)
|
||||
|
||||
# Specifying forbidden traits weren't available until version 1.22
|
||||
def test_fail_if_forbidden_trait_wrong_version(self):
|
||||
self.assertCommandFailed(
|
||||
'Operation or argument is not supported with version 1.21',
|
||||
self.allocation_candidate_list,
|
||||
resources=('MEMORY_MB=1024', 'DISK_GB=80'),
|
||||
forbidden=('STORAGE_DISK_HDD',))
|
||||
|
||||
|
||||
class TestAllocationCandidate122(base.BaseTestCase):
|
||||
VERSION = '1.22'
|
||||
|
||||
def test_hide_forbidden_trait(self):
|
||||
rp1 = self.resource_provider_create()
|
||||
rp2 = self.resource_provider_create()
|
||||
rp3 = self.resource_provider_create()
|
||||
self.resource_inventory_set(
|
||||
rp1['uuid'], 'MEMORY_MB=1024', 'DISK_GB=256')
|
||||
self.resource_inventory_set(
|
||||
rp2['uuid'], 'MEMORY_MB=1024', 'DISK_GB=256')
|
||||
self.resource_inventory_set(
|
||||
rp3['uuid'], 'MEMORY_MB=1024', 'DISK_GB=256')
|
||||
self.resource_provider_trait_set(
|
||||
rp1['uuid'], 'STORAGE_DISK_SSD', 'HW_CPU_X86_BMI')
|
||||
self.resource_provider_trait_set(
|
||||
rp2['uuid'], 'STORAGE_DISK_HDD', 'HW_CPU_X86_BMI')
|
||||
self.resource_provider_trait_set(
|
||||
rp3['uuid'], 'STORAGE_DISK_HDD', 'HW_CPU_X86_BMI')
|
||||
|
||||
rps = self.allocation_candidate_list(
|
||||
resources=('MEMORY_MB=1024', 'DISK_GB=80'),
|
||||
required=('HW_CPU_X86_BMI',),
|
||||
forbidden=('STORAGE_DISK_HDD',))
|
||||
|
||||
self.assertEqual(1, len(rps))
|
||||
self.assertEqual(rp1['uuid'], rps[0]['resource provider'])
|
||||
|
||||
rps = self.allocation_candidate_list(
|
||||
resources=('MEMORY_MB=1024', 'DISK_GB=80'),
|
||||
required=('HW_CPU_X86_BMI',),
|
||||
forbidden=('STORAGE_DISK_SSD',))
|
||||
|
||||
uuids = [rp['resource provider'] for rp in rps]
|
||||
|
||||
self.assertEqual(2, len(uuids))
|
||||
self.assertNotIn(rp1['uuid'], uuids)
|
||||
self.assertIn(rp2['uuid'], uuids)
|
||||
self.assertIn(rp3['uuid'], uuids)
|
||||
|
@ -303,3 +303,52 @@ class TestResourceProvider118(base.BaseTestCase):
|
||||
|
||||
self.assertEqual(1, len(rps))
|
||||
self.assertEqual(rp2['uuid'], rps[0]['uuid'])
|
||||
|
||||
# Specifying forbidden traits weren't available until version 1.22
|
||||
def test_fail_if_forbidden_trait_wrong_version(self):
|
||||
self.assertCommandFailed(
|
||||
'Operation or argument is not supported with version 1.18',
|
||||
self.resource_provider_list,
|
||||
resources=('MEMORY_MB=1024', 'DISK_GB=80'),
|
||||
forbidden=('STORAGE_DISK_HDD',))
|
||||
|
||||
|
||||
class TestResourceProvider122(base.BaseTestCase):
|
||||
VERSION = '1.22'
|
||||
|
||||
def test_hide_forbidden_trait(self):
|
||||
rp1 = self.resource_provider_create()
|
||||
rp2 = self.resource_provider_create()
|
||||
rp3 = self.resource_provider_create()
|
||||
self.resource_inventory_set(
|
||||
rp1['uuid'], 'MEMORY_MB=1024', 'DISK_GB=256')
|
||||
self.resource_inventory_set(
|
||||
rp2['uuid'], 'MEMORY_MB=1024', 'DISK_GB=256')
|
||||
self.resource_inventory_set(
|
||||
rp3['uuid'], 'MEMORY_MB=1024', 'DISK_GB=256')
|
||||
self.resource_provider_trait_set(
|
||||
rp1['uuid'], 'STORAGE_DISK_SSD', 'HW_CPU_X86_VMX')
|
||||
self.resource_provider_trait_set(
|
||||
rp2['uuid'], 'STORAGE_DISK_HDD', 'HW_CPU_X86_VMX')
|
||||
self.resource_provider_trait_set(
|
||||
rp3['uuid'], 'STORAGE_DISK_HDD', 'HW_CPU_X86_VMX')
|
||||
|
||||
rps = self.resource_provider_list(
|
||||
resources=('MEMORY_MB=1024', 'DISK_GB=80'),
|
||||
required=('HW_CPU_X86_VMX',),
|
||||
forbidden=('STORAGE_DISK_HDD',))
|
||||
|
||||
self.assertEqual(1, len(rps))
|
||||
self.assertEqual(rp1['uuid'], rps[0]['uuid'])
|
||||
|
||||
rps = self.resource_provider_list(
|
||||
resources=('MEMORY_MB=1024', 'DISK_GB=80'),
|
||||
required=('HW_CPU_X86_VMX',),
|
||||
forbidden=('!STORAGE_DISK_SSD',))
|
||||
|
||||
uuids = [rp['uuid'] for rp in rps]
|
||||
|
||||
self.assertEqual(2, len(uuids))
|
||||
self.assertNotIn(rp1['uuid'], uuids)
|
||||
self.assertIn(rp2['uuid'], uuids)
|
||||
self.assertIn(rp3['uuid'], uuids)
|
||||
|
@ -37,6 +37,7 @@ SUPPORTED_VERSIONS = [
|
||||
'1.19',
|
||||
'1.20', # unused
|
||||
'1.21',
|
||||
'1.22',
|
||||
]
|
||||
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The `1.22 microversion`_ of placement adds support for
|
||||
excluding resource providers and allocation candidates
|
||||
with specified traits. A forbidden trait may be specified
|
||||
with ``--forbidden`` option.
|
||||
|
||||
.. _1.22 microversion: https://docs.openstack.org/placement/latest/placement-api-microversion-history.html#support-forbidden-traits-on-resource-providers-and-allocations-candidates
|
Loading…
Reference in New Issue
Block a user