Add placement resource_provider and inventory schemas
Change-Id: Ic4c592b2c3d7ef89b6bdda84d041a17c93e3c5c4
This commit is contained in:
@@ -26,9 +26,11 @@ from codegenerator.openapi.base import OpenStackServerSourceBase
|
||||
from codegenerator.openapi.utils import merge_api_ref_doc
|
||||
from codegenerator.openapi.placement_schemas import allocation
|
||||
from codegenerator.openapi.placement_schemas import allocation_candidate
|
||||
from codegenerator.openapi.placement_schemas import resource_class
|
||||
from codegenerator.openapi.placement_schemas import trait
|
||||
from codegenerator.openapi.placement_schemas import inventory
|
||||
from codegenerator.openapi.placement_schemas import reshaper
|
||||
from codegenerator.openapi.placement_schemas import resource_class
|
||||
from codegenerator.openapi.placement_schemas import resource_provider
|
||||
from codegenerator.openapi.placement_schemas import trait
|
||||
|
||||
|
||||
class PlacementGenerator(OpenStackServerSourceBase):
|
||||
@@ -37,8 +39,10 @@ class PlacementGenerator(OpenStackServerSourceBase):
|
||||
RESOURCE_MODULES = [
|
||||
allocation,
|
||||
allocation_candidate,
|
||||
inventory,
|
||||
reshaper,
|
||||
resource_class,
|
||||
resource_provider,
|
||||
trait,
|
||||
]
|
||||
|
||||
|
||||
118
codegenerator/openapi/placement_schemas/inventory.py
Normal file
118
codegenerator/openapi/placement_schemas/inventory.py
Normal file
@@ -0,0 +1,118 @@
|
||||
# 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.
|
||||
#
|
||||
import copy
|
||||
|
||||
from typing import Any
|
||||
|
||||
from codegenerator.common.schema import TypeSchema
|
||||
from codegenerator.common.schema import ParameterSchema
|
||||
|
||||
INVENTORY_PROPERTIES: dict[str, Any] = {
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "The actual amount of the resource that the provider can accommodate.",
|
||||
},
|
||||
"reserved": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "The amount of the resource a provider has reserved for its own use.",
|
||||
},
|
||||
"min_unit": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "A minimum amount any single allocation against an inventory can have.",
|
||||
},
|
||||
"max_unit": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "A maximum amount any single allocation against an inventory can have.",
|
||||
},
|
||||
"step_size": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "A representation of the divisible amount of the resource that may be requested. For example, step_size = 5 means that only values divisible by 5 (5, 10, 15, etc.) can be requested.",
|
||||
},
|
||||
"allocation_ratio": {
|
||||
"type": "number",
|
||||
"description": "It is used in determining whether consumption of the resource of the provider can exceed physical constraints. For example, for a vCPU resource with: ``allocation_ratio = 16.0 total = 8`` Overall capacity is equal to 128 vCPUs.",
|
||||
},
|
||||
}
|
||||
|
||||
INVENTORIES_SCHEMA: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"inventories": {
|
||||
"type": "object",
|
||||
"description": "A dictionary of inventories keyed by resource classes.",
|
||||
"patternProperties": {
|
||||
"^[A-Z0-9_]+$": {
|
||||
"type": "object",
|
||||
"properties": INVENTORY_PROPERTIES,
|
||||
"required": ["total"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
},
|
||||
},
|
||||
"resource_provider_generation": {
|
||||
"type": "integer",
|
||||
"description": "A consistent view marker that assists with the management of concurrent resource provider updates.",
|
||||
},
|
||||
},
|
||||
"required": ["inventories", "resource_provider_generation"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
INVENTORY_SCHEMA: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"resource_provider_generation": {
|
||||
"type": "integer",
|
||||
"description": "A consistent view marker that assists with the management of concurrent resource provider updates.",
|
||||
},
|
||||
**INVENTORY_PROPERTIES,
|
||||
},
|
||||
"required": ["total", "resource_provider_generation"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
def _get_schema_ref(
|
||||
openapi_spec, name, description=None, schema_def=None, action_name=None
|
||||
) -> tuple[str | None, str | None, bool]:
|
||||
mime_type: str = "application/json"
|
||||
ref: str
|
||||
if name in [
|
||||
"Resource_ProvidersInventoriesGet_InventoriesResponse",
|
||||
"Resource_ProvidersInventoriesCreate_InventoryRequest",
|
||||
"Resource_ProvidersInventoriesCreate_InventoryResponse",
|
||||
"Resource_ProvidersInventoriesSet_InventoriesRequest",
|
||||
"Resource_ProvidersInventoriesSet_InventoriesResponse",
|
||||
]:
|
||||
openapi_spec.components.schemas.setdefault(
|
||||
name, TypeSchema(**INVENTORIES_SCHEMA)
|
||||
)
|
||||
ref = f"#/components/schemas/{name}"
|
||||
elif name in [
|
||||
"Resource_ProvidersInventoryGet_InventoryResponse",
|
||||
"Resource_ProvidersInventoryUpdate_InventoryRequest",
|
||||
"Resource_ProvidersInventoryUpdate_InventoryResponse",
|
||||
]:
|
||||
openapi_spec.components.schemas.setdefault(
|
||||
name, TypeSchema(**INVENTORY_SCHEMA)
|
||||
)
|
||||
ref = f"#/components/schemas/{name}"
|
||||
else:
|
||||
return (None, None, False)
|
||||
|
||||
return (ref, mime_type, True)
|
||||
201
codegenerator/openapi/placement_schemas/resource_provider.py
Normal file
201
codegenerator/openapi/placement_schemas/resource_provider.py
Normal file
@@ -0,0 +1,201 @@
|
||||
# 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.
|
||||
#
|
||||
import copy
|
||||
|
||||
from typing import Any
|
||||
|
||||
from codegenerator.common.schema import TypeSchema
|
||||
from codegenerator.common.schema import ParameterSchema
|
||||
from placement.schemas import resource_provider
|
||||
|
||||
RESOURCE_PROVIDER_SCHEMA: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"generation": {
|
||||
"type": "integer",
|
||||
"description": "A consistent view marker that assists with the management of concurrent resource provider updates.",
|
||||
},
|
||||
"uuid": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "The uuid of a resource provider.",
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"href": {"type": "string", "format": "uri"},
|
||||
"rel": {"type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of one resource provider.",
|
||||
},
|
||||
"parent_provider_uuid": {
|
||||
"type": "string",
|
||||
"description": "The UUID of the immediate parent of the resource provider.",
|
||||
"x-openstack": {"min-ver": "1.14"},
|
||||
},
|
||||
"root_provider_uuid": {
|
||||
"type": "string",
|
||||
"description": "Read-only UUID of the top-most provider in this provider tree.",
|
||||
"x-openstack": {"min-ver": "1.14"},
|
||||
},
|
||||
},
|
||||
"required": ["generation", "uuid", "links", "name"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
RESOURCE_PROVIDER_LIST_SCHEMA: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"resource_providers": {
|
||||
"type": "array",
|
||||
"items": RESOURCE_PROVIDER_SCHEMA,
|
||||
}
|
||||
},
|
||||
"required": ["resource_providers"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
RESOURCE_PROVIDER_POST_REQUEST_SCHEMA: dict[str, Any] = {
|
||||
"oneOf": [
|
||||
{
|
||||
**resource_provider.POST_RESOURCE_PROVIDER_SCHEMA,
|
||||
"x-openstack": {"min-ver": "1.0", "max-ver": "1.13"},
|
||||
},
|
||||
{
|
||||
**resource_provider.POST_RP_SCHEMA_V1_14,
|
||||
"x-openstack": {"min-ver": "1.14"},
|
||||
},
|
||||
],
|
||||
"x-openstack": {"discriminator": "microversion"},
|
||||
}
|
||||
|
||||
RESOURCE_PROVIDER_PUT_REQUEST_SCHEMA: dict[str, Any] = {
|
||||
"oneOf": [
|
||||
{
|
||||
**resource_provider.PUT_RESOURCE_PROVIDER_SCHEMA,
|
||||
"x-openstack": {"min-ver": "1.0", "max-ver": "1.13"},
|
||||
},
|
||||
{
|
||||
**resource_provider.PUT_RP_SCHEMA_V1_14,
|
||||
"x-openstack": {"min-ver": "1.14"},
|
||||
},
|
||||
],
|
||||
"x-openstack": {"discriminator": "microversion"},
|
||||
}
|
||||
|
||||
RESOURCE_PROVIDER_POST_SCHEMA: dict[str, Any] = {"oneOf": {}}
|
||||
|
||||
RESOURCE_PROVIDER_LIST_PARAMETERS: dict[str, Any] = {
|
||||
"name": {
|
||||
"in": "query",
|
||||
"name": "name",
|
||||
"description": "The name of a resource provider to filter the list.",
|
||||
"schema": {"type": "string"},
|
||||
},
|
||||
"uuid": {
|
||||
"in": "query",
|
||||
"name": "uuid",
|
||||
"description": "The uuid of a resource provider.",
|
||||
"schema": {"type": "string"},
|
||||
},
|
||||
"resources": {
|
||||
"in": "query",
|
||||
"name": "resources",
|
||||
"description": "A comma-separated list of strings indicating an amount of resource of a specified class that providers in each allocation request must collectively have the capacity and availability to serve: ``resources=VCPU:4,DISK_GB:64,MEMORY_MB:2048`` These resources may be satisfied by any provider in the same non-sharing tree or associated via aggregate.",
|
||||
"schema": {"type": "string"},
|
||||
"x-openstack": {"min-ver": "1.4"},
|
||||
},
|
||||
"required": {
|
||||
"in": "query",
|
||||
"name": "required",
|
||||
"description": "A comma-separated list of traits that a provider must have:\n ``required=HW_CPU_X86_AVX,HW_CPU_X86_SSE``\n Allocation requests in the response will be for resource providers that have capacity for all requested resources and the set of those resource providers will collectively contain all of the required traits. These traits may be satisfied by any provider in the same non-sharing tree or associated via aggregate as far as that provider also contributes resource to the request. Starting from microversion 1.22 traits which are forbidden from any resource provider contributing resources to the request may be expressed by prefixing a trait with a `!`.\nStarting from microversion 1.39 the required query parameter can be repeated. The trait lists from the repeated parameters are AND-ed together. So:\n``required=T1,!T2&required=T3`` means T1 and not T2 and T3.\n Also starting from microversion 1.39 the required parameter supports the syntax:\n``required=in:T1,T2,T3`` which means T1 or T2 or T3.\nMixing forbidden traits into an in: prefixed value is not supported and rejected. But mixing a normal trait list and an in: prefixed trait list in two query params within the same request is supported. So: ``required=in:T3,T4&required=T1,!T2`` is supported and it means T1 and not T2 and (T3 or T4).",
|
||||
"schema": {"type": "array", "items": {"type": "string"}},
|
||||
"style": "form",
|
||||
"explode": True,
|
||||
"x-openstack": {"min-ver": "1.18"},
|
||||
},
|
||||
"member_of": {
|
||||
"in": "query",
|
||||
"name": "member_of",
|
||||
"description": "A string representing an aggregate uuid; or the prefix in: followed by a comma-separated list of strings representing aggregate uuids. The resource providers in the allocation request in the response must directly or via the root provider be associated with the aggregate or aggregates identified by uuid:\n``member_of=5e08ea53-c4c6-448e-9334-ac4953de3cfa``, ``member_of=in:42896e0d-205d-4fe3-bd1e-100924931787,5e08ea53-c4c6-448e-9334-ac4953de3cfa``\nStarting from microversion 1.24 specifying multiple member_of query string parameters is possible. Multiple member_of parameters will result in filtering providers that are directly or via root provider associated with aggregates listed in all of the member_of query string values. For example, to get the providers that are associated with aggregate A as well as associated with any of aggregates B or C, the user could issue the following query: ``member_of=AGGA_UUID&member_of=in:AGGB_UUID,AGGC_UUID``\nStarting from microversion 1.32 specifying forbidden aggregates is supported in the member_of query string parameter. Forbidden aggregates are prefixed with a !. This negative expression can also be used in multiple member_of parameters: ``member_of=AGGA_UUID&member_of=!AGGB_UUID`` would translate logically to “Candidate resource providers must be in AGGA and not in AGGB.” We do NOT support ! on the values within in:, but we support !in:. Both of the following two example queries return candidate resource providers that are NOT in AGGA, AGGB, or AGGC: ``member_of=!in:AGGA_UUID,AGGB_UUID,AGGC_UUID``, ``member_of=!AGGA_UUID&member_of=!AGGB_UUID&member_of=!AGGC_UUID``\nWe do not check if the same aggregate uuid is in both positive and negative expression to return 400 BadRequest. We still return 200 for such cases. For example: ``member_of=AGGA_UUID&member_of=!AGGA_UUID`` would return empty allocation_requests and provider_summaries, while: ``member_of=in:AGGA_UUID,AGGB_UUID&member_of=!AGGA_UUID`` would return resource providers that are NOT in AGGA but in AGGB.",
|
||||
"schema": {"type": "array", "items": {"type": "string"}},
|
||||
"style": "form",
|
||||
"explode": True,
|
||||
"x-openstack": {"min-ver": "1.3"},
|
||||
},
|
||||
"in_tree": {
|
||||
"in": "query",
|
||||
"name": "in_tree",
|
||||
"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.",
|
||||
"schema": {"type": "string"},
|
||||
"x-openstack": {"min-ver": "1.14"},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _post_process_operation_hook(
|
||||
openapi_spec, operation_spec, path: str | None = None
|
||||
):
|
||||
"""Hook to allow service specific generator to modify details"""
|
||||
operationId = operation_spec.operationId
|
||||
|
||||
if operationId == "resource_providers:get":
|
||||
for key, val in RESOURCE_PROVIDER_LIST_PARAMETERS.items():
|
||||
openapi_spec.components.parameters.setdefault(
|
||||
key, ParameterSchema(**val)
|
||||
)
|
||||
ref = f"#/components/parameters/{key}"
|
||||
|
||||
if ref not in [x.ref for x in operation_spec.parameters]:
|
||||
operation_spec.parameters.append(ParameterSchema(ref=ref))
|
||||
|
||||
|
||||
def _get_schema_ref(
|
||||
openapi_spec, name, description=None, schema_def=None, action_name=None
|
||||
) -> tuple[str | None, str | None, bool]:
|
||||
mime_type: str = "application/json"
|
||||
ref: str
|
||||
if name == "Resource_ProvidersList_Resource_ProvidersResponse":
|
||||
openapi_spec.components.schemas.setdefault(
|
||||
name, TypeSchema(**RESOURCE_PROVIDER_LIST_SCHEMA)
|
||||
)
|
||||
ref = f"#/components/schemas/{name}"
|
||||
elif name in [
|
||||
"Resource_ProviderGet_Resource_ProviderResponse",
|
||||
"Resource_ProvidersCreate_Resource_ProviderResponse",
|
||||
"Resource_ProviderUpdate_Resource_ProviderResponse",
|
||||
]:
|
||||
openapi_spec.components.schemas.setdefault(
|
||||
name, TypeSchema(**RESOURCE_PROVIDER_SCHEMA)
|
||||
)
|
||||
ref = f"#/components/schemas/{name}"
|
||||
elif name == "Resource_ProvidersCreate_Resource_ProviderRequest":
|
||||
openapi_spec.components.schemas.setdefault(
|
||||
name, TypeSchema(**RESOURCE_PROVIDER_POST_REQUEST_SCHEMA)
|
||||
)
|
||||
ref = f"#/components/schemas/{name}"
|
||||
elif name == "Resource_ProviderUpdate_Resource_ProviderRequest":
|
||||
openapi_spec.components.schemas.setdefault(
|
||||
name, TypeSchema(**RESOURCE_PROVIDER_PUT_REQUEST_SCHEMA)
|
||||
)
|
||||
ref = f"#/components/schemas/{name}"
|
||||
else:
|
||||
return (None, None, False)
|
||||
|
||||
return (ref, mime_type, True)
|
||||
Reference in New Issue
Block a user