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:
@@ -427,6 +427,9 @@ def get_operation_variants(spec: dict, operation_name: str):
|
|||||||
elif "application/json-patch+json" in content:
|
elif "application/json-patch+json" in content:
|
||||||
mime_type = "application/json-patch+json"
|
mime_type = "application/json-patch+json"
|
||||||
operation_variants.append({"mime_type": mime_type})
|
operation_variants.append({"mime_type": mime_type})
|
||||||
|
elif "*" in content:
|
||||||
|
mime_type = "*"
|
||||||
|
operation_variants.append({"mime_type": mime_type})
|
||||||
elif content == {}:
|
elif content == {}:
|
||||||
operation_variants.append({"body": None})
|
operation_variants.append({"body": None})
|
||||||
else:
|
else:
|
||||||
@@ -521,6 +524,12 @@ def get_resource_names_from_url(path: str):
|
|||||||
path_resource_names.remove("lbaa")
|
path_resource_names.remove("lbaa")
|
||||||
if path.startswith("/v2/octavia/amphorae"):
|
if path.startswith("/v2/octavia/amphorae"):
|
||||||
path_resource_names.remove("octavia")
|
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:
|
if len(path_resource_names) == 0:
|
||||||
return ["version"]
|
return ["version"]
|
||||||
|
|
||||||
|
|||||||
@@ -909,6 +909,8 @@ class TypeManager:
|
|||||||
name
|
name
|
||||||
and name in unique_models
|
and name in unique_models
|
||||||
and unique_models[name].hash_ == model_.reference.hash_
|
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
|
# Ignore duplicated (or more precisely same) model
|
||||||
self.ignored_models.append(model_.reference)
|
self.ignored_models.append(model_.reference)
|
||||||
|
|||||||
@@ -352,6 +352,34 @@ class MetadataGenerator(BaseGenerator):
|
|||||||
):
|
):
|
||||||
# No need in HEAD defaults
|
# No need in HEAD defaults
|
||||||
continue
|
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:
|
if operation_key in resource_model:
|
||||||
raise RuntimeError("Operation name conflict")
|
raise RuntimeError("Operation name conflict")
|
||||||
@@ -740,6 +768,10 @@ def post_process_operation(
|
|||||||
operation = post_process_network_operation(
|
operation = post_process_network_operation(
|
||||||
resource_name, operation_name, operation
|
resource_name, operation_name, operation
|
||||||
)
|
)
|
||||||
|
elif service_type == "object-store":
|
||||||
|
operation = post_process_object_store_operation(
|
||||||
|
resource_name, operation_name, operation
|
||||||
|
)
|
||||||
return operation
|
return operation
|
||||||
|
|
||||||
|
|
||||||
@@ -1092,3 +1124,29 @@ def post_process_network_operation(
|
|||||||
].cli_full_command.replace("delete-all", "purge")
|
].cli_full_command.replace("delete-all", "purge")
|
||||||
|
|
||||||
return operation
|
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_schema = schema.get("schema")
|
||||||
param_typ = param_schema.get("type")
|
param_typ = param_schema.get("type")
|
||||||
dt: PrimitiveType | ADT | None = None
|
dt: PrimitiveType | ADT | None = None
|
||||||
if isinstance(param_typ, list) and "null" in param_typ:
|
if isinstance(param_typ, list):
|
||||||
param_typ.remove("null")
|
if "null" in param_typ:
|
||||||
|
param_typ.remove("null")
|
||||||
if len(param_typ) == 1:
|
if len(param_typ) == 1:
|
||||||
param_typ = param_typ[0]
|
param_typ = param_typ[0]
|
||||||
if param_typ == "string":
|
if param_typ == "string":
|
||||||
|
|||||||
@@ -640,8 +640,6 @@ class NovaGenerator(OpenStackServerSourceBase):
|
|||||||
schema.openstack = {}
|
schema.openstack = {}
|
||||||
schema.openstack.setdefault("action-name", action_name)
|
schema.openstack.setdefault("action-name", action_name)
|
||||||
|
|
||||||
if schema:
|
|
||||||
print(schema.model_dump())
|
|
||||||
return (ref, mime_type)
|
return (ref, mime_type)
|
||||||
|
|
||||||
def _post_process_operation_hook(
|
def _post_process_operation_hook(
|
||||||
|
|||||||
@@ -657,10 +657,23 @@ class RequestTypeManager(common_rust.TypeManager):
|
|||||||
field_data_type = field_data_type.item_type
|
field_data_type = field_data_type.item_type
|
||||||
elif isinstance(field_data_type, EnumGroupStruct):
|
elif isinstance(field_data_type, EnumGroupStruct):
|
||||||
field_data_type.is_required = field.is_required
|
field_data_type.is_required = field.is_required
|
||||||
elif isinstance(
|
elif (
|
||||||
field_data_type, DictionaryInput
|
# is Dictionary
|
||||||
) and not isinstance(
|
isinstance(field_data_type, DictionaryInput)
|
||||||
field_data_type.value_type, common_rust.BasePrimitiveType
|
# 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)
|
dict_type_model = self._get_adt_by_reference(field.data_type)
|
||||||
simplified_data_type = JsonValue()
|
simplified_data_type = JsonValue()
|
||||||
@@ -1201,11 +1214,25 @@ class RustCliGenerator(BaseGenerator):
|
|||||||
response_def
|
response_def
|
||||||
)
|
)
|
||||||
if isinstance(root, model.Dictionary):
|
if isinstance(root, model.Dictionary):
|
||||||
value_type = (
|
value_type: (
|
||||||
response_type_manager.convert_model(
|
common_rust.BasePrimitiveType
|
||||||
root.value_type
|
| 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):
|
# if not isinstance(value_type, common_rust.BasePrimitiveType):
|
||||||
# value_type = JsonValue(original_data_type=value_type)
|
# value_type = JsonValue(original_data_type=value_type)
|
||||||
root_dict = HashMapResponse(
|
root_dict = HashMapResponse(
|
||||||
|
|||||||
@@ -176,13 +176,20 @@ class BTreeMap(common_rust.Dictionary):
|
|||||||
".map(|(k, v)| (k, v.map(Into::into)))"
|
".map(|(k, v)| (k, v.map(Into::into)))"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
type_hint: str
|
||||||
if isinstance(self.value_type, BTreeMap):
|
if isinstance(self.value_type, BTreeMap):
|
||||||
|
type_hint = self.value_type.value_type.type_hint.replace(
|
||||||
|
"Cow<'a, str>", "String"
|
||||||
|
)
|
||||||
return (
|
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()))"
|
f".map(|(k, v)| (k, v.into_iter()))"
|
||||||
)
|
)
|
||||||
else:
|
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):
|
def get_mandatory_init(self):
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -250,6 +250,8 @@ impl {{ target_class_name }}Command {
|
|||||||
let rsp: Response<Bytes> = ep.raw_query_async(client).await?;
|
let rsp: Response<Bytes> = ep.raw_query_async(client).await?;
|
||||||
let data: serde_json::Value = serde_json::from_slice(rsp.body())?;
|
let data: serde_json::Value = serde_json::from_slice(rsp.body())?;
|
||||||
op.output_machine(data)?;
|
op.output_machine(data)?;
|
||||||
|
{%- else %}
|
||||||
|
// not implemented
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- endwith %}
|
{%- endwith %}
|
||||||
|
|||||||
@@ -16,4 +16,10 @@
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
op.output_list::<ResponseData>(split)?;
|
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 %}
|
{%- endif %}
|
||||||
|
|||||||
@@ -273,12 +273,15 @@ mod tests {
|
|||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
use super::*;
|
use super::*;
|
||||||
{%- if method.upper() == "HEAD" %}
|
{%- if method.upper() == "HEAD" %}
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
use crate::api::RawQuery;
|
use crate::api::RawQuery;
|
||||||
{%- else %}
|
{%- else %}
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
use crate::api::Query;
|
use crate::api::Query;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
use crate::types::ServiceType;
|
use crate::types::ServiceType;
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
use crate::test::client::MockServerClient;
|
use crate::test::client::MockServerClient;
|
||||||
use http::{HeaderName, HeaderValue};
|
use http::{HeaderName, HeaderValue};
|
||||||
{%- if is_json_patch %}
|
{%- if is_json_patch %}
|
||||||
@@ -312,6 +315,7 @@ mod tests {
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
#[test]
|
#[test]
|
||||||
fn endpoint() {
|
fn endpoint() {
|
||||||
let client = MockServerClient::new();
|
let client = MockServerClient::new();
|
||||||
@@ -343,6 +347,7 @@ mod tests {
|
|||||||
mock.assert();
|
mock.assert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
#[test]
|
#[test]
|
||||||
fn endpoint_headers() {
|
fn endpoint_headers() {
|
||||||
let client = MockServerClient::new();
|
let client = MockServerClient::new();
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ pub struct {{ data_type.name }}{{ type_manager.get_request_static_lifetimes(dat
|
|||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
{%- for name, param in type_manager.parameters | dictsort %}
|
{%- for name, param in type_manager.parameters | dictsort %}
|
||||||
|
{%- if param.location != "header" %}
|
||||||
{{ macros.docstring(param.description, indent=4) }}
|
{{ macros.docstring(param.description, indent=4) }}
|
||||||
{{ param.builder_macros }}
|
{{ param.builder_macros }}
|
||||||
{{ param.local_name }}: {{ param.type_hint }},
|
{{ param.local_name }}: {{ param.type_hint }},
|
||||||
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
{% if is_json_patch %}
|
{% if is_json_patch %}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ METADATA=metadata
|
|||||||
DST=~/workspace/github/gtema/openstack
|
DST=~/workspace/github/gtema/openstack
|
||||||
NET_RESOURCES=(
|
NET_RESOURCES=(
|
||||||
"image"
|
"image"
|
||||||
|
"metadef"
|
||||||
"schema"
|
"schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ WRK_DIR=wrk
|
|||||||
METADATA=metadata
|
METADATA=metadata
|
||||||
DST=~/workspace/github/gtema/openstack
|
DST=~/workspace/github/gtema/openstack
|
||||||
NET_RESOURCES=(
|
NET_RESOURCES=(
|
||||||
|
"address_group"
|
||||||
|
"address_scope"
|
||||||
"availability_zone"
|
"availability_zone"
|
||||||
"extension"
|
"extension"
|
||||||
"floatingip"
|
"floatingip"
|
||||||
@@ -18,10 +20,8 @@ openstack-codegenerator --work-dir ${WRK_DIR} --target rust-cli --metadata ${MET
|
|||||||
|
|
||||||
|
|
||||||
for resource in "${NET_RESOURCES[@]}"; do
|
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}" ${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_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/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;
|
done;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ METADATA=metadata
|
|||||||
DST=~/workspace/github/gtema/openstack
|
DST=~/workspace/github/gtema/openstack
|
||||||
NET_RESOURCES=(
|
NET_RESOURCES=(
|
||||||
"account"
|
"account"
|
||||||
|
"container"
|
||||||
|
"object"
|
||||||
)
|
)
|
||||||
|
|
||||||
openstack-codegenerator --work-dir ${WRK_DIR} --target rust-sdk --metadata ${METADATA}/object-store_metadata.yaml --service object-store
|
openstack-codegenerator --work-dir ${WRK_DIR} --target rust-sdk --metadata ${METADATA}/object-store_metadata.yaml --service object-store
|
||||||
|
|||||||
Reference in New Issue
Block a user