Merge "Implement allocation candidate mappings"

This commit is contained in:
Zuul 2019-06-14 11:23:57 +00:00 committed by Gerrit Code Review
commit 942643eef0
21 changed files with 618 additions and 18 deletions

View File

@ -57,10 +57,17 @@ Response (microversions 1.12 - )
- traits: traits_1_17
- parent_provider_uuid: resource_provider_parent_provider_uuid_response_1_29
- root_provider_uuid: resource_provider_root_provider_uuid_1_29
- mappings: mappings
Response Example (microversions 1.29 - )
Response Example (microversions 1.34 - )
----------------------------------------
.. literalinclude:: ./samples/allocation_candidates/get-allocation_candidates-1.34.json
:language: javascript
Response Example (microversions 1.29 - 1.33)
--------------------------------------------
.. literalinclude:: ./samples/allocation_candidates/get-allocation_candidates-1.29.json
:language: javascript

View File

@ -43,6 +43,7 @@ Request
- allocations: allocations_dict_empty
- generation: resource_provider_generation_optional
- resources: resources
- mappings: mappings_in_allocations
Request example (microversions 1.28 - )
---------------------------------------
@ -136,6 +137,7 @@ Request (microversions 1.12 - )
- project_id: project_id_body
- user_id: user_id_body
- generation: resource_provider_generation_optional
- mappings: mappings_in_allocations
Request example (microversions 1.28 - )
---------------------------------------

View File

@ -462,6 +462,20 @@ inventories:
required: true
description: >
A dictionary of inventories keyed by resource classes.
mappings: &mappings
type: object
in: body
required: true
description: >
A dictionary associating request group suffixes with a list of uuids
identifying the resource providers that satisfied each group. The empty
string and ``[a-zA-Z0-9_-]+`` are valid suffixes. This field may be sent
when writing allocations back to the server but will be ignored; this
preserves symmetry between read and write representations.
min_version: 1.34
mappings_in_allocations:
<<: *mappings
required: false
max_unit: &max_unit
type: integer
in: body

View File

@ -38,6 +38,7 @@ Request
- allocations.{consumer_uuid}.allocations.{resource_provider_uuid}.resources: resources
- allocations.{consumer_uuid}.project_id: project_id_body
- allocations.{consumer_uuid}.user_id: user_id_body
- allocations.{consumer_uuid}.mappings: mappings
- allocations.{consumer_uuid}.consumer_generation: consumer_generation
Request Example

View File

@ -0,0 +1,96 @@
{
"allocation_requests": [
{
"allocations": {
"92e971c9-777a-48bf-a181-a2ca1105c015": {
"resources": {
"NET_BW_EGR_KILOBIT_PER_SEC": 10
}
},
"cefbdf54-05a8-4db4-ad2b-d6729e5a4de8": {
"resources": {
"NET_BW_EGR_KILOBIT_PER_SEC": 20
}
},
"9a9c6b0f-e8d1-4d16-b053-a2bfe8a76757": {
"resources": {
"VCPU": 1
}
}
},
"mappings": {
"_NET1": [
"92e971c9-777a-48bf-a181-a2ca1105c015"
],
"_NET2": [
"cefbdf54-05a8-4db4-ad2b-d6729e5a4de8"
],
"": [
"9a9c6b0f-e8d1-4d16-b053-a2bfe8a76757"
]
}
}
],
"provider_summaries": {
"be99627d-e848-44ef-8341-683e2e557c58": {
"resources": {},
"traits": [
"COMPUTE_VOLUME_MULTI_ATTACH"
],
"parent_provider_uuid": null,
"root_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58"
},
"9a9c6b0f-e8d1-4d16-b053-a2bfe8a76757": {
"resources": {
"VCPU": {
"capacity": 4,
"used": 0
},
"MEMORY_MB": {
"capacity": 2048,
"used": 0
}
},
"traits": [
"HW_NUMA_ROOT",
"CUSTOM_FOO"
],
"parent_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58",
"root_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58"
},
"ba415f98-1960-4488-b2ed-4518b77eaa60": {
"resources": {},
"traits": [
"CUSTOM_VNIC_TYPE_DIRECT"
],
"parent_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58",
"root_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58"
},
"92e971c9-777a-48bf-a181-a2ca1105c015": {
"resources": {
"NET_BW_EGR_KILOBIT_PER_SEC": {
"capacity": 10000,
"used": 0
}
},
"traits": [
"CUSTOM_PHYSNET1"
],
"parent_provider_uuid": "ba415f98-1960-4488-b2ed-4518b77eaa60",
"root_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58"
},
"cefbdf54-05a8-4db4-ad2b-d6729e5a4de8": {
"resources": {
"NET_BW_EGR_KILOBIT_PER_SEC": {
"capacity": 20000,
"used": 0
}
},
"traits": [
"CUSTOM_PHYSNET2"
],
"parent_provider_uuid": "ba415f98-1960-4488-b2ed-4518b77eaa60",
"root_provider_uuid": "be99627d-e848-44ef-8341-683e2e557c58"
}
}
}

