Add ApiVersion info into generated RestEndpoint
Render min/required api version info directly into the rust sdk RestEndpoint to be able to rely on the results of version discovery and not hardcode the version prefix as part of the path. Change-Id: I5491d94392a6c32b5d700e47831971f170bf737d
This commit is contained in:
parent
c81e8c44b7
commit
3ac8000fcb
@ -20,7 +20,7 @@ import yaml
|
||||
from openapi_core import Spec
|
||||
from pydantic import BaseModel
|
||||
|
||||
VERSION_RE = re.compile(r"[Vv][0-9.]*")
|
||||
VERSION_RE = re.compile(r"^[Vv]([0-9]+)(\.([0-9]+))?$")
|
||||
# RE to split name from camelCase or by [`:`,`_`,`-`]
|
||||
SPLIT_NAME_RE = re.compile(r"(?<=[a-z])(?=[A-Z])|:|_|-")
|
||||
|
||||
|
@ -978,6 +978,8 @@ class TypeManager:
|
||||
"""Return static lifetimes of the Structure"""
|
||||
lifetimes = request_model.lifetimes
|
||||
for param in self.parameters.values():
|
||||
if param.location == "header":
|
||||
continue
|
||||
lt = param.lifetimes
|
||||
if lt:
|
||||
lifetimes.update(lt)
|
||||
|
@ -367,6 +367,16 @@ class RustSdkGenerator(BaseGenerator):
|
||||
spec, args.operation_name
|
||||
)
|
||||
|
||||
api_ver_matches: re.Match | None = None
|
||||
path_elements = path.lstrip("/").split("/")
|
||||
api_ver: dict[str, int] = {}
|
||||
ver_prefix: str | None = None
|
||||
if path_elements:
|
||||
api_ver_matches = re.match(common.VERSION_RE, path_elements[0])
|
||||
if api_ver_matches and api_ver_matches.groups():
|
||||
# Remember the version prefix to discard it in the template
|
||||
ver_prefix = path_elements[0]
|
||||
|
||||
for operation_variant in operation_variants:
|
||||
logging.debug("Processing variant %s" % operation_variant)
|
||||
# TODO(gtema): if we are in MV variants filter out unsupported query
|
||||
@ -374,6 +384,14 @@ class RustSdkGenerator(BaseGenerator):
|
||||
# TODO(gtema): previously we were ensuring `router_id` path param
|
||||
# is renamed to `id`
|
||||
|
||||
if api_ver_matches:
|
||||
api_ver = {
|
||||
"major": api_ver_matches.group(1),
|
||||
"minor": api_ver_matches.group(3) or 0,
|
||||
}
|
||||
else:
|
||||
api_ver = {}
|
||||
|
||||
class_name = res_name.title()
|
||||
operation_body = operation_variant.get("body")
|
||||
type_manager = TypeManager()
|
||||
@ -395,6 +413,13 @@ class RustSdkGenerator(BaseGenerator):
|
||||
min_ver = operation_body.get("x-openstack", {}).get("min-ver")
|
||||
if min_ver:
|
||||
mod_name += "_" + min_ver.replace(".", "")
|
||||
v = min_ver.split(".")
|
||||
if not len(v) == 2:
|
||||
raise RuntimeError(
|
||||
"Version information is not in format MAJOR.MINOR"
|
||||
)
|
||||
api_ver = {"major": v[0], "minor": v[1]}
|
||||
|
||||
# There is request body. Get the ADT from jsonschema
|
||||
# if args.operation_type != "action":
|
||||
(_, all_types) = openapi_parser.parse(
|
||||
@ -464,13 +489,14 @@ class RustSdkGenerator(BaseGenerator):
|
||||
sdk_service_name=common.get_rust_service_type_from_str(
|
||||
args.service_type
|
||||
),
|
||||
url=path[1:] if path.startswith("/") else path,
|
||||
url=path.lstrip("/").lstrip(ver_prefix).lstrip("/"),
|
||||
method=method,
|
||||
type_manager=type_manager,
|
||||
response_key=response_key,
|
||||
response_list_item_key=args.response_list_item_key,
|
||||
mime_type=mime_type,
|
||||
is_json_patch=is_json_patch,
|
||||
api_ver=api_ver,
|
||||
)
|
||||
|
||||
work_dir = Path(target_dir, "rust", "openstack_sdk", "src")
|
||||
|
@ -261,6 +261,13 @@ impl{{ type_manager.get_request_static_lifetimes(request) }} RestEndpoint for Re
|
||||
fn request_headers(&self) -> Option<&HeaderMap> {
|
||||
self._headers.as_ref()
|
||||
}
|
||||
{%- if api_ver %}
|
||||
|
||||
/// Returns required API version
|
||||
fn api_version(&self) -> Option<ApiVersion> {
|
||||
Some(ApiVersion::new({{ api_ver['major'] }}, {{ api_ver['minor'] }}))
|
||||
}
|
||||
{%- endif %}
|
||||
}
|
||||
|
||||
{#- EP is pageable if operation_type is list and there is limit or marker query parameter #}
|
||||
|
Loading…
x
Reference in New Issue
Block a user