Finalize openstack_sdk crate features work
Finishing work on introducing features in the sdk/cli it is necessary to populate sync/async feature macros already in templates. Since this is anyway causing major regeneration pull object-store (the sdk part) and fix new issues (caused by sequential updates without mass regeneration - to be fixed by introducing a separate job). Change-Id: I4f69325cf31a1ab677b4da96bf2dc92f17e85637
This commit is contained in:
parent
e084a3334e
commit
3bc9e13176
@ -427,6 +427,9 @@ def get_operation_variants(spec: dict, operation_name: str):
|
||||
elif "application/json-patch+json" in content:
|
||||
mime_type = "application/json-patch+json"
|
||||
operation_variants.append({"mime_type": mime_type})
|
||||
elif "*" in content:
|
||||
mime_type = "*"
|
||||
operation_variants.append({"mime_type": mime_type})
|
||||
elif content == {}:
|
||||
operation_variants.append({"body": None})
|
||||
else:
|
||||
@ -521,6 +524,12 @@ def get_resource_names_from_url(path: str):
|
||||
path_resource_names.remove("lbaa")
|
||||
if path.startswith("/v2/octavia/amphorae"):
|
||||
path_resource_names.remove("octavia")
|
||||
if path == "/v1/{account}":
|
||||
return ["account"]
|
||||
elif path == "/v1/{account}/{container}":
|
||||
return ["container"]
|
||||
elif path == "/v1/{account}/{container}/{object}":
|
||||
return ["object"]
|
||||
if len(path_resource_names) == 0:
|
||||
return ["version"]
|
||||
|
||||
|
@ -909,6 +909,8 @@ class TypeManager:
|
||||
name
|
||||
and name in unique_models
|
||||
and unique_models[name].hash_ == model_.reference.hash_
|
||||
# image.metadef.namespace have weird occurences of itself
|
||||
and model_.reference != unique_models[name]
|
||||
):
|
||||
# Ignore duplicated (or more precisely same) model
|
||||
self.ignored_models.append(model_.reference)
|
||||
|
@ -352,6 +352,34 @@ class MetadataGenerator(BaseGenerator):
|
||||
):
|
||||
# No need in HEAD defaults
|
||||
continue
|
||||
if args.service_type == "object-store":
|
||||
if resource_name == "object":
|
||||
mapping_obj: dict[str, str] = {
|
||||
"head": "head",
|
||||
"get": "get",
|
||||
"delete": "delete",
|
||||
"put": "put",
|
||||
"post": "update",
|
||||
}
|
||||
operation_key = mapping_obj[method]
|
||||
elif resource_name == "container":
|
||||
mapping_cont: dict[str, str] = {
|
||||
"head": "head",
|
||||
"get": "get",
|
||||
"delete": "delete",
|
||||
"put": "create",
|
||||
"post": "update",
|
||||
}
|
||||
operation_key = mapping_cont[method]
|
||||
elif resource_name == "account":
|
||||
mapping_account: dict[str, str] = {
|
||||
"head": "head",
|
||||
"get": "get",
|
||||
"delete": "delete",
|
||||
"put": "create",
|
||||
"post": "update",
|
||||
}
|
||||
operation_key = mapping_account[method]
|
||||
|
||||
if operation_key in resource_model:
|
||||
raise RuntimeError("Operation name conflict")
|
||||
@ -740,6 +768,10 @@ def post_process_operation(
|
||||
operation = post_process_network_operation(
|
||||
resource_name, operation_name, operation
|
||||
)
|
||||
elif service_type == "object-store":
|
||||
operation = post_process_object_store_operation(
|
||||
resource_name, operation_name, operation
|
||||
)
|
||||
return operation
|
||||
|
||||
|
||||
@ -1092,3 +1124,29 @@ def post_process_network_operation(
|
||||
].cli_full_command.replace("delete-all", "purge")
|
||||
|
||||
return operation
|
||||
|
||||
|
||||
def post_process_object_store_operation(
|
||||
resource_name: str, operation_name: str, operation
|
||||
):
|
||||
if resource_name == "account":
|
||||
if operation_name == "get":
|
||||
operation.targets["rust-cli"].cli_full_command = "container list"
|
||||
elif operation_name == "head":
|
||||
operation.targets["rust-cli"].cli_full_command = "account show"
|
||||
elif resource_name == "container":
|
||||
if operation_name == "get":
|
||||
operation.targets["rust-cli"].cli_full_command = "object list"
|
||||
elif operation_name == "head":
|
||||
operation.targets["rust-cli"].cli_full_command = "container show"
|
||||
elif resource_name == "object":
|
||||
if operation_name == "get":
|
||||
operation.targets["rust-cli"].cli_full_command = "object download"
|
||||
operation.operation_type = "download"
|
||||
elif operation_name == "head":
|
||||
operation.targets["rust-cli"].cli_full_command = "object show"
|
||||
elif operation_name == "put":
|
||||
operation.targets["rust-cli"].cli_full_command = "object upload"
|
||||
operation.operation_type = "upload"
|
||||
|
||||
return operation
|
||||
|
@ -673,8 +673,9 @@ class OpenAPISchemaParser(JsonSchemaParser):
|
||||
param_schema = schema.get("schema")
|
||||
param_typ = param_schema.get("type")
|
||||
dt: PrimitiveType | ADT | None = None
|
||||
if isinstance(param_typ, list) and "null" in param_typ:
|
||||
param_typ.remove("null")
|
||||
if isinstance(param_typ, list):
|
||||
if "null" in param_typ:
|
||||
param_typ.remove("null")
|
||||
if len(param_typ) == 1:
|
||||
param_typ = param_typ[0]
|
||||
if param_typ == "string":
|
||||
|
@ -640,8 +640,6 @@ class NovaGenerator(OpenStackServerSourceBase):
|
||||
schema.openstack = {}
|
||||
schema.openstack.setdefault("action-name", action_name)
|
||||
|
||||
if schema:
|
||||
print(schema.model_dump())
|
||||
return (ref, mime_type)
|
||||
|
||||
def _post_process_operation_hook(
|
||||
|
@ -657,10 +657,23 @@ class RequestTypeManager(common_rust.TypeManager):
|
||||
field_data_type = field_data_type.item_type
|
||||
elif isinstance(field_data_type, EnumGroupStruct):
|
||||
field_data_type.is_required = field.is_required
|
||||
elif isinstance(
|
||||
field_data_type, DictionaryInput
|
||||
) and not isinstance(
|
||||
field_data_type.value_type, common_rust.BasePrimitiveType
|
||||
elif (
|
||||
# is Dictionary
|
||||
isinstance(field_data_type, DictionaryInput)
|
||||
# of Primitives
|
||||
and not isinstance(
|
||||
field_data_type.value_type, common_rust.BasePrimitiveType
|
||||
)
|
||||
and not (
|
||||
# and not Option<Primitive>
|
||||
isinstance(
|
||||
field_data_type.value_type, self.option_type_class
|
||||
)
|
||||
and isinstance(
|
||||
field_data_type.value_type.item_type,
|
||||
common_rust.BasePrimitiveType,
|
||||
)
|
||||
)
|
||||
):
|
||||
dict_type_model = self._get_adt_by_reference(field.data_type)
|
||||
simplified_data_type = JsonValue()
|
||||
@ -1201,11 +1214,25 @@ class RustCliGenerator(BaseGenerator):
|
||||
response_def
|
||||
)
|
||||
if isinstance(root, model.Dictionary):
|
||||
value_type = (
|
||||
response_type_manager.convert_model(
|
||||
root.value_type
|
||||
value_type: (
|
||||
common_rust.BasePrimitiveType
|
||||
| common_rust.BaseCombinedType
|
||||
| common_rust.BaseCompoundType
|
||||
| None
|
||||
) = None
|
||||
try:
|
||||
value_type = (
|
||||
response_type_manager.convert_model(
|
||||
root.value_type
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
# In rare cases we can not conter
|
||||
# value_type since it depends on different
|
||||
# types. We are here in the output
|
||||
# simplification, so just downcast it to
|
||||
# JsonValue (what is anyway our goal)
|
||||
value_type = JsonValue()
|
||||
# if not isinstance(value_type, common_rust.BasePrimitiveType):
|
||||
# value_type = JsonValue(original_data_type=value_type)
|
||||
root_dict = HashMapResponse(
|
||||
|
@ -176,13 +176,20 @@ class BTreeMap(common_rust.Dictionary):
|
||||
".map(|(k, v)| (k, v.map(Into::into)))"
|
||||
)
|
||||
else:
|
||||
type_hint: str
|
||||
if isinstance(self.value_type, BTreeMap):
|
||||
type_hint = self.value_type.value_type.type_hint.replace(
|
||||
"Cow<'a, str>", "String"
|
||||
)
|
||||
return (
|
||||
f"BTreeMap::<String, BTreeMap<String, {self.value_type.value_type.type_hint}>>::new().into_iter()"
|
||||
f"BTreeMap::<String, BTreeMap<String, {type_hint}>>::new().into_iter()"
|
||||
f".map(|(k, v)| (k, v.into_iter()))"
|
||||
)
|
||||
else:
|
||||
return f"BTreeMap::<String, {self.value_type.type_hint}>::new().into_iter()"
|
||||
type_hint = self.value_type.type_hint.replace(
|
||||
"Cow<'a, str>", "String"
|
||||
)
|
||||
return f"BTreeMap::<String, {type_hint}>::new().into_iter()"
|
||||
|
||||
def get_mandatory_init(self):
|
||||
return ""
|
||||
|
@ -250,6 +250,8 @@ impl {{ target_class_name }}Command {
|
||||
let rsp: Response<Bytes> = ep.raw_query_async(client).await?;
|
||||
let data: serde_json::Value = serde_json::from_slice(rsp.body())?;
|
||||
op.output_machine(data)?;
|
||||
{%- else %}
|
||||
// not implemented
|
||||
{%- endif %}
|
||||
|
||||
{%- endwith %}
|
||||
|
@ -16,4 +16,10 @@
|
||||
.collect();
|
||||
|
||||
op.output_list::<ResponseData>(split)?;
|
||||
{%- elif data_type.__class__.__name__ in ["HashMapResponse"] %}
|
||||
let data: serde_json::Value = ep.query_async(client).await?;
|
||||
op.output_single::<ResponseData>(data)?;
|
||||
{%- else %}
|
||||
let data: serde_json::Value = ep.query_async(client).await?;
|
||||
op.output_list::<ResponseData>(data)?;
|
||||
{%- endif %}
|
||||
|
@ -273,12 +273,15 @@ mod tests {
|
||||
#![allow(unused_imports)]
|
||||
use super::*;
|
||||
{%- if method.upper() == "HEAD" %}
|
||||
#[cfg(feature = "sync")]
|
||||
use crate::api::RawQuery;
|
||||
{%- else %}
|
||||
#[cfg(feature = "sync")]
|
||||
use crate::api::Query;
|
||||
use serde_json::json;
|
||||
{%- endif %}
|
||||
use crate::types::ServiceType;
|
||||
#[cfg(feature = "sync")]
|
||||
use crate::test::client::MockServerClient;
|
||||
use http::{HeaderName, HeaderValue};
|
||||
{%- if is_json_patch %}
|
||||
@ -312,6 +315,7 @@ mod tests {
|
||||
{%- endif %}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
#[test]
|
||||
fn endpoint() {
|
||||
let client = MockServerClient::new();
|
||||
@ -343,6 +347,7 @@ mod tests {
|
||||
mock.assert();
|
||||
}
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
#[test]
|
||||
fn endpoint_headers() {
|
||||
let client = MockServerClient::new();
|
||||
|
@ -15,9 +15,11 @@ pub struct {{ data_type.name }}{{ type_manager.get_request_static_lifetimes(dat
|
||||
{%- endfor %}
|
||||
|
||||
{%- for name, param in type_manager.parameters | dictsort %}
|
||||
{%- if param.location != "header" %}
|
||||
{{ macros.docstring(param.description, indent=4) }}
|
||||
{{ param.builder_macros }}
|
||||
{{ param.local_name }}: {{ param.type_hint }},
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{% if is_json_patch %}
|
||||
|
@ -5,6 +5,7 @@ METADATA=metadata
|
||||
DST=~/workspace/github/gtema/openstack
|
||||
NET_RESOURCES=(
|
||||
"image"
|
||||
"metadef"
|
||||
"schema"
|
||||
)
|
||||
|
||||
|
@ -4,6 +4,8 @@ WRK_DIR=wrk
|
||||
METADATA=metadata
|
||||
DST=~/workspace/github/gtema/openstack
|
||||
NET_RESOURCES=(
|
||||
"address_group"
|
||||
"address_scope"
|
||||
"availability_zone"
|
||||
"extension"
|
||||
"floatingip"
|
||||
@ -18,10 +20,8 @@ openstack-codegenerator --work-dir ${WRK_DIR} --target rust-cli --metadata ${MET
|
||||
|
||||
|
||||
for resource in "${NET_RESOURCES[@]}"; do
|
||||
# openstack-codegenerator --work-dir ${WRK_DIR} --target rust-sdk --metadata ${METADATA}/network_metadata.yaml --service network # --resource ${resource}
|
||||
# openstack-codegenerator --work-dir ${WRK_DIR} --target rust-cli --metadata ${METADATA}/network_metadata.yaml --service network # --resource ${resource}
|
||||
|
||||
cp -av "${WRK_DIR}/rust/openstack_sdk/src/api/network/v2/${resource}" ${DST}/openstack_sdk/src/api/network/v2
|
||||
cp -av "${WRK_DIR}/rust/openstack_sdk/src/api/network/v2/${resource}.rs" ${DST}/openstack_sdk/src/api/network/v2
|
||||
cp -av "${WRK_DIR}/rust/openstack_cli/src/network/v2/${resource}" ${DST}/openstack_cli/src/network/v2
|
||||
cp -av "${WRK_DIR}/rust/openstack_cli/tests/network/v2/${resource}" ${DST}/openstack_cli/tests/network/v2
|
||||
done;
|
||||
|
@ -6,6 +6,8 @@ METADATA=metadata
|
||||
DST=~/workspace/github/gtema/openstack
|
||||
NET_RESOURCES=(
|
||||
"account"
|
||||
"container"
|
||||
"object"
|
||||
)
|
||||
|
||||
openstack-codegenerator --work-dir ${WRK_DIR} --target rust-sdk --metadata ${METADATA}/object-store_metadata.yaml --service object-store
|
||||
|
Loading…
x
Reference in New Issue
Block a user