View File

@ -483,12 +483,19 @@ def set_allocations_for_consumer(req):
@wsgi_wrapper.PlacementWsgify # noqa
@microversion.version_handler('1.28')
@microversion.version_handler('1.28', '1.33')
@util.require_content('application/json')
def set_allocations_for_consumer(req):
return _set_allocations_for_consumer(req, schema.ALLOCATION_SCHEMA_V1_28)
@wsgi_wrapper.PlacementWsgify # noqa
@microversion.version_handler('1.34')
@util.require_content('application/json')
def set_allocations_for_consumer(req):
return _set_allocations_for_consumer(req, schema.ALLOCATION_SCHEMA_V1_34)
@wsgi_wrapper.PlacementWsgify
@microversion.version_handler('1.13')
@util.require_content('application/json')
@ -499,6 +506,8 @@ def set_allocations(req):
want_schema = schema.POST_ALLOCATIONS_V1_13
if want_version.matches((1, 28)):
want_schema = schema.POST_ALLOCATIONS_V1_28
if want_version.matches((1, 34)):
want_schema = schema.POST_ALLOCATIONS_V1_34
data = util.extract_json(req.body, want_schema)
consumers, new_consumers_created = inspect_consumers(

View File

@ -30,7 +30,7 @@ from placement import util
from placement import wsgi_wrapper
def _transform_allocation_requests_dict(alloc_reqs):
def _transform_allocation_requests_dict(alloc_reqs, want_version):
"""Turn supplied list of AllocationRequest objects into a list of
allocations dicts keyed by resource provider uuid of resources involved
in the allocation request. The returned results are intended to be used
@ -53,6 +53,12 @@ def _transform_allocation_requests_dict(alloc_reqs):
}
}
},
# If microversion >=1.34 then map suffixes to providers.
"mappings": {
"_COMPUTE": [$rp_uuid2],
"": [$rp_uuid1]
},
},
...
]
@ -62,10 +68,18 @@ def _transform_allocation_requests_dict(alloc_reqs):
for ar in alloc_reqs:
# A default dict of {$rp_uuid: "resources": {})
rp_resources = collections.defaultdict(lambda: dict(resources={}))
# A dict to map request group suffixes to the providers that provided
# solutions to that group.
mappings = collections.defaultdict(list)
for rr in ar.resource_requests:
suffix = rr.suffix
mappings[suffix].append(rr.resource_provider.uuid)
res_dict = rp_resources[rr.resource_provider.uuid]['resources']
res_dict[rr.resource_class] = rr.amount
results.append(dict(allocations=rp_resources))
result = dict(allocations=rp_resources)
if want_version.matches((1, 34)):
result['mappings'] = mappings
results.append(result)
return results
@ -214,7 +228,7 @@ def _transform_allocation_candidates(alloc_cands, requests, want_version):
"""
if want_version.matches((1, 12)):
a_reqs = _transform_allocation_requests_dict(
alloc_cands.allocation_requests)
alloc_cands.allocation_requests, want_version)
else:
a_reqs = _transform_allocation_requests_list(
alloc_cands.allocation_requests)

