diff --git a/codegenerator/openapi/placement.py b/codegenerator/openapi/placement.py index d822270..5a8084c 100644 --- a/codegenerator/openapi/placement.py +++ b/codegenerator/openapi/placement.py @@ -24,6 +24,7 @@ from codegenerator.common.schema import ParameterSchema from codegenerator.openapi import base from codegenerator.openapi.base import OpenStackServerSourceBase from codegenerator.openapi.utils import merge_api_ref_doc +from codegenerator.openapi.placement_schemas import aggregate from codegenerator.openapi.placement_schemas import allocation from codegenerator.openapi.placement_schemas import allocation_candidate from codegenerator.openapi.placement_schemas import inventory @@ -37,6 +38,7 @@ class PlacementGenerator(OpenStackServerSourceBase): URL_TAG_MAP = {"/versions": "version"} RESOURCE_MODULES = [ + aggregate, allocation, allocation_candidate, inventory, @@ -177,11 +179,20 @@ class PlacementGenerator(OpenStackServerSourceBase): contr = action action = None + f = controller.func closurevars = inspect.getclosurevars(controller.func) nonlocals = closurevars.nonlocals qualified_name: str | None = nonlocals.get("qualified_name") if qualified_name: action = qualified_name + else: + if "f" in nonlocals: + # RP aggregates uses additional decorator + closurevars = inspect.getclosurevars( + inspect.unwrap(nonlocals["f"]) + ) + nonlocals = closurevars.nonlocals + action = nonlocals.get("qualified_name") else: raise RuntimeError(f"Unsupported controller {controller}") diff --git a/codegenerator/openapi/placement_schemas/aggregate.py b/codegenerator/openapi/placement_schemas/aggregate.py new file mode 100644 index 0000000..ac74d38 --- /dev/null +++ b/codegenerator/openapi/placement_schemas/aggregate.py @@ -0,0 +1,76 @@ +# 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 aggregate + +AGGREGATES_SCHEMA: dict[str, Any] = { + "type": "object", + "properties": { + "aggregates": { + "type": "array", + "description": "A list of aggregate uuids. Previously nonexistent aggregates are created automatically.", + "items": {"type": "string", "format": "uuid"}, + "uniqueItems": True, + }, + "resource_provider_generation": { + "type": "integer", + "description": "A consistent view marker that assists with the management of concurrent resource provider updates.", + "x-openstack": {"min-ver": "1.19"}, + }, + }, + "required": ["aggregates", "resource_provider_generation"], + "additionalProperties": False, +} + +AGGREGATE_PUT_SCHEMA: dict[str, Any] = { + "oneOf": [ + { + **aggregate.PUT_AGGREGATES_SCHEMA_V1_1, + "x-openstack": {"min-ver": "1.1", "max-ver": "1.18"}, + }, + { + **aggregate.PUT_AGGREGATES_SCHEMA_V1_19, + "x-openstack": {"min-ver": "1.19"}, + }, + ], + "x-openstack": {"discriminator": "microversion"}, +} + + +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_ProvidersAggregatesGet_AggregatesResponse", + "Resource_ProvidersAggregatesSet_AggregatesResponse", + ]: + openapi_spec.components.schemas.setdefault( + name, TypeSchema(**AGGREGATES_SCHEMA) + ) + ref = f"#/components/schemas/{name}" + elif name == "Resource_ProvidersAggregatesSet_AggregatesRequest": + openapi_spec.components.schemas.setdefault( + name, TypeSchema(**AGGREGATE_PUT_SCHEMA) + ) + ref = f"#/components/schemas/{name}" + else: + return (None, None, False) + + return (ref, mime_type, True)