From 52eee9df4d5dec53843933c77c6e39c316e974fa Mon Sep 17 00:00:00 2001 From: Artem Goncharov Date: Mon, 14 Apr 2025 18:10:44 +0200 Subject: [PATCH] Repair image container_format and disk_format schema container_format and disk_format in reality need to be `anyOf[String, Enum]` since it is possible to modify this list on the deployment level. Unfortunately this also means that the CLI (create case) is becoming very tricky. For now prepare, but not enable corresponding changes in the create schema until a good way of handling this in cli has been found. Change-Id: I9162e238d98fd494131c01ff02990e2ddeda4887 --- codegenerator/common/__init__.py | 9 +++++ codegenerator/openapi/glance.py | 58 ++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/codegenerator/common/__init__.py b/codegenerator/common/__init__.py index 0f00ec3..b657372 100644 --- a/codegenerator/common/__init__.py +++ b/codegenerator/common/__init__.py @@ -168,6 +168,15 @@ def find_resource_schema( for kind in schema["allOf"]: kinds.update(kind) schema["type"] = kinds["type"] + elif "anyOf" in schema: + # {'anyOf': [ + # {'type': 'string'}, + # {'enum': ['a', 'b', 'c']}] + # } + kinds = {} + for kind in schema["anyOf"]: + kinds.update(kind) + schema["type"] = kinds["type"] elif schema == {}: return (None, None) elif "properties" in schema: diff --git a/codegenerator/openapi/glance.py b/codegenerator/openapi/glance.py index 873d77c..c466db0 100644 --- a/codegenerator/openapi/glance.py +++ b/codegenerator/openapi/glance.py @@ -11,6 +11,7 @@ # under the License. # import copy +from typing import Any from multiprocessing import Process from pathlib import Path @@ -420,7 +421,16 @@ class GlanceGenerator(OpenStackServerSourceBase): ref: str | None mime_type: str | None = "application/json" - if name == "TasksListResponse": + if name in [ + "ImagesIndexRequest", + "ImageShowRequest", + "ImagesTasksGet_Task_InfoRequest", + "ImageDeleteRequest", + "StoreDelete_From_StoreRequest", + "ImagesLocationsGet_LocationsRequest", + ]: + ref = None + elif name == "TasksListResponse": openapi_spec.components.schemas.setdefault( name, TypeSchema( @@ -717,9 +727,43 @@ class GlanceGenerator(OpenStackServerSourceBase): res["properties"]["images"]["items"]["properties"][field][ "format" ] = "int64" - elif name == "ImageShowResponse": + cf = res["properties"]["images"]["items"]["properties"][ + "container_format" + ] + res["properties"]["images"]["items"]["properties"][ + "container_format" + ] = self.fix_image_x_format_schema(cf) + cf = res["properties"]["images"]["items"]["properties"][ + "disk_format" + ] + res["properties"]["images"]["items"]["properties"][ + "disk_format" + ] = self.fix_image_x_format_schema(cf) + elif name in ["ImagesCreateRequest"]: + cf = res["properties"]["container_format"] + # TODO: Once a way to deal with this in CLI is found uncomment it + # res["properties"]["container_format"] = ( + # self.fix_image_x_format_schema(cf) + # ) + # cf = res["properties"]["disk_format"] + # res["properties"]["disk_format"] = ( + # self.fix_image_x_format_schema(cf) + # ) + elif name in [ + "ImageShowResponse", + "ImagesCreateResponse", + "ImageUpdateResponse", + ]: for field in i32_fixes: res["properties"][field]["format"] = "int64" + cf = res["properties"]["container_format"] + res["properties"]["container_format"] = ( + self.fix_image_x_format_schema(cf) + ) + cf = res["properties"]["disk_format"] + res["properties"]["disk_format"] = ( + self.fix_image_x_format_schema(cf) + ) elif name in [ "ImagesLocationsGet_LocationsResponse", "ImagesLocationsAdd_LocationResponse", @@ -739,6 +783,16 @@ class GlanceGenerator(OpenStackServerSourceBase): res.pop("links", None) return TypeSchema(**res) + @classmethod + def fix_image_x_format_schema( + cls, schema: dict[str, Any] + ) -> dict[str, Any]: + if "enum" in schema and "type" in schema: + cf_enum = schema.pop("enum") + cf_type = schema.pop("type") + schema.update({"anyOf": [{"enum": cf_enum}, {"type": cf_type}]}) + return schema + @classmethod def _get_response_codes(cls, method: str, operationId: str) -> list[str]: response_codes = super()._get_response_codes(method, operationId)