View File

@ -44,7 +44,11 @@ def reshape(req):
context = req.environ['placement.context']
want_version = req.environ[microversion.MICROVERSION_ENVIRON]
context.can(policies.RESHAPE)
data = util.extract_json(req.body, schema.POST_RESHAPER_SCHEMA)
reshaper_schema = schema.POST_RESHAPER_SCHEMA
if want_version.matches((1, 34)):
reshaper_schema = schema.POST_RESHAPER_SCHEMA_V1_34
data = util.extract_json(req.body, reshaper_schema)
inventories = data['inventories']
allocations = data['allocations']
# We're going to create several lists of Inventory objects, keyed by rp

View File

@ -19,7 +19,7 @@ import re
import webob
from placement import microversion
from placement.schemas import allocation_candidate
from placement.schemas import common
from placement import util
@ -31,11 +31,11 @@ _QS_IN_TREE = 'in_tree'
_QS_KEY_PATTERN = re.compile(
r"^(%s)(%s)?$" % ('|'.join(
(_QS_RESOURCES, _QS_REQUIRED, _QS_MEMBER_OF, _QS_IN_TREE)),
allocation_candidate.GROUP_PAT))
common.GROUP_PAT))
_QS_KEY_PATTERN_1_33 = re.compile(
r"^(%s)(%s)?$" % ('|'.join(
(_QS_RESOURCES, _QS_REQUIRED, _QS_MEMBER_OF, _QS_IN_TREE)),
allocation_candidate.GROUP_PAT_1_33))
common.GROUP_PAT_1_33))
class RequestGroup(object):

View File

@ -83,6 +83,8 @@ VERSIONS = [
# `GET /resource_providers` and `GET /allocation_candidates`
'1.33', # Support granular resource requests with suffixes that match
# [A-Za-z0-9_-]{1,64}.
'1.34', # Include a mappings key in allocation requests that shows which
# resource providers satisfied which request group suffix.
]

View File

@ -625,3 +625,16 @@ it is now possible to use more complex strings, including UUIDs::
resources_PORT_fccc7adb-095e-4bfd-8c9b-942f41990664=XXX
&required_PORT_fccc7adb-095e-4bfd-8c9b-942f41990664=YYY
&member_of_PORT_fccc7adb-095e-4bfd-8c9b-942f41990664=ZZZ
1.34 - Request group mappings in allocation candidates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: Train
The body of the response to a ``GET /allocation_candidates`` request has been
extended to include a ``mappings`` field with each allocation request. The
value is a dictionary associating request group suffixes with the uuids of
those resource providers that satisfy the identified request group. For
convenience, this mapping can be included in the request payload for
``POST /allocations``, ``PUT /allocations/{consumer_uuid}``, and
``POST /reshaper``, but it will be ignored.

View File

@ -167,3 +167,26 @@ POST_ALLOCATIONS_V1_28 = copy.deepcopy(POST_ALLOCATIONS_V1_13)
POST_ALLOCATIONS_V1_28["patternProperties"] = {
common.UUID_PATTERN: REQUIRED_GENERATION_ALLOCS_POST
}
# Microversion 1.34 allows an optional mappings object which associates
# request group suffixes with lists of resource provider uuids.
mappings_schema = {
"type": "object",
"minProperites": 1,
"patternProperties": {
common.GROUP_PAT_1_33: {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"format": "uuid"
}
}
}
}
ALLOCATION_SCHEMA_V1_34 = copy.deepcopy(ALLOCATION_SCHEMA_V1_28)
ALLOCATION_SCHEMA_V1_34['properties']['mappings'] = mappings_schema
POST_ALLOCATIONS_V1_34 = copy.deepcopy(POST_ALLOCATIONS_V1_28)
POST_ALLOCATIONS_V1_34["patternProperties"] = {
common.UUID_PATTERN: ALLOCATION_SCHEMA_V1_34
}

View File

