Implement allocation candidate mappings
In microversion 1.34 add a 'mappings' key to each allocation request. Its value is dict keyed by resource group suffixes with values of a list of resource providers satisfying that group. To preserve symmetry, the mappings key may be sent back when writing allocations so the schema for POST and PUT allocations and POST /reshaper are updated. api history, api-ref and reno are added Change-Id: Ie78ed7e050416d4ccb62697ba608131038bb4303 Story: 2005575 Task: 33536
This commit is contained in:
parent
eb07913442
commit
d38844e390
@ -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
|
||||
|
||||
|
@ -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 - )
|
||||
---------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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.
|
||||
]
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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')}
|
||||
|
@ -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}'
|
||||
|
@ -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
|
||||
|
@ -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']
|
@ -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'])/
|
100
placement/tests/functional/gabbits/allocations-mappings.yaml
Normal file
100
placement/tests/functional/gabbits/allocations-mappings.yaml
Normal 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/
|
@ -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: /
|
||||
|
@ -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/
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user