in_tree[N] alloc_cands with microversion 1.31
This patch adds microversion 1.31 supporting the `in_tree`/`in_tree<N>` query parameters to the `GET /allocation_candidates` API. It accepts a UUID for a resource provider. If this parameter is provided, the only resource providers returned will be those with the same tree with the given resource provider. Change-Id: I24d333d1437168f27aaaac6d894a18271cb6ab91 Blueprint: alloc-candidates-in-tree
This commit is contained in:
parent
e7f3b1d59d
commit
ce10de2a29
@ -32,9 +32,11 @@ Request
|
|||||||
- resources: resources_query_ac
|
- resources: resources_query_ac
|
||||||
- required: required_traits_unnumbered
|
- required: required_traits_unnumbered
|
||||||
- member_of: member_of_1_21
|
- member_of: member_of_1_21
|
||||||
|
- in_tree: allocation_candidates_in_tree
|
||||||
- resourcesN: resources_query_granular
|
- resourcesN: resources_query_granular
|
||||||
- requiredN: required_traits_granular
|
- requiredN: required_traits_granular
|
||||||
- member_ofN: member_of_granular
|
- member_ofN: member_of_granular
|
||||||
|
- in_treeN: allocation_candidates_in_tree_granular
|
||||||
- group_policy: allocation_candidates_group_policy
|
- group_policy: allocation_candidates_group_policy
|
||||||
- limit: allocation_candidates_limit
|
- limit: allocation_candidates_limit
|
||||||
|
|
||||||
|
@ -55,6 +55,24 @@ allocation_candidates_group_policy:
|
|||||||
``group_policy=isolate``, numbered groups are guaranteed to be satisfied by
|
``group_policy=isolate``, numbered groups are guaranteed to be satisfied by
|
||||||
*different* providers - though there may still be overlap with the
|
*different* providers - though there may still be overlap with the
|
||||||
unnumbered group.
|
unnumbered group.
|
||||||
|
allocation_candidates_in_tree: &allocation_candidates_in_tree
|
||||||
|
type: string
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: >
|
||||||
|
A string representing a resource provider uuid. When supplied, it will
|
||||||
|
filter the returned allocation candidates to only those resource providers
|
||||||
|
that are in the same tree with the given resource provider.
|
||||||
|
min_version: 1.31
|
||||||
|
allocation_candidates_in_tree_granular:
|
||||||
|
<<: *allocation_candidates_in_tree
|
||||||
|
description: >
|
||||||
|
A string representing a resource provider uuid. The parameter key is
|
||||||
|
``in_treeN``, where ``N`` represents a positive integer suffix
|
||||||
|
corresponding with a ``resourcesN`` parameter. When supplied, it will
|
||||||
|
filter the returned allocation candidates for that numbered group to only
|
||||||
|
those resource providers that are in the same tree with the given resource
|
||||||
|
provider.
|
||||||
allocation_candidates_limit:
|
allocation_candidates_limit:
|
||||||
type: integer
|
type: integer
|
||||||
in: query
|
in: query
|
||||||
|
@ -282,7 +282,9 @@ def list_allocation_candidates(req):
|
|||||||
context.can(policies.LIST)
|
context.can(policies.LIST)
|
||||||
want_version = req.environ[microversion.MICROVERSION_ENVIRON]
|
want_version = req.environ[microversion.MICROVERSION_ENVIRON]
|
||||||
get_schema = schema.GET_SCHEMA_1_10
|
get_schema = schema.GET_SCHEMA_1_10
|
||||||
if want_version.matches((1, 25)):
|
if want_version.matches((1, 31)):
|
||||||
|
get_schema = schema.GET_SCHEMA_1_31
|
||||||
|
elif want_version.matches((1, 25)):
|
||||||
get_schema = schema.GET_SCHEMA_1_25
|
get_schema = schema.GET_SCHEMA_1_25
|
||||||
elif want_version.matches((1, 21)):
|
elif want_version.matches((1, 21)):
|
||||||
get_schema = schema.GET_SCHEMA_1_21
|
get_schema = schema.GET_SCHEMA_1_21
|
||||||
|
@ -27,14 +27,16 @@ from placement import util
|
|||||||
_QS_RESOURCES = 'resources'
|
_QS_RESOURCES = 'resources'
|
||||||
_QS_REQUIRED = 'required'
|
_QS_REQUIRED = 'required'
|
||||||
_QS_MEMBER_OF = 'member_of'
|
_QS_MEMBER_OF = 'member_of'
|
||||||
|
_QS_IN_TREE = 'in_tree'
|
||||||
_QS_KEY_PATTERN = re.compile(
|
_QS_KEY_PATTERN = re.compile(
|
||||||
r"^(%s)([1-9][0-9]*)?$" % '|'.join(
|
r"^(%s)([1-9][0-9]*)?$" % '|'.join(
|
||||||
(_QS_RESOURCES, _QS_REQUIRED, _QS_MEMBER_OF)))
|
(_QS_RESOURCES, _QS_REQUIRED, _QS_MEMBER_OF, _QS_IN_TREE)))
|
||||||
|
|
||||||
|
|
||||||
class RequestGroup(object):
|
class RequestGroup(object):
|
||||||
def __init__(self, use_same_provider=True, resources=None,
|
def __init__(self, use_same_provider=True, resources=None,
|
||||||
required_traits=None, forbidden_traits=None, member_of=None):
|
required_traits=None, forbidden_traits=None, member_of=None,
|
||||||
|
in_tree=None):
|
||||||
"""Create a grouping of resource and trait requests.
|
"""Create a grouping of resource and trait requests.
|
||||||
|
|
||||||
:param use_same_provider:
|
:param use_same_provider:
|
||||||
@ -47,12 +49,15 @@ class RequestGroup(object):
|
|||||||
:param forbidden_traits: A set of { trait_name, ... }
|
:param forbidden_traits: A set of { trait_name, ... }
|
||||||
:param member_of: A list of [ [aggregate_UUID],
|
:param member_of: A list of [ [aggregate_UUID],
|
||||||
[aggregate_UUID, aggregate_UUID] ... ]
|
[aggregate_UUID, aggregate_UUID] ... ]
|
||||||
|
:param in_tree: A UUID of a root or a non-root provider from whose
|
||||||
|
tree this RequestGroup must be satisfied.
|
||||||
"""
|
"""
|
||||||
self.use_same_provider = use_same_provider
|
self.use_same_provider = use_same_provider
|
||||||
self.resources = resources or {}
|
self.resources = resources or {}
|
||||||
self.required_traits = required_traits or set()
|
self.required_traits = required_traits or set()
|
||||||
self.forbidden_traits = forbidden_traits or set()
|
self.forbidden_traits = forbidden_traits or set()
|
||||||
self.member_of = member_of or []
|
self.member_of = member_of or []
|
||||||
|
self.in_tree = in_tree
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
ret = 'RequestGroup(use_same_provider=%s' % str(self.use_same_provider)
|
ret = 'RequestGroup(use_same_provider=%s' % str(self.use_same_provider)
|
||||||
@ -75,7 +80,7 @@ class RequestGroup(object):
|
|||||||
match = _QS_KEY_PATTERN.match(key)
|
match = _QS_KEY_PATTERN.match(key)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
# `prefix` is 'resources', 'required', or 'member_of'
|
# `prefix` is 'resources', 'required', 'member_of', or 'in_tree'
|
||||||
# `suffix` is an integer string, or None
|
# `suffix` is an integer string, or None
|
||||||
prefix, suffix = match.groups()
|
prefix, suffix = match.groups()
|
||||||
suffix = suffix or ''
|
suffix = suffix or ''
|
||||||
@ -99,6 +104,9 @@ class RequestGroup(object):
|
|||||||
# JSONSchema
|
# JSONSchema
|
||||||
request_group.member_of = util.normalize_member_of_qs_params(
|
request_group.member_of = util.normalize_member_of_qs_params(
|
||||||
req, suffix)
|
req, suffix)
|
||||||
|
elif prefix == _QS_IN_TREE:
|
||||||
|
request_group.in_tree = util.normalize_in_tree_qs_params(
|
||||||
|
val)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -160,6 +168,7 @@ class RequestGroup(object):
|
|||||||
|
|
||||||
?resources=$RESOURCE_CLASS_NAME:$AMOUNT,$RESOURCE_CLASS_NAME:$AMOUNT
|
?resources=$RESOURCE_CLASS_NAME:$AMOUNT,$RESOURCE_CLASS_NAME:$AMOUNT
|
||||||
&required=$TRAIT_NAME,$TRAIT_NAME&member_of=in:$AGG1_UUID,$AGG2_UUID
|
&required=$TRAIT_NAME,$TRAIT_NAME&member_of=in:$AGG1_UUID,$AGG2_UUID
|
||||||
|
&in_tree=$RP_UUID
|
||||||
&resources1=$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT
|
&resources1=$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT
|
||||||
&required1=$TRAIT_NAME,$TRAIT_NAME&member_of1=$AGG_UUID
|
&required1=$TRAIT_NAME,$TRAIT_NAME&member_of1=$AGG_UUID
|
||||||
&resources2=$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT
|
&resources2=$RESOURCE_CLASS_NAME:$AMOUNT,RESOURCE_CLASS_NAME:$AMOUNT
|
||||||
@ -186,6 +195,7 @@ class RequestGroup(object):
|
|||||||
&required=HW_CPU_X86_VMX,CUSTOM_STORAGE_RAID
|
&required=HW_CPU_X86_VMX,CUSTOM_STORAGE_RAID
|
||||||
&member_of=9323b2b1-82c9-4e91-bdff-e95e808ef954
|
&member_of=9323b2b1-82c9-4e91-bdff-e95e808ef954
|
||||||
&member_of=in:8592a199-7d73-4465-8df6-ab00a6243c82,ddbd9226-d6a6-475e-a85f-0609914dd058 # noqa
|
&member_of=in:8592a199-7d73-4465-8df6-ab00a6243c82,ddbd9226-d6a6-475e-a85f-0609914dd058 # noqa
|
||||||
|
&in_tree=b9fc9abb-afc2-44d7-9722-19afc977446a
|
||||||
&resources1=SRIOV_NET_VF:2
|
&resources1=SRIOV_NET_VF:2
|
||||||
&required1=CUSTOM_PHYSNET_PUBLIC,CUSTOM_SWITCH_A
|
&required1=CUSTOM_PHYSNET_PUBLIC,CUSTOM_SWITCH_A
|
||||||
&resources2=SRIOV_NET_VF:1
|
&resources2=SRIOV_NET_VF:1
|
||||||
@ -209,6 +219,7 @@ class RequestGroup(object):
|
|||||||
[8592a199-7d73-4465-8df6-ab00a6243c82,
|
[8592a199-7d73-4465-8df6-ab00a6243c82,
|
||||||
ddbd9226-d6a6-475e-a85f-0609914dd058],
|
ddbd9226-d6a6-475e-a85f-0609914dd058],
|
||||||
],
|
],
|
||||||
|
in_tree=b9fc9abb-afc2-44d7-9722-19afc977446a,
|
||||||
),
|
),
|
||||||
'1': RequestGroup(
|
'1': RequestGroup(
|
||||||
use_same_provider=True,
|
use_same_provider=True,
|
||||||
|
@ -77,6 +77,8 @@ VERSIONS = [
|
|||||||
'1.29', # Support nested providers in GET /allocation_candidates API.
|
'1.29', # Support nested providers in GET /allocation_candidates API.
|
||||||
'1.30', # Add POST /reshaper for atomically migrating resource provider
|
'1.30', # Add POST /reshaper for atomically migrating resource provider
|
||||||
# inventories and allocations.
|
# inventories and allocations.
|
||||||
|
'1.31', # Add in_tree and in_tree<N> queryparam on
|
||||||
|
# `GET /allocation_candidates` API
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -4129,6 +4129,15 @@ class AllocationCandidates(object):
|
|||||||
|
|
||||||
member_of = request.member_of
|
member_of = request.member_of
|
||||||
tree_root_id = None
|
tree_root_id = None
|
||||||
|
if request.in_tree:
|
||||||
|
tree_ids = _provider_ids_from_uuid(context, request.in_tree)
|
||||||
|
if tree_ids is None:
|
||||||
|
# List operations should simply return an empty list when a
|
||||||
|
# non-existing resource provider UUID is given for in_tree.
|
||||||
|
return [], []
|
||||||
|
tree_root_id = tree_ids.root_id
|
||||||
|
LOG.debug("getting allocation candidates in the same tree"
|
||||||
|
"with the root provider %s", tree_ids.root_uuid)
|
||||||
|
|
||||||
any_sharing = any(sharing_providers.values())
|
any_sharing = any(sharing_providers.values())
|
||||||
if not request.use_same_provider and (has_trees or any_sharing):
|
if not request.use_same_provider and (has_trees or any_sharing):
|
||||||
|
@ -517,3 +517,26 @@ of inventory moves from a parent provider to a new child provider.
|
|||||||
.. note:: This is a special operation that should only be used in rare cases
|
.. note:: This is a special operation that should only be used in rare cases
|
||||||
of resource provider topology changing when inventory is in use.
|
of resource provider topology changing when inventory is in use.
|
||||||
Only use this if you are really sure of what you are doing.
|
Only use this if you are really sure of what you are doing.
|
||||||
|
|
||||||
|
1.31 Add in_tree queryparam on GET /allocation_candidates (Maximum in Stein)
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.. versionadded:: Stein
|
||||||
|
|
||||||
|
Add support for the ``in_tree`` query parameter to the ``GET
|
||||||
|
/allocation_candidates`` API. It accepts a UUID for a resource provider.
|
||||||
|
If this parameter is provided, the only resource providers returned will be
|
||||||
|
those in the same tree with the given resource provider. The numbered syntax
|
||||||
|
``in_tree<N>`` is also supported. This restricts providers satisfying the Nth
|
||||||
|
granular request group to the tree of the specified provider. This may be
|
||||||
|
redundant with other ``in_tree<N>`` values specified in other groups
|
||||||
|
(including the unnumbered group). However, it can be useful in cases where a
|
||||||
|
specific resource (e.g. DISK_GB) needs to come from a specific sharing
|
||||||
|
provider (e.g. shared storage).
|
||||||
|
|
||||||
|
For example, a request for ``VCPU`` and ``VGPU`` resources from ``myhost``
|
||||||
|
and ``DISK_GB`` resources from ``sharing1`` might look like::
|
||||||
|
|
||||||
|
?resources=VCPU:1&in_tree=<myhost_uuid>
|
||||||
|
&resources1=VGPU:1&in_tree1=<myhost_uuid>
|
||||||
|
&resources2=DISK_GB:100&in_tree2=<sharing1_uuid>
|
||||||
|
@ -76,3 +76,8 @@ GET_SCHEMA_1_25["properties"]["group_policy"] = {
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["none", "isolate"],
|
"enum": ["none", "isolate"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add in_tree parameter.
|
||||||
|
GET_SCHEMA_1_31 = copy.deepcopy(GET_SCHEMA_1_25)
|
||||||
|
GET_SCHEMA_1_31["patternProperties"][_GROUP_PAT_FMT % "in_tree"] = {
|
||||||
|
"type": "string"}
|
||||||
|
@ -419,3 +419,186 @@ tests:
|
|||||||
response_json_paths:
|
response_json_paths:
|
||||||
$.allocation_requests.`len`: 4
|
$.allocation_requests.`len`: 4
|
||||||
$.provider_summaries.`len`: 5
|
$.provider_summaries.`len`: 5
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree old microversion
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,SRIOV_NET_VF:4&in_tree=$ENVIRON['CN1_UUID']
|
||||||
|
status: 400
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.30
|
||||||
|
response_strings:
|
||||||
|
- "Invalid query string parameters"
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree with invalid uuid
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,SRIOV_NET_VF:4&in_tree=life-is-beautiful
|
||||||
|
status: 400
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_strings:
|
||||||
|
- "Expected 'in_tree' parameter to be a format of uuid"
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree with root
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,SRIOV_NET_VF:4&in_tree=$ENVIRON['CN1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 2
|
||||||
|
$.provider_summaries.`len`: 5
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: [1, 1]
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_1_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_2_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree with child
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,SRIOV_NET_VF:4&in_tree=$ENVIRON['PF1_2_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 2
|
||||||
|
$.provider_summaries.`len`: 5
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: [1, 1]
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_1_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_2_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree with shared 1
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,DISK_GB:10&in_tree=$ENVIRON['CN1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
# CN1 has no local disk. SS can't be used since it's out of the CN1 tree.
|
||||||
|
$.allocation_requests.`len`: 0
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree with shared 2
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,DISK_GB:10&in_tree=$ENVIRON['CN2_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
# CN2 has local disk, but we don't get SS's disk
|
||||||
|
# because it's out of the CN2 tree.
|
||||||
|
$.allocation_requests.`len`: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 10
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree with shared 3
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1,DISK_GB:10&in_tree=$ENVIRON['SS_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
# SS doesn't have VCPU.
|
||||||
|
$.allocation_requests.`len`: 0
|
||||||
|
|
||||||
|
# Test granular scenarios with `in_tree<N>`
|
||||||
|
- name: get allocation candidates in tree granular error orphaned
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1&in_tree1=$ENVIRON['CN1_UUID']
|
||||||
|
status: 400
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_strings:
|
||||||
|
- "All request groups must specify resources."
|
||||||
|
|
||||||
|
- name: get allocation candidates, in_tree=$root, granular root resource
|
||||||
|
GET: /allocation_candidates?resources1=VCPU:1&in_tree1=$ENVIRON['CN1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1
|
||||||
|
|
||||||
|
- name: get allocation candidates, in_tree=$child, granular root resource
|
||||||
|
GET: /allocation_candidates?resources1=VCPU:1&in_tree1=$ENVIRON['PF1_1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1
|
||||||
|
|
||||||
|
- name: get allocation candidates, in_tree=$root, granular child resource
|
||||||
|
GET: /allocation_candidates?resources1=SRIOV_NET_VF:4&in_tree1=$ENVIRON['CN1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 2
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_1_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_2_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
|
||||||
|
- name: get allocation candidates, in_tree=$child, granular child resource
|
||||||
|
GET: /allocation_candidates?resources1=SRIOV_NET_VF:4&in_tree1=$ENVIRON['PF1_1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 2
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_1_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['PF1_2_UUID']"].resources.SRIOV_NET_VF: 4
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree granular local storage 1
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1&resources1=DISK_GB:10&in_tree1=$ENVIRON['CN1_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
# CN1 has no local storage
|
||||||
|
$.allocation_requests.`len`: 0
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree granular local storage 2
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1&resources1=DISK_GB:10&in_tree1=$ENVIRON['CN2_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 10
|
||||||
|
|
||||||
|
# Practical usage for "Give me DISK_GB from SS and VCPU from I-don't-care-where"
|
||||||
|
- name: get allocation candidates in tree granular shared storage
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1&resources1=DISK_GB:10&in_tree1=$ENVIRON['SS_UUID']
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 2
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['SS_UUID']"].resources.DISK_GB: [10, 10]
|
||||||
|
|
||||||
|
# Practical usage for "Give me VCPU from CN1 and DISK_GB from I-don't-care-where"
|
||||||
|
- name: get allocation candidates in tree granular compute 1
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1&in_tree=$ENVIRON['CN1_UUID']&resources1=DISK_GB:10
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
# CN1 has no local storage
|
||||||
|
$.allocation_requests.`len`: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['SS_UUID']"].resources.DISK_GB: 10
|
||||||
|
|
||||||
|
- name: get allocation candidates in tree granular compute 2
|
||||||
|
GET: /allocation_candidates?resources=VCPU:1&in_tree=$ENVIRON['CN2_UUID']&resources1=DISK_GB:10
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
# CN2 has local storage
|
||||||
|
$.allocation_requests.`len`: 2
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 10
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['SS_UUID']"].resources.DISK_GB: 10
|
||||||
|
|
||||||
|
# Practical usage for "Give me VCPU from CN1 and DISK_GB from SS"
|
||||||
|
- name: get allocation candidates in tree granular compute and granular shared storage
|
||||||
|
GET: /allocation_candidates?resources1=VCPU:1&in_tree1=$ENVIRON['CN1_UUID']&resources2=DISK_GB:10&in_tree2=$ENVIRON['SS_UUID']&group_policy=none
|
||||||
|
status: 200
|
||||||
|
request_headers:
|
||||||
|
openstack-api-version: placement 1.31
|
||||||
|
response_json_paths:
|
||||||
|
$.allocation_requests.`len`: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1
|
||||||
|
$.allocation_requests..allocations["$ENVIRON['SS_UUID']"].resources.DISK_GB: 10
|
||||||
|
@ -41,13 +41,13 @@ tests:
|
|||||||
response_json_paths:
|
response_json_paths:
|
||||||
$.errors[0].title: Not Acceptable
|
$.errors[0].title: Not Acceptable
|
||||||
|
|
||||||
- name: latest microversion is 1.30
|
- name: latest microversion is 1.31
|
||||||
GET: /
|
GET: /
|
||||||
request_headers:
|
request_headers:
|
||||||
openstack-api-version: placement latest
|
openstack-api-version: placement latest
|
||||||
response_headers:
|
response_headers:
|
||||||
vary: /openstack-api-version/
|
vary: /openstack-api-version/
|
||||||
openstack-api-version: placement 1.30
|
openstack-api-version: placement 1.31
|
||||||
|
|
||||||
- name: other accept header bad version
|
- name: other accept header bad version
|
||||||
GET: /
|
GET: /
|
||||||
|
@ -393,6 +393,23 @@ def normalize_member_of_qs_param(value):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_in_tree_qs_params(value):
|
||||||
|
"""Parse a in_tree query string parameter value.
|
||||||
|
|
||||||
|
:param value: in_tree query parameter: A UUID of a resource provider.
|
||||||
|
:return: A UUID of a resource provider.
|
||||||
|
:raises `webob.exc.HTTPBadRequest` if the val parameter is not in the
|
||||||
|
expected format.
|
||||||
|
"""
|
||||||
|
ret = value.strip()
|
||||||
|
if not uuidutils.is_uuid_like(ret):
|
||||||
|
msg = _("Invalid query string parameters: Expected 'in_tree' "
|
||||||
|
"parameter to be a format of uuid. "
|
||||||
|
"Got: %(val)s") % {'val': value}
|
||||||
|
raise webob.exc.HTTPBadRequest(msg)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def run_once(message, logger, cleanup=None):
|
def run_once(message, logger, cleanup=None):
|
||||||
"""This is a utility function decorator to ensure a function
|
"""This is a utility function decorator to ensure a function
|
||||||
is run once and only once in an interpreter instance.
|
is run once and only once in an interpreter instance.
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add support for the ``in_tree`` query parameter to the ``GET
|
||||||
|
/allocation_candidates`` API. It accepts a UUID for a resource provider.
|
||||||
|
If this parameter is provided, the only resource providers returned will
|
||||||
|
be those in the same tree with the given resource provider. The numbered
|
||||||
|
syntax ``in_tree<N>`` is also supported. This restricts providers
|
||||||
|
satisfying the Nth granular request group to the tree of the specified
|
||||||
|
provider. This may be redundant with other ``in_tree<N>`` values specified
|
||||||
|
in other groups (including the unnumbered group). However, it can be
|
||||||
|
useful in cases where a specific resource (e.g. DISK_GB) needs to come
|
||||||
|
from a specific sharing provider (e.g. shared storage).
|
||||||
|
|
||||||
|
For example, a request for ``VCPU`` and ``VGPU`` resources from ``myhost``
|
||||||
|
and ``DISK_GB`` resources from ``sharing1`` might look like::
|
||||||
|
|
||||||
|
?resources=VCPU:1&in_tree=<myhost_uuid>
|
||||||
|
&resources1=VGPU:1&in_tree1=<myhost_uuid>
|
||||||
|
&resources2=DISK_GB:100&in_tree2=<sharing1_uuid>
|
Loading…
Reference in New Issue
Block a user