@ -13,11 +13,7 @@
import copy
# The suffix used with request groups. Prior to 1.33, the group were numbered.
# With 1.33 they become alphanumeric, '_', and '-' with a length limit of 64.
GROUP_PAT = r'[1-9][0-9]*'
GROUP_PAT_1_33 = r'[a-zA-Z0-9_-]{1,64}'
from placement.schemas import common
# Represents the allowed query string parameters to the GET
@ -66,7 +62,7 @@ del GET_SCHEMA_1_25["required"]
del GET_SCHEMA_1_25["properties"]["required"]
del GET_SCHEMA_1_25["properties"]["member_of"]
# Pattern property key format for a numbered or un-numbered grouping
_GROUP_PAT_FMT = "^%s(" + GROUP_PAT + ")?$"
_GROUP_PAT_FMT = "^%s(" + common.GROUP_PAT + ")?$"
GET_SCHEMA_1_25["patternProperties"] = {
_GROUP_PAT_FMT % "resources": {
"type": "string",
@ -90,7 +86,7 @@ GET_SCHEMA_1_31["patternProperties"][_GROUP_PAT_FMT % "in_tree"] = {
# Microversion 1.33 allows more complex resource group suffixes.
GET_SCHEMA_1_33 = copy.deepcopy(GET_SCHEMA_1_31)
_GROUP_PAT_FMT_1_33 = "^%s(" + GROUP_PAT_1_33 + ")?$"
_GROUP_PAT_FMT_1_33 = "^%s(" + common.GROUP_PAT_1_33 + ")?$"
GET_SCHEMA_1_33["patternProperties"] = {
_GROUP_PAT_FMT_1_33 % group_type: {"type": "string"}
for group_type in ('resources', 'required', 'member_of', 'in_tree')}

View File

@ -20,3 +20,8 @@ RC_PATTERN = _RC_TRAIT_PATTERN
_CUSTOM_RC_TRAIT_PATTERN = "^CUSTOM_%s+$" % _RC_TRAIT_CHAR
CUSTOM_RC_PATTERN = _CUSTOM_RC_TRAIT_PATTERN
CUSTOM_TRAIT_PATTERN = _CUSTOM_RC_TRAIT_PATTERN
# The suffix used with request groups. Prior to 1.33, the group were numbered.
# With 1.33 they become alphanumeric, '_', and '-' with a length limit of 64.
GROUP_PAT = r'[1-9][0-9]*'
GROUP_PAT_1_33 = r'[a-zA-Z0-9_-]{1,64}'

View File

@ -45,3 +45,8 @@ POST_RESHAPER_SCHEMA = {
],
"additionalProperties": False,
}
POST_RESHAPER_SCHEMA_V1_34 = copy.deepcopy(POST_RESHAPER_SCHEMA)
ALLOCATIONS_V1_34 = copy.deepcopy(allocation.POST_ALLOCATIONS_V1_34)
ALLOCATIONS_V1_34['minProperties'] = 0
POST_RESHAPER_SCHEMA_V1_34['properties']['allocations'] = ALLOCATIONS_V1_34

View File

@ -0,0 +1,87 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Tests for allocation request mappings when using nested providers.
fixtures:
# See the layout diagram in this fixture's docstring in ../fixtures.py
- NUMANetworkFixture
defaults:
request_headers:
x-auth-token: admin
content-type: application/json
accept: application/json
# 1.34 is the microversion at which mappings are expected
openstack-api-version: placement 1.34
tests:
- name: simple mapping non granular
GET: /allocation_candidates
query_parameters:
resources: VCPU:1
response_json_paths:
$.allocation_requests.`len`: 3
$.provider_summaries.`len`: 23
# keys are allocations, mappings
$.allocation_requests[0].`len`: 2
$.allocation_requests[0].mappings[''].`len`: 1
$.allocation_requests[0].mappings[''][0]: /$ENVIRON['CN2_UUID']|$ENVIRON['NUMA0_UUID']|$ENVIRON['NUMA1_UUID']/
- name: no mappings in 1.33
GET: /allocation_candidates
query_parameters:
resources: VCPU:1
request_headers:
openstack-api-version: placement 1.33
response_json_paths:
$.allocation_requests.`len`: 3
$.provider_summaries.`len`: 23
# keys are solely 'allocations'
$.allocation_requests[0].`len`: 1
- name: simple isolated mapping
GET: /allocation_candidates
query_parameters:
resources_LEFT: VCPU:1
resources_RIGHT: VCPU:1
group_policy: isolate
response_json_paths:
$.allocation_requests.`len`: 2
$.provider_summaries.`len`: 12
$.allocation_requests[0].mappings.`len`: 2
$.allocation_requests[0].mappings['_LEFT'][0]: /$ENVIRON['NUMA0_UUID']|$ENVIRON['NUMA1_UUID']/
$.allocation_requests[0].mappings['_RIGHT'][0]: /$ENVIRON['NUMA1_UUID']|$ENVIRON['NUMA0_UUID']/
- name: granular plus not granular
GET: /allocation_candidates
query_parameters:
required_NET1: CUSTOM_PHYSNET1
resources_NET1: NET_BW_EGR_KILOBIT_PER_SEC:10
required_NET2: CUSTOM_PHYSNET2
resources_NET2: NET_BW_EGR_KILOBIT_PER_SEC:20
resources: VCPU:1
group_policy: isolate
response_json_paths:
# two candidates, one for each NUMA node providing VCPU
$.allocation_requests.`len`: 2
$.provider_summaries.`len`: 12
# 3 members of the mappings dict
$.allocation_requests[0].mappings.`len`: 3
# One member of each list in the mappings
$.allocation_requests[0].mappings[''].`len`: 1
$.allocation_requests[0].mappings._NET1.`len`: 1
$.allocation_requests[0].mappings._NET2.`len`: 1
$.allocation_requests[0].mappings[''][0]: /$ENVIRON['NUMA0_UUID']|$ENVIRON['NUMA1_UUID']/
$.allocation_requests[0].mappings._NET1[0]: $ENVIRON['ESN1_UUID']
$.allocation_requests[0].mappings._NET2[0]: $ENVIRON['ESN2_UUID']

View File

@ -0,0 +1,77 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Tests for allocation request mappings.
fixtures:
# See the layout diagram in this fixture's docstring in ../fixtures.py
- GranularFixture
defaults:
request_headers:
x-auth-token: admin
content-type: application/json
accept: application/json
# 1.34 is the microversion at which mappings are expected
openstack-api-version: placement 1.34
tests:
- name: simple mapping non granular
GET: /allocation_candidates
query_parameters:
resources: VCPU:1
required: HW_CPU_X86_SSE
response_json_paths:
$.allocation_requests.`len`: 1
$.provider_summaries.`len`: 1
$.allocation_requests[0].allocations["$ENVIRON['CN_MIDDLE']"].resources:
VCPU: 1
$.allocation_requests[0].mappings:
"":
- $ENVIRON['CN_MIDDLE']
- name: simple mapping with shared
GET: /allocation_candidates
query_parameters:
resources: VCPU:1,DISK_GB:1
required: HW_CPU_X86_SSE
response_json_paths:
$.allocation_requests.`len`: 2
$.provider_summaries.`len`: 3
$.allocation_requests[0].allocations["$ENVIRON['CN_MIDDLE']"].resources:
VCPU: 1
# We can't cleanly test for which providers will show up in which
# mappings in this request, so instead we confirm the size. Other tests
# cover which suitably.
$.allocation_requests[0].mappings.`len`: 1
$.allocation_requests[0].mappings[""].`len`: 2
$.allocation_requests[1].mappings.`len`: 1
$.allocation_requests[1].mappings[""].`len`: 2
- name: group mapping with shared
GET: /allocation_candidates
query_parameters:
resources: VCPU:1
resources_DISK_A: DISK_GB:1
resources_DISK_B: DISK_GB:1
required: HW_CPU_X86_SSE
group_policy: isolate
response_json_paths:
$.allocation_requests.`len`: 2
$.provider_summaries.`len`: 3
$.allocation_requests[0].allocations["$ENVIRON['CN_MIDDLE']"].resources:
VCPU: 1
$.allocation_requests[0].mappings.`len`: 3
$.allocation_requests[0].mappings[""][0]: $ENVIRON['CN_MIDDLE']
$.allocation_requests[0].mappings['_DISK_A'][0]: /(?:$ENVIRON['SHR_DISK_1']|$ENVIRON['SHR_DISK_2'])/
$.allocation_requests[0].mappings['_DISK_B'][0]: /(?:$ENVIRON['SHR_DISK_1']|$ENVIRON['SHR_DISK_2'])/

View File

@ -0,0 +1,100 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Tests that allocation request mappings can be sent back
fixtures:
# See the layout diagram in this fixture's docstring in ../fixtures.py
- NUMANetworkFixture
defaults:
request_headers:
x-auth-token: admin
content-type: application/json
accept: application/json
# 1.34 is the microversion at which mappings are expected
openstack-api-version: placement 1.34
tests:
- name: mappings request
GET: /allocation_candidates
query_parameters:
required_NET1: CUSTOM_PHYSNET1
resources_NET1: NET_BW_EGR_KILOBIT_PER_SEC:10
required_NET2: CUSTOM_PHYSNET2
resources_NET2: NET_BW_EGR_KILOBIT_PER_SEC:20
resources: VCPU:1
group_policy: isolate
- name: put allocation with results
PUT: /allocations/254eea13-27e1-4305-b35f-5dedd9f58ba0
data:
allocations: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].allocations']
mappings: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].mappings']
consumer_generation: null
user_id: 8c974f9a-f266-42f7-8613-a8017cbfb87F
project_id: b2e599e0-ded8-47fd-b8ab-ceb7fca578bd
status: 204
- name: put allocation wrong microversion
PUT: /allocations/5662942e-497f-4a54-8257-dcbb3fa3e5f4
request_headers:
openstack-api-version: placement 1.33
data:
allocations: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].allocations']
mappings: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].mappings']
consumer_generation: null
user_id: 8c974f9a-f266-42f7-8613-a8017cbfb87F
project_id: b2e599e0-ded8-47fd-b8ab-ceb7fca578bd
status: 400
response_json_paths:
$.errors[0].detail: /Additional properties are not allowed/
- name: put allocation mapping bad form
PUT: /allocations/5f9588de-079d-462a-a459-408524ab9b60
data:
allocations: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].allocations']
mappings:
alpha: beta
consumer_generation: null
user_id: 8c974f9a-f266-42f7-8613-a8017cbfb87F
project_id: b2e599e0-ded8-47fd-b8ab-ceb7fca578bd
status: 400
response_json_paths:
# u? accounts for difference in Python 2.7 v. 3.x response
$.errors[0].detail: "/JSON does not validate: u?'beta' is not of type 'array'/"
- name: post allocation with results
POST: /allocations
data:
'0b2c687e-89eb-47f6-bb68-2fc83e28032a':
allocations: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].allocations']
mappings: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].mappings']
consumer_generation: null
user_id: 8c974f9a-f266-42f7-8613-a8017cbfb87F
project_id: b2e599e0-ded8-47fd-b8ab-ceb7fca578bd
status: 204
- name: post allocation wrong microversion
POST: /allocations
request_headers:
openstack-api-version: placement 1.33
data:
'0b2c687e-89eb-47f6-bb68-2fc83e28032a':
allocations: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].allocations']
mappings: $HISTORY['mappings request'].$RESPONSE['$.allocation_requests[0].mappings']
consumer_generation: null
user_id: 8c974f9a-f266-42f7-8613-a8017cbfb87F
project_id: b2e599e0-ded8-47fd-b8ab-ceb7fca578bd
status: 400
response_json_paths:
$.errors[0].detail: /Additional properties are not allowed/

View File

@ -41,13 +41,13 @@ tests:
response_json_paths:
$.errors[0].title: Not Acceptable
- name: latest microversion is 1.33
- name: latest microversion is 1.34
GET: /
request_headers:
openstack-api-version: placement latest
response_headers:
vary: /openstack-api-version/
openstack-api-version: placement 1.33
openstack-api-version: placement 1.34
- name: other accept header bad version
GET: /

View File

@ -556,3 +556,134 @@ tests:
response_json_paths:
$.usages: {}
$.resource_provider_generation: 5
# At microversion 1.34 we accept a mappings key with allocations.
- name: reshape with mappings
POST: /reshaper
request_headers:
openstack-api-version: placement 1.34
data:
inventories:
$ENVIRON['RP_UUID']:
resource_provider_generation: 11
inventories:
DISK_GB:
total: 2048
step_size: 10
min_unit: 10
max_unit: 1200
VCPU:
total: 10
max_unit: 8
$ENVIRON['ALT_RP_UUID']:
resource_provider_generation: 5
inventories: {}
allocations:
$ENVIRON['CONSUMER_0']:
allocations:
$ENVIRON['RP_UUID']:
resources:
DISK_GB: 1000
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['USER_ID']
consumer_generation: 3
mappings:
'':
- $ENVIRON['RP_UUID']
'7bd2e864-0415-445c-8fc2-328520ef7642':
allocations:
$ENVIRON['RP_UUID']:
resources:
VCPU: 8
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['USER_ID']
consumer_generation: 1
'2dfa608c-cecb-4fe0-a1bb-950015fa731f':
allocations:
$ENVIRON['RP_UUID']:
resources:
DISK_GB: 20
VCPU: 1
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['ALT_USER_ID']
consumer_generation: 1
$ENVIRON['CONSUMER_ID']:
allocations: {}
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['USER_ID']
consumer_generation: null
$ENVIRON['ALT_CONSUMER_ID']:
allocations:
$ENVIRON['RP_UUID']:
resources:
DISK_GB: 20
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['ALT_USER_ID']
consumer_generation: 3
status: 204
- name: reshape with mappings wrong microversion
POST: /reshaper
request_headers:
openstack-api-version: placement 1.33
data:
inventories:
$ENVIRON['RP_UUID']:
resource_provider_generation: 8
inventories:
DISK_GB:
total: 2048
step_size: 10
min_unit: 10
max_unit: 1200
VCPU:
total: 10
max_unit: 8
$ENVIRON['ALT_RP_UUID']:
resource_provider_generation: 3
inventories: {}
allocations:
$ENVIRON['CONSUMER_0']:
allocations:
$ENVIRON['RP_UUID']:
resources:
DISK_GB: 1000
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['USER_ID']
consumer_generation: 2
mappings:
'':
- $ENVIRON['RP_UUID']
'7bd2e864-0415-445c-8fc2-328520ef7642':
allocations:
$ENVIRON['RP_UUID']:
resources:
VCPU: 8
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['USER_ID']
consumer_generation: null
'2dfa608c-cecb-4fe0-a1bb-950015fa731f':
allocations:
$ENVIRON['RP_UUID']:
resources:
DISK_GB: 20
VCPU: 1
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['ALT_USER_ID']
consumer_generation: null
$ENVIRON['CONSUMER_ID']:
allocations: {}
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['USER_ID']
consumer_generation: 2
$ENVIRON['ALT_CONSUMER_ID']:
allocations:
$ENVIRON['RP_UUID']:
resources:
DISK_GB: 20
project_id: $ENVIRON['PROJECT_ID']
user_id: $ENVIRON['ALT_USER_ID']
consumer_generation: 2
status: 400
response_json_paths:
$.errors[0].detail: /Additional properties are not allowed/

View File

@ -0,0 +1,14 @@
---
features:
- |
In microversion 1.34_ the body of the response to a
``GET /allocation_candidates`` request_ has been extended to include a
``mappings`` field with each allocation request. The value is a dictionary
associating request group suffixes with the uuids of those resource
providers that satisfy the identified request group. For convenience, this
mapping can be included in the request payload for ``POST /allocations``,
``PUT /allocations/{consumer_uuid}``, and ``POST /reshaper``, but it will
be ignored.
.. _1.34: https://docs.openstack.org/placement/latest/placement-api-microversion-history.html#request-group-mappings-in-allocation-candidates
.. _request: https://developer.openstack.org/api-ref/placement/?expanded=list-allocation-candidates-detail#list-allocation-candidates