From 3b52662985b581a361fbe40d4c0a37ba73bdc917 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 3 May 2023 00:48:54 +0100 Subject: [PATCH 1/4] feat: paperclip cli-ng openapiv3 codegen Adds a new cli capability to generate code from openapiv3 As a start try to generate the same code as https://github.com/openebs/openapi-generator/blob/rust_mayastor/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustMayastorCodegen.java From then on we can improve on this code generation, making it more similar to the current v2 generation. Signed-off-by: Tiago Castro --- .github/workflows/cicd.yml | 8 +- .github/workflows/docs.yml | 2 +- .github/workflows/linter.yml | 2 +- Cargo.toml | 7 +- Makefile | 2 +- cli-ng/Cargo.toml | 27 + cli-ng/src/bin/cli/error.rs | 30 + cli-ng/src/bin/cli/main.rs | 99 ++ cli-ng/src/lib.rs | 5 + cli-ng/src/v3/mod.rs | 520 ++++++ cli-ng/src/v3/operation.rs | 243 +++ cli-ng/src/v3/parameter.rs | 101 ++ cli-ng/src/v3/property.rs | 981 +++++++++++ .../src/v3/templates/default/Cargo.mustache | 61 + cli-ng/src/v3/templates/default/README.md | 50 + .../default/actix/client/api_clients.mustache | 201 +++ .../default/actix/client/client.mustache | 134 ++ .../actix/client/configuration.mustache | 105 ++ .../v3/templates/default/actix/mod.mustache | 4 + .../default/actix/server/api.mustache | 21 + .../default/actix/server/api_mod.mustache | 251 +++ .../default/actix/server/handlers.mustache | 60 + .../src/v3/templates/default/api_doc.mustache | 47 + .../src/v3/templates/default/api_mod.mustache | 55 + .../v3/templates/default/gitignore.mustache | 2 + cli-ng/src/v3/templates/default/lib.mustache | 24 + cli-ng/src/v3/templates/default/mod.mustache | 4 + .../v3/templates/default/mod_clients.mustache | 9 + .../src/v3/templates/default/model.mustache | 129 ++ .../v3/templates/default/model_doc.mustache | 12 + .../v3/templates/default/model_mod.mustache | 6 + .../src/v3/templates/default/openapi.mustache | 1 + .../tower-hyper/client/api_clients.mustache | 291 ++++ .../default/tower-hyper/client/body.mustache | 46 + .../tower-hyper/client/client.mustache | 318 ++++ .../tower-hyper/client/configuration.mustache | 485 ++++++ .../default/tower-hyper/mod.mustache | 2 + cli-ng/src/v3/templates/mod.rs | 339 ++++ core/src/v2/mod.rs | 4 +- core/src/v3/mod.rs | 23 +- core/src/v3/{ => models}/contact.rs | 0 .../v3/{ => models}/external_documentation.rs | 0 core/src/v3/{ => models}/header.rs | 0 core/src/v3/{ => models}/info.rs | 0 core/src/v3/{ => models}/license.rs | 0 core/src/v3/models/mod.rs | 21 + core/src/v3/{ => models}/openapi.rs | 0 core/src/v3/{ => models}/operation.rs | 0 core/src/v3/{ => models}/parameter.rs | 0 core/src/v3/{ => models}/paths.rs | 0 core/src/v3/{ => models}/reference.rs | 0 core/src/v3/{ => models}/request_body.rs | 0 core/src/v3/{ => models}/response.rs | 0 core/src/v3/{ => models}/schema.rs | 0 core/src/v3/{ => models}/security_scheme.rs | 0 core/src/v3/{ => models}/tag.rs | 0 src/bin/main.rs | 65 +- src/v2/mod.rs | 28 + testgen/src/autogen/.gitignore | 2 + testgen/src/autogen/Cargo.toml | 61 + testgen/src/autogen/apis/actix_server.rs | 679 ++++++++ .../apis/app_nodes_api/actix/client/mod.rs | 295 ++++ .../autogen/apis/app_nodes_api/actix/mod.rs | 4 + .../app_nodes_api/actix/server/handlers.rs | 107 ++ .../apis/app_nodes_api/actix/server/mod.rs | 29 + testgen/src/autogen/apis/app_nodes_api/mod.rs | 4 + .../apis/app_nodes_api/tower/client/mod.rs | 472 ++++++ .../autogen/apis/app_nodes_api/tower/mod.rs | 2 + .../block_devices_api/actix/client/mod.rs | 107 ++ .../apis/block_devices_api/actix/mod.rs | 4 + .../actix/server/handlers.rs | 55 + .../block_devices_api/actix/server/mod.rs | 17 + .../src/autogen/apis/block_devices_api/mod.rs | 4 + .../block_devices_api/tower/client/mod.rs | 176 ++ .../apis/block_devices_api/tower/mod.rs | 2 + .../apis/children_api/actix/client/mod.rs | 523 ++++++ .../autogen/apis/children_api/actix/mod.rs | 4 + .../children_api/actix/server/handlers.rs | 157 ++ .../apis/children_api/actix/server/mod.rs | 45 + testgen/src/autogen/apis/children_api/mod.rs | 4 + .../apis/children_api/tower/client/mod.rs | 829 +++++++++ .../autogen/apis/children_api/tower/mod.rs | 2 + .../apis/json_grpc_api/actix/client/mod.rs | 96 ++ .../autogen/apis/json_grpc_api/actix/mod.rs | 4 + .../json_grpc_api/actix/server/handlers.rs | 45 + .../apis/json_grpc_api/actix/server/mod.rs | 17 + testgen/src/autogen/apis/json_grpc_api/mod.rs | 4 + .../apis/json_grpc_api/tower/client/mod.rs | 157 ++ .../autogen/apis/json_grpc_api/tower/mod.rs | 2 + testgen/src/autogen/apis/mod.rs | 77 + .../apis/nexuses_api/actix/client/mod.rs | 584 +++++++ .../src/autogen/apis/nexuses_api/actix/mod.rs | 4 + .../apis/nexuses_api/actix/server/handlers.rs | 173 ++ .../apis/nexuses_api/actix/server/mod.rs | 49 + testgen/src/autogen/apis/nexuses_api/mod.rs | 4 + .../apis/nexuses_api/tower/client/mod.rs | 925 ++++++++++ .../src/autogen/apis/nexuses_api/tower/mod.rs | 2 + .../apis/nodes_api/actix/client/mod.rs | 484 ++++++ .../src/autogen/apis/nodes_api/actix/mod.rs | 4 + .../apis/nodes_api/actix/server/handlers.rs | 161 ++ .../apis/nodes_api/actix/server/mod.rs | 41 + testgen/src/autogen/apis/nodes_api/mod.rs | 4 + .../apis/nodes_api/tower/client/mod.rs | 771 +++++++++ .../src/autogen/apis/nodes_api/tower/mod.rs | 2 + testgen/src/autogen/apis/openapi.yaml | 0 .../apis/pools_api/actix/client/mod.rs | 462 +++++ .../src/autogen/apis/pools_api/actix/mod.rs | 4 + .../apis/pools_api/actix/server/handlers.rs | 141 ++ .../apis/pools_api/actix/server/mod.rs | 41 + testgen/src/autogen/apis/pools_api/mod.rs | 4 + .../apis/pools_api/tower/client/mod.rs | 733 ++++++++ .../src/autogen/apis/pools_api/tower/mod.rs | 2 + .../apis/replicas_api/actix/client/mod.rs | 850 ++++++++++ .../autogen/apis/replicas_api/actix/mod.rs | 4 + .../replicas_api/actix/server/handlers.rs | 257 +++ .../apis/replicas_api/actix/server/mod.rs | 65 + testgen/src/autogen/apis/replicas_api/mod.rs | 4 + .../apis/replicas_api/tower/client/mod.rs | 1347 +++++++++++++++ .../autogen/apis/replicas_api/tower/mod.rs | 2 + .../apis/snapshots_api/actix/client/mod.rs | 508 ++++++ .../autogen/apis/snapshots_api/actix/mod.rs | 4 + .../snapshots_api/actix/server/handlers.rs | 177 ++ .../apis/snapshots_api/actix/server/mod.rs | 41 + testgen/src/autogen/apis/snapshots_api/mod.rs | 4 + .../apis/snapshots_api/tower/client/mod.rs | 811 +++++++++ .../autogen/apis/snapshots_api/tower/mod.rs | 2 + .../apis/specs_api/actix/client/mod.rs | 96 ++ .../src/autogen/apis/specs_api/actix/mod.rs | 4 + .../apis/specs_api/actix/server/handlers.rs | 45 + .../apis/specs_api/actix/server/mod.rs | 17 + testgen/src/autogen/apis/specs_api/mod.rs | 4 + .../apis/specs_api/tower/client/mod.rs | 157 ++ .../src/autogen/apis/specs_api/tower/mod.rs | 2 + .../apis/volumes_api/actix/client/mod.rs | 934 +++++++++++ .../src/autogen/apis/volumes_api/actix/mod.rs | 4 + .../apis/volumes_api/actix/server/handlers.rs | 291 ++++ .../apis/volumes_api/actix/server/mod.rs | 69 + testgen/src/autogen/apis/volumes_api/mod.rs | 4 + .../apis/volumes_api/tower/client/mod.rs | 1482 +++++++++++++++++ .../src/autogen/apis/volumes_api/tower/mod.rs | 2 + .../apis/watches_api/actix/client/mod.rs | 236 +++ .../src/autogen/apis/watches_api/actix/mod.rs | 4 + .../apis/watches_api/actix/server/handlers.rs | 97 ++ .../apis/watches_api/actix/server/mod.rs | 25 + testgen/src/autogen/apis/watches_api/mod.rs | 4 + .../apis/watches_api/tower/client/mod.rs | 379 +++++ .../src/autogen/apis/watches_api/tower/mod.rs | 2 + testgen/src/autogen/clients/mod.rs | 9 + testgen/src/autogen/clients/tower/body.rs | 46 + .../autogen/clients/tower/configuration.rs | 485 ++++++ testgen/src/autogen/clients/tower/mod.rs | 688 ++++++++ testgen/src/autogen/docs/apis/AppNodes.md | 140 ++ testgen/src/autogen/docs/apis/BlockDevices.md | 44 + testgen/src/autogen/docs/apis/Children.md | 286 ++++ testgen/src/autogen/docs/apis/JsonGrpc.md | 44 + testgen/src/autogen/docs/apis/Nexuses.md | 306 ++++ testgen/src/autogen/docs/apis/Nodes.md | 248 +++ testgen/src/autogen/docs/apis/Pools.md | 236 +++ testgen/src/autogen/docs/apis/Replicas.md | 456 +++++ testgen/src/autogen/docs/apis/Snapshots.md | 250 +++ testgen/src/autogen/docs/apis/Specs.md | 38 + testgen/src/autogen/docs/apis/Volumes.md | 472 ++++++ testgen/src/autogen/docs/apis/Watches.md | 110 ++ .../src/autogen/docs/models/AffinityGroup.md | 11 + testgen/src/autogen/docs/models/AppNode.md | 13 + .../src/autogen/docs/models/AppNodeSpec.md | 13 + .../src/autogen/docs/models/AppNodeState.md | 13 + testgen/src/autogen/docs/models/AppNodes.md | 12 + .../src/autogen/docs/models/BlockDevice.md | 23 + .../docs/models/BlockDeviceFilesystem.md | 14 + .../docs/models/BlockDevicePartition.md | 16 + testgen/src/autogen/docs/models/Child.md | 14 + testgen/src/autogen/docs/models/ChildState.md | 10 + .../autogen/docs/models/ChildStateReason.md | 10 + .../autogen/docs/models/CordonDrainState.md | 13 + .../src/autogen/docs/models/CordonedState.md | 11 + .../autogen/docs/models/CreateNexusBody.md | 12 + .../src/autogen/docs/models/CreatePoolBody.md | 12 + .../autogen/docs/models/CreateReplicaBody.md | 14 + .../autogen/docs/models/CreateVolumeBody.md | 18 + testgen/src/autogen/docs/models/DrainState.md | 12 + .../docs/models/ExplicitNodeTopology.md | 12 + .../autogen/docs/models/LabelledTopology.md | 13 + testgen/src/autogen/docs/models/Nexus.md | 18 + .../autogen/docs/models/NexusShareProtocol.md | 10 + testgen/src/autogen/docs/models/NexusSpec.md | 19 + .../autogen/docs/models/NexusSpecOperation.md | 12 + testgen/src/autogen/docs/models/NexusState.md | 10 + testgen/src/autogen/docs/models/Node.md | 13 + .../src/autogen/docs/models/NodeAccessInfo.md | 12 + testgen/src/autogen/docs/models/NodeSpec.md | 15 + testgen/src/autogen/docs/models/NodeState.md | 14 + testgen/src/autogen/docs/models/NodeStatus.md | 10 + .../src/autogen/docs/models/NodeTopology.md | 12 + .../models/OfflineReplicaSnapshotState.md | 14 + .../docs/models/OnlineReplicaSnapshotState.md | 18 + testgen/src/autogen/docs/models/Pool.md | 13 + testgen/src/autogen/docs/models/PoolSpec.md | 15 + testgen/src/autogen/docs/models/PoolState.md | 17 + testgen/src/autogen/docs/models/PoolStatus.md | 10 + .../src/autogen/docs/models/PoolTopology.md | 11 + testgen/src/autogen/docs/models/Protocol.md | 10 + .../autogen/docs/models/PublishVolumeBody.md | 16 + .../autogen/docs/models/RebuildJobState.md | 10 + .../src/autogen/docs/models/RebuildRecord.md | 21 + .../autogen/docs/models/RegisterAppNode.md | 12 + testgen/src/autogen/docs/models/Replica.md | 22 + .../src/autogen/docs/models/ReplicaKind.md | 10 + .../docs/models/ReplicaShareProtocol.md | 10 + .../autogen/docs/models/ReplicaSnapshot.md | 13 + .../docs/models/ReplicaSnapshotState.md | 12 + .../docs/models/ReplicaSnapshotStatus.md | 10 + .../autogen/docs/models/ReplicaSpaceUsage.md | 17 + .../src/autogen/docs/models/ReplicaSpec.md | 21 + .../docs/models/ReplicaSpecOperation.md | 12 + .../autogen/docs/models/ReplicaSpecOwners.md | 12 + .../src/autogen/docs/models/ReplicaState.md | 10 + .../autogen/docs/models/ReplicaTopology.md | 17 + .../src/autogen/docs/models/ReplicaUsage.md | 14 + .../autogen/docs/models/ResizeVolumeBody.md | 11 + .../src/autogen/docs/models/RestJsonError.md | 13 + testgen/src/autogen/docs/models/RestWatch.md | 12 + .../docs/models/SetVolumePropertyBody.md | 11 + .../autogen/docs/models/SnapshotAsSource.md | 12 + testgen/src/autogen/docs/models/SpecStatus.md | 10 + testgen/src/autogen/docs/models/Specs.md | 14 + testgen/src/autogen/docs/models/Topology.md | 12 + testgen/src/autogen/docs/models/Volume.md | 12 + .../docs/models/VolumeContentSource.md | 11 + .../src/autogen/docs/models/VolumePolicy.md | 11 + .../docs/models/VolumeShareProtocol.md | 10 + .../src/autogen/docs/models/VolumeSnapshot.md | 12 + .../docs/models/VolumeSnapshotDefinition.md | 12 + .../docs/models/VolumeSnapshotMetadata.md | 19 + .../autogen/docs/models/VolumeSnapshotSpec.md | 12 + .../docs/models/VolumeSnapshotState.md | 16 + .../autogen/docs/models/VolumeSnapshots.md | 12 + testgen/src/autogen/docs/models/VolumeSpec.md | 25 + .../docs/models/VolumeSpecOperation.md | 12 + .../src/autogen/docs/models/VolumeState.md | 16 + .../src/autogen/docs/models/VolumeStatus.md | 10 + .../src/autogen/docs/models/VolumeTarget.md | 13 + .../src/autogen/docs/models/VolumeUsage.md | 18 + testgen/src/autogen/docs/models/Volumes.md | 12 + .../src/autogen/docs/models/WatchCallback.md | 11 + testgen/src/autogen/mod.rs | 24 + testgen/src/autogen/models/affinity_group.rs | 52 + testgen/src/autogen/models/app_node.rs | 68 + testgen/src/autogen/models/app_node_spec.rs | 68 + testgen/src/autogen/models/app_node_state.rs | 89 + testgen/src/autogen/models/app_nodes.rs | 60 + testgen/src/autogen/models/block_device.rs | 148 ++ .../autogen/models/block_device_filesystem.rs | 76 + .../autogen/models/block_device_partition.rs | 92 + testgen/src/autogen/models/child.rs | 76 + testgen/src/autogen/models/child_state.rs | 61 + .../src/autogen/models/child_state_reason.rs | 46 + .../src/autogen/models/cordon_drain_state.rs | 49 + testgen/src/autogen/models/cordoned_state.rs | 52 + .../src/autogen/models/create_nexus_body.rs | 60 + .../src/autogen/models/create_pool_body.rs | 60 + .../src/autogen/models/create_replica_body.rs | 76 + .../src/autogen/models/create_volume_body.rs | 108 ++ testgen/src/autogen/models/drain_state.rs | 60 + .../autogen/models/explicit_node_topology.rs | 60 + .../src/autogen/models/labelled_topology.rs | 68 + testgen/src/autogen/models/mod.rs | 248 +++ testgen/src/autogen/models/nexus.rs | 108 ++ .../autogen/models/nexus_share_protocol.rs | 51 + testgen/src/autogen/models/nexus_spec.rs | 116 ++ .../autogen/models/nexus_spec_operation.rs | 96 ++ testgen/src/autogen/models/nexus_state.rs | 71 + testgen/src/autogen/models/node.rs | 68 + .../src/autogen/models/node_access_info.rs | 60 + testgen/src/autogen/models/node_spec.rs | 84 + testgen/src/autogen/models/node_state.rs | 76 + testgen/src/autogen/models/node_status.rs | 56 + testgen/src/autogen/models/node_topology.rs | 43 + .../models/offline_replica_snapshot_state.rs | 76 + .../models/online_replica_snapshot_state.rs | 108 ++ testgen/src/autogen/models/pool.rs | 68 + testgen/src/autogen/models/pool_spec.rs | 84 + testgen/src/autogen/models/pool_state.rs | 100 ++ testgen/src/autogen/models/pool_status.rs | 61 + testgen/src/autogen/models/pool_topology.rs | 37 + testgen/src/autogen/models/protocol.rs | 61 + .../src/autogen/models/publish_volume_body.rs | 92 + .../src/autogen/models/rebuild_job_state.rs | 71 + testgen/src/autogen/models/rebuild_record.rs | 132 ++ .../src/autogen/models/register_app_node.rs | 60 + testgen/src/autogen/models/replica.rs | 140 ++ testgen/src/autogen/models/replica_kind.rs | 56 + .../autogen/models/replica_share_protocol.rs | 46 + .../src/autogen/models/replica_snapshot.rs | 68 + .../autogen/models/replica_snapshot_state.rs | 43 + .../autogen/models/replica_snapshot_status.rs | 56 + .../src/autogen/models/replica_space_usage.rs | 100 ++ testgen/src/autogen/models/replica_spec.rs | 132 ++ .../autogen/models/replica_spec_operation.rs | 87 + .../src/autogen/models/replica_spec_owners.rs | 60 + testgen/src/autogen/models/replica_state.rs | 61 + .../src/autogen/models/replica_topology.rs | 100 ++ testgen/src/autogen/models/replica_usage.rs | 76 + .../src/autogen/models/resize_volume_body.rs | 52 + testgen/src/autogen/models/rest_json_error.rs | 161 ++ testgen/src/autogen/models/rest_watch.rs | 60 + .../models/set_volume_property_body.rs | 37 + .../src/autogen/models/snapshot_as_source.rs | 60 + testgen/src/autogen/models/spec_status.rs | 61 + testgen/src/autogen/models/specs.rs | 76 + testgen/src/autogen/models/topology.rs | 60 + testgen/src/autogen/models/volume.rs | 60 + .../autogen/models/volume_content_source.rs | 37 + testgen/src/autogen/models/volume_policy.rs | 52 + .../autogen/models/volume_share_protocol.rs | 51 + testgen/src/autogen/models/volume_snapshot.rs | 60 + .../models/volume_snapshot_definition.rs | 60 + .../models/volume_snapshot_metadata.rs | 116 ++ .../autogen/models/volume_snapshot_spec.rs | 60 + .../autogen/models/volume_snapshot_state.rs | 92 + .../src/autogen/models/volume_snapshots.rs | 60 + testgen/src/autogen/models/volume_spec.rs | 164 ++ .../autogen/models/volume_spec_operation.rs | 114 ++ testgen/src/autogen/models/volume_state.rs | 92 + testgen/src/autogen/models/volume_status.rs | 66 + testgen/src/autogen/models/volume_target.rs | 68 + testgen/src/autogen/models/volume_usage.rs | 108 ++ testgen/src/autogen/models/volumes.rs | 60 + testgen/src/autogen/models/watch_callback.rs | 37 + 329 files changed, 32687 insertions(+), 37 deletions(-) create mode 100644 cli-ng/Cargo.toml create mode 100644 cli-ng/src/bin/cli/error.rs create mode 100644 cli-ng/src/bin/cli/main.rs create mode 100644 cli-ng/src/lib.rs create mode 100644 cli-ng/src/v3/mod.rs create mode 100644 cli-ng/src/v3/operation.rs create mode 100644 cli-ng/src/v3/parameter.rs create mode 100644 cli-ng/src/v3/property.rs create mode 100644 cli-ng/src/v3/templates/default/Cargo.mustache create mode 100644 cli-ng/src/v3/templates/default/README.md create mode 100644 cli-ng/src/v3/templates/default/actix/client/api_clients.mustache create mode 100644 cli-ng/src/v3/templates/default/actix/client/client.mustache create mode 100644 cli-ng/src/v3/templates/default/actix/client/configuration.mustache create mode 100644 cli-ng/src/v3/templates/default/actix/mod.mustache create mode 100644 cli-ng/src/v3/templates/default/actix/server/api.mustache create mode 100644 cli-ng/src/v3/templates/default/actix/server/api_mod.mustache create mode 100644 cli-ng/src/v3/templates/default/actix/server/handlers.mustache create mode 100644 cli-ng/src/v3/templates/default/api_doc.mustache create mode 100644 cli-ng/src/v3/templates/default/api_mod.mustache create mode 100644 cli-ng/src/v3/templates/default/gitignore.mustache create mode 100644 cli-ng/src/v3/templates/default/lib.mustache create mode 100644 cli-ng/src/v3/templates/default/mod.mustache create mode 100644 cli-ng/src/v3/templates/default/mod_clients.mustache create mode 100644 cli-ng/src/v3/templates/default/model.mustache create mode 100644 cli-ng/src/v3/templates/default/model_doc.mustache create mode 100644 cli-ng/src/v3/templates/default/model_mod.mustache create mode 100644 cli-ng/src/v3/templates/default/openapi.mustache create mode 100644 cli-ng/src/v3/templates/default/tower-hyper/client/api_clients.mustache create mode 100644 cli-ng/src/v3/templates/default/tower-hyper/client/body.mustache create mode 100644 cli-ng/src/v3/templates/default/tower-hyper/client/client.mustache create mode 100644 cli-ng/src/v3/templates/default/tower-hyper/client/configuration.mustache create mode 100644 cli-ng/src/v3/templates/default/tower-hyper/mod.mustache create mode 100644 cli-ng/src/v3/templates/mod.rs rename core/src/v3/{ => models}/contact.rs (100%) rename core/src/v3/{ => models}/external_documentation.rs (100%) rename core/src/v3/{ => models}/header.rs (100%) rename core/src/v3/{ => models}/info.rs (100%) rename core/src/v3/{ => models}/license.rs (100%) create mode 100644 core/src/v3/models/mod.rs rename core/src/v3/{ => models}/openapi.rs (100%) rename core/src/v3/{ => models}/operation.rs (100%) rename core/src/v3/{ => models}/parameter.rs (100%) rename core/src/v3/{ => models}/paths.rs (100%) rename core/src/v3/{ => models}/reference.rs (100%) rename core/src/v3/{ => models}/request_body.rs (100%) rename core/src/v3/{ => models}/response.rs (100%) rename core/src/v3/{ => models}/schema.rs (100%) rename core/src/v3/{ => models}/security_scheme.rs (100%) rename core/src/v3/{ => models}/tag.rs (100%) create mode 100644 testgen/src/autogen/.gitignore create mode 100644 testgen/src/autogen/Cargo.toml create mode 100644 testgen/src/autogen/apis/actix_server.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/mod.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/app_nodes_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/mod.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/block_devices_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/children_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/children_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/children_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/children_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/children_api/mod.rs create mode 100644 testgen/src/autogen/apis/children_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/children_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/mod.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/json_grpc_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/mod.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/mod.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/nexuses_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/nodes_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/nodes_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/nodes_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/nodes_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/nodes_api/mod.rs create mode 100644 testgen/src/autogen/apis/nodes_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/nodes_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/openapi.yaml create mode 100644 testgen/src/autogen/apis/pools_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/pools_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/pools_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/pools_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/pools_api/mod.rs create mode 100644 testgen/src/autogen/apis/pools_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/pools_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/replicas_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/replicas_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/replicas_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/replicas_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/replicas_api/mod.rs create mode 100644 testgen/src/autogen/apis/replicas_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/replicas_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/mod.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/snapshots_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/specs_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/specs_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/specs_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/specs_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/specs_api/mod.rs create mode 100644 testgen/src/autogen/apis/specs_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/specs_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/volumes_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/volumes_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/volumes_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/volumes_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/volumes_api/mod.rs create mode 100644 testgen/src/autogen/apis/volumes_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/volumes_api/tower/mod.rs create mode 100644 testgen/src/autogen/apis/watches_api/actix/client/mod.rs create mode 100644 testgen/src/autogen/apis/watches_api/actix/mod.rs create mode 100644 testgen/src/autogen/apis/watches_api/actix/server/handlers.rs create mode 100644 testgen/src/autogen/apis/watches_api/actix/server/mod.rs create mode 100644 testgen/src/autogen/apis/watches_api/mod.rs create mode 100644 testgen/src/autogen/apis/watches_api/tower/client/mod.rs create mode 100644 testgen/src/autogen/apis/watches_api/tower/mod.rs create mode 100644 testgen/src/autogen/clients/mod.rs create mode 100644 testgen/src/autogen/clients/tower/body.rs create mode 100644 testgen/src/autogen/clients/tower/configuration.rs create mode 100644 testgen/src/autogen/clients/tower/mod.rs create mode 100644 testgen/src/autogen/docs/apis/AppNodes.md create mode 100644 testgen/src/autogen/docs/apis/BlockDevices.md create mode 100644 testgen/src/autogen/docs/apis/Children.md create mode 100644 testgen/src/autogen/docs/apis/JsonGrpc.md create mode 100644 testgen/src/autogen/docs/apis/Nexuses.md create mode 100644 testgen/src/autogen/docs/apis/Nodes.md create mode 100644 testgen/src/autogen/docs/apis/Pools.md create mode 100644 testgen/src/autogen/docs/apis/Replicas.md create mode 100644 testgen/src/autogen/docs/apis/Snapshots.md create mode 100644 testgen/src/autogen/docs/apis/Specs.md create mode 100644 testgen/src/autogen/docs/apis/Volumes.md create mode 100644 testgen/src/autogen/docs/apis/Watches.md create mode 100644 testgen/src/autogen/docs/models/AffinityGroup.md create mode 100644 testgen/src/autogen/docs/models/AppNode.md create mode 100644 testgen/src/autogen/docs/models/AppNodeSpec.md create mode 100644 testgen/src/autogen/docs/models/AppNodeState.md create mode 100644 testgen/src/autogen/docs/models/AppNodes.md create mode 100644 testgen/src/autogen/docs/models/BlockDevice.md create mode 100644 testgen/src/autogen/docs/models/BlockDeviceFilesystem.md create mode 100644 testgen/src/autogen/docs/models/BlockDevicePartition.md create mode 100644 testgen/src/autogen/docs/models/Child.md create mode 100644 testgen/src/autogen/docs/models/ChildState.md create mode 100644 testgen/src/autogen/docs/models/ChildStateReason.md create mode 100644 testgen/src/autogen/docs/models/CordonDrainState.md create mode 100644 testgen/src/autogen/docs/models/CordonedState.md create mode 100644 testgen/src/autogen/docs/models/CreateNexusBody.md create mode 100644 testgen/src/autogen/docs/models/CreatePoolBody.md create mode 100644 testgen/src/autogen/docs/models/CreateReplicaBody.md create mode 100644 testgen/src/autogen/docs/models/CreateVolumeBody.md create mode 100644 testgen/src/autogen/docs/models/DrainState.md create mode 100644 testgen/src/autogen/docs/models/ExplicitNodeTopology.md create mode 100644 testgen/src/autogen/docs/models/LabelledTopology.md create mode 100644 testgen/src/autogen/docs/models/Nexus.md create mode 100644 testgen/src/autogen/docs/models/NexusShareProtocol.md create mode 100644 testgen/src/autogen/docs/models/NexusSpec.md create mode 100644 testgen/src/autogen/docs/models/NexusSpecOperation.md create mode 100644 testgen/src/autogen/docs/models/NexusState.md create mode 100644 testgen/src/autogen/docs/models/Node.md create mode 100644 testgen/src/autogen/docs/models/NodeAccessInfo.md create mode 100644 testgen/src/autogen/docs/models/NodeSpec.md create mode 100644 testgen/src/autogen/docs/models/NodeState.md create mode 100644 testgen/src/autogen/docs/models/NodeStatus.md create mode 100644 testgen/src/autogen/docs/models/NodeTopology.md create mode 100644 testgen/src/autogen/docs/models/OfflineReplicaSnapshotState.md create mode 100644 testgen/src/autogen/docs/models/OnlineReplicaSnapshotState.md create mode 100644 testgen/src/autogen/docs/models/Pool.md create mode 100644 testgen/src/autogen/docs/models/PoolSpec.md create mode 100644 testgen/src/autogen/docs/models/PoolState.md create mode 100644 testgen/src/autogen/docs/models/PoolStatus.md create mode 100644 testgen/src/autogen/docs/models/PoolTopology.md create mode 100644 testgen/src/autogen/docs/models/Protocol.md create mode 100644 testgen/src/autogen/docs/models/PublishVolumeBody.md create mode 100644 testgen/src/autogen/docs/models/RebuildJobState.md create mode 100644 testgen/src/autogen/docs/models/RebuildRecord.md create mode 100644 testgen/src/autogen/docs/models/RegisterAppNode.md create mode 100644 testgen/src/autogen/docs/models/Replica.md create mode 100644 testgen/src/autogen/docs/models/ReplicaKind.md create mode 100644 testgen/src/autogen/docs/models/ReplicaShareProtocol.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSnapshot.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSnapshotState.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSnapshotStatus.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSpaceUsage.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSpec.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSpecOperation.md create mode 100644 testgen/src/autogen/docs/models/ReplicaSpecOwners.md create mode 100644 testgen/src/autogen/docs/models/ReplicaState.md create mode 100644 testgen/src/autogen/docs/models/ReplicaTopology.md create mode 100644 testgen/src/autogen/docs/models/ReplicaUsage.md create mode 100644 testgen/src/autogen/docs/models/ResizeVolumeBody.md create mode 100644 testgen/src/autogen/docs/models/RestJsonError.md create mode 100644 testgen/src/autogen/docs/models/RestWatch.md create mode 100644 testgen/src/autogen/docs/models/SetVolumePropertyBody.md create mode 100644 testgen/src/autogen/docs/models/SnapshotAsSource.md create mode 100644 testgen/src/autogen/docs/models/SpecStatus.md create mode 100644 testgen/src/autogen/docs/models/Specs.md create mode 100644 testgen/src/autogen/docs/models/Topology.md create mode 100644 testgen/src/autogen/docs/models/Volume.md create mode 100644 testgen/src/autogen/docs/models/VolumeContentSource.md create mode 100644 testgen/src/autogen/docs/models/VolumePolicy.md create mode 100644 testgen/src/autogen/docs/models/VolumeShareProtocol.md create mode 100644 testgen/src/autogen/docs/models/VolumeSnapshot.md create mode 100644 testgen/src/autogen/docs/models/VolumeSnapshotDefinition.md create mode 100644 testgen/src/autogen/docs/models/VolumeSnapshotMetadata.md create mode 100644 testgen/src/autogen/docs/models/VolumeSnapshotSpec.md create mode 100644 testgen/src/autogen/docs/models/VolumeSnapshotState.md create mode 100644 testgen/src/autogen/docs/models/VolumeSnapshots.md create mode 100644 testgen/src/autogen/docs/models/VolumeSpec.md create mode 100644 testgen/src/autogen/docs/models/VolumeSpecOperation.md create mode 100644 testgen/src/autogen/docs/models/VolumeState.md create mode 100644 testgen/src/autogen/docs/models/VolumeStatus.md create mode 100644 testgen/src/autogen/docs/models/VolumeTarget.md create mode 100644 testgen/src/autogen/docs/models/VolumeUsage.md create mode 100644 testgen/src/autogen/docs/models/Volumes.md create mode 100644 testgen/src/autogen/docs/models/WatchCallback.md create mode 100644 testgen/src/autogen/mod.rs create mode 100644 testgen/src/autogen/models/affinity_group.rs create mode 100644 testgen/src/autogen/models/app_node.rs create mode 100644 testgen/src/autogen/models/app_node_spec.rs create mode 100644 testgen/src/autogen/models/app_node_state.rs create mode 100644 testgen/src/autogen/models/app_nodes.rs create mode 100644 testgen/src/autogen/models/block_device.rs create mode 100644 testgen/src/autogen/models/block_device_filesystem.rs create mode 100644 testgen/src/autogen/models/block_device_partition.rs create mode 100644 testgen/src/autogen/models/child.rs create mode 100644 testgen/src/autogen/models/child_state.rs create mode 100644 testgen/src/autogen/models/child_state_reason.rs create mode 100644 testgen/src/autogen/models/cordon_drain_state.rs create mode 100644 testgen/src/autogen/models/cordoned_state.rs create mode 100644 testgen/src/autogen/models/create_nexus_body.rs create mode 100644 testgen/src/autogen/models/create_pool_body.rs create mode 100644 testgen/src/autogen/models/create_replica_body.rs create mode 100644 testgen/src/autogen/models/create_volume_body.rs create mode 100644 testgen/src/autogen/models/drain_state.rs create mode 100644 testgen/src/autogen/models/explicit_node_topology.rs create mode 100644 testgen/src/autogen/models/labelled_topology.rs create mode 100644 testgen/src/autogen/models/mod.rs create mode 100644 testgen/src/autogen/models/nexus.rs create mode 100644 testgen/src/autogen/models/nexus_share_protocol.rs create mode 100644 testgen/src/autogen/models/nexus_spec.rs create mode 100644 testgen/src/autogen/models/nexus_spec_operation.rs create mode 100644 testgen/src/autogen/models/nexus_state.rs create mode 100644 testgen/src/autogen/models/node.rs create mode 100644 testgen/src/autogen/models/node_access_info.rs create mode 100644 testgen/src/autogen/models/node_spec.rs create mode 100644 testgen/src/autogen/models/node_state.rs create mode 100644 testgen/src/autogen/models/node_status.rs create mode 100644 testgen/src/autogen/models/node_topology.rs create mode 100644 testgen/src/autogen/models/offline_replica_snapshot_state.rs create mode 100644 testgen/src/autogen/models/online_replica_snapshot_state.rs create mode 100644 testgen/src/autogen/models/pool.rs create mode 100644 testgen/src/autogen/models/pool_spec.rs create mode 100644 testgen/src/autogen/models/pool_state.rs create mode 100644 testgen/src/autogen/models/pool_status.rs create mode 100644 testgen/src/autogen/models/pool_topology.rs create mode 100644 testgen/src/autogen/models/protocol.rs create mode 100644 testgen/src/autogen/models/publish_volume_body.rs create mode 100644 testgen/src/autogen/models/rebuild_job_state.rs create mode 100644 testgen/src/autogen/models/rebuild_record.rs create mode 100644 testgen/src/autogen/models/register_app_node.rs create mode 100644 testgen/src/autogen/models/replica.rs create mode 100644 testgen/src/autogen/models/replica_kind.rs create mode 100644 testgen/src/autogen/models/replica_share_protocol.rs create mode 100644 testgen/src/autogen/models/replica_snapshot.rs create mode 100644 testgen/src/autogen/models/replica_snapshot_state.rs create mode 100644 testgen/src/autogen/models/replica_snapshot_status.rs create mode 100644 testgen/src/autogen/models/replica_space_usage.rs create mode 100644 testgen/src/autogen/models/replica_spec.rs create mode 100644 testgen/src/autogen/models/replica_spec_operation.rs create mode 100644 testgen/src/autogen/models/replica_spec_owners.rs create mode 100644 testgen/src/autogen/models/replica_state.rs create mode 100644 testgen/src/autogen/models/replica_topology.rs create mode 100644 testgen/src/autogen/models/replica_usage.rs create mode 100644 testgen/src/autogen/models/resize_volume_body.rs create mode 100644 testgen/src/autogen/models/rest_json_error.rs create mode 100644 testgen/src/autogen/models/rest_watch.rs create mode 100644 testgen/src/autogen/models/set_volume_property_body.rs create mode 100644 testgen/src/autogen/models/snapshot_as_source.rs create mode 100644 testgen/src/autogen/models/spec_status.rs create mode 100644 testgen/src/autogen/models/specs.rs create mode 100644 testgen/src/autogen/models/topology.rs create mode 100644 testgen/src/autogen/models/volume.rs create mode 100644 testgen/src/autogen/models/volume_content_source.rs create mode 100644 testgen/src/autogen/models/volume_policy.rs create mode 100644 testgen/src/autogen/models/volume_share_protocol.rs create mode 100644 testgen/src/autogen/models/volume_snapshot.rs create mode 100644 testgen/src/autogen/models/volume_snapshot_definition.rs create mode 100644 testgen/src/autogen/models/volume_snapshot_metadata.rs create mode 100644 testgen/src/autogen/models/volume_snapshot_spec.rs create mode 100644 testgen/src/autogen/models/volume_snapshot_state.rs create mode 100644 testgen/src/autogen/models/volume_snapshots.rs create mode 100644 testgen/src/autogen/models/volume_spec.rs create mode 100644 testgen/src/autogen/models/volume_spec_operation.rs create mode 100644 testgen/src/autogen/models/volume_state.rs create mode 100644 testgen/src/autogen/models/volume_status.rs create mode 100644 testgen/src/autogen/models/volume_target.rs create mode 100644 testgen/src/autogen/models/volume_usage.rs create mode 100644 testgen/src/autogen/models/volumes.rs create mode 100644 testgen/src/autogen/models/watch_callback.rs diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 6e91b1029..9f51f76de 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -61,14 +61,14 @@ jobs: timeout-minutes: 10 with: command: build - args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator" + args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator cli-ng" - name: Build actix3 features uses: actions-rs/cargo@v1 timeout-minutes: 10 with: command: build - args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator" + args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator cli-ng" # - name: Build actix2 features # uses: actions-rs/cargo@v1 @@ -82,14 +82,14 @@ jobs: timeout-minutes: 20 with: command: test - args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator" + args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator cli-ng" - name: Run actix3 tests uses: actions-rs/cargo@v1 timeout-minutes: 20 with: command: test - args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator" + args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator cli-ng" # - name: Run actix2 tests # uses: actions-rs/cargo@v1 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3c098f75d..b6e780378 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: doc - args: --all --features "actix4 cli chrono url uuid swagger-ui v3" --no-deps + args: --all --features "actix4 cli chrono url uuid swagger-ui v3 cli-ng" --no-deps - name: Setup GitBook run: | diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 971593fff..d42d57f20 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -37,7 +37,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} with: token: ${{ secrets.GITHUB_TOKEN }} - args: --all --features "actix4 cli chrono url uuid swagger-ui v3" -- -D clippy::all ${{ matrix.exclude }} + args: --all --features "actix4 cli chrono url uuid swagger-ui v3 cli-ng" -- -D clippy::all ${{ matrix.exclude }} fmt: name: rustfmt diff --git a/Cargo.toml b/Cargo.toml index d1a75ec16..2f2902439 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,9 +20,10 @@ required-features = ["cli"] paperclip-actix = { path = "plugins/actix-web", version = "0.7.2", optional = true } paperclip-core = { path = "core", version = "0.7.2" } paperclip-macros = { path = "macros", version = "0.7.0", optional = true } +paperclip-ng = { path = "cli-ng", version = "0.1.0", optional = true } env_logger = { version = "0.8", optional = true } -git2 = { version = "0.15", optional = true } +git2 = { version = "0.15", default-features = false, optional = true } heck = { version = "0.4", optional = true } http = { version = "0.2", optional = true } itertools = "0.10" @@ -83,7 +84,8 @@ codegen = ["heck", "http", "log", "regex", "tinytemplate", "paperclip-core/codeg v2 = ["paperclip-macros/v2", "paperclip-core/v2"] # OpenAPI v2 to v3 support v3 = ["openapiv3-paper", "v2", "paperclip-core/v3", "paperclip-actix/v3"] - +# Experimental V3 CodeGen +cli-ng = ["cli", "paperclip-ng", "openapiv3-paper"] # Features for implementing traits for dependencies. actix-multipart = ["paperclip-core/actix-multipart"] @@ -107,6 +109,7 @@ members = [ "core", "macros", "plugins/actix-web", + "cli-ng" ] [[test]] diff --git a/Makefile b/Makefile index 029808b99..811e233e7 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ doc: build: cargo build cargo build --features actix4 - cargo build --features cli + cargo build --features "cli cli-ng" test: cargo test --all --features "actix4 cli chrono uuid swagger-ui rapidoc actix4-validator" diff --git a/cli-ng/Cargo.toml b/cli-ng/Cargo.toml new file mode 100644 index 000000000..a8fdb5204 --- /dev/null +++ b/cli-ng/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "paperclip-ng" +version = "0.1.0" +edition = "2018" +license = "MIT OR Apache-2.0" +keywords = [ "openapi", "openapiv3", "cli", "codegen" ] +description = "Experimental OpenAPI V3.0.3 Code Generator" +homepage = "https://github.com/paperclip-rs/paperclip" +repository = "https://github.com/paperclip-rs/paperclip" + +[[bin]] +name = "paperclip-ng" +path = "src/bin/cli/main.rs" + +[dependencies] +ramhorns = { version = "1.0", default-features = false, features = ["indexes"] } +ramhorns-derive = { version = "1.0" } +openapiv3-paper = { version = "2.0" } +heck = { version = "0.4" } +itertools = { version = "0.10" } + +env_logger = "0.8" +log = { version = "0.4", features = ["kv_unstable"] } +structopt = { version = "0.3" } +serde_json = "1.0" +serde_yaml = "0.9" +thiserror = "1.0" \ No newline at end of file diff --git a/cli-ng/src/bin/cli/error.rs b/cli-ng/src/bin/cli/error.rs new file mode 100644 index 000000000..8ea1091b1 --- /dev/null +++ b/cli-ng/src/bin/cli/error.rs @@ -0,0 +1,30 @@ +macro_rules! impl_err_from { + ($err:ident :: $type:ty > $variant:ident) => { + impl From<$type> for $err { + fn from(s: $type) -> Self { + $err::$variant(s) + } + } + }; +} + +/// Global error which encapsulates all related errors. +#[derive(Debug, thiserror::Error)] +pub(crate) enum Error { + /// The given directory cannot be used for generating code. + #[error("Cannot generate code in the given directory")] + InvalidCodegenDirectory, + /// I/O errors. + #[error("I/O error: {}", _0)] + Io(std::io::Error), + /// JSON coding errors. + #[error("JSON error: {}", _0)] + Json(serde_json::Error), + /// YAML coding errors. + #[error("YAML error: {}", _0)] + Yaml(serde_yaml::Error), +} + +impl_err_from!(Error::std::io::Error > Io); +impl_err_from!(Error::serde_json::Error > Json); +impl_err_from!(Error::serde_yaml::Error > Yaml); diff --git a/cli-ng/src/bin/cli/main.rs b/cli-ng/src/bin/cli/main.rs new file mode 100644 index 000000000..9919928df --- /dev/null +++ b/cli-ng/src/bin/cli/main.rs @@ -0,0 +1,99 @@ +use heck::ToSnakeCase; +use std::{ + fs::{self, File}, + io::Read, + path::PathBuf, +}; +use structopt::StructOpt; + +mod error; +use error::Error; + +/// Deserialize the schema from the given reader. Currently, this only supports +/// JSON and YAML formats. +fn from_reader_v3(mut reader: R) -> Result +where + R: Read, +{ + let mut buf = [b' ']; + while buf[0].is_ascii_whitespace() { + reader.read_exact(&mut buf)?; + } + let reader = buf.as_ref().chain(reader); + + Ok(if buf[0] == b'{' { + serde_json::from_reader::<_, openapiv3::OpenAPI>(reader)? + } else { + serde_yaml::from_reader::<_, openapiv3::OpenAPI>(reader)? + }) +} +fn parse_spec_v3(s: &str) -> Result { + let fd = File::open(s)?; + from_reader_v3(fd) +} + +#[derive(Debug, StructOpt)] +struct Opt { + /// Path to OpenAPI spec in JSON/YAML format (also supports publicly accessible URLs). + #[structopt(long)] + spec: std::path::PathBuf, + /// Output directory to write code (default: current working directory). + #[structopt(short = "o", long = "out", parse(from_os_str))] + output: Option, + /// Don't Render models. + #[structopt(long)] + no_models: bool, + /// Don't Render operations. + #[structopt(long)] + no_ops: bool, + /// Name of the crate. If this is not specified, then the name of the + /// working directory is assumed to be crate name. + #[structopt(long = "name")] + pub name: Option, + /// The Version of the crate. + #[structopt(long = "version", default_value = "0.1.0")] + pub version: String, + /// The Edition of the crate. + #[structopt(long = "edition", default_value = "2018")] + pub edition: String, + /// Use custom templates (mustache) files, rather than the builtin ones. + /// The root dir in this path must be the template name, example: default. + #[structopt(short = "t", long = "templates", parse(from_os_str))] + templates: Option, +} + +fn parse_args_and_run() -> Result<(), Error> { + let opt: Opt = Opt::from_args(); + + if let Some(o) = &opt.output { + fs::create_dir_all(o)?; + } + + let spec = parse_spec_v3(opt.spec.to_string_lossy().as_ref())?; + let name = opt.name.map(Ok::).unwrap_or_else(|| { + Ok(fs::canonicalize(std::path::Path::new("."))? + .file_name() + .ok_or(Error::InvalidCodegenDirectory)? + .to_string_lossy() + .into_owned() + .to_snake_case()) + })?; + let info = paperclip_ng::v3_03::PackageInfo { + libname: name.to_snake_case(), + name, + version: opt.version, + edition: opt.edition, + }; + + paperclip_ng::v3_03::OpenApiV3::new(spec, opt.templates, opt.output, info)? + .run(!opt.no_models, !opt.no_ops)?; + Ok(()) +} + +fn main() { + env_logger::init(); + if let Err(e) = parse_args_and_run() { + eprintln!("{}", e); + std::process::exit(1); + } +} diff --git a/cli-ng/src/lib.rs b/cli-ng/src/lib.rs new file mode 100644 index 000000000..1fc2085c9 --- /dev/null +++ b/cli-ng/src/lib.rs @@ -0,0 +1,5 @@ +mod v3; + +pub mod v3_03 { + pub use super::v3::{OpenApiV3, PackageInfo}; +} diff --git a/cli-ng/src/v3/mod.rs b/cli-ng/src/v3/mod.rs new file mode 100644 index 000000000..99cd0cdeb --- /dev/null +++ b/cli-ng/src/v3/mod.rs @@ -0,0 +1,520 @@ +mod operation; +mod parameter; +mod property; +mod templates; + +use std::{cell::RefCell, collections::HashSet, ops::Deref}; + +use operation::Operation; +use parameter::Parameter; +use property::Property; +use templates::*; + +use itertools::Itertools; +use ramhorns::Template; +use ramhorns_derive::Content; + +use log::{debug, trace}; + +/// OpenApiV3 code generator. +#[derive(Debug)] +pub struct OpenApiV3 { + api: openapiv3::OpenAPI, + + output_path: std::path::PathBuf, + package_info: PackageInfo, + + api_template: Vec, + model_templates: Vec, + supporting_templates: Vec, + + suppress_errors: bool, + circ_ref_checker: RefCell, +} +impl OpenApiV3 { + /// Creates a new OpenApi V3 Generator. + pub fn new( + api: openapiv3::OpenAPI, + tpl_path: Option, + output_path: Option, + package_info: PackageInfo, + ) -> Result { + let output_path = output_path.unwrap_or_else(|| std::path::Path::new(".").to_path_buf()); + let (api_template, model_templates, supporting_templates) = + templates::default_templates(&tpl_path)?; + Ok(Self { + api, + output_path, + package_info, + api_template, + model_templates, + supporting_templates, + suppress_errors: false, + circ_ref_checker: RefCell::new(CircularRefChecker::default()), + }) + } +} + +#[derive(Debug)] +pub struct PackageInfo { + pub name: String, + pub version: String, + pub libname: String, + pub edition: String, +} + +#[derive(Clone, Content)] +struct ApiInfoTpl<'a> { + apis: &'a Vec>, +} +#[derive(Clone, Content)] +#[ramhorns(rename_all = "camelCase")] +struct SupportingTpl<'a> { + api_info: ApiInfoTpl<'a>, + operations: OperationsTpl<'a>, + models: ModelTpl<'a>, + package_name: &'a str, + package_version: &'a str, + package_libname: &'a str, + package_edition: &'a str, +} +#[derive(Clone, Content)] +#[ramhorns(rename_all = "camelCase")] +struct ModelsTpl<'a> { + models: ModelTpl<'a>, +} +#[derive(Clone, Content)] +struct ModelTpl<'a> { + model: &'a Vec, +} + +#[derive(Content, Debug, Clone)] +struct OperationsTpl<'a> { + operation: &'a Vec, +} + +#[derive(Content, Clone, Debug)] +#[ramhorns(rename_all = "camelCase")] +pub(super) struct OperationsApiTpl<'a> { + classname: &'a str, + class_filename: &'a str, + + operations: OperationsTpl<'a>, +} +pub(super) struct OperationsApi { + classname: String, + class_filename: String, + + operations: Vec, +} + +impl OpenApiV3 { + /// Run the OpenApi V3 Code Generator. + pub fn run(&self, models: bool, ops: bool) -> Result<(), std::io::Error> { + let models = if models { self.models()? } else { vec![] }; + let operations = if ops { self.operations()? } else { vec![] }; + let apis = self.apis(&operations)?; + let apis = apis + .iter() + .map(|o| OperationsApiTpl { + classname: o.classname(), + class_filename: o.class_filename(), + operations: OperationsTpl { + operation: &o.operations, + }, + }) + .collect::>(); + + self.ensure_templates()?; + + self.render_supporting(&models, &operations, &apis)?; + self.render_models(&models)?; + self.render_apis(&apis)?; + + Ok(()) + } + fn ensure_templates(&self) -> Result<(), std::io::Error> { + Self::ensure_path(&self.output_path, true)?; + let templates = self + .supporting_templates + .iter() + .map(Deref::deref) + .chain(self.api_template.iter().map(Deref::deref)) + .chain(self.model_templates.iter().map(Deref::deref)) + .collect::>(); + self.ensure_template(&templates) + } + fn ensure_template_path( + &self, + path: &std::path::Path, + clean: bool, + ) -> Result<(), std::io::Error> { + let path = self.output_path.join(path); + Self::ensure_path(&path, clean) + } + fn ensure_path(path: &std::path::Path, clean: bool) -> Result<(), std::io::Error> { + if clean && path.exists() { + if path.is_dir() { + std::fs::remove_dir_all(path)?; + } else { + std::fs::remove_file(path)?; + } + } + std::fs::create_dir_all(path) + } + fn ensure_template(&self, templates: &[&GenTemplateFile]) -> Result<(), std::io::Error> { + templates + .iter() + .try_for_each(|template| self.ensure_template_path(template.target_prefix(), true))?; + templates + .iter() + .try_for_each(|template| self.ensure_template_path(template.target_prefix(), false)) + } + fn render_supporting( + &self, + models: &Vec, + operations: &Vec, + apis: &Vec, + ) -> Result<(), std::io::Error> { + self.supporting_templates + .iter() + .try_for_each(|e| self.render_supporting_template(e, models, operations, apis)) + } + fn render_apis(&self, apis: &Vec) -> Result<(), std::io::Error> { + self.api_template + .iter() + .try_for_each(|e| self.render_template_apis(e, apis)) + } + fn render_models(&self, models: &Vec) -> Result<(), std::io::Error> { + for property in models { + let model = &vec![property.clone()]; + for template in &self.model_templates { + let tpl = self.tpl(template)?; + + let path = self.output_path.join(template.model_path(property)); + + tpl.render_to_file( + path, + &ModelsTpl { + models: ModelTpl { model }, + }, + )?; + } + } + + Ok(()) + } + + fn tpl<'a>(&self, template: &'a GenTemplateFile) -> Result, std::io::Error> { + let Some(mustache) = template.input().buffer() else { + return Err(std::io::Error::new( + std::io::ErrorKind::Unsupported, + "Template from path not supported yet", + )); + }; + let tpl = Template::new(mustache).map_err(|error| { + std::io::Error::new(std::io::ErrorKind::InvalidInput, error.to_string()) + })?; + + Ok(tpl) + } + + fn render_supporting_template( + &self, + template: &SuppTemplateFile, + models: &Vec, + operations: &Vec, + apis: &Vec, + ) -> Result<(), std::io::Error> { + let tpl = self.tpl(template)?; + + let path = self + .output_path + .join(template.target_prefix()) + .join(template.target_postfix()); + tpl.render_to_file( + path, + &SupportingTpl { + api_info: ApiInfoTpl { apis }, + operations: OperationsTpl { + operation: operations, + }, + models: ModelTpl { model: models }, + package_name: self.package_info.name.as_str(), + package_version: self.package_info.version.as_str(), + package_libname: self.package_info.libname.as_str(), + package_edition: self.package_info.edition.as_str(), + }, + )?; + + Ok(()) + } + + #[allow(unused)] + fn render_template_models( + &self, + template: &ModelTemplateFile, + models: &Vec, + ) -> Result<(), std::io::Error> { + let tpl = self.tpl(template)?; + + for model in models { + let path = self.output_path.join(template.model_path(model)); + let model = &vec![model.clone()]; + tpl.render_to_file( + path, + &ModelsTpl { + models: ModelTpl { model }, + }, + )?; + } + + Ok(()) + } + + fn render_template_apis( + &self, + template: &ApiTemplateFile, + apis: &Vec, + ) -> Result<(), std::io::Error> { + let tpl = self.tpl(template)?; + + for api in apis { + let path = self.output_path.join(template.api_path(api)); + if let Some(parent) = path.parent() { + // we already cleaned the top-level, don't clean it again as we might have other templates + // with the form $output/$target-folder/$api-classname/$any + Self::ensure_path(parent, false)?; + } + tpl.render_to_file(path, api)?; + } + + Ok(()) + } + + fn models(&self) -> Result, std::io::Error> { + let model = self + .api + .components + .as_ref() + .unwrap() + .schemas + .iter() + //.filter(|(name, _)| name.starts_with("ReplicaSpec")) + .map(|(name, ref_or)| { + let model = self.resolve_reference_or(ref_or, None, None, Some(name)); + debug!("Model: {} => {}", name, model); + model + }) + .flat_map(|m| m.discovered_models().into_iter().chain(vec![m])) + .filter(|m| m.is_model() && !m.data_type().is_empty()) + .map(Self::post_process) + // todo: when discovering models we should use a cache to avoid re-processing models + // then we won't need to do this dedup. + .sorted_by(|a, b| a.schema().cmp(b.schema())) + .dedup_by(|a, b| a.schema() == b.schema()) + .inspect(|model| debug!("Model => {}", model)) + .collect::>(); + Ok(model) + } + fn operations(&self) -> Result, std::io::Error> { + let operation = self + .api + .operations() + .map(|(path, method, operation)| Operation::new(self, path, method, operation)) + .collect::>(); + + Ok(operation) + } + fn apis(&self, operations: &Vec) -> Result, std::io::Error> { + let mut tags = std::collections::HashMap::::new(); + for op in operations { + for tag in op.tags() { + match tags.get_mut(tag) { + Some(api) => { + api.add_op(op); + } + None => { + tags.insert(tag.clone(), op.into()); + } + } + } + } + + // let apis = tags + // .clone() + // .into_values() + // .map(|o| o.classname().to_string()) + // .collect::>(); + // debug!("apis: {:?}", apis); + + Ok(tags + .into_values() + .sorted_by(|l, r| l.classname().cmp(r.classname())) + .collect::>()) + } +} + +impl OpenApiV3 { + fn missing_schema_ref(&self, reference: &str) { + if !self.suppress_errors { + eprintln!("Schema reference({}) not found", reference); + } + } + fn contains_schema(&self, type_: &str) -> bool { + let contains = match &self.api.components { + None => false, + Some(components) => components.schemas.contains_key(type_), + }; + trace!("Contains {} => {}", type_, contains); + contains + } + fn set_resolving(&self, type_name: &str) { + let mut checker = self.circ_ref_checker.borrow_mut(); + checker.add(type_name); + } + fn resolving(&self, property: &Property) -> bool { + let checker = self.circ_ref_checker.borrow(); + checker.exists(property.type_ref()) + } + fn clear_resolving(&self, type_name: &str) { + let mut checker = self.circ_ref_checker.borrow_mut(); + checker.remove(type_name); + } + fn resolve_schema_name(&self, var_name: Option<&str>, reference: &str) -> Property { + let type_name = match reference.strip_prefix("#/components/schemas/") { + Some(type_name) => type_name, + None => todo!("schema not found..."), + }; + trace!("Resolving: {:?}/{}", var_name, type_name); + let schemas = self.api.components.as_ref().map(|c| &c.schemas); + match schemas.and_then(|s| s.get(type_name)) { + None => { + panic!("Schema {} Not found!", type_name); + } + Some(ref_or) => self.resolve_reference_or(ref_or, None, var_name, Some(type_name)), + } + } + fn resolve_schema( + &self, + schema: &openapiv3::Schema, + parent: Option<&Property>, + name: Option<&str>, + type_: Option<&str>, + ) -> Property { + trace!("ResolvingSchema: {:?}/{:?}", name, type_); + if let Some(type_) = &type_ { + self.set_resolving(type_); + } + let property = Property::from_schema(self, parent, schema, name, type_); + if let Some(type_) = &type_ { + self.clear_resolving(type_); + } + property + } + + fn resolve_reference_or( + &self, + reference: &openapiv3::ReferenceOr, + parent: Option<&Property>, + name: Option<&str>, // parameter name, only known for object vars + type_: Option<&str>, // type, only known when walking the component schema list + ) -> Property { + match reference { + openapiv3::ReferenceOr::Reference { reference } => { + self.resolve_schema_name(name, reference) + } + openapiv3::ReferenceOr::Item(schema) => { + self.resolve_schema(schema, parent, name, type_) + } + } + } + fn resolve_reference_or_resp( + &self, + content: &str, + reference: &openapiv3::ReferenceOr, + ) -> Property { + debug!("Response: {reference:?}"); + match reference { + openapiv3::ReferenceOr::Reference { reference } => { + self.resolve_schema_name(None, reference) + } + openapiv3::ReferenceOr::Item(item) => match item.content.get(content) { + Some(media) => match &media.schema { + Some(schema) => self.resolve_reference_or(schema, None, None, None), + None => Property::default(), + }, + None => Property::default().with_data_property(&property::PropertyDataType::Empty), + }, + } + } + + fn post_process(property: Property) -> Property { + property.post_process() + } +} + +impl OperationsApiTpl<'_> { + /// Get a reference to the api classname. + pub fn classname(&self) -> &str { + self.classname + } + /// Get a reference to the api class filename. + pub fn class_filename(&self) -> &str { + self.class_filename + } +} +impl OperationsApi { + /// Get a reference to the api classname. + pub fn classname(&self) -> &str { + &self.classname + } + /// Get a reference to the api class filename. + pub fn class_filename(&self) -> &str { + &self.class_filename + } + /// Add the given operation. + pub(super) fn add_op(&mut self, operation: &Operation) { + self.operations.push(operation.clone()); + } +} + +impl From<&Operation> for OperationsApi { + fn from(src: &Operation) -> OperationsApi { + OperationsApi { + class_filename: src.class_filename().into(), + classname: src.classname().into(), + operations: vec![src.clone()], + } + } +} + +/// Circular Reference Checker +/// If a model's member variable references a model currently being resolved +/// (either parent, or another elder) then a reference check must be used +/// to break out of an infinit loop. +/// In this case we don't really need to re-resolve the entire model +/// because the model itself will resolve itself. +#[derive(Clone, Debug, Default)] +struct CircularRefChecker { + /// List of type_names in the resolve chain. + type_names: HashSet, + /// Current type being resolved. + current: String, +} +impl CircularRefChecker { + fn add(&mut self, type_name: &str) { + if self.type_names.insert(type_name.to_string()) { + // trace!("Added cache: {type_name}"); + self.current = type_name.to_string(); + } + } + fn exists(&self, type_name: &str) -> bool { + self.current.as_str() != type_name && self.type_names.contains(type_name) + } + fn remove(&mut self, type_name: &str) { + if self.type_names.remove(type_name) { + // trace!("Removed cache: {type_name}"); + } + } +} diff --git a/cli-ng/src/v3/operation.rs b/cli-ng/src/v3/operation.rs new file mode 100644 index 000000000..26e26db11 --- /dev/null +++ b/cli-ng/src/v3/operation.rs @@ -0,0 +1,243 @@ +use std::collections::HashMap; + +use super::{OpenApiV3, Parameter, Property}; + +use heck::{ToLowerCamelCase, ToSnakeCase, ToUpperCamelCase}; +use ramhorns_derive::Content; + +use log::debug; + +#[derive(Default, Content, Clone, Debug)] +#[ramhorns(rename_all = "camelCase")] +pub(crate) struct Operation { + classname: String, + class_filename: String, + + response_headers: Vec, + + return_type_is_primitive: bool, + return_simple_type: bool, + subresource_operation: bool, + is_multipart: bool, + is_response_binary: bool, + is_response_file: bool, + is_response_optional: bool, + has_reference: bool, + is_restful_index: bool, + is_restful_show: bool, + is_restful_create: bool, + is_restful_update: bool, + is_restful_destroy: bool, + is_restful: bool, + is_deprecated: Option, + is_callback_request: bool, + unique_items: bool, + has_default_response: bool, + // if 4xx, 5xx responses have at least one error object defined + has_error_response_object: bool, + + path: String, + operation_id: Option, + return_type: String, + return_format: String, + http_method: String, + return_base_type: String, + return_container: String, + summary: Option, + unescaped_notes: String, + basename: String, + default_response: String, + + consumes: Vec>, + has_consumes: bool, + produces: Vec>, + has_produces: bool, + prioritized_content_types: Vec>, + + body_param: Parameter, + + all_params: Vec, + has_params: bool, + path_params: Vec, + has_path_params: bool, + query_params: Vec, + has_query_params: bool, + header_params: Vec, + has_header_params: bool, + implicit_headers_params: Vec, + has_implicit_headers_params: bool, + form_params: Vec, + has_form_params: bool, + required_params: Vec, + has_required_params: bool, + optional_params: Vec, + has_optional_params: bool, + auth_methods: Vec, + has_auth_methods: bool, + + tags: Vec, + responses: Vec<()>, + callbacks: Vec<()>, + + examples: Vec>, + request_body_examples: Vec>, + + vendor_extensions: HashMap, + + operation_id_original: Option, + operation_id_camel_case: Option, + support_multiple_responses: bool, +} + +fn query_param(api: &OpenApiV3, value: &openapiv3::Parameter) -> Option { + match value { + openapiv3::Parameter::Query { parameter_data, .. } => { + let parameter = Parameter::new(api, parameter_data); + Some(parameter) + } + _ => None, + } +} +fn path_param(api: &OpenApiV3, value: &openapiv3::Parameter) -> Option { + match value { + openapiv3::Parameter::Path { parameter_data, .. } => { + let parameter = Parameter::new(api, parameter_data); + Some(parameter) + } + _ => None, + } +} +#[allow(unused)] +fn header_param(api: &OpenApiV3, value: &openapiv3::Parameter) -> Option { + match value { + openapiv3::Parameter::Header { parameter_data, .. } => { + let parameter = Parameter::new(api, parameter_data); + Some(parameter) + } + _ => None, + } +} + +impl Operation { + /// Create an Operation based on the deserialized openapi operation. + pub(crate) fn new( + root: &OpenApiV3, + path: &str, + method: &str, + operation: &openapiv3::Operation, + ) -> Self { + debug!( + "Operation::{id:?} => {method}::{path}::{tags:?}", + id = operation.operation_id, + tags = operation.tags + ); + let mut vendor_extensions = operation + .extensions + .iter() + .map(|(k, v)| (k.clone(), v.to_string())) + .collect::>(); + + vendor_extensions.insert("x-httpMethodLower".into(), method.to_ascii_lowercase()); + vendor_extensions.insert("x-httpMethodUpper".into(), method.to_ascii_uppercase()); + + let query_params = operation + .parameters + .iter() + .flat_map(|p| { + match p { + // todo: need to handle this + openapiv3::ReferenceOr::Reference { .. } => todo!(), + openapiv3::ReferenceOr::Item(item) => query_param(root, item), + } + }) + .collect::>(); + let path_params = operation + .parameters + .iter() + .flat_map(|p| { + match p { + // todo: need to handle this + openapiv3::ReferenceOr::Reference { .. } => todo!(), + openapiv3::ReferenceOr::Item(item) => path_param(root, item), + } + }) + .collect::>(); + + let mut ext_path = path.to_string(); + for param in &path_params { + if param.data_format() == "url" { + //info!("path: {path}"); + //info!("path_params: {param:?}"); + ext_path = path.replace(param.name(), &format!("{}:.*", param.base_name())); + vendor_extensions.insert("x-actix-query-string".into(), "true".into()); + } + } + vendor_extensions.insert("x-actixPath".into(), ext_path); + + let all_params = query_params + .iter() + .chain(&path_params) + .cloned() + .collect::>(); + // todo: support multiple responses + let return_model = match operation + .responses + .responses + .get(&openapiv3::StatusCode::Code(200)) + .or(operation + .responses + .responses + .get(&openapiv3::StatusCode::Code(204))) + { + Some(ref_or) => root.resolve_reference_or_resp("application/json", ref_or), + None => todo!(), + }; + // todo: should we post process after all operations are processed? + let return_model = return_model.post_process_data_type(); + let (class, class_file) = match operation.tags.first() { + Some(class) => (class.clone(), format!("{class}_api").to_snake_case()), + // How should this be handled? Shuld it be required? What if there's more than 1 tag? + None => (String::new(), String::new()), + }; + Self { + classname: class, + class_filename: class_file, + summary: operation.summary.clone(), + tags: operation.tags.clone(), + is_deprecated: Some(operation.deprecated), + operation_id_camel_case: operation + .operation_id + .as_ref() + .map(|o| o.to_lower_camel_case()), + operation_id: operation.operation_id.clone(), + operation_id_original: operation.operation_id.clone(), + has_params: !all_params.is_empty(), + all_params, + has_path_params: !path_params.is_empty(), + path_params, + has_query_params: !query_params.is_empty(), + query_params, + header_params: vec![], + has_header_params: false, + path: path.to_string(), + http_method: method.to_upper_camel_case(), + support_multiple_responses: false, + return_type: return_model.data_type(), + has_auth_methods: operation.security.is_some(), + vendor_extensions, + ..Default::default() + } + } + /// Get a reference to the operation tags list. + pub fn tags(&self) -> &Vec { + &self.tags + } + /// Get a reference to the operation class name. + pub fn classname(&self) -> &str { + &self.classname + } + /// Get a reference to the operation class filename. + pub fn class_filename(&self) -> &str { + &self.class_filename + } +} diff --git a/cli-ng/src/v3/parameter.rs b/cli-ng/src/v3/parameter.rs new file mode 100644 index 000000000..a7a80651e --- /dev/null +++ b/cli-ng/src/v3/parameter.rs @@ -0,0 +1,101 @@ +use heck::ToSnakeCase; +use ramhorns_derive::Content; +use std::collections::HashMap; + +use super::{property::Property, OpenApiV3}; + +#[derive(Default, Content, Clone, Debug)] +#[ramhorns(rename_all = "camelCase")] +pub(crate) struct Parameter { + param_name: String, + base_name: String, + example: Option, + examples: Vec, + required: bool, + deprecated: Option, + is_nullable: bool, + is_string: bool, + is_array: bool, + is_uuid: bool, + is_primitive_type: bool, + is_container: bool, + data_type: String, + data_format: String, + vendor_extensions: HashMap, + items: Option>, +} + +impl Parameter { + /// Create a new Parameter based on the deserialized parameter data. + pub(super) fn new(api: &OpenApiV3, param: &openapiv3::ParameterData) -> Self { + let schema_back; + let schema = match ¶m.format { + openapiv3::ParameterSchemaOrContent::Schema(ref_s) => match ref_s { + openapiv3::ReferenceOr::Reference { reference } => { + match api.api.components.as_ref().and_then(|c| { + c.schemas + .get(&reference.replace("#/components/schemas/", "")) + }) { + None => { + api.missing_schema_ref(reference); + schema_back = openapiv3::Schema { + schema_data: Default::default(), + schema_kind: openapiv3::SchemaKind::Any( + openapiv3::AnySchema::default(), + ), + }; + &schema_back + } + Some(ref_or) => match ref_or { + openapiv3::ReferenceOr::Reference { .. } => { + panic!("double reference not supported"); + } + openapiv3::ReferenceOr::Item(schema) => schema, + }, + } + } + openapiv3::ReferenceOr::Item(schema) => schema, + }, + openapiv3::ParameterSchemaOrContent::Content(_) => { + todo!() + } + }; + let property = Property::from_schema(api, None, schema, Some(¶m.name), None); + let property = super::OpenApiV3::post_process(property); + Self { + // todo: should have snake case param + param_name: param.name.to_snake_case(), + base_name: param.name.clone(), + example: param.example.as_ref().map(|v| v.to_string()), + examples: vec![], + required: param.required, + deprecated: param.deprecated, + is_nullable: schema.schema_data.nullable, + is_string: property.is_string(), + is_array: property.is_array(), + is_uuid: property.is_uuid(), + is_primitive_type: property.is_primitive_type(), + is_container: property.is_container(), + items: property.items().clone(), + data_type: property.data_type(), + data_format: property.data_format(), + vendor_extensions: param + .extensions + .iter() + .map(|(k, v)| (k.clone(), v.to_string())) + .collect(), + } + } + /// Get a reference to the parameter data type format. + pub fn data_format(&self) -> &str { + &self.data_format + } + /// Get a reference to the parameter base name (no case modifications). + pub fn base_name(&self) -> &str { + &self.base_name + } + /// Get a reference to the parameter name. + pub fn name(&self) -> &str { + &self.param_name + } +} diff --git a/cli-ng/src/v3/property.rs b/cli-ng/src/v3/property.rs new file mode 100644 index 000000000..57a140a02 --- /dev/null +++ b/cli-ng/src/v3/property.rs @@ -0,0 +1,981 @@ +use std::{collections::HashMap, fmt::Display, ops::Deref, rc::Rc}; + +use heck::{ToSnakeCase, ToUpperCamelCase}; +use ramhorns_derive::Content; + +use log::{error, trace}; + +/// The various openapi v3 property data types. +#[derive(Clone, Debug)] +pub(crate) enum PropertyDataType { + Unknown, + Resolved(String, Option), + Any, + RawString, + String(openapiv3::StringType), + Enum(String, String), + Boolean, + Integer(openapiv3::IntegerType), + Number(openapiv3::NumberType), + Model(String), + DiscModel(String, String), + Map(Box, Box), + Array(Box), + Empty, +} + +impl Display for PropertyDataType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl PropertyDataType { + fn as_str(&self) -> &str { + match self { + PropertyDataType::Unknown => "Unkown", + PropertyDataType::Resolved(inner, _) => inner.as_ref(), + PropertyDataType::Array(inner) => inner.as_str(), + PropertyDataType::Any => "Any", + PropertyDataType::Map(_, _) => "Map", + PropertyDataType::RawString => "String", + PropertyDataType::String(_) => "String", + PropertyDataType::Enum(_, _) => "Enum", + PropertyDataType::Boolean => "bool", + PropertyDataType::Integer(_) => "integer", + PropertyDataType::Number(_) => "number", + PropertyDataType::Model(inner) => inner.as_str(), + PropertyDataType::DiscModel(_, _) => "Disc", + PropertyDataType::Empty => "Empty", + } + } + fn format(&self) -> Option<&String> { + match self { + PropertyDataType::Resolved(_, format) => format.as_ref(), + _ => None, + } + } + fn resolve(&mut self, data_type: &str) { + self.set_if_unresolved(Self::Resolved(data_type.into(), None)); + } + fn resolve_format>(&mut self, data_type: &str, format: T) { + self.set_if_unresolved(Self::Resolved(data_type.into(), Some(format.into()))); + } + fn resolve_format_opt(&mut self, data_type: &str, format: Option) { + self.set_if_unresolved(Self::Resolved(data_type.into(), format)); + } + fn set_string(&mut self, data_type: &openapiv3::StringType) { + self.set_if_unresolved(Self::String(data_type.clone())); + } + fn set_array(&mut self, data_type: &Self) { + self.set_if_unresolved(Self::Array(Box::new(data_type.clone()))); + } + fn set_boolean(&mut self) { + self.set_if_unresolved(Self::Boolean); + } + fn set_integer(&mut self, data_type: &openapiv3::IntegerType) { + self.set_if_unresolved(Self::Integer(data_type.clone())); + } + fn set_number(&mut self, data_type: &openapiv3::NumberType) { + self.set_if_unresolved(Self::Number(data_type.clone())); + } + fn set_model(&mut self, data_type: &str) { + self.set_if_unresolved(Self::Model(data_type.to_string())); + } + fn set_disc_model(&mut self, parent: String, name: &str) { + self.set_if_unresolved(Self::DiscModel(parent, name.to_string())); + } + fn set_map(&mut self, key: &Self, value: &Self) { + self.set_if_unresolved(Self::Map(Box::new(key.clone()), Box::new(value.clone()))); + } + fn set_enum(&mut self, name: &str, data_type: &str) { + self.set_if_unresolved(Self::Enum(name.to_string(), data_type.to_string())); + } + fn set_any(&mut self) { + self.set_if_unresolved(Self::Any); + } + fn set_if_unresolved(&mut self, to: Self) { + if !matches!(self, Self::Resolved(_, _)) { + *self = to; + } + } +} + +impl Default for PropertyDataType { + fn default() -> Self { + Self::Unknown + } +} + +impl ramhorns::Content for PropertyDataType { + #[inline] + fn is_truthy(&self) -> bool { + !self.as_str().is_empty() + } + + #[inline] + fn capacity_hint(&self, _tpl: &ramhorns::Template) -> usize { + self.as_str().len() + } + + #[inline] + fn render_escaped( + &self, + encoder: &mut E, + ) -> Result<(), E::Error> { + encoder.write_escaped(self.as_str()) + } + + #[inline] + fn render_unescaped( + &self, + encoder: &mut E, + ) -> Result<(), E::Error> { + encoder.write_unescaped(self.as_str()) + } +} + +/// A list of properties. +pub(crate) type Properties = Vec; + +/// An OpenApiV3 property of a Schema Object. +/// https://spec.openapis.org/oas/v3.0.3#properties +/// Including fixed fields, composition, etc. +/// These fields are used for both managing the template generation as well as input for +/// the templates themselves. +#[derive(Default, Content, Clone, Debug)] +#[ramhorns(rename_all = "camelCase")] +pub(crate) struct Property { + // The schema name as written in the OpenAPI document. + name: String, + + // The language-specific name of the "class" that implements this schema. + // The name of the class is derived from the OpenAPI schema name with formatting rules applied. + // The classname is derived from the OpenAPI schema name, with sanitization and escaping rules + // applied. + pub classname: String, + schema_name: String, + class_filename: String, + + base_name: String, + enum_name: Option, + // The value of the 'title' attribute in the OpenAPI document. + title: Option, + description: Option, + example: Option, + class_var_name: String, + model_json: String, + data_type: PropertyDataType, + data_format: String, + /// The type_ coming from component schema. + type_: String, + unescaped_description: String, + + /// Booleans for is_$-like type checking. + is_string: bool, + is_integer: bool, + is_long: bool, + is_number: bool, + is_numeric: bool, + is_float: bool, + is_double: bool, + is_date: bool, + is_date_time: bool, + is_password: bool, + is_decimal: bool, + is_binary: bool, + is_byte: bool, + is_short: bool, + is_unbounded_integer: bool, + is_primitive_type: bool, + is_boolean: bool, + is_uuid: bool, + is_any_type: bool, + is_enum: bool, + is_array: bool, + is_container: bool, + is_map: bool, + is_null: bool, + is_var: bool, + + /// Indicates whether additional properties has defined this as an Any type. + additional_properties_is_any_type: bool, + + /// If Self is an object, these are all its child properties. + vars: Properties, + /// And this? Inludes the parent properties? What does this mean? + all_vars: Properties, + + /// These could be "special" ramhorn methods rather than fields to avoid copy. + /// Only the required properties. + required_vars: Properties, + /// Only the optional properties. + optional_vars: Properties, + // Only the read-only properties. + read_only_vars: Properties, + // The read/write properties. + read_write_vars: Properties, + /// The Self's parent properties. + parent_vars: Properties, + + /// If this is an enum, all the allowed values. + allowable_values: HashMap>, + + /// If this is an array, the inner property of each index. + items: Option>, + + /// Indicates whether Self has child variables or not. + has_vars: bool, + /// Indicates whether there are enpty vars? What does this mean? + empty_vars: bool, + has_enums: bool, + /// Validation rules? Like patterns? + has_validation: bool, + /// Indicates the OAS schema specifies "nullable: true". + is_nullable: bool, + /// Indicates the type has at least one required property. + has_required: bool, + /// Indicates the type has at least one optional property. + has_optional: bool, + /// Indicates wether we have children vars? Or are these for inline schemas/properties? + has_children: bool, + + is_deprecated: bool, + has_only_read_only: bool, + required: bool, + max_properties: Option, + min_properties: Option, + unique_items: bool, + max_items: Option, + min_items: Option, + max_length: Option, + min_length: Option, + exclusive_minimum: bool, + exclusive_maximum: bool, + minimum: Option, + maximum: Option, + pattern: Option, + + /// If we are a schema defined model? + is_model: bool, + /// If we are a component model defined in the root component schemas: #/components/schemas. + is_component_model: bool, + + one_of: Properties, + all_of: Properties, + + /// Inline models discovered through the schema of this very model. + discovered_props: Rc, + + /// The parent property of this property, if this property is defined "inline" as an Item or a class member or item. + parent: Option>, +} + +impl Display for Property { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "{}/{}/{}.rs", + self.data_type(), + self.classname, + self.class_filename + ) + } +} + +impl Property { + /// Mutate the inner properties with the OpenAPI `openapiv3::SchemaData`. + pub fn with_data(mut self, data: &openapiv3::SchemaData) -> Self { + self.is_null = data.nullable; + self.is_nullable = data.nullable; + self.is_deprecated = data.deprecated; + self.title = data.title.clone(); + self.description = data + .description + .as_ref() + .map(|s| s.escape_default().to_string().replace("\\n", " ")); + self.example = data.example.as_ref().map(ToString::to_string); + self + } + /// Set wether the property is a model or not. + pub fn with_model(mut self, model: bool) -> Self { + self.is_model = model; + self + } + /// Set wether the property is a component model or not. + pub fn with_component_model(mut self, root_model: bool) -> Self { + if root_model { + self.is_component_model = true; + } + self + } + /// Get a reference to the property type. + pub fn type_ref(&self) -> &str { + &self.type_ + } + /// Get the property data type. + pub fn data_type(&self) -> String { + self.data_type.to_string() + } + /// Get the property data format. + pub fn data_format(&self) -> String { + self.data_type.format().map(Into::into).unwrap_or_default() + } + /// Get the class filename, if the property is a model. + pub fn filename(&self) -> &str { + self.class_filename.as_str() + } + /// Set the property data type. + pub fn with_data_property(mut self, type_: &PropertyDataType) -> Self { + self.data_type = type_.clone(); + self + } + /// Set the model type. + pub fn with_model_type(mut self, type_: &str) -> Self { + match self.parent() { + Some(parent) if type_.is_empty() => { + let parent_type = parent.type_.clone(); + self.data_type.set_disc_model(parent_type, &self.name); + } + _ => { + self.data_type.set_model(type_); + } + } + self + } + /// Set the data type Any, and if there's additional properties. + fn with_data_type_any(mut self, is_add_props: bool) -> Self { + self.data_type.set_any(); + self.is_any_type = true; + self.additional_properties_is_any_type = is_add_props; + self + } + /// Set the property type. + pub fn with_type(mut self, type_: &str) -> Self { + self.type_ = type_.to_string(); + self + } + /// The property is an OpenAPI AllOf, composed of a single property. + /// (This is because multiple properties is not supported yet) + pub fn with_one_all_of(self, single: Property) -> Self { + self.with_name(&single.name) + .with_type(&single.type_) + .with_data_property(&single.data_type) + .with_model(true) + .with_parent(&Some(&single)) + .with_all_of(vec![single]) + } + fn with_all_of(mut self, all_of: Vec) -> Self { + self.all_of = all_of; + self + } + /// Get a reference to the list of properties discovered through this property. + fn discovered_props(&self) -> &Vec { + &self.discovered_props + } + /// Similar as `discovered_props` but filters for models and applied recursively. + pub fn discovered_models(&self) -> Vec { + self.discovered_props() + .iter() + .flat_map(|m| { + let mut v = m.discovered_models(); + v.push(m.clone()); + v + }) + .filter(|p| !p.is_component_model && p.is_model && !p.is_all_of() && !p.is_enum) + .collect::>() + } +} +impl From<&openapiv3::SchemaData> for Property { + fn from(data: &openapiv3::SchemaData) -> Self { + Self::default().with_data(data) + } +} + +impl Property { + /// Create a `Property` from an OpenAPI schema, with some other information. + pub fn from_schema( + root: &super::OpenApiV3, + parent: Option<&Property>, + schema: &openapiv3::Schema, + name: Option<&str>, + type_: Option<&str>, + ) -> Self { + let name = name.unwrap_or_default(); + let type_ = type_.unwrap_or_default(); + trace!("PropertyFromSchema: {}/{}", name, type_); + let prop = Property::from(&schema.schema_data) + .with_name(name) + .with_parent(&parent) + .with_type(type_) + .with_component_model(root.contains_schema(type_)); + + prop.with_kind(root, schema, &schema.schema_kind, parent, name, type_) + } + + fn with_kind( + mut self, + root: &super::OpenApiV3, + schema: &openapiv3::Schema, + schema_kind: &openapiv3::SchemaKind, + parent: Option<&Self>, + name: &str, + type_: &str, + ) -> Self { + match schema_kind { + openapiv3::SchemaKind::Type(t) => match t { + openapiv3::Type::String(t) => self.with_string(root, t), + openapiv3::Type::Number(t) => self.with_number(root, t), + openapiv3::Type::Integer(t) => self.with_integer(root, t), + openapiv3::Type::Object(t) => self.with_model_type(type_).with_obj(root, t), + openapiv3::Type::Array(t) => self.with_array(root, t), + openapiv3::Type::Boolean(_) => { + self.data_type.set_boolean(); + self.is_boolean = true; + self.is_primitive_type = true; + self + } + }, + openapiv3::SchemaKind::OneOf { .. } => { + panic!("OneOf: {:#?} not implemented", schema); + } + openapiv3::SchemaKind::AllOf { all_of } if all_of.len() != 1 => { + unimplemented!() + } + openapiv3::SchemaKind::AllOf { all_of } => { + let first = all_of.first().unwrap(); + let first_model = root + .resolve_reference_or(first, parent, Some(name), None) + .with_data(&schema.schema_data); + Self::from(&schema.schema_data).with_one_all_of(first_model) + } + openapiv3::SchemaKind::AnyOf { .. } => { + unimplemented!() + } + openapiv3::SchemaKind::Not { .. } => { + unimplemented!() + } + // In some cases, we get Any rather than a specific kind :( + // For more info: https://github.com/glademiller/openapiv3/pull/79 + // todo: this needs a lot of tweaking... + openapiv3::SchemaKind::Any(any_schema) => match &any_schema.typ { + Some(typ) => match typ.as_str() { + "bool" => { + let kind = openapiv3::SchemaKind::Type(openapiv3::Type::Boolean( + openapiv3::BooleanType { + enumeration: vec![], + }, + )); + self.with_kind(root, schema, &kind, parent, name, type_) + } + "object" => self.with_model_type(type_).with_anyobj(root, any_schema), + not_handled => { + // See above, we must handle all types in the match :( + error!("BUG - must handle {not_handled} data type as AnySchema"); + self.with_data_type_any(false) + } + }, + // not sure how to handle this? default to Any for now. + None => self.with_data_type_any(false), + }, + } + } + + fn assign_classnames(&mut self) { + if self.classname.is_empty() && self.is_model && !self.is_var { + let schema_name = self.data_type.as_str(); + self.class_filename = schema_name.to_snake_case(); + self.classname = schema_name.to_upper_camel_case(); + } + self.assign_enumnames(); + } + fn assign_varnames(&mut self) { + if !self.name.is_empty() { + self.name = self.name.to_snake_case(); + } + } + fn assign_enumnames(&mut self) { + if self.is_enum { + self.enum_name = Some(self.data_type()); + } + } + fn string_format_str(format: openapiv3::StringFormat) -> &'static str { + match format { + openapiv3::StringFormat::Date => "date", + openapiv3::StringFormat::DateTime => "date-time", + openapiv3::StringFormat::Password => "password", + openapiv3::StringFormat::Byte => "byte", + openapiv3::StringFormat::Binary => "binary", + } + } + // This can be provided for a way of custumizing the types. + fn post_process_dt(data_type: &mut PropertyDataType, is_decl: bool) { + match data_type.clone() { + PropertyDataType::Unknown => {} + PropertyDataType::Resolved(_, _) => {} + PropertyDataType::Any => data_type.resolve("serde_json::Value"), + PropertyDataType::RawString => data_type.resolve("String"), + PropertyDataType::String(str) => { + match str.format { + openapiv3::VariantOrUnknownOrEmpty::Item(format) => { + // todo: handle these formats + data_type.resolve_format("String", Self::string_format_str(format)); + } + openapiv3::VariantOrUnknownOrEmpty::Unknown(format) => match format.as_str() { + "uuid" => data_type.resolve("uuid::Uuid"), + _ => data_type.resolve_format("String", format), + }, + openapiv3::VariantOrUnknownOrEmpty::Empty => { + data_type.resolve("String"); + } + } + } + PropertyDataType::Enum(name, type_) if !is_decl => { + let enum_ = if type_.is_empty() { name } else { type_ }.to_upper_camel_case(); + data_type.resolve(&format!("crate::models::{enum_}")) + } + PropertyDataType::Enum(name, type_) => { + let enum_ = if type_.is_empty() { name } else { type_ }.to_upper_camel_case(); + data_type.resolve(&enum_) + } + PropertyDataType::Boolean => data_type.resolve("bool"), + PropertyDataType::Integer(type_) => { + let (signed, bits, format) = match type_.format { + openapiv3::VariantOrUnknownOrEmpty::Item(item) => match item { + openapiv3::IntegerFormat::Int32 => (true, 32, Some("int32".into())), + openapiv3::IntegerFormat::Int64 => (true, 64, Some("int64".into())), + }, + openapiv3::VariantOrUnknownOrEmpty::Unknown(format) => match format.as_str() { + "uint32" => (false, 32, Some(format)), + "uint64" => (false, 64, Some(format)), + "int16" => (true, 16, Some(format)), + "uint16" => (false, 16, Some(format)), + "int8" => (true, 8, Some(format)), + "uint8" => (false, 8, Some(format)), + _ => (true, 0, Some(format)), + }, + _ => (true, 0, None), + }; + let signed = type_.minimum.map(|m| m < 0).unwrap_or(signed); + + // no format specified + let bits = if bits == 0 { + "size".to_string() + } else { + bits.to_string() + }; + + // todo: check min and max + data_type.resolve_format_opt( + &format!("{}{}", if signed { "i" } else { "u" }, bits), + format, + ) + } + PropertyDataType::Number(type_) => { + data_type.resolve(match type_.format { + openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::NumberFormat::Float) => { + "f32" + } + openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::NumberFormat::Double) => { + "f64" + } + openapiv3::VariantOrUnknownOrEmpty::Unknown(_) => "f64", + openapiv3::VariantOrUnknownOrEmpty::Empty => "f64", + }); + } + PropertyDataType::Model(model) if !is_decl => { + data_type.resolve(&format!("crate::models::{model}")) + } + PropertyDataType::Model(model) => data_type.resolve(&model), + PropertyDataType::DiscModel(parent, this) => { + let this = this.to_upper_camel_case(); + let parent = parent.to_upper_camel_case(); + if is_decl { + data_type.resolve(&format!("{parent}{this}")); + } else { + data_type.resolve(&format!("crate::models::{parent}{this}")); + } + } + PropertyDataType::Map(key, mut value) => { + Self::post_process_dt(&mut value, false); + data_type.resolve(&format!( + "::std::collections::HashMap<{}, {}>", + key.as_ref(), + value.as_str() + )) + } + PropertyDataType::Array(mut inner) => { + Self::post_process_dt(&mut inner, is_decl); + data_type.resolve(&format!("Vec<{}>", inner.as_str())) + } + PropertyDataType::Empty => data_type.resolve("()"), + } + } + /// This is a specific template hack, basically pretends this is not an enum + /// preventing it from being declared in the same module as the property where it was defined. + pub(crate) fn uninline_enums(&mut self) { + if self.is_var && self.is_component_model && self.is_enum { + // this is a very specific template hack? + self.is_enum = false; + } + } + /// Processes the data type for usage. + /// Properties which are not discovered at the top (eg: discovered via reference schema) get + /// a code import prefix added to them. + pub fn post_process(mut self) -> Property { + self.post_process_refmut(); + self + } + /// Process the data type for a non-declaration usage. + /// The property **will** get the code import prefix added. + pub fn post_process_data_type(mut self) -> Property { + Self::post_process_dt(&mut self.data_type, false); + self + } + fn post_process_refmut(&mut self) { + // 1. setup data type, eg: add crate::models:: prefix for import. + // This is not required if the type is declared in the same module which currently is only + // true for enums. + let mut is_decl = !self.is_var && !self.is_container; + if self.is_var && !self.is_component_model && self.is_enum { + is_decl = true; + } + Self::post_process_dt(&mut self.data_type, is_decl); + + // 2. fixup classname/type of non-enums defined within a type using Item + self.assign_classnames(); + // 3. setup var names to be snake case + self.assign_varnames(); + + // 4. Uninline enums to avoid inline code generation. + // todo: template itself should do this!? + self.uninline_enums(); + + // 5. apply the same logic for variables within this object. + for var in &mut self.vars { + var.post_process_refmut(); + } + for var in &mut self.required_vars { + var.post_process_refmut(); + } + for var in &mut self.optional_vars { + var.post_process_refmut(); + } + for var in &mut self.all_vars { + var.post_process_refmut(); + } + for var in &mut self.all_of { + var.post_process_refmut(); + } + for var in &mut self.one_of { + var.post_process_refmut(); + } + if let Some(item) = &mut self.items { + item.post_process_refmut(); + } + } + + fn parent(&self) -> Option<&Self> { + match &self.parent { + None => None, + Some(parent) => Some(parent.deref()), + } + } + /// Get a reference to the inner type of the collection. + pub fn items(&self) -> &Option> { + &self.items + } + /// Extend property with a new name. + pub fn with_name(mut self, name: &str) -> Self { + self.name = name.to_string(); + self.base_name = name.to_string(); + self + } + /// Extend property with a new is_var boolean. + fn with_is_var(mut self, is_var: bool) -> Self { + self.is_var = is_var; + self + } + /// Get a reference to the schema's data type. + /// # Warning: will panic if there is no data type (bug). + pub fn schema(&self) -> &str { + if self.data_type.as_str().is_empty() { + panic!("Schema data type should not be empty! Schema: {:#?}", self); + } + self.data_type.as_str() + } + /// Extend property with a new is_var boolean. + pub fn with_required(mut self, required: bool) -> Self { + self.required = required; + self + } + /// Extend property with a new parent property. + pub fn with_parent(mut self, parent: &Option<&Self>) -> Self { + self.parent = parent.map(|p| Rc::new(p.clone())); + self + } + /// Check if the property is a model. + pub fn is_model(&self) -> bool { + self.is_model + } + /// Check if the property is a string. + pub fn is_string(&self) -> bool { + self.is_string + } + /// Check if the property is an array. + pub fn is_array(&self) -> bool { + self.is_array + } + /// Check if the property is a string uuid. + pub fn is_uuid(&self) -> bool { + self.is_uuid + } + /// Check if the property is a container. + pub fn is_container(&self) -> bool { + self.is_container + } + /// Check if the property is a primitive type. + pub fn is_primitive_type(&self) -> bool { + self.is_primitive_type + } + /// Check if the property is an AllOf. + pub fn is_all_of(&self) -> bool { + !self.all_of.is_empty() + } + fn with_array(mut self, _root: &super::OpenApiV3, by: &openapiv3::ArrayType) -> Self { + self.items = by + .items + .clone() + .map(|i| _root.resolve_reference_or(&i.unbox(), Some(&self), None, None)) + .map(|i| i.with_is_var(true)) + .map(Box::new); + self.min_items = by.min_items; + self.max_items = by.max_items; + self.unique_items = by.unique_items; + self.is_array = true; + match &self.items { + Some(items) => { + self.data_type.set_array(&items.data_type); + } + None => { + panic!("BUG: an array without an inner type: {:?}", self); + } + } + self.is_container = true; + self + } + fn with_anyobj(mut self, root: &super::OpenApiV3, by: &openapiv3::AnySchema) -> Self { + self.min_properties = by.min_properties; + self.max_properties = by.max_properties; + + self.is_model = true; + + let vars = by + .properties + .iter() + .map(|(k, v)| root.resolve_reference_or(&v.clone().unbox(), Some(&self), Some(k), None)) + .map(|m| { + let required = by.required.contains(&m.name); + m.with_required(required) + }) + .collect::>(); + + let vars = vars + .into_iter() + .map(|p| p.with_is_var(true)) + .collect::>(); + + self.required_vars = vars + .iter() + .filter(|m| m.required) + .cloned() + .collect::>(); + self.optional_vars = vars + .iter() + .filter(|m| !m.required) + .cloned() + .collect::>(); + self.vars = vars; + + let mut vars_ = self.vars.iter().filter(|p| !p.required).collect::>(); + if vars_.len() != self.vars.len() { + panic!("Not Supported - all vars of oneOf must be optional"); + } + + let one_of = &by.one_of; + one_of + .iter() + .flat_map(|p| p.as_item()) + .map(|s| match &s.schema_kind { + openapiv3::SchemaKind::Any(schema) => schema, + _ => todo!(), + }) + .filter(|o| o.required.len() == 1) + .for_each(|o| vars_.retain(|v| v.name != o.required[0])); + + self.one_of = vec![self.clone()]; + self + } + fn with_obj(mut self, root: &super::OpenApiV3, by: &openapiv3::ObjectType) -> Self { + self.min_properties = by.min_properties; + self.max_properties = by.max_properties; + + if let Some(props) = &by.additional_properties { + match props { + openapiv3::AdditionalProperties::Any(any) => { + if *any { + return self.with_data_type_any(*any); + } + } + openapiv3::AdditionalProperties::Schema(ref_or) => match ref_or.deref() { + openapiv3::ReferenceOr::Reference { reference } => { + let inner = root.resolve_schema_name(None, reference); + self.data_type + .set_map(&PropertyDataType::RawString, &inner.data_type); + self.discovered_props = Rc::new(vec![inner]); + return self; + } + openapiv3::ReferenceOr::Item(item) => { + let property = Self::from_schema(root, None, item, None, None); + self.data_type + .set_map(&PropertyDataType::RawString, &property.data_type); + return self; + } + }, + } + } + + if !root.resolving(&self) { + let vars = by + .properties + .iter() + .map(|(k, v)| { + root.resolve_reference_or(&v.clone().unbox(), Some(&self), Some(k), None) + }) + .map(|m| { + let required = by.required.contains(&m.name); + m.with_required(required) + }) + .collect::>(); + + if vars.is_empty() { + return self.with_data_type_any(false); + } + self.is_model = true; + + self.discovered_props = Rc::new(vars.clone()); + let vars = vars + .into_iter() + .map(|p| p.with_is_var(true)) + .collect::>(); + + self.required_vars = vars + .iter() + .filter(|m| m.required) + .cloned() + .collect::>(); + self.optional_vars = vars + .iter() + .filter(|m| !m.required) + .cloned() + .collect::>(); + self.vars = vars; + } else { + // it's a circular reference, we must be a model + self.is_model = true; + } + + // if let Some(one_of) = &by.one_of { + // let mut vars_ = self.vars.iter().filter(|p| !p.required).collect::>(); + // if vars_.len() != self.vars.len() { + // panic!("Not Supported - all vars of oneOf must be optional"); + // } + // one_of + // .iter() + // .flat_map(|p| p.as_item()) + // .filter(|o| o.required.len() == 1) + // .for_each(|o| vars_.retain(|v| v.name != o.required[0])); + // if vars_.is_empty() { + // self.one_of = vec![self.clone()]; + // } else { + // panic!("OneOf with incorrect combination of required fields"); + // } + // } + self + } + fn with_integer(mut self, _root: &super::OpenApiV3, by: &openapiv3::IntegerType) -> Self { + self.exclusive_maximum = by.exclusive_maximum; + self.exclusive_minimum = by.exclusive_minimum; + self.minimum = by.minimum.map(|v| v.to_string()); + self.maximum = by.maximum.map(|v| v.to_string()); + self.is_integer = true; + self.is_primitive_type = true; + self.data_type.set_integer(by); + self + } + fn with_number(mut self, _root: &super::OpenApiV3, by: &openapiv3::NumberType) -> Self { + self.exclusive_maximum = by.exclusive_maximum; + self.exclusive_minimum = by.exclusive_minimum; + self.minimum = by.minimum.map(|v| v.to_string()); + self.maximum = by.maximum.map(|v| v.to_string()); + self.data_type.set_number(by); + self.is_primitive_type = true; + self + } + fn with_string(mut self, _root: &super::OpenApiV3, by: &openapiv3::StringType) -> Self { + self.pattern = by.pattern.clone(); + self.has_enums = !by.enumeration.is_empty(); + self.is_enum = self.has_enums; + + self.min_length = by.min_length; + self.data_type.set_string(by); + + match &by.format { + openapiv3::VariantOrUnknownOrEmpty::Item(item) => match item { + openapiv3::StringFormat::Date => self.is_date = true, + openapiv3::StringFormat::DateTime => self.is_date_time = true, + openapiv3::StringFormat::Password => self.is_date = true, + openapiv3::StringFormat::Byte => self.is_byte = true, + openapiv3::StringFormat::Binary => self.is_binary = true, + }, + openapiv3::VariantOrUnknownOrEmpty::Unknown(format) => match format.as_str() { + "uuid" => self.is_uuid = true, + "date" => self.is_date = true, + "date-time" => self.is_date_time = true, + _ => { + self.is_string = true; + } + }, + openapiv3::VariantOrUnknownOrEmpty::Empty => { + self.is_string = true; + } + } + + if self.is_enum { + let enum_vars = by + .enumeration + .iter() + .flatten() + .map(|v| EnumValue { + name: v.to_upper_camel_case(), + value: v.to_string(), + }) + .collect::>(); + + self.is_model = true; + self.allowable_values.insert("enumVars".into(), enum_vars); + self.data_type.set_enum(&self.name, &self.type_); + } else { + self.is_primitive_type = true; + } + + self + } +} + +#[derive(Default, Content, Clone, Debug)] +#[ramhorns(rename_all = "camelCase")] +pub(crate) struct EnumValue { + name: String, + value: String, +} diff --git a/cli-ng/src/v3/templates/default/Cargo.mustache b/cli-ng/src/v3/templates/default/Cargo.mustache new file mode 100644 index 000000000..32f59ccad --- /dev/null +++ b/cli-ng/src/v3/templates/default/Cargo.mustache @@ -0,0 +1,61 @@ +[package] +name = "{{{packageName}}}" +version = "{{{packageVersion}}}" +edition = "{{{packageEdition}}}" + +[lib] +name = "{{{packageLibname}}}" +path = "src/lib.rs" + +[features] +default = [ "tower-client-rls", "tower-trace" ] +actix-server = [ "actix" ] +actix-client = [ "actix", "actix-web-opentelemetry", "awc" ] +actix = [ "actix-web", "rustls" ] +tower-client-rls = [ "tower-client", "rustls_feat" ] +tower-client-tls = [ "tower-client", "hyper_tls_feat" ] +tower-client = [ "tower-hyper" ] +tower-hyper = [ "hyper", "tower", "tower-http", "http-body", "futures", "pin-project", "tokio" ] +hyper_tls_feat = [ "hyper-tls", "tokio-native-tls" ] +rustls_feat = [ "rustls", "webpki", "hyper-rustls" ] +tower-trace = [ "opentelemetry-jaeger", "tracing-opentelemetry", "opentelemetry", "opentelemetry-http", "tracing", "tracing-subscriber" ] + +[dependencies] +serde = "^1.0" +serde_derive = "^1.0" +serde_json = "^1.0" +url = { version = "^2.4", features = ["serde"] } +async-trait = "0.1.73" +dyn-clonable = "0.9.0" +uuid = { version = "1.4.1", features = ["serde", "v4"] } +serde_urlencoded = "0.7" + +# actix dependencies +actix-web = { version = "4.4.0", features = ["rustls-0_21"], optional = true } +actix-web-opentelemetry = { version = "0.17.0", optional = true } +awc = { version = "3.2.0", optional = true } + +# tower and hyper dependencies +hyper = { version = "0.14.27", features = [ "client", "http1", "http2", "tcp", "stream" ], optional = true } +tower = { version = "0.4.13", features = [ "timeout", "util", "limit" ], optional = true } +tower-http = { version = "0.4.4", features = [ "trace", "map-response-body", "auth" ], optional = true } +tokio = { version = "1.32.0", features = ["full"], optional = true } +http-body = { version = "0.4.5", optional = true } +futures = { version = "0.3.28", optional = true } +pin-project = { version = "1.1.3", optional = true } + +# SSL +rustls = { version = "0.21.12", optional = true, features = [ "dangerous_configuration" ] } +rustls-pemfile = "1.0.3" +webpki = { version = "0.22.2", optional = true } +hyper-rustls = { version = "0.24.1", optional = true } +hyper-tls = { version = "0.5.0", optional = true } +tokio-native-tls = { version = "0.3.1", optional = true } + +# tracing and telemetry +opentelemetry-jaeger = { version = "0.21.0", features = ["rt-tokio-current-thread"], optional = true } +tracing-opentelemetry = { version = "0.23.0", optional = true } +opentelemetry = { version = "0.22.0", optional = true } +opentelemetry-http = { version = "0.11.1", optional = true } +tracing = { version = "0.1.37", optional = true } +tracing-subscriber = { version = "0.3.18", optional = true } \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/README.md b/cli-ng/src/v3/templates/default/README.md new file mode 100644 index 000000000..e375a30f7 --- /dev/null +++ b/cli-ng/src/v3/templates/default/README.md @@ -0,0 +1,50 @@ +# Rust API client for {{{packageName}}} + +{{#appDescriptionWithNewLines}} +{{{appDescriptionWithNewLines}}} +{{/appDescriptionWithNewLines}} + +## Overview + +- API version: {{{appVersion}}} +- Package version: {{{packageVersion}}} +{{^hideGenerationTimestamp}} +- Build date: {{{generatedDate}}} +{{/hideGenerationTimestamp}} +- Build package: {{{generatorClass}}} +{{#infoUrl}} +For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) +{{/infoUrl}} + +## Installation + +Put the package under your project folder and add the following to `Cargo.toml` under `[dependencies]`: + +``` + openapi = { path = "./generated" } +``` + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{{classname}}}* | [**{{{operationId}}}**]({{{apiDocPath}}}{{classname}}.md#{{{operationIdLowerCase}}}) | **{{{httpMethod}}}** {{{path}}} | {{#summary}}{{{summary}}}{{/summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +## Documentation For Models + +{{#models}}{{#model}} - [{{{classname}}}]({{{modelDocPath}}}{{{classname}}}.md) +{{/model}}{{/models}} + +To get access to the crate's generated documentation, use: + +``` +cargo doc --open +``` + +## Author + +{{#apiInfo}}{{#apis}}{{#-last}}{{{infoEmail}}} +{{/-last}}{{/apis}}{{/apiInfo}} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/actix/client/api_clients.mustache b/cli-ng/src/v3/templates/default/actix/client/api_clients.mustache new file mode 100644 index 000000000..f386bdbe3 --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/client/api_clients.mustache @@ -0,0 +1,201 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct {{{classname}}}Client { + configuration: Rc, +} + +impl {{{classname}}}Client { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait {{{classname}}}: Clone { + {{#operations}} + {{#operation}} + {{#description}} + /// {{{.}}} + {{/description}} + {{#notes}} + /// {{{.}}} + {{/notes}} + async fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error>; + {{/operation}} + {{/operations}} +} + +#[async_trait::async_trait(?Send)] +impl {{{classname}}} for {{{classname}}}Client { + {{#operations}} + {{#operation}} + {{#vendorExtensions.x-group-parameters}} + async fn {{{operationId}}}(&self{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error> { + // unbox the parameters + {{#allParams}} + let {{paramName}} = params.{{paramName}}; + {{/allParams}} + + {{/vendorExtensions.x-group-parameters}} + {{^vendorExtensions.x-group-parameters}} + async fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error> { + {{/vendorExtensions.x-group-parameters}} + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}{{{path}}}", configuration.base_path{{#pathParams}}, {{{baseName}}}={{#isString}}crate::apis::urlencode({{/isString}}{{{paramName}}}{{^required}}.unwrap_or_default(){{/required}}{{#required}}{{#isNullable}}.unwrap_or_default(){{/isNullable}}{{/required}}{{#isArray}}.join(",").as_ref(){{/isArray}}{{#isString}}){{/isString}}{{^isString}}.to_string(){{/isString}}{{/pathParams}}); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::{{#vendorExtensions}}{{x-httpMethodUpper}}{{/vendorExtensions}}, local_var_uri_str.as_str()); + + {{#hasQueryParams}} + let mut query_params = vec![]; + {{#queryParams}} + {{#required}} + query_params.push(("{{{baseName}}}", {{{paramName}}}{{#isArray}}.into_iter().map(|p| p.to_string()).collect::>().join(","){{/isArray}}.to_string())); + {{/required}} + {{^required}} + if let Some(ref local_var_str) = {{{paramName}}} { + query_params.push(("{{{baseName}}}", local_var_str{{#isArray}}.into_iter().map(|p| p.to_string()).collect::>().join(","){{/isArray}}.to_string())); + } + {{/required}} + {{/queryParams}} + local_var_req_builder = local_var_req_builder.query(&query_params)?; + {{/hasQueryParams}} + {{#hasAuthMethods}} + {{#authMethods}} + {{#isApiKey}} + {{#isKeyInQuery}} + if let Some(ref local_var_apikey) = configuration.api_key { + let local_var_key = local_var_apikey.key.clone(); + let local_var_value = match local_var_apikey.prefix { + Some(ref local_var_prefix) => format!("{local_var_prefix} {local_var_key}"), + None => local_var_key, + }; + {{^hasQueryParams}}let mut query_params = vec![];{{/hasQueryParams}} + query_params.push(("{{{keyParamName}}}", local_var_value)); + local_var_req_builder = local_var_req_builder.query(&query_params)?; + } + {{/isKeyInQuery}} + {{/isApiKey}} + {{/authMethods}} + {{/hasAuthMethods}} + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + {{#hasHeaderParams}} + {{#headerParams}} + {{#required}} + {{^isNullable}} + local_var_req_builder = local_var_req_builder.insert_header(("{{{baseName}}}", {{{paramName}}}{{#isArray}}.join(","){{/isArray}}.to_string())); + {{/isNullable}} + {{#isNullable}} + match {{{paramName}}} { + Some(local_var_param_value) => { local_var_req_builder = local_var_req_builder.insert_header(("{{{baseName}}}", local_var_param_value{{#isArray}}.join(","){{/isArray}}.to_string())); }, + None => { local_var_req_builder = local_var_req_builder.insert_header(("{{{baseName}}}", "")); }, + } + {{/isNullable}} + {{/required}} + {{^required}} + if let Some(local_var_param_value) = {{{paramName}}} { + local_var_req_builder = local_var_req_builder.insert_header(("{{{baseName}}}", local_var_param_value{{#isArray}}.join(","){{/isArray}}.to_string())); + } + {{/required}} + {{/headerParams}} + {{/hasHeaderParams}} + {{#hasAuthMethods}} + {{#authMethods}} + {{#isApiKey}} + {{#isKeyInHeader}} + if let Some(ref local_var_apikey) = configuration.api_key { + let local_var_key = local_var_apikey.key.clone(); + let local_var_value = match local_var_apikey.prefix { + Some(ref local_var_prefix) => format!("{local_var_prefix} {local_var_key}"), + None => local_var_key, + }; + local_var_req_builder = local_var_req_builder.insert_header(("{{{keyParamName}}}", local_var_value)); + } + {{/isKeyInHeader}} + {{/isApiKey}} + {{#isBasic}} + {{#isBasicBasic}} + if let Some(ref local_var_auth_conf) = configuration.basic_auth { + local_var_req_builder = local_var_req_builder.basic_auth(local_var_auth_conf.0.to_owned(), local_var_auth_conf.1.to_owned()); + } + {{/isBasicBasic}} + {{#isBasicBearer}} + if let Some(ref local_var_token) = configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + } + {{/isBasicBearer}} + {{/isBasic}} + {{#isOAuth}} + if let Some(ref local_var_token) = configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + } + {{/isOAuth}} + {{/authMethods}} + {{/hasAuthMethods}} + {{#isMultipart}} + $NOT_SUPPORTED$ + {{/isMultipart}} + {{#hasBodyParam}} + {{#bodyParam}} + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.send_json(&{{{paramName}}}).await + } else { + local_var_req_builder.trace_request().send_json(&{{{paramName}}}).await + }?; + {{/bodyParam}} + {{/hasBodyParam}} + {{^hasBodyParam}} + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + {{/hasBodyParam}} + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + {{^supportMultipleResponses}} + {{^returnType}} + Ok(()) + {{/returnType}} + {{#returnType}} + let local_var_content = local_var_resp.json::<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}>().await?; + Ok(local_var_content) + {{/returnType}} + {{/supportMultipleResponses}} + {{#supportMultipleResponses}} + let local_var_content = local_var_resp.json::<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}>().await?; + let local_var_entity: Option<{{{operationIdCamelCase}}}Success> = serde_json::from_str(&local_var_content).ok(); + let local_var_result = ResponseContent { status: local_var_status, entity: local_var_entity }; + Ok(local_var_result) + {{/supportMultipleResponses}} + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + {{/operation}} + {{/operations}} +} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/actix/client/client.mustache b/cli-ng/src/v3/templates/default/actix/client/client.mustache new file mode 100644 index 000000000..9681f9262 --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/client/client.mustache @@ -0,0 +1,134 @@ +pub mod configuration; + +pub use configuration::Configuration; +use std::{error, fmt, rc::Rc}; + +#[derive(Clone)] +pub struct ApiClient { +{{#apiInfo}} +{{#apis}} +{{#operations}} + {{{classFilename}}}: Box, +{{/operations}} +{{/apis}} +{{/apiInfo}} +} + +impl ApiClient { + pub fn new(configuration: Configuration) -> ApiClient { + let rc = Rc::new(configuration); + + ApiClient { +{{#apiInfo}} +{{#apis}} +{{#operations}} + {{^-last}} + {{{classFilename}}}: Box::new(crate::apis::{{{classFilename}}}::actix::client::{{{classname}}}Client::new(rc.clone())), + {{/-last}} + {{#-last}} + {{{classFilename}}}: Box::new(crate::apis::{{{classFilename}}}::actix::client::{{{classname}}}Client::new(rc)), + {{/-last}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + } + } + +{{#apiInfo}} +{{#apis}} +{{#operations}} + pub fn {{{classFilename}}}(&self) -> &dyn crate::apis::{{{classFilename}}}::actix::client::{{{classname}}} { + self.{{{classFilename}}}.as_ref() + } +{{/operations}} +{{/apis}} +{{/apiInfo}} +} + +#[derive(Debug, Clone)] +pub struct ResponseContent { + pub status: awc::http::StatusCode, + pub error: T, +} + +#[derive(Debug, Clone)] +pub struct ResponseContentUnexpected { + pub status: awc::http::StatusCode, + pub text: String, +} + +#[derive(Debug)] +pub enum Error { + Request(awc::error::SendRequestError), + Serde(serde_json::Error), + SerdeEncoded(serde_urlencoded::ser::Error), + PayloadError(awc::error::JsonPayloadError), + Io(std::io::Error), + ResponseError(ResponseContent), + ResponseUnexpected(ResponseContentUnexpected), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + Error::Request(e) => ("request", e.to_string()), + Error::Serde(e) => ("serde", e.to_string()), + Error::SerdeEncoded(e) => ("serde", e.to_string()), + Error::PayloadError(e) => ("payload", e.to_string()), + Error::Io(e) => ("IO", e.to_string()), + Error::ResponseError(e) => ( + "response", + format!("status code '{}', content: '{:?}'", e.status, e.error), + ), + Error::ResponseUnexpected(e) => ( + "response", + format!("status code '{}', text '{}'", e.status, e.text), + ), + }; + write!(f, "error in {module}: {e}") + } +} + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(match self { + Error::Request(e) => e, + Error::Serde(e) => e, + Error::SerdeEncoded(e) => e, + Error::PayloadError(e) => e, + Error::Io(e) => e, + Error::ResponseError(_) => return None, + Error::ResponseUnexpected(_) => return None, + }) + } +} + +impl From for Error { + fn from(e: awc::error::SendRequestError) -> Self { + Error::Request(e) + } +} + +impl From for Error { + fn from(e: awc::error::JsonPayloadError) -> Self { + Error::PayloadError(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Error::Serde(e) + } +} + +impl From for Error { + fn from(e: serde_urlencoded::ser::Error) -> Self { + Error::SerdeEncoded(e) + } +} + +impl From for Error { + fn from(e: std::io::Error) -> Self { + Error::Io(e) + } +} diff --git a/cli-ng/src/v3/templates/default/actix/client/configuration.mustache b/cli-ng/src/v3/templates/default/actix/client/configuration.mustache new file mode 100644 index 000000000..fda28e7e8 --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/client/configuration.mustache @@ -0,0 +1,105 @@ +#[derive(Clone)] +pub struct Configuration { + pub base_path: String, + pub user_agent: Option, + pub client: awc::Client, + pub basic_auth: Option, + pub oauth_access_token: Option, + pub bearer_access_token: Option, + pub api_key: Option, + pub trace_requests: bool, + // TODO: take an oauth2 token source, similar to the go one +} + +pub type BasicAuth = (String, Option); + +#[derive(Debug, Clone)] +pub struct ApiKey { + pub prefix: Option, + pub key: String, +} + +/// Configuration creation Error +#[derive(Debug)] +pub enum Error { + Certificate, +} + +impl Configuration { + /// New Configuration + pub fn new( + uri: &str, + timeout: std::time::Duration, + bearer_access_token: Option, + certificate: Option<&[u8]>, + trace_requests: bool, + ) -> Result { + let (client, url) = match certificate { + Some(bytes) => { + let cert_file = &mut std::io::BufReader::new(bytes); + + let mut config = rustls::ClientConfig::new(); + config + .root_store + .add_pem_file(cert_file) + .map_err(|_| Error::Certificate)?; + let connector = awc::Connector::new().rustls(std::sync::Arc::new(config)); + let client = awc::Client::builder() + .timeout(timeout) + .connector(connector) + .finish(); + + (client, format!("https://{uri}")) + } + None => { + let client = awc::Client::builder().timeout(timeout).finish(); + (client, format!("http://{uri}")) + } + }; + + Ok(Configuration { + base_path: url, + user_agent: None, + client, + basic_auth: None, + oauth_access_token: None, + bearer_access_token, + api_key: None, + trace_requests, + }) + } + + /// New Configuration with a provided client + pub fn new_with_client( + url: &str, + client: awc::Client, + bearer_access_token: Option, + trace_requests: bool, + ) -> Self { + Self { + base_path: url.to_string(), + user_agent: None, + client, + basic_auth: None, + oauth_access_token: None, + bearer_access_token, + api_key: None, + trace_requests, + } + } +} + +impl Default for Configuration { + fn default() -> Self { + Configuration { + base_path: "http://localhost/v0".to_owned(), + user_agent: Some("OpenAPI-Generator/v0/rust".to_owned()), + client: awc::Client::new(), + basic_auth: None, + oauth_access_token: None, + bearer_access_token: None, + api_key: None, + trace_requests: false, + } + } +} diff --git a/cli-ng/src/v3/templates/default/actix/mod.mustache b/cli-ng/src/v3/templates/default/actix/mod.mustache new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/mod.mustache @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/actix/server/api.mustache b/cli-ng/src/v3/templates/default/actix/server/api.mustache new file mode 100644 index 000000000..714c23f45 --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/server/api.mustache @@ -0,0 +1,21 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait {{{classname}}} { +{{#operations}} +{{#operation}} +{{#description}} + /// {{{.}}} +{{/description}} +{{#notes}} + /// {{{.}}} +{{/notes}} + async fn {{{operationId}}}({{#vendorExtensions.x-actix-query-string}}query: &str{{#hasParams}}, {{/hasParams}}{{/vendorExtensions.x-actix-query-string}}{{#hasPathParams}}Path({{#pathParams.1}}({{/pathParams.1}}{{#pathParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/pathParams}}{{#pathParams.1}}){{/pathParams.1}}): Path<{{#pathParams.1}}({{/pathParams.1}}{{#pathParams}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/pathParams}}{{#pathParams.1}}){{/pathParams.1}}>{{/hasPathParams}}{{#hasQueryParams}}{{#hasPathParams}}, {{/hasPathParams}}Query({{#queryParams.1}}({{/queryParams.1}}{{#queryParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/queryParams}}{{#queryParams.1}}){{/queryParams.1}}): Query<{{#queryParams.1}}({{/queryParams.1}}{{#queryParams}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{{dataType}}}{{/isString}}{{#isUuid}}uuid::Uuid{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/queryParams}}{{#queryParams.1}}){{/queryParams.1}}>{{/hasQueryParams}}{{#hasBodyParam}}{{#hasQueryParams}}, {{/hasQueryParams}}{{^hasQueryParams}}{{#hasPathParams}}, {{/hasPathParams}}{{/hasQueryParams}}{{#bodyParam}}Body({{{paramName}}}): Body<{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}>{{/bodyParam}}{{/hasBodyParam}}) -> Result<{{#returnType}}{{/returnType}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, RestError>; +{{/operation}} +{{/operations}} +} + +pub mod handlers; \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/actix/server/api_mod.mustache b/cli-ng/src/v3/templates/default/actix/server/api_mod.mustache new file mode 100644 index 000000000..61f7c438f --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/server/api_mod.mustache @@ -0,0 +1,251 @@ +use actix_web::http::StatusCode; +use actix_web::{web::ServiceConfig, FromRequest, HttpResponse, ResponseError}; +use serde::Serialize; +use std::{ + fmt::{self, Debug, Display, Formatter}, + ops, +}; + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} +{{#-last}} +pub use crate::apis::{{{classFilename}}}::actix::server::{{{classname}}}; +{{/-last}} +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + +/// Rest Error wrapper with a status code and a JSON error +/// Note: Only a single error type for each handler is supported at the moment +pub struct RestError { + status_code: StatusCode, + error_response: T, +} + +impl RestError { + pub fn new(status_code: StatusCode, error_response: T) -> Self { + Self { + status_code, + error_response + } + } +} + +impl Debug for RestError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("RestError") + .field("status_code", &self.status_code) + .field("error_response", &self.error_response) + .finish() + } +} + +impl Display for RestError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +impl ResponseError for RestError { + fn status_code(&self) -> StatusCode { + self.status_code + } + + fn error_response(&self) -> HttpResponse { + HttpResponse::build(self.status_code).json(&self.error_response) + } +} + +/// 204 Response with no content +#[derive(Default)] +pub(crate) struct NoContent; + +impl From> for NoContent { + fn from(_: actix_web::web::Json<()>) -> Self { + NoContent {} + } +} +impl From<()> for NoContent { + fn from(_: ()) -> Self { + NoContent {} + } +} +impl actix_web::Responder for NoContent { + {{^actixWeb4Beta}}type Body = actix_web::body::BoxBody;{{/actixWeb4Beta}} + + fn respond_to(self, _: &actix_web::HttpRequest) -> actix_web::HttpResponse { + actix_web::HttpResponse::NoContent().finish() + } +} + +/// Wrapper type used as tag to easily distinguish the 3 different parameter types: +/// 1. Path 2. Query 3. Body +/// Example usage: +/// fn delete_resource(Path((p1, p2)): Path<(String, u64)>) { ... } +pub struct Path(pub T); + +impl Path { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.0 + } +} + +impl AsRef for Path { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl ops::Deref for Path { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Path { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// Wrapper type used as tag to easily distinguish the 3 different parameter types: +/// 1. Path 2. Query 3. Body +/// Example usage: +/// fn delete_resource(Path((p1, p2)): Path<(String, u64)>) { ... } +pub struct Query(pub T); + +impl Query { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.0 + } +} + +impl AsRef for Query { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl ops::Deref for Query { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Query { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// Wrapper type used as tag to easily distinguish the 3 different parameter types: +/// 1. Path 2. Query 3. Body +/// Example usage: +/// fn delete_resource(Path((p1, p2)): Path<(String, u64)>) { ... } +pub struct Body(pub T); + +impl Body { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.0 + } +} + +impl AsRef for Body { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl ops::Deref for Body { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Body { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// Configure all actix server handlers +pub fn configure(cfg: &mut ServiceConfig) { +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} +{{#-last}} + crate::apis::{{{classFilename}}}::actix::server::handlers::configure::(cfg); +{{/-last}} +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} +} + +/// Used with Query to deserialize into Vec. +#[allow(dead_code)] +pub(crate) fn deserialize_stringified_list<'de, D, I>( + deserializer: D, +) -> std::result::Result, D::Error> +where + D: serde::de::Deserializer<'de>, + I: serde::de::DeserializeOwned, +{ + struct StringVecVisitor(std::marker::PhantomData); + + impl<'de, I> serde::de::Visitor<'de> for StringVecVisitor + where + I: serde::de::DeserializeOwned, + { + type Value = Vec; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a string containing a list") + } + + fn visit_str(self, v: &str) -> std::result::Result + where + E: serde::de::Error, + { + let mut list = Vec::new(); + if !v.is_empty() { + for item in v.split(',') { + let item = I::deserialize(serde::de::IntoDeserializer::into_deserializer(item))?; + list.push(item); + } + } + Ok(list) + } + } + + deserializer.deserialize_any(StringVecVisitor(std::marker::PhantomData::)) +} + +/// Used with Query to deserialize into Option>. +#[allow(dead_code)] +pub(crate) fn deserialize_option_stringified_list<'de, D, I>( + deserializer: D, +) -> std::result::Result>, D::Error> +where + D: serde::de::Deserializer<'de>, + I: serde::de::DeserializeOwned, +{ + let list = deserialize_stringified_list(deserializer)?; + match list.is_empty() { + true => Ok(None), + false => Ok(Some(list)), + } +} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/actix/server/handlers.mustache b/cli-ng/src/v3/templates/default/actix/server/handlers.mustache new file mode 100644 index 000000000..03b44b79d --- /dev/null +++ b/cli-ng/src/v3/templates/default/actix/server/handlers.mustache @@ -0,0 +1,60 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + {{{classFilename}}}::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the {{{classname}}} resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg +{{#operations}} +{{#operation}} + .service( + actix_web::web::resource("{{#vendorExtensions.x-actixPath}}{{{vendorExtensions.x-actixPath}}}{{/vendorExtensions.x-actixPath}}{{^vendorExtensions.x-actixPath}}{{{path}}}{{/vendorExtensions.x-actixPath}}") + .name("{{{operationId}}}") + .guard(actix_web::guard::{{{httpMethod}}}()) + .route(actix_web::web::{{#vendorExtensions}}{{x-httpMethodLower}}{{/vendorExtensions}}().to({{{operationId}}}::)) + ){{#-last}};{{/-last}} +{{/operation}} +{{/operations}} +} + +{{#operations}} +{{#operation}} +{{#hasQueryParams}} +#[derive(serde::Deserialize)] +struct {{{operationId}}}QueryParams { +{{#queryParams}} + {{#description}}/// {{{description}}}{{/description}} + #[serde(rename = "{{{baseName}}}"{{^required}}, default, skip_serializing_if = "Option::is_none"{{#isContainer}}{{#items}}{{#isString}}, deserialize_with = "deserialize_option_stringified_list"{{/isString}}{{/items}}{{/isContainer}}{{/required}}{{#required}}{{#isContainer}}{{#items}}{{#isString}}, deserialize_with = "deserialize_stringified_list"{{/isString}}{{/items}}{{/isContainer}}{{/required}})] + pub {{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{{dataType}}}{{/isString}}{{#isUuid}}uuid::Uuid{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}, +{{/queryParams}} +} +{{/hasQueryParams}} +{{/operation}} +{{/operations}} + +{{#operations}} +{{#operation}} +{{#description}} +/// {{{.}}} +{{/description}} +{{#notes}} +/// {{{.}}} +{{/notes}} +async fn {{{operationId}}}({{#vendorExtensions.x-actix-query-string}}request: HttpRequest{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#hasAuthMethods}}, {{/hasAuthMethods}}{{/hasParams}}{{/vendorExtensions.x-actix-query-string}}{{#hasAuthMethods}}_token: A{{#hasParams}}, {{/hasParams}}{{/hasAuthMethods}}{{#hasPathParams}}path: Path<{{#pathParams.1}}({{/pathParams.1}}{{#pathParams}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/pathParams}}{{#pathParams.1}}){{/pathParams.1}}>{{/hasPathParams}}{{#hasQueryParams}}{{#hasPathParams}}, {{/hasPathParams}}query: Query<{{{operationId}}}QueryParams>{{/hasQueryParams}}{{#hasBodyParam}}{{#hasQueryParams}}, {{/hasQueryParams}}{{^hasQueryParams}}{{#hasPathParams}}, {{/hasPathParams}}{{/hasQueryParams}}{{#bodyParam}}Json({{{paramName}}}): Json<{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}{{{dataType}}}{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}>{{/bodyParam}}{{/hasBodyParam}}) -> Result<{{#supportMultipleResponses}}Json>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}NoContent{{/returnType}}{{#returnType}}Json<{{{returnType}}}>{{/returnType}}{{/supportMultipleResponses}}, RestError> { + {{#hasQueryParams}}let query = query.into_inner(); + {{/hasQueryParams}}T::{{{operationId}}}({{#vendorExtensions.x-actix-query-string}}request.query_string(){{#hasParams}}, {{/hasParams}}{{/vendorExtensions.x-actix-query-string}}{{#hasPathParams}}crate::apis::actix_server::Path(path.into_inner()){{/hasPathParams}}{{#hasQueryParams}}{{#hasPathParams}}, {{/hasPathParams}}crate::apis::actix_server::Query({{#queryParams.1}}({{/queryParams.1}}{{#queryParams}}query.{{{paramName}}}{{^-last}}, {{/-last}}{{/queryParams}}{{#queryParams.1}}){{/queryParams.1}}){{/hasQueryParams}}{{#hasBodyParam}}{{#hasQueryParams}}, {{/hasQueryParams}}{{^hasQueryParams}}{{#hasPathParams}}, {{/hasPathParams}}{{/hasQueryParams}}{{#bodyParam}}Body({{{paramName}}}){{/bodyParam}}{{/hasBodyParam}}).await.map(Json){{^supportMultipleResponses}}{{^returnType}}.map(Into::into){{/returnType}}{{/supportMultipleResponses}} +} + +{{/operation}} +{{/operations}} diff --git a/cli-ng/src/v3/templates/default/api_doc.mustache b/cli-ng/src/v3/templates/default/api_doc.mustache new file mode 100644 index 000000000..250db3fc5 --- /dev/null +++ b/cli-ng/src/v3/templates/default/api_doc.mustache @@ -0,0 +1,47 @@ +# {{#hasInvokerPackage}}{{{invokerPackage}}}\{{/hasInvokerPackage}}{{{classname}}}{{#description}} + +{{{description}}}{{/description}} + +All URIs are relative to *{{{basePath}}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#operations}}{{#operation}}[**{{{operationId}}}**]({{{classname}}}.md#{{{operationId}}}) | **{{{httpMethod}}}** {{{path}}} | {{#summary}}{{{summary}}}{{/summary}} +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} + +## {{{operationId}}} + +> {{#returnType}}{{{returnType}}} {{/returnType}}{{{operationId}}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}) +{{{summary}}}{{#notes}} + +{{{notes}}}{{/notes}} + +### Parameters + +{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}} +{{#allParams}} +**{{{paramName}}}** | {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{{dataType}}}**]({{{baseType}}}.md){{/isPrimitiveType}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}} | {{{description}}} | {{#required}}[required]{{/required}} |{{#defaultValue}}[default to {{{defaultValue}}}]{{/defaultValue}} +{{/allParams}} + +### Return type + +{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{{returnBaseType}}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}} (empty response body){{/returnType}} + +### Authorization + +{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}} + +### HTTP request headers + +- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}} +- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}} + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +{{/operation}} +{{/operations}} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/api_mod.mustache b/cli-ng/src/v3/templates/default/api_mod.mustache new file mode 100644 index 000000000..d19d3462a --- /dev/null +++ b/cli-ng/src/v3/templates/default/api_mod.mustache @@ -0,0 +1,55 @@ +{{#apiInfo}} +{{#apis}} +pub mod {{{classFilename}}}; +{{/apis}} +{{/apiInfo}} + +/// Actix server. +#[cfg(feature = "actix-server")] +pub mod actix_server; + +#[cfg(feature = "tower-hyper")] +pub use hyper::http::StatusCode; + +#[cfg(not(feature = "tower-hyper"))] +#[cfg(feature = "actix")] +pub use actix_web::http::StatusCode; + +/// Url. +pub use url::Url; +/// Uuid. +pub use uuid::Uuid; + +/// Encode string to use in a URL. +pub fn urlencode>(s: T) -> String { + ::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect() +} + +/// Helper to convert from Vec into Vec. +pub trait IntoVec: Sized { + /// Performs the conversion. + fn into_vec(self) -> Vec; +} + +impl, T> IntoVec for Vec { + fn into_vec(self) -> Vec { + self.into_iter().map(Into::into).collect() + } +} + +/// Helper to convert from Vec or Option> into Option>. +pub trait IntoOptVec: Sized { + /// Performs the conversion. + fn into_opt_vec(self) -> Option>; +} + +impl, T> IntoOptVec for Vec { + fn into_opt_vec(self) -> Option> { + Some(self.into_iter().map(Into::into).collect()) + } +} +impl, T> IntoOptVec for Option> { + fn into_opt_vec(self) -> Option> { + self.map(|s| s.into_iter().map(Into::into).collect()) + } +} diff --git a/cli-ng/src/v3/templates/default/gitignore.mustache b/cli-ng/src/v3/templates/default/gitignore.mustache new file mode 100644 index 000000000..eccd7b4ab --- /dev/null +++ b/cli-ng/src/v3/templates/default/gitignore.mustache @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/cli-ng/src/v3/templates/default/lib.mustache b/cli-ng/src/v3/templates/default/lib.mustache new file mode 100644 index 000000000..2ad74474f --- /dev/null +++ b/cli-ng/src/v3/templates/default/lib.mustache @@ -0,0 +1,24 @@ +#[macro_use] +extern crate serde_derive; + +extern crate serde; +extern crate serde_json; +extern crate url; + +pub mod apis; +pub mod models; +pub mod clients; + +#[cfg(feature = "tower-hyper")] +pub mod tower { + pub use crate::clients::tower as client; +} + +#[cfg(feature = "actix")] +pub mod actix { + #[cfg(feature = "actix-client")] + pub use crate::clients::actix as client; + + #[cfg(feature = "actix-server")] + pub use crate::apis::actix_server as server; +} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/mod.mustache b/cli-ng/src/v3/templates/default/mod.mustache new file mode 100644 index 000000000..a7e8d7d21 --- /dev/null +++ b/cli-ng/src/v3/templates/default/mod.mustache @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; diff --git a/cli-ng/src/v3/templates/default/mod_clients.mustache b/cli-ng/src/v3/templates/default/mod_clients.mustache new file mode 100644 index 000000000..3ee07f2de --- /dev/null +++ b/cli-ng/src/v3/templates/default/mod_clients.mustache @@ -0,0 +1,9 @@ +#[cfg(feature = "actix-client")] +pub mod actix; +#[cfg(feature = "tower-client")] +pub mod tower; + +// Enable once we move to rust-2021 +// #[cfg(all(feature = "tower-client-rls", feature = "tower-client-tls"))] +// compile_error!("feature \"tower-client-rls\" and feature \"tower-client-tls\" cannot be enabled +// at the same time"); \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/model.mustache b/cli-ng/src/v3/templates/default/model.mustache new file mode 100644 index 000000000..fd615e34d --- /dev/null +++ b/cli-ng/src/v3/templates/default/model.mustache @@ -0,0 +1,129 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + +{{#models}} +{{#model}} +{{#description}}/// {{{classname}}} : {{{description}}}{{/description}} + +{{!-- for enum schemas --}} +{{#isEnum}} +/// {{{description}}} +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum {{{classname}}} { +{{#allowableValues}} +{{#enumVars}} + #[serde(rename = "{{{value}}}")] + {{{name}}}, +{{/enumVars}}{{/allowableValues}} +} + +impl ToString for {{{classname}}} { + fn to_string(&self) -> String { + match self { + {{#allowableValues}} + {{#enumVars}} + Self::{{{name}}} => String::from("{{{value}}}"), + {{/enumVars}} + {{/allowableValues}} + } + } +} + +impl Default for {{{classname}}} { + fn default() -> Self { + Self::{{#allowableValues}}{{#enumVars}}{{#-first}}{{{name}}}{{/-first}}{{/enumVars}}{{/allowableValues}} + } +} + +{{/isEnum}} +{{!-- for schemas that have a discriminator --}} +{{#discriminator}} +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(tag = "{{{vendorExtensions.x-tag-name}}}")] +pub enum {{{classname}}} { +{{#vendorExtensions}} + {{#x-mapped-models}} + #[serde(rename="{{mappingName}}")] + {{{modelName}}} { + {{#vars}} + {{#description}}/// {{{description}}}{{/description}} + #[serde(rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})] + {{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}}, + {{/vars}} + }, + {{/x-mapped-models}} +{{/vendorExtensions}} +} + +{{/discriminator}} +{{!-- for non-enum schemas --}} +{{^isEnum}} +{{^discriminator}} +{{#description}}/// {{{description}}}{{/description}} +{{^oneOf}} +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct {{{classname}}} { +{{#vars}} + {{#description}}/// {{{description}}}{{/description}} + #[serde(default, rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})] + pub {{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}}, +{{/vars}} +} + +impl {{{classname}}} { + /// {{{classname}}} using only the required fields + pub fn new({{#requiredVars}}{{{name}}}: {{#isArray}}impl IntoVec<{{#items}}{{dataType}}{{/items}}>{{/isArray}}{{^isArray}}impl Into<{{#isNullable}}Option<{{/isNullable}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}{{/isNullable}}>{{/isArray}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} { + {{{classname}}} { + {{#vars}}{{{name}}}{{#required}}{{#isArray}}: {{{name}}}.into_vec(){{/isArray}}{{^isArray}}: {{{name}}}.into(){{/isArray}}{{/required}}{{^required}}{{#isArray}}: None{{/isArray}}{{#isMap}}: None{{/isMap}}{{^isContainer}}: None{{/isContainer}}{{/required}}{{#required}}{{/required}}, + {{/vars}} + } + } + /// {{{classname}}} using all fields + pub fn new_all({{#vars}}{{{name}}}: {{#isArray}}impl Into{{^required}}Opt{{/required}}Vec<{{#items}}{{dataType}}{{/items}}>{{/isArray}}{{^isArray}}impl Into<{{^required}}Option<{{/required}}{{#isNullable}}Option<{{/isNullable}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}}>{{/isArray}}{{^-last}}, {{/-last}}{{/vars}}) -> {{{classname}}} { + {{{classname}}} { + {{#vars}}{{{name}}}: {{{name}}}{{#isArray}}.into_{{^required}}opt_{{/required}}vec(){{/isArray}}{{^isArray}}.into(){{/isArray}}, + {{/vars}} + } + } +} +{{/oneOf}} +{{#oneOf}} +{{#-first}} +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum {{{classname}}} { +{{#vars}} + {{#description}}/// {{{description}}}{{/description}} + #[serde(rename = "{{{baseName}}}")] + {{{name}}}({{#isNullable}}Option<{{/isNullable}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}), +{{/vars}} +} +{{/-first}} +{{/oneOf}} + +{{/discriminator}} +{{/isEnum}} +{{!-- for properties that are of enum type --}} +{{#vars}} +{{#isEnum}} +{{#description}}/// {{{description}}}{{/description}} +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum {{{enumName}}} { +{{#allowableValues}} +{{#enumVars}} + #[serde(rename = "{{{value}}}")] + {{{name}}}, +{{/enumVars}} +{{/allowableValues}} +} + +impl Default for {{{enumName}}} { + fn default() -> Self { + Self::{{#allowableValues}}{{#enumVars}}{{#-first}}{{{name}}}{{/-first}}{{/enumVars}}{{/allowableValues}} + } +} + +{{/isEnum}} +{{/vars}} +{{/model}} +{{/models}} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/model_doc.mustache b/cli-ng/src/v3/templates/default/model_doc.mustache new file mode 100644 index 000000000..c0cc2980f --- /dev/null +++ b/cli-ng/src/v3/templates/default/model_doc.mustache @@ -0,0 +1,12 @@ +{{#models}}{{#model}}# {{{classname}}} + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +{{#vars}}**{{{name}}}** | {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{{dataType}}}**]({{{complexType}}}.md){{/isPrimitiveType}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}} | {{{description}}} | {{^required}}[optional]{{/required}}{{#isReadOnly}}[readonly]{{/isReadOnly}}{{#defaultValue}}[default to {{{defaultValue}}}]{{/defaultValue}} +{{/vars}} + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + +{{/model}}{{/models}} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/model_mod.mustache b/cli-ng/src/v3/templates/default/model_mod.mustache new file mode 100644 index 000000000..46c382005 --- /dev/null +++ b/cli-ng/src/v3/templates/default/model_mod.mustache @@ -0,0 +1,6 @@ +{{#models}} +{{#model}} +pub mod {{{classFilename}}}; +pub use self::{{{classFilename}}}::{{{classname}}}; +{{/model}} +{{/models}} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/openapi.mustache b/cli-ng/src/v3/templates/default/openapi.mustache new file mode 100644 index 000000000..51ebafb01 --- /dev/null +++ b/cli-ng/src/v3/templates/default/openapi.mustache @@ -0,0 +1 @@ +{{{openapi-yaml}}} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/tower-hyper/client/api_clients.mustache b/cli-ng/src/v3/templates/default/tower-hyper/client/api_clients.mustache new file mode 100644 index 000000000..0cd755be9 --- /dev/null +++ b/cli-ng/src/v3/templates/default/tower-hyper/client/api_clients.mustache @@ -0,0 +1,291 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct {{{classname}}}Client { + configuration: Arc, +} + +impl {{{classname}}}Client { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for {{{classname}}}Client { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait {{{classname}}}: Clone + Send + Sync { + {{#operations}} + {{#operation}} + {{#description}} + /// {{{.}}} + {{/description}} + {{#notes}} + /// {{{.}}} + {{/notes}} + async fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}ResponseContent<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}>{{/supportMultipleResponses}}, Error>; + {{/operation}} + {{/operations}} +} + +/// Same as `{{{classname}}}` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait {{{classname}}}: Clone + Send + Sync { + {{#operations}} + {{#operation}} + {{#description}} + /// {{{.}}} + {{/description}} + {{#notes}} + /// {{{.}}} + {{/notes}} + async fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, super::Error>; + {{/operation}} + {{/operations}} + } +} + +#[async_trait::async_trait] +impl direct::{{{classname}}} for {{{classname}}}Client { + {{#operations}} + {{#operation}} + {{#vendorExtensions.x-group-parameters}} + async fn {{{operationId}}}(&self{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}ResponseContent<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}>{{/supportMultipleResponses}}, Error> { + {{{classname}}}::{{{operationId}}}(self, {{#allParams}}{{#-first}}, params{{/-first}}{{/allParams}}).map(|r| r.into_body()) + {{/vendorExtensions.x-group-parameters}} + {{^vendorExtensions.x-group-parameters}} + async fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error> { + {{/vendorExtensions.x-group-parameters}} + {{{classname}}}::{{{operationId}}}(self, {{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}).await.map(|r| r.into_body()) + } + {{/operation}} + {{/operations}} +} + +#[async_trait::async_trait] +impl {{{classname}}} for {{{classname}}}Client { + {{#operations}} + {{#operation}} + {{#vendorExtensions.x-group-parameters}} + async fn {{{operationId}}}(&self{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}ResponseContent<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}>{{/supportMultipleResponses}}, Error> { + // unbox the parameters + {{#allParams}} + let {{paramName}} = params.{{paramName}}; + {{/allParams}} + + {{/vendorExtensions.x-group-parameters}} + {{^vendorExtensions.x-group-parameters}} + async fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}ResponseContent<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}>{{/supportMultipleResponses}}, Error> { + {{/vendorExtensions.x-group-parameters}} + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}{{{path}}}", configuration.base_path{{#pathParams}}, {{{baseName}}}={{#isString}}crate::apis::urlencode({{/isString}}{{{paramName}}}{{^required}}.unwrap_or_default(){{/required}}{{#required}}{{#isNullable}}.unwrap_or_default(){{/isNullable}}{{/required}}{{#isArray}}.join(",").as_ref(){{/isArray}}{{#isString}}){{/isString}}{{^isString}}.to_string(){{/isString}}{{/pathParams}}); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::{{#vendorExtensions}}{{x-httpMethodUpper}}{{/vendorExtensions}}); + + {{#hasQueryParams}} + let query_params: Option = None; + {{#queryParams}} + {{#required}} + let query_params = match query_params { + None => Some(format!("{{{baseName}}}={}", {{{paramName}}}{{#isArray}}{{#items}}{{^isString}}.into_iter().map(|p| p.to_string()).collect::>(){{/isString}}.join(","){{/items}}{{/isArray}}{{^isArray}}.to_string(){{/isArray}})), + Some(previous) => Some(format!("{previous}&{{{baseName}}}={}", {{{paramName}}}{{#isArray}}{{#items}}{{^isString}}.into_iter().map(|p| p.to_string()).collect::>(){{/isString}}.join(","){{/items}}{{/isArray}}{{^isArray}}.to_string(){{/isArray}})) + }; + {{/required}} + {{^required}} + let query_params = if let Some(local_var_str) = {{{paramName}}} { + match query_params { + None => Some(format!("{{{baseName}}}={}", local_var_str{{#isArray}}{{#items}}{{^isString}}.into_iter().map(|p| p.to_string()).collect::>(){{/isString}}.join(","){{/items}}{{/isArray}}{{^isArray}}.to_string(){{/isArray}})), + Some(previous) => Some(format!("{previous}&{{{baseName}}}={}", local_var_str{{#isArray}}{{#items}}{{^isString}}.into_iter().map(|p| p.to_string()).collect::>(){{/isString}}.join(","){{/items}}{{/isArray}}{{^isArray}}.to_string(){{/isArray}})) + } + } else { + query_params + }; + {{/required}} + {{/queryParams}} + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + {{/hasQueryParams}} + {{#hasAuthMethods}} + {{#authMethods}} + {{#isApiKey}} + {{#isKeyInQuery}} + let local_var_uri_str = if let Some(ref local_var_apikey) = configuration.api_key { + let local_var_key = local_var_apikey.key.clone(); + let local_var_value = match local_var_apikey.prefix { + Some(ref local_var_prefix) => format!("{local_var_prefix} {local_var_key}"), + None => local_var_key, + }; + {{#hasQueryParams}} + let local_var_uri_str = match query_params { + None => format!("{local_var_uri_str}?{{{keyParamName}}}={local_var_value}"), + Some(_) => format!("{local_var_uri_str}&{{{keyParamName}}}={local_var_value}"), + }; + {{/hasQueryParams}} + {{^hasQueryParams}} + let local_var_uri_str = format!("{local_var_uri_str}?{{{keyParamName}}}={local_var_value}"); + {{/hasQueryParams}} + local_var_uri_str + } else { + local_var_uri_str + } + {{/isKeyInQuery}} + {{/isApiKey}} + {{/authMethods}} + {{/hasAuthMethods}} + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + {{#hasHeaderParams}} + {{#headerParams}} + {{#required}} + {{^isNullable}} + local_var_req_builder = local_var_req_builder.header("{{{baseName}}}", {{{paramName}}}{{#isArray}}.join(","){{/isArray}}{{^isArray}}.to_string(){{/isArray}}); + {{/isNullable}} + {{#isNullable}} + match {{{paramName}}} { + Some(local_var_param_value) => { local_var_req_builder = local_var_req_builder.insert_header(("{{{baseName}}}", local_var_param_value{{#isArray}}.join(","){{/isArray}}{{^isArray}}.to_string(){{/isArray}})); }, + None => { local_var_req_builder = local_var_req_builder.insert_header(("{{{baseName}}}", "")); }, + } + {{/isNullable}} + {{/required}} + {{^required}} + if let Some(local_var_param_value) = {{{paramName}}} { + local_var_req_builder = local_var_req_builder.header("{{{baseName}}}", local_var_param_value{{#isArray}}.join(","){{/isArray}}{{^isArray}}.to_string(){{/isArray}}); + } + {{/required}} + {{/headerParams}} + {{/hasHeaderParams}} + {{#hasAuthMethods}} + {{#authMethods}} + {{#isApiKey}} + {{#isKeyInHeader}} + if let Some(ref local_var_apikey) = configuration.api_key { + let local_var_key = local_var_apikey.key.clone(); + let local_var_value = match local_var_apikey.prefix { + Some(ref local_var_prefix) => format!("{local_var_prefix} {local_var_key}"), + None => local_var_key, + }; + local_var_req_builder = local_var_req_builder.header("{{{keyParamName}}}", local_var_value); + }; + {{/isKeyInHeader}} + {{/isApiKey}} + {{#isBasic}} + {{#isBasicBasic}} + if let Some(ref local_var_auth_conf) = configuration.basic_auth { + local_var_req_builder = local_var_req_builder.header(hyper::header::AUTHORIZATION, format!("Basic {local_var_auth_conf}")); + }; + {{/isBasicBasic}} + {{#isBasicBearer}} + if let Some(ref local_var_token) = configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.header(hyper::header::AUTHORIZATION, format!("Bearer {local_var_token}")); + }; + {{/isBasicBearer}} + {{/isBasic}} + {{#isOAuth}} + if let Some(ref local_var_token) = configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.header(hyper::header::AUTHORIZATION, format!("Bearer {local_var_token}")); + }; + {{/isOAuth}} + {{/authMethods}} + {{/hasAuthMethods}} + {{#isMultipart}} + $NOT_SUPPORTED$ + {{/isMultipart}} + {{#hasBodyParam}} + {{#bodyParam}} + let body = hyper::Body::from( + serde_json::to_vec(&{{{paramName}}}).map_err(RequestError::Serde)?, + ); + {{/bodyParam}} + {{/hasBodyParam}} + {{^hasBodyParam}} + let body = hyper::Body::empty(); + {{/hasBodyParam}} + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + {{^supportMultipleResponses}} + {{^returnType}} + Ok(ResponseContent { status: local_var_status, body: () }) + {{/returnType}} + {{#returnType}} + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: {{{returnType}}} = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + {{/returnType}} + {{/supportMultipleResponses}} + {{#supportMultipleResponses}} + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: ResponseContent<{{{operationIdCamelCase}}}Success> = serde_json::from_slice(&body)?; + let local_var_entity: Option<{{{operationIdCamelCase}}}Success> = serde_json::from_str(&local_var_content).ok(); + let local_var_resp = ResponseContent { status: local_var_status, entity: local_var_entity }; + Ok(local_var_resp) + {{/supportMultipleResponses}} + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + {{/operation}} + {{/operations}} +} \ No newline at end of file diff --git a/cli-ng/src/v3/templates/default/tower-hyper/client/body.mustache b/cli-ng/src/v3/templates/default/tower-hyper/client/body.mustache new file mode 100644 index 000000000..0a262a19a --- /dev/null +++ b/cli-ng/src/v3/templates/default/tower-hyper/client/body.mustache @@ -0,0 +1,46 @@ +//! Kube-builder convertion from `tower_http::trace::ResponseBody` to `hyper::Body` +//! + +use std::{ + pin::Pin, + task::{Context, Poll}, +}; + +use futures::stream::Stream; +use http_body::Body; +use pin_project::pin_project; + +// Wrap `http_body::Body` to implement `Stream`. +#[pin_project] +pub struct IntoStream { + #[pin] + body: B, +} + +impl IntoStream { + pub(crate) fn new(body: B) -> Self { + Self { body } + } +} + +impl Stream for IntoStream +where + B: Body, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().body.poll_data(cx) + } +} + +pub trait BodyStreamExt: Body { + fn into_stream(self) -> IntoStream + where + Self: Sized, + { + IntoStream::new(self) + } +} + +impl BodyStreamExt for T where T: Body {} diff --git a/cli-ng/src/v3/templates/default/tower-hyper/client/client.mustache b/cli-ng/src/v3/templates/default/tower-hyper/client/client.mustache new file mode 100644 index 000000000..f2dcfa2ae --- /dev/null +++ b/cli-ng/src/v3/templates/default/tower-hyper/client/client.mustache @@ -0,0 +1,318 @@ +mod body; +pub mod configuration; + +use configuration::BoxedError; +pub use configuration::Configuration; +pub use hyper::{self, StatusCode, Uri}; +pub use url::Url; + +use std::{error, fmt, ops::Deref, sync::Arc}; + +#[derive(Clone)] +pub struct ApiClient { +{{#apiInfo}} +{{#apis}} +{{#operations}} + {{{classFilename}}}: Box, +{{/operations}} +{{/apis}} +{{/apiInfo}} +} + +/// Same as `ApiClient` but returns the body directly. +pub mod direct { + #[derive(Clone)] + pub struct ApiClient { + {{#apiInfo}} + {{#apis}} + {{#operations}} + {{{classFilename}}}: Box, + {{/operations}} + {{/apis}} + {{/apiInfo}} + } + + impl ApiClient { + pub fn new(configuration: super::Configuration) -> ApiClient { + let rc = super::Arc::new(configuration); + + ApiClient { + {{#apiInfo}} + {{#apis}} + {{#operations}} + {{^-last}} + {{{classFilename}}}: Box::new(crate::apis::{{{classFilename}}}::tower::client::{{{classname}}}Client::new(rc.clone())), + {{/-last}} + {{#-last}} + {{{classFilename}}}: Box::new(crate::apis::{{{classFilename}}}::tower::client::{{{classname}}}Client::new(rc)), + {{/-last}} + {{/operations}} + {{/apis}} + {{/apiInfo}} + } + } + + {{#apiInfo}} + {{#apis}} + {{#operations}} + pub fn {{{classFilename}}}(&self) -> &dyn crate::apis::{{{classFilename}}}::tower::client::direct::{{{classname}}} { + self.{{{classFilename}}}.as_ref() + } + {{/operations}} + {{/apis}} + {{/apiInfo}} + } +} + +impl ApiClient { + pub fn new(configuration: Configuration) -> ApiClient { + let rc = Arc::new(configuration); + + ApiClient { +{{#apiInfo}} +{{#apis}} +{{#operations}} + {{^-last}} + {{{classFilename}}}: Box::new(crate::apis::{{{classFilename}}}::tower::client::{{{classname}}}Client::new(rc.clone())), + {{/-last}} + {{#-last}} + {{{classFilename}}}: Box::new(crate::apis::{{{classFilename}}}::tower::client::{{{classname}}}Client::new(rc)), + {{/-last}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + } + } + +{{#apiInfo}} +{{#apis}} +{{#operations}} + pub fn {{{classFilename}}}(&self) -> &dyn crate::apis::{{{classFilename}}}::tower::client::{{{classname}}} { + self.{{{classFilename}}}.as_ref() + } +{{/operations}} +{{/apis}} +{{/apiInfo}} +} + +/// Http Response with status and body. +#[derive(Debug, Clone)] +pub struct ResponseContent { + pub(crate) status: hyper::StatusCode, + pub(crate) body: T, +} +impl ResponseContent { + /// Get the status code. + pub fn status(&self) -> hyper::StatusCode { + self.status + } + /// Get a reference to the body. + pub fn body(&self) -> &T { + &self.body + } + /// Convert self into the body. + pub fn into_body(self) -> T { + self.body + } + /// Convert ResponseContent into ResponseContent>. + pub fn with_vec_body(self) -> ResponseContent> { + ResponseContent { + status: self.status, + body: vec![self.body] + } + } +} + +/// Http Response with status and body as text (could not be coerced into the expected type). +#[derive(Debug, Clone)] +pub struct ResponseContentUnexpected { + pub(crate) status: hyper::StatusCode, + pub(crate) text: String, +} +impl ResponseContentUnexpected { + /// Get the status code. + pub fn status(&self) -> hyper::StatusCode { + self.status + } + /// Get a reference to the text. + pub fn text(&self) -> &str { + self.text.as_ref() + } +} + +/// Error type for all Requests with the various variants. +#[derive(Debug)] +pub enum Error { + Request(RequestError), + Response(ResponseError), +} +impl Error { + /// Get the request error, if that is the case. + pub fn request(&self) -> Option<&RequestError> { + match self { + Error::Request(request) => Some(request), + Error::Response(_) => None, + } + } + /// Get the response error, if that is the case. + pub fn response(&self) -> Option<&ResponseError> { + match self { + Error::Request(_) => None, + Error::Response(response) => Some(response), + } + } + /// Get the expected error, if received. + pub fn expected(&self) -> Option<&ResponseContent> { + match self { + Error::Request(_) => None, + Error::Response(response) => response.expected(), + } + } + /// Get the inner body error, if expected. + pub fn error_body(&self) -> Option<&T> { + match self { + Error::Request(_) => None, + Error::Response(response) => response.error_body(), + } + } + /// Get the response status code, if any received. + pub fn status(&self) -> Option { + self.response().map(|response| response.status()) + } +} +impl From for Error { + fn from(src: RequestError) -> Self { + Self::Request(src) + } +} +impl From> for Error { + fn from(src: ResponseError) -> Self { + Self::Response(src) + } +} +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::Request(r) => r.fmt(f), + Error::Response(r) => r.fmt(f), + } + } +} +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Error::Request(r) => r.source(), + Error::Response(r) => r.source(), + } + } +} + +/// Failed to issue the request. +#[derive(Debug)] +pub enum RequestError { + /// Failed to build the http request. + BuildRequest(hyper::http::Error), + /// Service Request call returned an error. + Request(BoxedError), + /// Service was not ready to process the request. + NotReady(BoxedError), + /// Failed to serialize request payload. + Serde(serde_json::Error), + /// Failed to encode the url path. + SerdeEncoded(serde_urlencoded::ser::Error), +} +impl fmt::Display for RequestError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + RequestError::BuildRequest(e) => ("build_request", e.to_string()), + RequestError::Request(e) => ("request", e.to_string()), + RequestError::NotReady(e) => ("not_ready", e.to_string()), + RequestError::Serde(e) => ("serde", e.to_string()), + RequestError::SerdeEncoded(e) => ("serde_encoding", e.to_string()), + }; + write!(f, "error in {module}: {e}") + } +} +impl error::Error for RequestError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(match self { + RequestError::BuildRequest(e) => e, + RequestError::Request(e) => e.deref(), + RequestError::NotReady(e) => e.deref(), + RequestError::Serde(e) => e, + RequestError::SerdeEncoded(e) => e, + }) + } +} + +/// Error type for all Requests with the various variants. +#[derive(Debug)] +pub enum ResponseError { + /// The OpenAPI call returned the "expected" OpenAPI JSON content. + Expected(ResponseContent), + /// Failed to convert the response payload to bytes. + PayloadError { + status: hyper::StatusCode, + error: hyper::Error, + }, + /// The OpenAPI call returned an "unexpected" JSON content. + Unexpected(ResponseContentUnexpected), +} +impl fmt::Display for ResponseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + ResponseError::Expected(e) => ( + "response", + format!("status code '{}', content: '{:?}'", e.status, e.body), + ), + ResponseError::PayloadError { status, error } => ( + "response", + format!("status code '{status}', error: '{error:?}'"), + ), + ResponseError::Unexpected(e) => ( + "response", + format!("status code '{}', text '{}'", e.status, e.text), + ), + }; + write!(f, "error in {module}: {e}") + } +} +impl error::Error for ResponseError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + ResponseError::Expected(_) => None, + ResponseError::PayloadError { error, .. } => Some(error), + ResponseError::Unexpected(_) => None, + } + } +} +impl ResponseError { + /// Get the inner status. + pub fn status(&self) -> StatusCode { + match self { + ResponseError::Expected(expected) => expected.status, + ResponseError::PayloadError { status, .. } => *status, + ResponseError::Unexpected(unexpected) => unexpected.status, + } + } + /// Get the expected error, if received. + pub fn expected(&self) -> Option<&ResponseContent> { + match self { + ResponseError::Expected(expected) => Some(expected), + _ => None, + } + } + /// Get the inner body error, if expected. + pub fn error_body(&self) -> Option<&T> { + match self { + ResponseError::Expected(expected) => Some(&expected.body), + _ => None, + } + } +} + +impl std::fmt::Debug for ApiClient { + fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> fmt::Result { + fmt::Result::Ok(()) + } +} diff --git a/cli-ng/src/v3/templates/default/tower-hyper/client/configuration.mustache b/cli-ng/src/v3/templates/default/tower-hyper/client/configuration.mustache new file mode 100644 index 000000000..c100b7e1c --- /dev/null +++ b/cli-ng/src/v3/templates/default/tower-hyper/client/configuration.mustache @@ -0,0 +1,485 @@ +#![allow(clippy::type_complexity)] +use super::body::BodyStreamExt; + +pub use hyper::{body, service::Service, Body, Request, Response, Uri}; + +use std::{sync::Arc, time::Duration}; +use tokio::sync::Mutex; +use tower::{util::BoxCloneService, Layer, ServiceExt}; + +#[cfg(feature = "tower-trace")] +use opentelemetry::global; +#[cfg(feature = "tower-trace")] +use opentelemetry_http::HeaderInjector; + +#[cfg(all(feature = "tower-client-rls", not(feature = "tower-client-tls")))] +use rustls::{ + client::{ServerCertVerified, ServerCertVerifier}, + Certificate, Error as TLSError, +}; + +use tower_http::map_response_body::MapResponseBodyLayer; +#[cfg(feature = "tower-trace")] +use tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer}; + +#[cfg(feature = "tower-trace")] +use tracing::Span; +#[cfg(feature = "tower-trace")] +use tracing_opentelemetry::OpenTelemetrySpanExt; + +/// Tower Service Error +pub type BoxedError = Box; + +/// `ConfigurationBuilder` that can be used to build a `Configuration`. +#[derive(Clone)] +pub struct ConfigurationBuilder { + /// Timeout for each HTTP Request. + timeout: Option, + /// Bearer Access Token for bearer-configured routes. + bearer_token: Option, + /// OpenTel and Tracing layer. + #[cfg(feature = "tower-trace")] + tracing_layer: bool, + certificate: Option>, + concurrency_limit: Option, +} + +impl Default for ConfigurationBuilder { + fn default() -> Self { + Self { + timeout: Some(std::time::Duration::from_secs(5)), + bearer_token: None, + #[cfg(feature = "tower-trace")] + tracing_layer: true, + certificate: None, + concurrency_limit: None, + } + } +} + +impl ConfigurationBuilder { + /// Return a new `Self`. + pub fn new() -> Self { + Self::default() + } + /// Enable/Disable a request timeout layer with the given request timeout. + pub fn with_timeout>>(mut self, timeout: O) -> Self { + self.timeout = timeout.into(); + self + } + /// Enable/Disable the given request bearer token. + pub fn with_bearer_token(mut self, bearer_token: Option) -> Self { + self.bearer_token = bearer_token; + self + } + /// Add a request concurrency limit. + pub fn with_concurrency_limit(mut self, limit: Option) -> Self { + self.concurrency_limit = limit; + self + } + /// Add a PEM-format certificate file. + pub fn with_certificate(mut self, certificate: &[u8]) -> Self { + self.certificate = Some(certificate.to_vec()); + self + } + /// Enable/Disable the telemetry and tracing layer. + #[cfg(feature = "tower-trace")] + pub fn with_tracing(mut self, tracing_layer: bool) -> Self { + self.tracing_layer = tracing_layer; + self + } + /// Build a `Configuration` from the Self parameters. + pub fn build(self, uri: hyper::Uri) -> Result { + Configuration::new( + uri.to_string().parse().map_err(Error::UriToUrl)?, + self.timeout.unwrap(), + self.bearer_token, + self.certificate.as_ref().map(|c| &c[..]), + self.tracing_layer, + self.concurrency_limit, + ) + } + /// Build a `Configuration` from the Self parameters. + pub fn build_url(self, url: url::Url) -> Result { + Configuration::new( + url, + self.timeout.unwrap_or_else(|| Duration::from_secs(5)), + self.bearer_token, + self.certificate.as_ref().map(|c| &c[..]), + self.tracing_layer, + self.concurrency_limit, + ) + } + /// Build a `Configuration` from the Self parameters. + pub fn build_with_svc( + self, + uri: hyper::Uri, + client_service: S, + ) -> Result + where + S: Service, Response = Response> + Sync + Send + Clone + 'static, + S::Future: Send + 'static, + S::Error: Into + std::fmt::Debug, + { + #[cfg(feature = "tower-trace")] + let tracing_layer = self.tracing_layer; + #[cfg(not(feature = "tower-trace"))] + let tracing_layer = false; + Configuration::new_with_client( + uri, + client_service, + self.timeout, + self.bearer_token, + tracing_layer, + self.concurrency_limit, + ) + } +} + +/// Configuration used by the `ApiClient`. +#[derive(Clone)] +pub struct Configuration { + pub base_path: hyper::Uri, + pub user_agent: Option, + pub client_service: Arc, Response, BoxedError>>>, + pub basic_auth: Option, + pub oauth_access_token: Option, + pub bearer_access_token: Option, + pub api_key: Option, +} + +/// Basic authentication. +pub type BasicAuth = (String, Option); + +/// ApiKey used for ApiKey authentication. +#[derive(Debug, Clone)] +pub struct ApiKey { + pub prefix: Option, + pub key: String, +} + +/// Configuration creation Error. +#[derive(Debug)] +pub enum Error { + Certificate, + TlsConnector, + NoTracingFeature, + UrlToUri(hyper::http::uri::InvalidUri), + UriToUrl(url::ParseError), + AddingVersionPath(hyper::http::uri::InvalidUri), +} + +impl Configuration { + /// Return a new `ConfigurationBuilder`. + pub fn builder() -> ConfigurationBuilder { + ConfigurationBuilder::new() + } + + /// New `Self` with a provided client. + pub fn new_with_client( + mut url: hyper::Uri, + client_service: S, + timeout: Option, + bearer_access_token: Option, + trace_requests: bool, + concurrency_limit: Option, + ) -> Result + where + S: Service, Response = Response> + Sync + Send + Clone + 'static, + S::Future: Send + 'static, + S::Error: Into + std::fmt::Debug, + { + #[cfg(feature = "tower-trace")] + let tracing_layer = tower::ServiceBuilder::new() + .layer( + TraceLayer::new_for_http() + .make_span_with(|request: &Request| { + tracing::info_span!( + "HTTP", + http.method = %request.method(), + http.url = %request.uri(), + http.status_code = tracing::field::Empty, + otel.name = %format!("{} {}", request.method(), request.uri()), + otel.kind = "client", + otel.status_code = tracing::field::Empty, + ) + }) + // to silence the default trace + .on_request(|request: &Request, _span: &Span| { + tracing::trace!("started {} {}", request.method(), request.uri().path()) + }) + .on_response( + |response: &Response, _latency: std::time::Duration, span: &Span| { + let status = response.status(); + span.record("http.status_code", status.as_u16()); + if status.is_client_error() || status.is_server_error() { + span.record("otel.status_code", "ERROR"); + } + }, + ) + .on_body_chunk(()) + .on_failure( + |ec: ServerErrorsFailureClass, + _latency: std::time::Duration, + span: &Span| { + span.record("otel.status_code", "ERROR"); + match ec { + ServerErrorsFailureClass::StatusCode(status) => { + span.record("http.status_code", status.as_u16()); + tracing::debug!(status=%status, "failed to issue request") + } + ServerErrorsFailureClass::Error(err) => { + tracing::debug!(error=%err, "failed to issue request") + } + } + }, + ), + ) + // injects the telemetry context in the http headers + .layer(OpenTelContext::new()) + .into_inner(); + + url = format!("{}/v0", url.to_string().trim_end_matches('/')) + .parse() + .map_err(Error::AddingVersionPath)?; + + let backend_service = tower::ServiceBuilder::new() + .option_layer(timeout.map(tower::timeout::TimeoutLayer::new)) + // .option_layer( + // bearer_access_token.map(|b| tower_http::auth::AddAuthorizationLayer::bearer(&b)), + // ) + .service(client_service); + + let service_builder = tower::ServiceBuilder::new() + .option_layer(concurrency_limit.map(tower::limit::ConcurrencyLimitLayer::new)); + + match trace_requests { + false => Ok(Self::new_with_client_inner( + url, + service_builder.service(backend_service), + bearer_access_token, + )), + true => { + #[cfg(feature = "tower-trace")] + let result = Ok(Self::new_with_client_inner( + url, + service_builder + .layer(tracing_layer) + .service(backend_service), + bearer_access_token, + )); + #[cfg(not(feature = "tower-trace"))] + let result = Err(Error::NoTracingFeature {}); + result + } + } + } + + /// New `Self`. + pub fn new( + mut url: url::Url, + timeout: std::time::Duration, + bearer_access_token: Option, + certificate: Option<&[u8]>, + trace_requests: bool, + concurrency_limit: Option, + ) -> Result { + #[cfg(all(not(feature = "tower-client-tls"), feature = "tower-client-rls"))] + let client = { + match certificate { + None => { + let mut http = hyper::client::HttpConnector::new(); + + let tls = match url.scheme() == "https" { + true => { + http.enforce_http(false); + rustls::ClientConfig::builder() + .with_safe_defaults() + .with_custom_certificate_verifier(std::sync::Arc::new( + DisableServerCertVerifier {}, + )) + .with_no_client_auth() + } + false => rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(rustls::RootCertStore::empty()) + .with_no_client_auth(), + }; + + let connector = + hyper_rustls::HttpsConnector::from((http, std::sync::Arc::new(tls))); + hyper::Client::builder().build(connector) + } + Some(bytes) => { + let mut cert_file = std::io::BufReader::new(bytes); + let mut root_store = rustls::RootCertStore::empty(); + root_store.add_parsable_certificates( + &rustls_pemfile::certs(&mut cert_file).map_err(|_| Error::Certificate)?, + ); + let config = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store) + .with_no_client_auth(); + + let mut http = hyper::client::HttpConnector::new(); + http.enforce_http(false); + let connector = + hyper_rustls::HttpsConnector::from((http, std::sync::Arc::new(config))); + url.set_scheme("https").ok(); + hyper::Client::builder().build(connector) + } + } + }; + #[cfg(feature = "tower-client-tls")] + let client = { + match certificate { + None => { + let mut http = hyper_tls::HttpsConnector::new(); + if url.scheme() == "https" { + http.https_only(true); + } + + let tls = hyper_tls::native_tls::TlsConnector::builder() + .danger_accept_invalid_certs(true) + .build() + .map_err(|_| Error::TlsConnector)?; + let tls = tokio_native_tls::TlsConnector::from(tls); + + let connector = hyper_tls::HttpsConnector::from((http, tls)); + hyper::Client::builder().build(connector) + } + Some(bytes) => { + let certificate = hyper_tls::native_tls::Certificate::from_pem(bytes) + .map_err(|_| Error::Certificate)?; + + let tls = hyper_tls::native_tls::TlsConnector::builder() + .add_root_certificate(certificate) + .danger_accept_invalid_hostnames(true) + .disable_built_in_roots(true) + .build() + .map_err(|_| Error::TlsConnector)?; + let tls = tokio_native_tls::TlsConnector::from(tls); + + let mut http = hyper_tls::HttpsConnector::new(); + http.https_only(true); + let connector = hyper_tls::HttpsConnector::from((http, tls)); + url.set_scheme("https").ok(); + hyper::Client::builder().build(connector) + } + } + }; + + let uri = url.to_string().parse().map_err(Error::UrlToUri)?; + Self::new_with_client( + uri, + client, + Some(timeout), + bearer_access_token, + trace_requests, + concurrency_limit, + ) + } + + /// New `Self` with a provided client. + pub fn new_with_client_inner( + url: hyper::Uri, + client_service: S, + bearer_access_token: Option, + ) -> Self + where + S: Service, Response = Response> + Sync + Send + Clone + 'static, + S::Future: Send + 'static, + S::Error: Into + std::fmt::Debug, + B: http_body::Body + Send + 'static, + B::Error: std::error::Error + Send + Sync + 'static, + { + // Transform response body to `hyper::Body` and use type erased error to avoid type + // parameters. + let client_service = MapResponseBodyLayer::new(|b: B| Body::wrap_stream(b.into_stream())) + .layer(client_service) + .map_err(|e| e.into()); + let client_service = Arc::new(Mutex::new(BoxCloneService::new(client_service))); + Self { + base_path: url, + user_agent: None, + client_service, + basic_auth: None, + oauth_access_token: None, + bearer_access_token, + api_key: None, + } + } +} + +/// Add OpenTelemetry Span to the Http Headers. +#[cfg(feature = "tower-trace")] +pub struct OpenTelContext {} +#[cfg(feature = "tower-trace")] +impl OpenTelContext { + fn new() -> Self { + Self {} + } +} +#[cfg(feature = "tower-trace")] +impl Layer for OpenTelContext { + type Service = OpenTelContextService; + + fn layer(&self, service: S) -> Self::Service { + OpenTelContextService::new(service) + } +} + +/// OpenTelemetry Service that injects the current span into the Http Headers. +#[cfg(feature = "tower-trace")] +#[derive(Clone)] +pub struct OpenTelContextService { + service: S, +} +#[cfg(feature = "tower-trace")] +impl OpenTelContextService { + fn new(service: S) -> Self { + Self { service } + } +} + +#[cfg(feature = "tower-trace")] +impl Service> for OpenTelContextService +where + S: Service>, +{ + type Response = S::Response; + type Error = S::Error; + type Future = S::Future; + + fn poll_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.service.poll_ready(cx) + } + + fn call(&mut self, mut request: hyper::Request) -> Self::Future { + let cx = tracing::Span::current().context(); + global::get_text_map_propagator(|propagator| { + propagator.inject_context(&cx, &mut HeaderInjector(request.headers_mut())) + }); + self.service.call(request) + } +} + +#[cfg(all(feature = "tower-client-rls", not(feature = "tower-client-tls")))] +struct DisableServerCertVerifier {} +#[cfg(all(feature = "tower-client-rls", not(feature = "tower-client-tls")))] +impl ServerCertVerifier for DisableServerCertVerifier { + fn verify_server_cert( + &self, + _end_entity: &Certificate, + _intermediates: &[Certificate], + _server_name: &rustls::ServerName, + _scts: &mut dyn Iterator, + _ocsp_response: &[u8], + _now: std::time::SystemTime, + ) -> Result { + Ok(ServerCertVerified::assertion()) + } +} diff --git a/cli-ng/src/v3/templates/default/tower-hyper/mod.mustache b/cli-ng/src/v3/templates/default/tower-hyper/mod.mustache new file mode 100644 index 000000000..a2b385a4b --- /dev/null +++ b/cli-ng/src/v3/templates/default/tower-hyper/mod.mustache @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; diff --git a/cli-ng/src/v3/templates/mod.rs b/cli-ng/src/v3/templates/mod.rs new file mode 100644 index 000000000..f8e02e8d8 --- /dev/null +++ b/cli-ng/src/v3/templates/mod.rs @@ -0,0 +1,339 @@ +use std::ops::Deref; + +use crate::v3::{OperationsApiTpl, Property}; +use heck::{ToPascalCase, ToSnakeCase}; + +/// Support cases for the class names. +#[derive(Debug, Clone)] +pub(super) enum ClassCase { + PascalCase, + SnakeCase, +} +impl ClassCase { + fn format(&self, name: &str) -> String { + match self { + ClassCase::PascalCase => name.to_pascal_case(), + ClassCase::SnakeCase => name.to_snake_case(), + } + } +} + +#[derive(Debug, Clone)] +pub(super) enum ApiTargetFileCfg { + /// $prefix/$class_fname/$postfix + ClassFileName, + /// $prefix/$class/$postfix + ClassName, +} + +/// Template file specification for support files. +#[derive(Debug, Clone)] +pub(super) struct SuppTemplateFile { + gen: GenTemplateFile, +} +impl SuppTemplateFile { + /// Create a new `Self` by specifying the template path, the target prefix and file extension. + pub(super) fn new(template: TemplateFile, target_prefix: &str, target_postfix: &str) -> Self { + let gen = GenTemplateFile { + template, + target_prefix: std::path::PathBuf::from(target_prefix), + target_postfix: std::path::PathBuf::from(target_postfix), + casing: ClassCase::PascalCase, + }; + Self { gen } + } +} +impl Deref for SuppTemplateFile { + type Target = GenTemplateFile; + fn deref(&self) -> &Self::Target { + &self.gen + } +} + +/// Template file specification for model files. +#[derive(Debug, Clone)] +pub(super) struct ModelTemplateFile { + gen: GenTemplateFile, + extension: String, +} +impl ModelTemplateFile { + /// Create a new `Self` by specifying the template path, the target prefix and file extension. + pub(super) fn new(template: TemplateFile, target_prefix: &str, ext: &str) -> Self { + let gen = GenTemplateFile { + template, + target_prefix: std::path::PathBuf::from(target_prefix), + target_postfix: std::path::PathBuf::from("."), + casing: ClassCase::SnakeCase, + }; + Self { + gen, + extension: ext.trim_start_matches('.').into(), + } + } + /// Override the class file case. + pub(super) fn with_file_case(mut self, casing: ClassCase) -> Self { + self.gen = self.gen.with_class_case(casing); + self + } + /// Generate the path for the model file. + pub(super) fn model_path(&self, property: &Property) -> std::path::PathBuf { + let model_fname = self.casing.format(property.filename()); + self.gen + .target_prefix + .join(model_fname) + .with_extension(&self.extension) + } +} +impl Deref for ModelTemplateFile { + type Target = GenTemplateFile; + fn deref(&self) -> &Self::Target { + &self.gen + } +} + +/// Template file specification for api files. +#[derive(Debug, Clone)] +pub(super) struct ApiTemplateFile { + gen: GenTemplateFile, + kind: ApiTargetFileCfg, +} +impl ApiTemplateFile { + /// Create a new `Self` by specifying the template path, the target prefix and postfix. + pub(super) fn new(template: TemplateFile, target_prefix: &str, target_postfix: &str) -> Self { + let gen = GenTemplateFile { + template, + target_prefix: std::path::PathBuf::from(target_prefix), + target_postfix: std::path::PathBuf::from(target_postfix), + casing: ClassCase::SnakeCase, + }; + Self { + gen, + kind: ApiTargetFileCfg::ClassFileName, + } + } + /// Override the class file case. + pub(super) fn with_class_case(mut self, casing: ClassCase) -> Self { + self.gen = self.gen.with_class_case(casing); + self + } + /// Override the class type. + pub(super) fn with_class(mut self, kind: ApiTargetFileCfg) -> Self { + self.kind = kind; + self + } + /// Generate the path for the api file. + pub(super) fn api_path(&self, api: &OperationsApiTpl) -> std::path::PathBuf { + let prefix = self.target_prefix(); + let postfix = self.gen.target_postfix().display().to_string(); + let class = self.casing.format(match &self.kind { + ApiTargetFileCfg::ClassFileName => api.class_filename(), + ApiTargetFileCfg::ClassName => api.classname(), + }); + match postfix.starts_with('.') { + true => prefix + .join(class) + .with_extension(postfix.trim_start_matches('.')), + false => prefix.join(class).join(postfix), + } + } +} +impl Deref for ApiTemplateFile { + type Target = GenTemplateFile; + fn deref(&self) -> &Self::Target { + &self.gen + } +} + +#[derive(Debug, Clone)] +pub(crate) enum TemplateFile { + #[allow(unused)] + Path(std::path::PathBuf), + Buffer(&'static str), + BufferOwned(String), +} +impl TemplateFile { + /// Get the template raw buffer. + pub(super) fn buffer(&self) -> Option<&str> { + match self { + TemplateFile::Path(_) => None, + TemplateFile::Buffer(buffer) => Some(buffer), + TemplateFile::BufferOwned(buffer) => Some(buffer.as_str()), + } + } +} + +/// A generic template file specification. +#[derive(Debug, Clone)] +pub(super) struct GenTemplateFile { + template: TemplateFile, + target_prefix: std::path::PathBuf, + target_postfix: std::path::PathBuf, + casing: ClassCase, +} +impl GenTemplateFile { + /// Override the class file case. + pub(super) fn with_class_case(mut self, casing: ClassCase) -> Self { + self.casing = casing; + self + } + /// Get the template input file. + pub(super) fn input(&self) -> &TemplateFile { + &self.template + } + /// Get the target path prefix. + pub(super) fn target_prefix(&self) -> &std::path::PathBuf { + &self.target_prefix + } + /// Get the target path postfix. + pub(super) fn target_postfix(&self) -> &std::path::PathBuf { + &self.target_postfix + } +} + +macro_rules! path_or_builtin { + ($tpl:ident, $offset:literal) => { + match $tpl { + None => TemplateFile::Buffer(include_str!($offset)), + Some(tpl) => { + let path = format!("{}/{}", tpl.display(), $offset); + let buffer = std::fs::read_to_string(path)?; + TemplateFile::BufferOwned(buffer) + } + } + }; +} + +/// The template files for thes default template. +#[allow(clippy::type_complexity)] +pub(super) fn default_templates( + tpl_path: &Option, +) -> Result< + ( + Vec, + Vec, + Vec, + ), + std::io::Error, +> { + let api_templates = vec![ + // Actix + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/actix/client/api_clients.mustache"), + "apis", + "actix/client/mod.rs", + ), + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/actix/server/handlers.mustache"), + "apis", + "actix/server/handlers.rs", + ), + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/actix/mod.mustache"), + "apis", + "actix/mod.rs", + ), + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/actix/server/api.mustache"), + "apis", + "actix/server/mod.rs", + ), + // Tower-hyper + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/tower-hyper/mod.mustache"), + "apis", + "tower/mod.rs", + ), + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/tower-hyper/client/api_clients.mustache"), + "apis", + "tower/client/mod.rs", + ), + // Common + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/mod.mustache"), + "apis", + "mod.rs", + ), + ApiTemplateFile::new( + path_or_builtin!(tpl_path, "default/api_doc.mustache"), + "docs/apis", + ".md", + ) + .with_class_case(ClassCase::PascalCase) + .with_class(ApiTargetFileCfg::ClassName), + ]; + let model_templates = vec![ + ModelTemplateFile::new( + path_or_builtin!(tpl_path, "default/model.mustache"), + "models", + ".rs", + ), + ModelTemplateFile::new( + path_or_builtin!(tpl_path, "default/model_doc.mustache"), + "docs/models", + ".md", + ) + .with_file_case(ClassCase::PascalCase), + ]; + let supporting_templates = vec![ + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/model_mod.mustache"), + "models", + "mod.rs", + ), + SuppTemplateFile::new( + path_or_builtin!( + tpl_path, + "default/tower-hyper/client/configuration.mustache" + ), + "clients/tower", + "configuration.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/tower-hyper/client/client.mustache"), + "clients/tower", + "mod.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/tower-hyper/client/body.mustache"), + "clients/tower", + "body.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/api_mod.mustache"), + "apis", + "mod.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/mod_clients.mustache"), + "clients", + "mod.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/lib.mustache"), + "", + "mod.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/actix/server/api_mod.mustache"), + "apis", + "actix_server.rs", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/Cargo.mustache"), + "", + "Cargo.toml", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/gitignore.mustache"), + "", + ".gitignore", + ), + SuppTemplateFile::new( + path_or_builtin!(tpl_path, "default/openapi.mustache"), + "apis", + "openapi.yaml", + ), + ]; + Ok((api_templates, model_templates, supporting_templates)) +} diff --git a/core/src/v2/mod.rs b/core/src/v2/mod.rs index 89a95a91f..5e3a883a4 100644 --- a/core/src/v2/mod.rs +++ b/core/src/v2/mod.rs @@ -25,9 +25,9 @@ pub use paperclip_macros::*; pub use serde_json; #[cfg(feature = "codegen")] -use self::resolver::Resolver; +pub(crate) use self::resolver::Resolver; #[cfg(feature = "codegen")] -use crate::error::ValidationError; +pub(crate) use crate::error::ValidationError; #[cfg(feature = "codegen")] impl ResolvableApi { diff --git a/core/src/v3/mod.rs b/core/src/v3/mod.rs index 5a4976441..94d0369ee 100644 --- a/core/src/v3/mod.rs +++ b/core/src/v3/mod.rs @@ -2,27 +2,8 @@ //! Conversion traits and helps functions that help converting openapi v2 types to openapi v3. //! For the OpenAPI v3 types the crate `openapiv3` is used. -mod contact; -mod external_documentation; -mod header; -mod info; -mod license; -mod openapi; -mod operation; -mod parameter; -mod paths; -mod reference; -mod request_body; -mod response; -mod schema; -mod security_scheme; -mod tag; - -use super::v2::{models as v2, models::Either}; - -use parameter::non_body_parameter_to_v3_parameter; -use reference::invalid_referenceor; -use response::OperationEitherResponse; +use super::v2::models as v2; +mod models; /// Convert this crates openapi v2 (`DefaultApiRaw`) to `openapiv3::OpenAPI` pub fn openapiv2_to_v3(v2: v2::DefaultApiRaw) -> openapiv3::OpenAPI { diff --git a/core/src/v3/contact.rs b/core/src/v3/models/contact.rs similarity index 100% rename from core/src/v3/contact.rs rename to core/src/v3/models/contact.rs diff --git a/core/src/v3/external_documentation.rs b/core/src/v3/models/external_documentation.rs similarity index 100% rename from core/src/v3/external_documentation.rs rename to core/src/v3/models/external_documentation.rs diff --git a/core/src/v3/header.rs b/core/src/v3/models/header.rs similarity index 100% rename from core/src/v3/header.rs rename to core/src/v3/models/header.rs diff --git a/core/src/v3/info.rs b/core/src/v3/models/info.rs similarity index 100% rename from core/src/v3/info.rs rename to core/src/v3/models/info.rs diff --git a/core/src/v3/license.rs b/core/src/v3/models/license.rs similarity index 100% rename from core/src/v3/license.rs rename to core/src/v3/models/license.rs diff --git a/core/src/v3/models/mod.rs b/core/src/v3/models/mod.rs new file mode 100644 index 000000000..17db1b4ba --- /dev/null +++ b/core/src/v3/models/mod.rs @@ -0,0 +1,21 @@ +mod contact; +mod external_documentation; +mod header; +mod info; +mod license; +mod openapi; +mod operation; +mod parameter; +mod paths; +mod reference; +mod request_body; +mod response; +mod schema; +mod security_scheme; +mod tag; + +pub use super::super::v2::{models as v2, models::Either}; + +use parameter::non_body_parameter_to_v3_parameter; +use reference::invalid_referenceor; +use response::OperationEitherResponse; diff --git a/core/src/v3/openapi.rs b/core/src/v3/models/openapi.rs similarity index 100% rename from core/src/v3/openapi.rs rename to core/src/v3/models/openapi.rs diff --git a/core/src/v3/operation.rs b/core/src/v3/models/operation.rs similarity index 100% rename from core/src/v3/operation.rs rename to core/src/v3/models/operation.rs diff --git a/core/src/v3/parameter.rs b/core/src/v3/models/parameter.rs similarity index 100% rename from core/src/v3/parameter.rs rename to core/src/v3/models/parameter.rs diff --git a/core/src/v3/paths.rs b/core/src/v3/models/paths.rs similarity index 100% rename from core/src/v3/paths.rs rename to core/src/v3/models/paths.rs diff --git a/core/src/v3/reference.rs b/core/src/v3/models/reference.rs similarity index 100% rename from core/src/v3/reference.rs rename to core/src/v3/models/reference.rs diff --git a/core/src/v3/request_body.rs b/core/src/v3/models/request_body.rs similarity index 100% rename from core/src/v3/request_body.rs rename to core/src/v3/models/request_body.rs diff --git a/core/src/v3/response.rs b/core/src/v3/models/response.rs similarity index 100% rename from core/src/v3/response.rs rename to core/src/v3/models/response.rs diff --git a/core/src/v3/schema.rs b/core/src/v3/models/schema.rs similarity index 100% rename from core/src/v3/schema.rs rename to core/src/v3/models/schema.rs diff --git a/core/src/v3/security_scheme.rs b/core/src/v3/models/security_scheme.rs similarity index 100% rename from core/src/v3/security_scheme.rs rename to core/src/v3/models/security_scheme.rs diff --git a/core/src/v3/tag.rs b/core/src/v3/models/tag.rs similarity index 100% rename from core/src/v3/tag.rs rename to core/src/v3/models/tag.rs diff --git a/src/bin/main.rs b/src/bin/main.rs index 9e1c37f3c..a34426542 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,4 +1,5 @@ use anyhow::Error; + use paperclip::{ v2::{ self, @@ -14,6 +15,11 @@ use std::{ path::PathBuf, }; +#[cfg(feature = "cli-ng")] +use heck::ToSnakeCase; +#[cfg(feature = "cli-ng")] +use paperclip_ng::v3_03 as v3; + fn parse_version(s: &str) -> Result { match s { "v2" => Ok(OApiVersion::V2), @@ -26,6 +32,11 @@ fn parse_spec(s: &str) -> Result, Error> { let fd = File::open(s)?; Ok(v2::from_reader(fd)?) } +#[cfg(feature = "cli-ng")] +fn parse_spec_v3(s: &str) -> Result { + let fd = File::open(s)?; + Ok(v2::from_reader_v3(fd)?) +} #[derive(Debug)] enum OApiVersion { @@ -36,8 +47,8 @@ enum OApiVersion { #[derive(Debug, StructOpt)] struct Opt { /// Path to OpenAPI spec in JSON/YAML format (also supports publicly accessible URLs). - #[structopt(parse(try_from_str = parse_spec))] - spec: ResolvableApi, + #[structopt(long)] + spec: std::path::PathBuf, /// OpenAPI version (e.g., v2). #[structopt(long = "api", parse(try_from_str = parse_version))] api: OApiVersion, @@ -47,6 +58,14 @@ struct Opt { /// Emit CLI target instead. #[structopt(long = "cli")] cli: bool, + #[cfg(feature = "cli-ng")] + /// Don't Render models. + #[structopt(long)] + no_models: bool, + #[cfg(feature = "cli-ng")] + /// Don't Render operations. + #[structopt(long)] + no_ops: bool, /// Do not make the crate a root crate. #[structopt(long = "no-root")] no_root: bool, @@ -57,19 +76,55 @@ struct Opt { /// Version (defaults to 0.1.0) #[structopt(long = "version")] pub version: Option, + #[cfg(feature = "cli-ng")] + /// The Edition of the crate. + #[structopt(long = "edition", default_value = "2018")] + pub edition: String, + #[cfg(feature = "cli-ng")] + /// Use custom templates (mustache) files, rather than the builtin ones. + /// The root dir in this path must be the template name, example: default. + #[structopt(short = "t", long = "templates", parse(from_os_str))] + templates: Option, } fn parse_args_and_run() -> Result<(), Error> { - let opt = Opt::from_args(); + let opt: Opt = Opt::from_args(); + + if let Some(o) = &opt.output { + fs::create_dir_all(o)?; + } + + #[cfg(feature = "cli-ng")] + if let OApiVersion::V3 = opt.api { + let spec = parse_spec_v3(opt.spec.to_string_lossy().as_ref())?; + let name = opt.name.map(Ok::).unwrap_or_else(|| { + Ok(fs::canonicalize(std::path::Path::new("."))? + .file_name() + .ok_or(PaperClipError::InvalidCodegenDirectory)? + .to_string_lossy() + .into_owned() + .to_snake_case()) + })?; + let info = v3::PackageInfo { + libname: name.to_snake_case(), + name, + version: opt.version.unwrap_or_else(|| "0.1.0".into()), + edition: opt.edition, + }; + v3::OpenApiV3::new(spec, opt.templates, opt.output, info)? + .run(!opt.no_models, !opt.no_ops)?; + return Ok(()); + } + + #[cfg(not(feature = "cli-ng"))] if let OApiVersion::V3 = opt.api { return Err(PaperClipError::UnsupportedOpenAPIVersion.into()); } - let spec = opt.spec.resolve()?; + let spec = parse_spec(&opt.spec.to_string_lossy())?.resolve()?; let mut state = EmitterState::default(); if let Some(o) = opt.output { - fs::create_dir_all(&o)?; state.working_dir = o; } diff --git a/src/v2/mod.rs b/src/v2/mod.rs index 28a14e8c1..e39d26424 100644 --- a/src/v2/mod.rs +++ b/src/v2/mod.rs @@ -134,3 +134,31 @@ where api.spec_format = fmt; Ok(api) } + +#[cfg(feature = "cli-ng")] +/// Deserialize the schema from the given reader. Currently, this only supports +/// JSON and YAML formats. +pub fn from_reader_v3(mut reader: R) -> Result +where + R: Read, +{ + let mut buf = [b' ']; + while buf[0].is_ascii_whitespace() { + reader.read_exact(&mut buf)?; + } + let reader = buf.as_ref().chain(reader); + + let (api, _fmt) = if buf[0] == b'{' { + ( + serde_json::from_reader::<_, openapiv3::OpenAPI>(reader)?, + SpecFormat::Json, + ) + } else { + ( + serde_yaml::from_reader::<_, openapiv3::OpenAPI>(reader)?, + SpecFormat::Yaml, + ) + }; + + Ok(api) +} diff --git a/testgen/src/autogen/.gitignore b/testgen/src/autogen/.gitignore new file mode 100644 index 000000000..a79a8002d --- /dev/null +++ b/testgen/src/autogen/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk \ No newline at end of file diff --git a/testgen/src/autogen/Cargo.toml b/testgen/src/autogen/Cargo.toml new file mode 100644 index 000000000..bd18afcfc --- /dev/null +++ b/testgen/src/autogen/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "paper" +version = "1.0.0" +edition = "2018" + +[lib] +name = "paper" +path = "src/lib.rs" + +[features] +default = [ "tower-client-rls", "tower-trace" ] +actix-server = [ "actix" ] +actix-client = [ "actix", "actix-web-opentelemetry", "awc" ] +actix = [ "actix-web", "rustls" ] +tower-client-rls = [ "tower-client", "rustls_feat" ] +tower-client-tls = [ "tower-client", "hyper_tls_feat" ] +tower-client = [ "tower-hyper" ] +tower-hyper = [ "hyper", "tower", "tower-http", "http-body", "futures", "pin-project", "tokio" ] +hyper_tls_feat = [ "hyper-tls", "tokio-native-tls" ] +rustls_feat = [ "rustls", "webpki", "hyper-rustls" ] +tower-trace = [ "opentelemetry-jaeger", "tracing-opentelemetry", "opentelemetry", "opentelemetry-http", "tracing", "tracing-subscriber" ] + +[dependencies] +serde = "^1.0" +serde_derive = "^1.0" +serde_json = "^1.0" +url = { version = "^2.4", features = ["serde"] } +async-trait = "0.1.73" +dyn-clonable = "0.9.0" +uuid = { version = "1.4.1", features = ["serde", "v4"] } +serde_urlencoded = "0.7" + +# actix dependencies +actix-web = { version = "4.4.0", features = ["rustls-0_21"], optional = true } +actix-web-opentelemetry = { version = "0.17.0", optional = true } +awc = { version = "3.2.0", optional = true } + +# tower and hyper dependencies +hyper = { version = "0.14.27", features = [ "client", "http1", "http2", "tcp", "stream" ], optional = true } +tower = { version = "0.4.13", features = [ "timeout", "util", "limit" ], optional = true } +tower-http = { version = "0.4.4", features = [ "trace", "map-response-body", "auth" ], optional = true } +tokio = { version = "1.32.0", features = ["full"], optional = true } +http-body = { version = "0.4.5", optional = true } +futures = { version = "0.3.28", optional = true } +pin-project = { version = "1.1.3", optional = true } + +# SSL +rustls = { version = "0.21.12", optional = true, features = [ "dangerous_configuration" ] } +rustls-pemfile = "1.0.3" +webpki = { version = "0.22.2", optional = true } +hyper-rustls = { version = "0.24.1", optional = true } +hyper-tls = { version = "0.5.0", optional = true } +tokio-native-tls = { version = "0.3.1", optional = true } + +# tracing and telemetry +opentelemetry-jaeger = { version = "0.21.0", features = ["rt-tokio-current-thread"], optional = true } +tracing-opentelemetry = { version = "0.23.0", optional = true } +opentelemetry = { version = "0.22.0", optional = true } +opentelemetry-http = { version = "0.11.1", optional = true } +tracing = { version = "0.1.37", optional = true } +tracing-subscriber = { version = "0.3.18", optional = true } \ No newline at end of file diff --git a/testgen/src/autogen/apis/actix_server.rs b/testgen/src/autogen/apis/actix_server.rs new file mode 100644 index 000000000..a8ff272b1 --- /dev/null +++ b/testgen/src/autogen/apis/actix_server.rs @@ -0,0 +1,679 @@ +use actix_web::http::StatusCode; +use actix_web::{web::ServiceConfig, FromRequest, HttpResponse, ResponseError}; +use serde::Serialize; +use std::{ + fmt::{self, Debug, Display, Formatter}, + ops, +}; + + + + + + + + + + + + +pub use crate::apis::app_nodes_api::actix::server::AppNodes; + + + + + + + +pub use crate::apis::block_devices_api::actix::server::BlockDevices; + + + + + + + + + + + + + + + + + + + + + +pub use crate::apis::children_api::actix::server::Children; + + + + + + + +pub use crate::apis::json_grpc_api::actix::server::JsonGrpc; + + + + + + + + + + + + + + + + + + + + + + + +pub use crate::apis::nexuses_api::actix::server::Nexuses; + + + + + + + + + + + + + + + + + + + +pub use crate::apis::nodes_api::actix::server::Nodes; + + + + + + + + + + + + + + + + + + + +pub use crate::apis::pools_api::actix::server::Pools; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub use crate::apis::replicas_api::actix::server::Replicas; + + + + + + + + + + + + + + + + + + + +pub use crate::apis::snapshots_api::actix::server::Snapshots; + + + + + + + +pub use crate::apis::specs_api::actix::server::Specs; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub use crate::apis::volumes_api::actix::server::Volumes; + + + + + + + + + + + +pub use crate::apis::watches_api::actix::server::Watches; + + + + + + +/// Rest Error wrapper with a status code and a JSON error +/// Note: Only a single error type for each handler is supported at the moment +pub struct RestError { + status_code: StatusCode, + error_response: T, +} + +impl RestError { + pub fn new(status_code: StatusCode, error_response: T) -> Self { + Self { + status_code, + error_response + } + } +} + +impl Debug for RestError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("RestError") + .field("status_code", &self.status_code) + .field("error_response", &self.error_response) + .finish() + } +} + +impl Display for RestError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +impl ResponseError for RestError { + fn status_code(&self) -> StatusCode { + self.status_code + } + + fn error_response(&self) -> HttpResponse { + HttpResponse::build(self.status_code).json(&self.error_response) + } +} + +/// 204 Response with no content +#[derive(Default)] +pub(crate) struct NoContent; + +impl From> for NoContent { + fn from(_: actix_web::web::Json<()>) -> Self { + NoContent {} + } +} +impl From<()> for NoContent { + fn from(_: ()) -> Self { + NoContent {} + } +} +impl actix_web::Responder for NoContent { + type Body = actix_web::body::BoxBody; + + fn respond_to(self, _: &actix_web::HttpRequest) -> actix_web::HttpResponse { + actix_web::HttpResponse::NoContent().finish() + } +} + +/// Wrapper type used as tag to easily distinguish the 3 different parameter types: +/// 1. Path 2. Query 3. Body +/// Example usage: +/// fn delete_resource(Path((p1, p2)): Path<(String, u64)>) { ... } +pub struct Path(pub T); + +impl Path { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.0 + } +} + +impl AsRef for Path { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl ops::Deref for Path { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Path { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// Wrapper type used as tag to easily distinguish the 3 different parameter types: +/// 1. Path 2. Query 3. Body +/// Example usage: +/// fn delete_resource(Path((p1, p2)): Path<(String, u64)>) { ... } +pub struct Query(pub T); + +impl Query { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.0 + } +} + +impl AsRef for Query { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl ops::Deref for Query { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Query { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// Wrapper type used as tag to easily distinguish the 3 different parameter types: +/// 1. Path 2. Query 3. Body +/// Example usage: +/// fn delete_resource(Path((p1, p2)): Path<(String, u64)>) { ... } +pub struct Body(pub T); + +impl Body { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.0 + } +} + +impl AsRef for Body { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl ops::Deref for Body { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Body { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +/// Configure all actix server handlers +pub fn configure(cfg: &mut ServiceConfig) { + + + + + + + + + + + + crate::apis::app_nodes_api::actix::server::handlers::configure::(cfg); + + + + + + + + crate::apis::block_devices_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + + + crate::apis::children_api::actix::server::handlers::configure::(cfg); + + + + + + + + crate::apis::json_grpc_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + + + + + crate::apis::nexuses_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + crate::apis::nodes_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + crate::apis::pools_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + crate::apis::replicas_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + crate::apis::snapshots_api::actix::server::handlers::configure::(cfg); + + + + + + + + crate::apis::specs_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + crate::apis::volumes_api::actix::server::handlers::configure::(cfg); + + + + + + + + + + + + crate::apis::watches_api::actix::server::handlers::configure::(cfg); + + + + + +} + +/// Used with Query to deserialize into Vec. +#[allow(dead_code)] +pub(crate) fn deserialize_stringified_list<'de, D, I>( + deserializer: D, +) -> std::result::Result, D::Error> +where + D: serde::de::Deserializer<'de>, + I: serde::de::DeserializeOwned, +{ + struct StringVecVisitor(std::marker::PhantomData); + + impl<'de, I> serde::de::Visitor<'de> for StringVecVisitor + where + I: serde::de::DeserializeOwned, + { + type Value = Vec; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a string containing a list") + } + + fn visit_str(self, v: &str) -> std::result::Result + where + E: serde::de::Error, + { + let mut list = Vec::new(); + if !v.is_empty() { + for item in v.split(',') { + let item = I::deserialize(serde::de::IntoDeserializer::into_deserializer(item))?; + list.push(item); + } + } + Ok(list) + } + } + + deserializer.deserialize_any(StringVecVisitor(std::marker::PhantomData::)) +} + +/// Used with Query to deserialize into Option>. +#[allow(dead_code)] +pub(crate) fn deserialize_option_stringified_list<'de, D, I>( + deserializer: D, +) -> std::result::Result>, D::Error> +where + D: serde::de::Deserializer<'de>, + I: serde::de::DeserializeOwned, +{ + let list = deserialize_stringified_list(deserializer)?; + match list.is_empty() { + true => Ok(None), + false => Ok(Some(list)), + } +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/app_nodes_api/actix/client/mod.rs b/testgen/src/autogen/apis/app_nodes_api/actix/client/mod.rs new file mode 100644 index 000000000..6f96b0fe6 --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/actix/client/mod.rs @@ -0,0 +1,295 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct AppNodesClient { + configuration: Rc, +} + +impl AppNodesClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait AppNodes: Clone { + + + + + async fn get_app_nodes(&self, max_entries: isize, starting_token: Option) -> Result>; + + + + async fn get_app_node(&self, app_node_id: &str) -> Result>; + + + + async fn register_app_node(&self, app_node_id: &str) -> Result<(), Error>; + + + + async fn deregister_app_node(&self, app_node_id: &str) -> Result<(), Error>; + + +} + +#[async_trait::async_trait(?Send)] +impl AppNodes for AppNodesClient { + + + + + async fn get_app_nodes(&self, max_entries: isize, starting_token: Option) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/app-nodes", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + query_params.push(("max_entries", max_entries.to_string())); + + + + + + if let Some(ref local_var_str) = starting_token { + query_params.push(("starting_token", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_app_node(&self, app_node_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/app-nodes/{app_node_id}", configuration.base_path, app_node_id=crate::apis::urlencode(app_node_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn register_app_node(&self, app_node_id: &str) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/app-nodes/{app_node_id}", configuration.base_path, app_node_id=crate::apis::urlencode(app_node_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn deregister_app_node(&self, app_node_id: &str) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/app-nodes/{app_node_id}", configuration.base_path, app_node_id=crate::apis::urlencode(app_node_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/app_nodes_api/actix/mod.rs b/testgen/src/autogen/apis/app_nodes_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/app_nodes_api/actix/server/handlers.rs b/testgen/src/autogen/apis/app_nodes_api/actix/server/handlers.rs new file mode 100644 index 000000000..ff07c51e9 --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/actix/server/handlers.rs @@ -0,0 +1,107 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + app_nodes_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the AppNodes resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/app-nodes") + .name("get_app_nodes") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_app_nodes::)) + ) + + .service( + actix_web::web::resource("/app-nodes/{app_node_id}") + .name("get_app_node") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_app_node::)) + ) + + .service( + actix_web::web::resource("/app-nodes/{app_node_id}") + .name("register_app_node") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(register_app_node::)) + ) + + .service( + actix_web::web::resource("/app-nodes/{app_node_id}") + .name("deregister_app_node") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(deregister_app_node::)) + ); + + +} + + + + +#[derive(serde::Deserialize)] +struct get_app_nodesQueryParams { + + + #[serde(rename = "max_entries")] + pub max_entries: isize, + + + #[serde(rename = "starting_token", default, skip_serializing_if = "Option::is_none")] + pub starting_token: Option, + +} + + + + + + + + + + + + + + +async fn get_app_nodes(_token: A, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::get_app_nodes(crate::apis::actix_server::Query(query.max_entries, query.starting_token)).await.map(Json) +} + + + + +async fn get_app_node(_token: A, path: Path) -> Result, RestError> { + T::get_app_node(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn register_app_node(_token: A, path: Path) -> Result, RestError> { + T::register_app_node(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn deregister_app_node(_token: A, path: Path) -> Result, RestError> { + T::deregister_app_node(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/app_nodes_api/actix/server/mod.rs b/testgen/src/autogen/apis/app_nodes_api/actix/server/mod.rs new file mode 100644 index 000000000..11efd9e1d --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/actix/server/mod.rs @@ -0,0 +1,29 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait AppNodes { + + + + + async fn get_app_nodes(Query(max_entries, starting_token): Query>) -> Result>; + + + + async fn get_app_node(Path(app_node_id): Path) -> Result>; + + + + async fn register_app_node(Path(app_node_id): Path) -> Result<(), RestError>; + + + + async fn deregister_app_node(Path(app_node_id): Path) -> Result<(), RestError>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/app_nodes_api/mod.rs b/testgen/src/autogen/apis/app_nodes_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/app_nodes_api/tower/client/mod.rs b/testgen/src/autogen/apis/app_nodes_api/tower/client/mod.rs new file mode 100644 index 000000000..b8e8a1bfe --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/tower/client/mod.rs @@ -0,0 +1,472 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct AppNodesClient { + configuration: Arc, +} + +impl AppNodesClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for AppNodesClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait AppNodes: Clone + Send + Sync { + + + + + async fn get_app_nodes(&self, max_entries: isize, starting_token: Option) -> Result, Error>; + + + + async fn get_app_node(&self, app_node_id: &str) -> Result, Error>; + + + + async fn register_app_node(&self, app_node_id: &str) -> Result, Error>; + + + + async fn deregister_app_node(&self, app_node_id: &str) -> Result, Error>; + + +} + +/// Same as `AppNodes` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait AppNodes: Clone + Send + Sync { + + + + + async fn get_app_nodes(&self, max_entries: isize, starting_token: Option) -> Result>; + + + + async fn get_app_node(&self, app_node_id: &str) -> Result>; + + + + async fn register_app_node(&self, app_node_id: &str) -> Result<(), super::Error>; + + + + async fn deregister_app_node(&self, app_node_id: &str) -> Result<(), super::Error>; + + + } +} + +#[async_trait::async_trait] +impl direct::AppNodes for AppNodesClient { + + + + + async fn get_app_nodes(&self, max_entries: isize, starting_token: Option) -> Result> { + + AppNodes::get_app_nodes(self, max_entries, starting_token).await.map(|r| r.into_body()) + } + + + + async fn get_app_node(&self, app_node_id: &str) -> Result> { + + AppNodes::get_app_node(self, app_node_id).await.map(|r| r.into_body()) + } + + + + async fn register_app_node(&self, app_node_id: &str) -> Result<(), Error> { + + AppNodes::register_app_node(self, app_node_id).await.map(|r| r.into_body()) + } + + + + async fn deregister_app_node(&self, app_node_id: &str) -> Result<(), Error> { + + AppNodes::deregister_app_node(self, app_node_id).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl AppNodes for AppNodesClient { + + + + + async fn get_app_nodes(&self, max_entries: isize, starting_token: Option) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/app-nodes", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + let query_params: Option = None; + + + let query_params = match query_params { + None => Some(format!("max_entries={}", max_entries.to_string())), + Some(previous) => Some(format!("{previous}&max_entries={}", max_entries.to_string())) + }; + + + + + + let query_params = if let Some(local_var_str) = starting_token { + match query_params { + None => Some(format!("starting_token={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&starting_token={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::AppNodes = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_app_node(&self, app_node_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/app-nodes/{app_node_id}", configuration.base_path, app_node_id=crate::apis::urlencode(app_node_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::AppNode = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn register_app_node(&self, app_node_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/app-nodes/{app_node_id}", configuration.base_path, app_node_id=crate::apis::urlencode(app_node_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn deregister_app_node(&self, app_node_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/app-nodes/{app_node_id}", configuration.base_path, app_node_id=crate::apis::urlencode(app_node_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/app_nodes_api/tower/mod.rs b/testgen/src/autogen/apis/app_nodes_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/app_nodes_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/block_devices_api/actix/client/mod.rs b/testgen/src/autogen/apis/block_devices_api/actix/client/mod.rs new file mode 100644 index 000000000..160ff98a5 --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/actix/client/mod.rs @@ -0,0 +1,107 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct BlockDevicesClient { + configuration: Rc, +} + +impl BlockDevicesClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait BlockDevices: Clone { + + + + + async fn get_node_block_devices(&self, all: Option, node: &str) -> Result, Error>; + + +} + +#[async_trait::async_trait(?Send)] +impl BlockDevices for BlockDevicesClient { + + + + + async fn get_node_block_devices(&self, all: Option, node: &str) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node}/block_devices", configuration.base_path, node=crate::apis::urlencode(node)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = all { + query_params.push(("all", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/block_devices_api/actix/mod.rs b/testgen/src/autogen/apis/block_devices_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/block_devices_api/actix/server/handlers.rs b/testgen/src/autogen/apis/block_devices_api/actix/server/handlers.rs new file mode 100644 index 000000000..7772d82f7 --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/actix/server/handlers.rs @@ -0,0 +1,55 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + block_devices_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the BlockDevices resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nodes/{node}/block_devices") + .name("get_node_block_devices") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_block_devices::)) + ); + + +} + + + + +#[derive(serde::Deserialize)] +struct get_node_block_devicesQueryParams { + + + #[serde(rename = "all", default, skip_serializing_if = "Option::is_none")] + pub all: Option, + +} + + + + + + + + +async fn get_node_block_devices(_token: A, path: Path, query: Query) -> Result>, RestError> { + let query = query.into_inner(); + T::get_node_block_devices(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.all)).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/block_devices_api/actix/server/mod.rs b/testgen/src/autogen/apis/block_devices_api/actix/server/mod.rs new file mode 100644 index 000000000..17d298afe --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/actix/server/mod.rs @@ -0,0 +1,17 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait BlockDevices { + + + + + async fn get_node_block_devices(Path(node): Path, Query(all): Query>) -> Result, RestError>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/block_devices_api/mod.rs b/testgen/src/autogen/apis/block_devices_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/block_devices_api/tower/client/mod.rs b/testgen/src/autogen/apis/block_devices_api/tower/client/mod.rs new file mode 100644 index 000000000..8b02d6b1a --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/tower/client/mod.rs @@ -0,0 +1,176 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct BlockDevicesClient { + configuration: Arc, +} + +impl BlockDevicesClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for BlockDevicesClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait BlockDevices: Clone + Send + Sync { + + + + + async fn get_node_block_devices(&self, all: Option, node: &str) -> Result>, Error>; + + +} + +/// Same as `BlockDevices` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait BlockDevices: Clone + Send + Sync { + + + + + async fn get_node_block_devices(&self, all: Option, node: &str) -> Result, super::Error>; + + + } +} + +#[async_trait::async_trait] +impl direct::BlockDevices for BlockDevicesClient { + + + + + async fn get_node_block_devices(&self, all: Option, node: &str) -> Result, Error> { + + BlockDevices::get_node_block_devices(self, all, node).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl BlockDevices for BlockDevicesClient { + + + + + async fn get_node_block_devices(&self, all: Option, node: &str) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node}/block_devices", configuration.base_path, node=crate::apis::urlencode(node)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = all { + match query_params { + None => Some(format!("all={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&all={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/block_devices_api/tower/mod.rs b/testgen/src/autogen/apis/block_devices_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/block_devices_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/children_api/actix/client/mod.rs b/testgen/src/autogen/apis/children_api/actix/client/mod.rs new file mode 100644 index 000000000..2b6ec3817 --- /dev/null +++ b/testgen/src/autogen/apis/children_api/actix/client/mod.rs @@ -0,0 +1,523 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct ChildrenClient { + configuration: Rc, +} + +impl ChildrenClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Children: Clone { + + + + + async fn get_nexus_children(&self, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn put_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn del_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), Error>; + + + + async fn get_node_nexus_children(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn put_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn del_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), Error>; + + +} + +#[async_trait::async_trait(?Send)] +impl Children for ChildrenClient { + + + + + async fn get_nexus_children(&self, nexus_id: &uuid::Uuid) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children", configuration.base_path, nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_nexus_children(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/children_api/actix/mod.rs b/testgen/src/autogen/apis/children_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/children_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/children_api/actix/server/handlers.rs b/testgen/src/autogen/apis/children_api/actix/server/handlers.rs new file mode 100644 index 000000000..ff052f580 --- /dev/null +++ b/testgen/src/autogen/apis/children_api/actix/server/handlers.rs @@ -0,0 +1,157 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + children_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Children resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nexuses/{nexus_id}/children") + .name("get_nexus_children") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_nexus_children::)) + ) + + .service( + actix_web::web::resource("/nexuses/{nexus_id}/children/{child_id}") + .name("get_nexus_child") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_nexus_child::)) + ) + + .service( + actix_web::web::resource("/nexuses/{nexus_id}/children/{child_id}") + .name("put_nexus_child") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_nexus_child::)) + ) + + .service( + actix_web::web::resource("/nexuses/{nexus_id}/children/{child_id}") + .name("del_nexus_child") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_nexus_child::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}/children") + .name("get_node_nexus_children") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_nexus_children::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}") + .name("get_node_nexus_child") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_nexus_child::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}") + .name("put_node_nexus_child") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_nexus_child::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}") + .name("del_node_nexus_child") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_node_nexus_child::)) + ); + + +} + + + + + + + + + + + + + + + + + + + + + + + + + +async fn get_nexus_children(_token: A, path: Path) -> Result>, RestError> { + T::get_nexus_children(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_nexus_child(_token: A, path: Path) -> Result, RestError> { + T::get_nexus_child(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_nexus_child(_token: A, path: Path) -> Result, RestError> { + T::put_nexus_child(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_nexus_child(_token: A, path: Path) -> Result, RestError> { + T::del_nexus_child(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_nexus_children(_token: A, path: Path) -> Result>, RestError> { + T::get_node_nexus_children(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_nexus_child(_token: A, path: Path) -> Result, RestError> { + T::get_node_nexus_child(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_nexus_child(_token: A, path: Path) -> Result, RestError> { + T::put_node_nexus_child(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_node_nexus_child(_token: A, path: Path) -> Result, RestError> { + T::del_node_nexus_child(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/children_api/actix/server/mod.rs b/testgen/src/autogen/apis/children_api/actix/server/mod.rs new file mode 100644 index 000000000..f9323f218 --- /dev/null +++ b/testgen/src/autogen/apis/children_api/actix/server/mod.rs @@ -0,0 +1,45 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Children { + + + + + async fn get_nexus_children(Path(nexus_id): Path) -> Result, RestError>; + + + + async fn get_nexus_child(Path(nexus_id, child_id): Path) -> Result>; + + + + async fn put_nexus_child(Path(nexus_id, child_id): Path) -> Result>; + + + + async fn del_nexus_child(Path(nexus_id, child_id): Path) -> Result<(), RestError>; + + + + async fn get_node_nexus_children(Path(node_id, nexus_id): Path) -> Result, RestError>; + + + + async fn get_node_nexus_child(Path(node_id, nexus_id, child_id): Path) -> Result>; + + + + async fn put_node_nexus_child(Path(node_id, nexus_id, child_id): Path) -> Result>; + + + + async fn del_node_nexus_child(Path(node_id, nexus_id, child_id): Path) -> Result<(), RestError>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/children_api/mod.rs b/testgen/src/autogen/apis/children_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/children_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/children_api/tower/client/mod.rs b/testgen/src/autogen/apis/children_api/tower/client/mod.rs new file mode 100644 index 000000000..4aea31cd6 --- /dev/null +++ b/testgen/src/autogen/apis/children_api/tower/client/mod.rs @@ -0,0 +1,829 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct ChildrenClient { + configuration: Arc, +} + +impl ChildrenClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for ChildrenClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Children: Clone + Send + Sync { + + + + + async fn get_nexus_children(&self, nexus_id: &uuid::Uuid) -> Result>, Error>; + + + + async fn get_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error>; + + + + async fn put_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error>; + + + + async fn del_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error>; + + + + async fn get_node_nexus_children(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result>, Error>; + + + + async fn get_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error>; + + + + async fn put_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error>; + + + + async fn del_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error>; + + +} + +/// Same as `Children` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Children: Clone + Send + Sync { + + + + + async fn get_nexus_children(&self, nexus_id: &uuid::Uuid) -> Result, super::Error>; + + + + async fn get_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn put_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn del_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), super::Error>; + + + + async fn get_node_nexus_children(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, super::Error>; + + + + async fn get_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn put_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result>; + + + + async fn del_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), super::Error>; + + + } +} + +#[async_trait::async_trait] +impl direct::Children for ChildrenClient { + + + + + async fn get_nexus_children(&self, nexus_id: &uuid::Uuid) -> Result, Error> { + + Children::get_nexus_children(self, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn get_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + Children::get_nexus_child(self, nexus_id, child_id).await.map(|r| r.into_body()) + } + + + + async fn put_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + Children::put_nexus_child(self, nexus_id, child_id).await.map(|r| r.into_body()) + } + + + + async fn del_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), Error> { + + Children::del_nexus_child(self, nexus_id, child_id).await.map(|r| r.into_body()) + } + + + + async fn get_node_nexus_children(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error> { + + Children::get_node_nexus_children(self, node_id, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn get_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + Children::get_node_nexus_child(self, node_id, nexus_id, child_id).await.map(|r| r.into_body()) + } + + + + async fn put_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result> { + + Children::put_node_nexus_child(self, node_id, nexus_id, child_id).await.map(|r| r.into_body()) + } + + + + async fn del_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result<(), Error> { + + Children::del_node_nexus_child(self, node_id, nexus_id, child_id).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Children for ChildrenClient { + + + + + async fn get_nexus_children(&self, nexus_id: &uuid::Uuid) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children", configuration.base_path, nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Child = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Child = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_nexus_child(&self, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_nexus_children(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Child = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Child = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_node_nexus_child(&self, node_id: &str, nexus_id: &uuid::Uuid, child_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/children/{child_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), child_id=crate::apis::urlencode(child_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/children_api/tower/mod.rs b/testgen/src/autogen/apis/children_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/children_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/json_grpc_api/actix/client/mod.rs b/testgen/src/autogen/apis/json_grpc_api/actix/client/mod.rs new file mode 100644 index 000000000..e1fe9dc8e --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/actix/client/mod.rs @@ -0,0 +1,96 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct JsonGrpcClient { + configuration: Rc, +} + +impl JsonGrpcClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait JsonGrpc: Clone { + + + + + async fn put_node_jsongrpc(&self, node: &str, method: &str) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl JsonGrpc for JsonGrpcClient { + + + + + async fn put_node_jsongrpc(&self, node: &str, method: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node}/jsongrpc/{method}", configuration.base_path, node=crate::apis::urlencode(node), method=crate::apis::urlencode(method)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/json_grpc_api/actix/mod.rs b/testgen/src/autogen/apis/json_grpc_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/json_grpc_api/actix/server/handlers.rs b/testgen/src/autogen/apis/json_grpc_api/actix/server/handlers.rs new file mode 100644 index 000000000..68bb3d3f3 --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/actix/server/handlers.rs @@ -0,0 +1,45 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + json_grpc_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the JsonGrpc resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nodes/{node}/jsongrpc/{method}") + .name("put_node_jsongrpc") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_jsongrpc::)) + ); + + +} + + + + + + + + + + + +async fn put_node_jsongrpc(_token: A, path: Path) -> Result, RestError> { + T::put_node_jsongrpc(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/json_grpc_api/actix/server/mod.rs b/testgen/src/autogen/apis/json_grpc_api/actix/server/mod.rs new file mode 100644 index 000000000..2edc86df8 --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/actix/server/mod.rs @@ -0,0 +1,17 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait JsonGrpc { + + + + + async fn put_node_jsongrpc(Path(node, method): Path) -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/json_grpc_api/mod.rs b/testgen/src/autogen/apis/json_grpc_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/json_grpc_api/tower/client/mod.rs b/testgen/src/autogen/apis/json_grpc_api/tower/client/mod.rs new file mode 100644 index 000000000..c6bb2f545 --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/tower/client/mod.rs @@ -0,0 +1,157 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct JsonGrpcClient { + configuration: Arc, +} + +impl JsonGrpcClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for JsonGrpcClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait JsonGrpc: Clone + Send + Sync { + + + + + async fn put_node_jsongrpc(&self, node: &str, method: &str) -> Result, Error>; + + +} + +/// Same as `JsonGrpc` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait JsonGrpc: Clone + Send + Sync { + + + + + async fn put_node_jsongrpc(&self, node: &str, method: &str) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::JsonGrpc for JsonGrpcClient { + + + + + async fn put_node_jsongrpc(&self, node: &str, method: &str) -> Result> { + + JsonGrpc::put_node_jsongrpc(self, node, method).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl JsonGrpc for JsonGrpcClient { + + + + + async fn put_node_jsongrpc(&self, node: &str, method: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node}/jsongrpc/{method}", configuration.base_path, node=crate::apis::urlencode(node), method=crate::apis::urlencode(method)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: serde_json::Value = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/json_grpc_api/tower/mod.rs b/testgen/src/autogen/apis/json_grpc_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/json_grpc_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/mod.rs b/testgen/src/autogen/apis/mod.rs new file mode 100644 index 000000000..baf387c1f --- /dev/null +++ b/testgen/src/autogen/apis/mod.rs @@ -0,0 +1,77 @@ + + +pub mod app_nodes_api; + +pub mod block_devices_api; + +pub mod children_api; + +pub mod json_grpc_api; + +pub mod nexuses_api; + +pub mod nodes_api; + +pub mod pools_api; + +pub mod replicas_api; + +pub mod snapshots_api; + +pub mod specs_api; + +pub mod volumes_api; + +pub mod watches_api; + + + +/// Actix server. +#[cfg(feature = "actix-server")] +pub mod actix_server; + +#[cfg(feature = "tower-hyper")] +pub use hyper::http::StatusCode; + +#[cfg(not(feature = "tower-hyper"))] +#[cfg(feature = "actix")] +pub use actix_web::http::StatusCode; + +/// Url. +pub use url::Url; +/// Uuid. +pub use uuid::Uuid; + +/// Encode string to use in a URL. +pub fn urlencode>(s: T) -> String { + ::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect() +} + +/// Helper to convert from Vec into Vec. +pub trait IntoVec: Sized { + /// Performs the conversion. + fn into_vec(self) -> Vec; +} + +impl, T> IntoVec for Vec { + fn into_vec(self) -> Vec { + self.into_iter().map(Into::into).collect() + } +} + +/// Helper to convert from Vec or Option> into Option>. +pub trait IntoOptVec: Sized { + /// Performs the conversion. + fn into_opt_vec(self) -> Option>; +} + +impl, T> IntoOptVec for Vec { + fn into_opt_vec(self) -> Option> { + Some(self.into_iter().map(Into::into).collect()) + } +} +impl, T> IntoOptVec for Option> { + fn into_opt_vec(self) -> Option> { + self.map(|s| s.into_iter().map(Into::into).collect()) + } +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/nexuses_api/actix/client/mod.rs b/testgen/src/autogen/apis/nexuses_api/actix/client/mod.rs new file mode 100644 index 000000000..325d20f1e --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/actix/client/mod.rs @@ -0,0 +1,584 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct NexusesClient { + configuration: Rc, +} + +impl NexusesClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Nexuses: Clone { + + + + + async fn get_nexuses(&self, ) -> Result, Error>; + + + + async fn get_nexus(&self, nexus_id: &uuid::Uuid) -> Result>; + + + + async fn del_nexus(&self, nexus_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn get_node_nexuses(&self, id: &str) -> Result, Error>; + + + + async fn get_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result>; + + + + async fn put_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result>; + + + + async fn del_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn del_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn put_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid, protocol: &str) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl Nexuses for NexusesClient { + + + + + async fn get_nexuses(&self, ) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_nexus(&self, nexus_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}", configuration.base_path, nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_nexus(&self, nexus_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}", configuration.base_path, nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_nexuses(&self, id: &str) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/nexuses", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/share", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid, protocol: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/share/{protocol}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), protocol=crate::apis::urlencode(protocol)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/nexuses_api/actix/mod.rs b/testgen/src/autogen/apis/nexuses_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nexuses_api/actix/server/handlers.rs b/testgen/src/autogen/apis/nexuses_api/actix/server/handlers.rs new file mode 100644 index 000000000..3b0e044a9 --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/actix/server/handlers.rs @@ -0,0 +1,173 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + nexuses_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Nexuses resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nexuses") + .name("get_nexuses") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_nexuses::)) + ) + + .service( + actix_web::web::resource("/nexuses/{nexus_id}") + .name("get_nexus") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_nexus::)) + ) + + .service( + actix_web::web::resource("/nexuses/{nexus_id}") + .name("del_nexus") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_nexus::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}/nexuses") + .name("get_node_nexuses") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_nexuses::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}") + .name("get_node_nexus") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_nexus::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}") + .name("put_node_nexus") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_nexus::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}") + .name("del_node_nexus") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_node_nexus::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}/share") + .name("del_node_nexus_share") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_node_nexus_share::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/nexuses/{nexus_id}/share/{protocol}") + .name("put_node_nexus_share") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_nexus_share::)) + ); + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +async fn get_nexuses(_token: A) -> Result>, RestError> { + T::get_nexuses().await.map(Json) +} + + + + +async fn get_nexus(_token: A, path: Path) -> Result, RestError> { + T::get_nexus(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_nexus(_token: A, path: Path) -> Result, RestError> { + T::del_nexus(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_nexuses(_token: A, path: Path) -> Result>, RestError> { + T::get_node_nexuses(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_nexus(_token: A, path: Path) -> Result, RestError> { + T::get_node_nexus(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_nexus(_token: A, path: Path) -> Result, RestError> { + T::put_node_nexus(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_node_nexus(_token: A, path: Path) -> Result, RestError> { + T::del_node_nexus(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_node_nexus_share(_token: A, path: Path) -> Result, RestError> { + T::del_node_nexus_share(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_nexus_share(_token: A, path: Path) -> Result, RestError> { + T::put_node_nexus_share(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/nexuses_api/actix/server/mod.rs b/testgen/src/autogen/apis/nexuses_api/actix/server/mod.rs new file mode 100644 index 000000000..cdbe04326 --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/actix/server/mod.rs @@ -0,0 +1,49 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Nexuses { + + + + + async fn get_nexuses() -> Result, RestError>; + + + + async fn get_nexus(Path(nexus_id): Path) -> Result>; + + + + async fn del_nexus(Path(nexus_id): Path) -> Result<(), RestError>; + + + + async fn get_node_nexuses(Path(id): Path) -> Result, RestError>; + + + + async fn get_node_nexus(Path(node_id, nexus_id): Path) -> Result>; + + + + async fn put_node_nexus(Path(node_id, nexus_id): Path) -> Result>; + + + + async fn del_node_nexus(Path(node_id, nexus_id): Path) -> Result<(), RestError>; + + + + async fn del_node_nexus_share(Path(node_id, nexus_id): Path) -> Result<(), RestError>; + + + + async fn put_node_nexus_share(Path(node_id, nexus_id, protocol): Path) -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nexuses_api/mod.rs b/testgen/src/autogen/apis/nexuses_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nexuses_api/tower/client/mod.rs b/testgen/src/autogen/apis/nexuses_api/tower/client/mod.rs new file mode 100644 index 000000000..397b293e0 --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/tower/client/mod.rs @@ -0,0 +1,925 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct NexusesClient { + configuration: Arc, +} + +impl NexusesClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for NexusesClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Nexuses: Clone + Send + Sync { + + + + + async fn get_nexuses(&self, ) -> Result>, Error>; + + + + async fn get_nexus(&self, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_nexus(&self, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_node_nexuses(&self, id: &str) -> Result>, Error>; + + + + async fn get_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid, protocol: &str) -> Result, Error>; + + +} + +/// Same as `Nexuses` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Nexuses: Clone + Send + Sync { + + + + + async fn get_nexuses(&self, ) -> Result, super::Error>; + + + + async fn get_nexus(&self, nexus_id: &uuid::Uuid) -> Result>; + + + + async fn del_nexus(&self, nexus_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn get_node_nexuses(&self, id: &str) -> Result, super::Error>; + + + + async fn get_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result>; + + + + async fn put_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result>; + + + + async fn del_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn del_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn put_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid, protocol: &str) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::Nexuses for NexusesClient { + + + + + async fn get_nexuses(&self, ) -> Result, Error> { + + Nexuses::get_nexuses(self, ).await.map(|r| r.into_body()) + } + + + + async fn get_nexus(&self, nexus_id: &uuid::Uuid) -> Result> { + + Nexuses::get_nexus(self, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn del_nexus(&self, nexus_id: &uuid::Uuid) -> Result<(), Error> { + + Nexuses::del_nexus(self, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn get_node_nexuses(&self, id: &str) -> Result, Error> { + + Nexuses::get_node_nexuses(self, id).await.map(|r| r.into_body()) + } + + + + async fn get_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result> { + + Nexuses::get_node_nexus(self, node_id, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn put_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result> { + + Nexuses::put_node_nexus(self, node_id, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn del_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), Error> { + + Nexuses::del_node_nexus(self, node_id, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn del_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result<(), Error> { + + Nexuses::del_node_nexus_share(self, node_id, nexus_id).await.map(|r| r.into_body()) + } + + + + async fn put_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid, protocol: &str) -> Result> { + + Nexuses::put_node_nexus_share(self, node_id, nexus_id, protocol).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Nexuses for NexusesClient { + + + + + async fn get_nexuses(&self, ) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_nexus(&self, nexus_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}", configuration.base_path, nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Nexus = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_nexus(&self, nexus_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nexuses/{nexus_id}", configuration.base_path, nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_nexuses(&self, id: &str) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/nexuses", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Nexus = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Nexus = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_node_nexus(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/share", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_nexus_share(&self, node_id: &str, nexus_id: &uuid::Uuid, protocol: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/nexuses/{nexus_id}/share/{protocol}", configuration.base_path, node_id=crate::apis::urlencode(node_id), nexus_id=nexus_id.to_string(), protocol=crate::apis::urlencode(protocol)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: String = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/nexuses_api/tower/mod.rs b/testgen/src/autogen/apis/nexuses_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/nexuses_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nodes_api/actix/client/mod.rs b/testgen/src/autogen/apis/nodes_api/actix/client/mod.rs new file mode 100644 index 000000000..cbd85bb94 --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/actix/client/mod.rs @@ -0,0 +1,484 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct NodesClient { + configuration: Rc, +} + +impl NodesClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Nodes: Clone { + + + + + async fn get_nodes(&self, node_id: Option<&str>) -> Result, Error>; + + + + async fn get_node(&self, id: &str) -> Result>; + + + + async fn put_node_cordon(&self, id: &str, label: &str) -> Result>; + + + + async fn delete_node_cordon(&self, id: &str, label: &str) -> Result>; + + + + async fn put_node_drain(&self, id: &str, label: &str) -> Result>; + + + + async fn put_node_label(&self, overwrite: Option, id: &str, key: &str, value: &str) -> Result>; + + + + async fn delete_node_label(&self, id: &str, key: &str) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl Nodes for NodesClient { + + + + + async fn get_nodes(&self, node_id: Option<&str>) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = node_id { + query_params.push(("node_id", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node(&self, id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_cordon(&self, id: &str, label: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/cordon/{label}", configuration.base_path, id=crate::apis::urlencode(id), label=crate::apis::urlencode(label)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn delete_node_cordon(&self, id: &str, label: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/cordon/{label}", configuration.base_path, id=crate::apis::urlencode(id), label=crate::apis::urlencode(label)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_drain(&self, id: &str, label: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/drain/{label}", configuration.base_path, id=crate::apis::urlencode(id), label=crate::apis::urlencode(label)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_label(&self, overwrite: Option, id: &str, key: &str, value: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/label/{key}={value}", configuration.base_path, id=crate::apis::urlencode(id), key=crate::apis::urlencode(key), value=crate::apis::urlencode(value)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = overwrite { + query_params.push(("overwrite", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn delete_node_label(&self, id: &str, key: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/label/{key}", configuration.base_path, id=crate::apis::urlencode(id), key=crate::apis::urlencode(key)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/nodes_api/actix/mod.rs b/testgen/src/autogen/apis/nodes_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nodes_api/actix/server/handlers.rs b/testgen/src/autogen/apis/nodes_api/actix/server/handlers.rs new file mode 100644 index 000000000..64aa0e4ab --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/actix/server/handlers.rs @@ -0,0 +1,161 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + nodes_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Nodes resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nodes") + .name("get_nodes") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_nodes::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}") + .name("get_node") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}/cordon/{label}") + .name("put_node_cordon") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_cordon::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}/cordon/{label}") + .name("delete_node_cordon") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(delete_node_cordon::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}/drain/{label}") + .name("put_node_drain") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_drain::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}/label/{key}={value}") + .name("put_node_label") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_label::)) + ) + + .service( + actix_web::web::resource("/nodes/{id}/label/{key}") + .name("delete_node_label") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(delete_node_label::)) + ); + + +} + + + + +#[derive(serde::Deserialize)] +struct get_nodesQueryParams { + + + #[serde(rename = "node_id", default, skip_serializing_if = "Option::is_none")] + pub node_id: Option, + +} + + + + + + + + + + + +#[derive(serde::Deserialize)] +struct put_node_labelQueryParams { + + + #[serde(rename = "overwrite", default, skip_serializing_if = "Option::is_none")] + pub overwrite: Option, + +} + + + + + + + + + + +async fn get_nodes(_token: A, query: Query) -> Result>, RestError> { + let query = query.into_inner(); + T::get_nodes(crate::apis::actix_server::Query(query.node_id)).await.map(Json) +} + + + + +async fn get_node(_token: A, path: Path) -> Result, RestError> { + T::get_node(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_cordon(_token: A, path: Path) -> Result, RestError> { + T::put_node_cordon(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn delete_node_cordon(_token: A, path: Path) -> Result, RestError> { + T::delete_node_cordon(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_drain(_token: A, path: Path) -> Result, RestError> { + T::put_node_drain(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_label(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::put_node_label(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.overwrite)).await.map(Json) +} + + + + +async fn delete_node_label(_token: A, path: Path) -> Result, RestError> { + T::delete_node_label(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/nodes_api/actix/server/mod.rs b/testgen/src/autogen/apis/nodes_api/actix/server/mod.rs new file mode 100644 index 000000000..2ab83b2de --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/actix/server/mod.rs @@ -0,0 +1,41 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Nodes { + + + + + async fn get_nodes(Query(node_id): Query>) -> Result, RestError>; + + + + async fn get_node(Path(id): Path) -> Result>; + + + + async fn put_node_cordon(Path(id, label): Path) -> Result>; + + + + async fn delete_node_cordon(Path(id, label): Path) -> Result>; + + + + async fn put_node_drain(Path(id, label): Path) -> Result>; + + + + async fn put_node_label(Path(id, key, value): Path, Query(overwrite): Query>) -> Result>; + + + + async fn delete_node_label(Path(id, key): Path) -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nodes_api/mod.rs b/testgen/src/autogen/apis/nodes_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/nodes_api/tower/client/mod.rs b/testgen/src/autogen/apis/nodes_api/tower/client/mod.rs new file mode 100644 index 000000000..67bf2b124 --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/tower/client/mod.rs @@ -0,0 +1,771 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct NodesClient { + configuration: Arc, +} + +impl NodesClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for NodesClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Nodes: Clone + Send + Sync { + + + + + async fn get_nodes(&self, node_id: Option<&str>) -> Result>, Error>; + + + + async fn get_node(&self, id: &str) -> Result, Error>; + + + + async fn put_node_cordon(&self, id: &str, label: &str) -> Result, Error>; + + + + async fn delete_node_cordon(&self, id: &str, label: &str) -> Result, Error>; + + + + async fn put_node_drain(&self, id: &str, label: &str) -> Result, Error>; + + + + async fn put_node_label(&self, overwrite: Option, id: &str, key: &str, value: &str) -> Result, Error>; + + + + async fn delete_node_label(&self, id: &str, key: &str) -> Result, Error>; + + +} + +/// Same as `Nodes` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Nodes: Clone + Send + Sync { + + + + + async fn get_nodes(&self, node_id: Option<&str>) -> Result, super::Error>; + + + + async fn get_node(&self, id: &str) -> Result>; + + + + async fn put_node_cordon(&self, id: &str, label: &str) -> Result>; + + + + async fn delete_node_cordon(&self, id: &str, label: &str) -> Result>; + + + + async fn put_node_drain(&self, id: &str, label: &str) -> Result>; + + + + async fn put_node_label(&self, overwrite: Option, id: &str, key: &str, value: &str) -> Result>; + + + + async fn delete_node_label(&self, id: &str, key: &str) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::Nodes for NodesClient { + + + + + async fn get_nodes(&self, node_id: Option<&str>) -> Result, Error> { + + Nodes::get_nodes(self, node_id).await.map(|r| r.into_body()) + } + + + + async fn get_node(&self, id: &str) -> Result> { + + Nodes::get_node(self, id).await.map(|r| r.into_body()) + } + + + + async fn put_node_cordon(&self, id: &str, label: &str) -> Result> { + + Nodes::put_node_cordon(self, id, label).await.map(|r| r.into_body()) + } + + + + async fn delete_node_cordon(&self, id: &str, label: &str) -> Result> { + + Nodes::delete_node_cordon(self, id, label).await.map(|r| r.into_body()) + } + + + + async fn put_node_drain(&self, id: &str, label: &str) -> Result> { + + Nodes::put_node_drain(self, id, label).await.map(|r| r.into_body()) + } + + + + async fn put_node_label(&self, overwrite: Option, id: &str, key: &str, value: &str) -> Result> { + + Nodes::put_node_label(self, overwrite, id, key, value).await.map(|r| r.into_body()) + } + + + + async fn delete_node_label(&self, id: &str, key: &str) -> Result> { + + Nodes::delete_node_label(self, id, key).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Nodes for NodesClient { + + + + + async fn get_nodes(&self, node_id: Option<&str>) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = node_id { + match query_params { + None => Some(format!("node_id={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&node_id={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node(&self, id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Node = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_cordon(&self, id: &str, label: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/cordon/{label}", configuration.base_path, id=crate::apis::urlencode(id), label=crate::apis::urlencode(label)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Node = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn delete_node_cordon(&self, id: &str, label: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/cordon/{label}", configuration.base_path, id=crate::apis::urlencode(id), label=crate::apis::urlencode(label)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Node = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_drain(&self, id: &str, label: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/drain/{label}", configuration.base_path, id=crate::apis::urlencode(id), label=crate::apis::urlencode(label)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Node = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_label(&self, overwrite: Option, id: &str, key: &str, value: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/label/{key}={value}", configuration.base_path, id=crate::apis::urlencode(id), key=crate::apis::urlencode(key), value=crate::apis::urlencode(value)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = overwrite { + match query_params { + None => Some(format!("overwrite={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&overwrite={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Node = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn delete_node_label(&self, id: &str, key: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/label/{key}", configuration.base_path, id=crate::apis::urlencode(id), key=crate::apis::urlencode(key)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Node = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/nodes_api/tower/mod.rs b/testgen/src/autogen/apis/nodes_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/nodes_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/openapi.yaml b/testgen/src/autogen/apis/openapi.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/testgen/src/autogen/apis/pools_api/actix/client/mod.rs b/testgen/src/autogen/apis/pools_api/actix/client/mod.rs new file mode 100644 index 000000000..6b4f8ba9d --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/actix/client/mod.rs @@ -0,0 +1,462 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct PoolsClient { + configuration: Rc, +} + +impl PoolsClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Pools: Clone { + + + + + async fn get_node_pools(&self, id: &str) -> Result, Error>; + + + + async fn get_node_pool(&self, node_id: &str, pool_id: &str) -> Result>; + + + + async fn put_node_pool(&self, node_id: &str, pool_id: &str) -> Result>; + + + + async fn del_node_pool(&self, node_id: &str, pool_id: &str) -> Result<(), Error>; + + + + async fn get_pools(&self, ) -> Result, Error>; + + + + async fn get_pool(&self, pool_id: &str) -> Result>; + + + + async fn del_pool(&self, pool_id: &str) -> Result<(), Error>; + + +} + +#[async_trait::async_trait(?Send)] +impl Pools for PoolsClient { + + + + + async fn get_node_pools(&self, id: &str) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/pools", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_pool(&self, node_id: &str, pool_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_pool(&self, node_id: &str, pool_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_node_pool(&self, node_id: &str, pool_id: &str) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_pools(&self, ) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_pool(&self, pool_id: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools/{pool_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_pool(&self, pool_id: &str) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools/{pool_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/pools_api/actix/mod.rs b/testgen/src/autogen/apis/pools_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/pools_api/actix/server/handlers.rs b/testgen/src/autogen/apis/pools_api/actix/server/handlers.rs new file mode 100644 index 000000000..b9d3ee97b --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/actix/server/handlers.rs @@ -0,0 +1,141 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + pools_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Pools resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nodes/{id}/pools") + .name("get_node_pools") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_pools::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}") + .name("get_node_pool") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_pool::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}") + .name("put_node_pool") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_pool::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}") + .name("del_node_pool") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_node_pool::)) + ) + + .service( + actix_web::web::resource("/pools") + .name("get_pools") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_pools::)) + ) + + .service( + actix_web::web::resource("/pools/{pool_id}") + .name("get_pool") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_pool::)) + ) + + .service( + actix_web::web::resource("/pools/{pool_id}") + .name("del_pool") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_pool::)) + ); + + +} + + + + + + + + + + + + + + + + + + + + + + + +async fn get_node_pools(_token: A, path: Path) -> Result>, RestError> { + T::get_node_pools(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_pool(_token: A, path: Path) -> Result, RestError> { + T::get_node_pool(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_pool(_token: A, path: Path) -> Result, RestError> { + T::put_node_pool(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_node_pool(_token: A, path: Path) -> Result, RestError> { + T::del_node_pool(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_pools(_token: A) -> Result>, RestError> { + T::get_pools().await.map(Json) +} + + + + +async fn get_pool(_token: A, path: Path) -> Result, RestError> { + T::get_pool(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_pool(_token: A, path: Path) -> Result, RestError> { + T::del_pool(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/pools_api/actix/server/mod.rs b/testgen/src/autogen/apis/pools_api/actix/server/mod.rs new file mode 100644 index 000000000..ed88c8879 --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/actix/server/mod.rs @@ -0,0 +1,41 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Pools { + + + + + async fn get_node_pools(Path(id): Path) -> Result, RestError>; + + + + async fn get_node_pool(Path(node_id, pool_id): Path) -> Result>; + + + + async fn put_node_pool(Path(node_id, pool_id): Path) -> Result>; + + + + async fn del_node_pool(Path(node_id, pool_id): Path) -> Result<(), RestError>; + + + + async fn get_pools() -> Result, RestError>; + + + + async fn get_pool(Path(pool_id): Path) -> Result>; + + + + async fn del_pool(Path(pool_id): Path) -> Result<(), RestError>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/pools_api/mod.rs b/testgen/src/autogen/apis/pools_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/pools_api/tower/client/mod.rs b/testgen/src/autogen/apis/pools_api/tower/client/mod.rs new file mode 100644 index 000000000..5f449e678 --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/tower/client/mod.rs @@ -0,0 +1,733 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct PoolsClient { + configuration: Arc, +} + +impl PoolsClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for PoolsClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Pools: Clone + Send + Sync { + + + + + async fn get_node_pools(&self, id: &str) -> Result>, Error>; + + + + async fn get_node_pool(&self, node_id: &str, pool_id: &str) -> Result, Error>; + + + + async fn put_node_pool(&self, node_id: &str, pool_id: &str) -> Result, Error>; + + + + async fn del_node_pool(&self, node_id: &str, pool_id: &str) -> Result, Error>; + + + + async fn get_pools(&self, ) -> Result>, Error>; + + + + async fn get_pool(&self, pool_id: &str) -> Result, Error>; + + + + async fn del_pool(&self, pool_id: &str) -> Result, Error>; + + +} + +/// Same as `Pools` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Pools: Clone + Send + Sync { + + + + + async fn get_node_pools(&self, id: &str) -> Result, super::Error>; + + + + async fn get_node_pool(&self, node_id: &str, pool_id: &str) -> Result>; + + + + async fn put_node_pool(&self, node_id: &str, pool_id: &str) -> Result>; + + + + async fn del_node_pool(&self, node_id: &str, pool_id: &str) -> Result<(), super::Error>; + + + + async fn get_pools(&self, ) -> Result, super::Error>; + + + + async fn get_pool(&self, pool_id: &str) -> Result>; + + + + async fn del_pool(&self, pool_id: &str) -> Result<(), super::Error>; + + + } +} + +#[async_trait::async_trait] +impl direct::Pools for PoolsClient { + + + + + async fn get_node_pools(&self, id: &str) -> Result, Error> { + + Pools::get_node_pools(self, id).await.map(|r| r.into_body()) + } + + + + async fn get_node_pool(&self, node_id: &str, pool_id: &str) -> Result> { + + Pools::get_node_pool(self, node_id, pool_id).await.map(|r| r.into_body()) + } + + + + async fn put_node_pool(&self, node_id: &str, pool_id: &str) -> Result> { + + Pools::put_node_pool(self, node_id, pool_id).await.map(|r| r.into_body()) + } + + + + async fn del_node_pool(&self, node_id: &str, pool_id: &str) -> Result<(), Error> { + + Pools::del_node_pool(self, node_id, pool_id).await.map(|r| r.into_body()) + } + + + + async fn get_pools(&self, ) -> Result, Error> { + + Pools::get_pools(self, ).await.map(|r| r.into_body()) + } + + + + async fn get_pool(&self, pool_id: &str) -> Result> { + + Pools::get_pool(self, pool_id).await.map(|r| r.into_body()) + } + + + + async fn del_pool(&self, pool_id: &str) -> Result<(), Error> { + + Pools::del_pool(self, pool_id).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Pools for PoolsClient { + + + + + async fn get_node_pools(&self, id: &str) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/pools", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_pool(&self, node_id: &str, pool_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Pool = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_pool(&self, node_id: &str, pool_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Pool = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_node_pool(&self, node_id: &str, pool_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_pools(&self, ) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_pool(&self, pool_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools/{pool_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Pool = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_pool(&self, pool_id: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools/{pool_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/pools_api/tower/mod.rs b/testgen/src/autogen/apis/pools_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/pools_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/replicas_api/actix/client/mod.rs b/testgen/src/autogen/apis/replicas_api/actix/client/mod.rs new file mode 100644 index 000000000..c00a52868 --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/actix/client/mod.rs @@ -0,0 +1,850 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct ReplicasClient { + configuration: Rc, +} + +impl ReplicasClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Replicas: Clone { + + + + + async fn get_node_replicas(&self, id: &str) -> Result, Error>; + + + + async fn get_node_pool_replicas(&self, node_id: &str, pool_id: &str) -> Result, Error>; + + + + async fn get_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn put_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn del_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn del_node_pool_replica_share(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn put_node_pool_replica_share(&self, allowed_hosts: Option>, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn put_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn del_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn del_pool_replica_share(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn put_pool_replica_share(&self, allowed_hosts: Option>, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn get_replicas(&self, ) -> Result, Error>; + + + + async fn get_replica(&self, id: &uuid::Uuid) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl Replicas for ReplicasClient { + + + + + async fn get_node_replicas(&self, id: &str) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{id}/replicas", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_pool_replicas(&self, node_id: &str, pool_id: &str) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_node_pool_replica_share(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_node_pool_replica_share(&self, allowed_hosts: Option>, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share/nvmf", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = allowed_hosts { + query_params.push(("allowed-hosts", local_var_str.into_iter().map(|p| p.to_string()).collect::>().join(",").to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_pool_replica_share(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}/share", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_pool_replica_share(&self, allowed_hosts: Option>, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}/share/nvmf", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = allowed_hosts { + query_params.push(("allowed-hosts", local_var_str.into_iter().map(|p| p.to_string()).collect::>().join(",").to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_replicas(&self, ) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/replicas", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_replica(&self, id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/replicas/{id}", configuration.base_path, id=id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/replicas_api/actix/mod.rs b/testgen/src/autogen/apis/replicas_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/replicas_api/actix/server/handlers.rs b/testgen/src/autogen/apis/replicas_api/actix/server/handlers.rs new file mode 100644 index 000000000..45de3d36e --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/actix/server/handlers.rs @@ -0,0 +1,257 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + replicas_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Replicas resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/nodes/{id}/replicas") + .name("get_node_replicas") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_replicas::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}/replicas") + .name("get_node_pool_replicas") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_pool_replicas::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}") + .name("get_node_pool_replica") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_node_pool_replica::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}") + .name("put_node_pool_replica") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_pool_replica::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}") + .name("del_node_pool_replica") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_node_pool_replica::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share") + .name("del_node_pool_replica_share") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_node_pool_replica_share::)) + ) + + .service( + actix_web::web::resource("/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share/nvmf") + .name("put_node_pool_replica_share") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_node_pool_replica_share::)) + ) + + .service( + actix_web::web::resource("/pools/{pool_id}/replicas/{replica_id}") + .name("put_pool_replica") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_pool_replica::)) + ) + + .service( + actix_web::web::resource("/pools/{pool_id}/replicas/{replica_id}") + .name("del_pool_replica") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_pool_replica::)) + ) + + .service( + actix_web::web::resource("/pools/{pool_id}/replicas/{replica_id}/share") + .name("del_pool_replica_share") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_pool_replica_share::)) + ) + + .service( + actix_web::web::resource("/pools/{pool_id}/replicas/{replica_id}/share/nvmf") + .name("put_pool_replica_share") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_pool_replica_share::)) + ) + + .service( + actix_web::web::resource("/replicas") + .name("get_replicas") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_replicas::)) + ) + + .service( + actix_web::web::resource("/replicas/{id}") + .name("get_replica") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_replica::)) + ); + + +} + + + + + + + + + + + + + + + + +#[derive(serde::Deserialize)] +struct put_node_pool_replica_shareQueryParams { + + + #[serde(rename = "allowed-hosts", default, skip_serializing_if = "Option::is_none", deserialize_with = "deserialize_option_stringified_list")] + pub allowed_hosts: Option>, + +} + + + + + + + + + +#[derive(serde::Deserialize)] +struct put_pool_replica_shareQueryParams { + + + #[serde(rename = "allowed-hosts", default, skip_serializing_if = "Option::is_none", deserialize_with = "deserialize_option_stringified_list")] + pub allowed_hosts: Option>, + +} + + + + + + + + + + + + +async fn get_node_replicas(_token: A, path: Path) -> Result>, RestError> { + T::get_node_replicas(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_pool_replicas(_token: A, path: Path) -> Result>, RestError> { + T::get_node_pool_replicas(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_node_pool_replica(_token: A, path: Path) -> Result, RestError> { + T::get_node_pool_replica(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_pool_replica(_token: A, path: Path) -> Result, RestError> { + T::put_node_pool_replica(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_node_pool_replica(_token: A, path: Path) -> Result, RestError> { + T::del_node_pool_replica(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_node_pool_replica_share(_token: A, path: Path) -> Result, RestError> { + T::del_node_pool_replica_share(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_node_pool_replica_share(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::put_node_pool_replica_share(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.allowed_hosts)).await.map(Json) +} + + + + +async fn put_pool_replica(_token: A, path: Path) -> Result, RestError> { + T::put_pool_replica(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_pool_replica(_token: A, path: Path) -> Result, RestError> { + T::del_pool_replica(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_pool_replica_share(_token: A, path: Path) -> Result, RestError> { + T::del_pool_replica_share(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_pool_replica_share(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::put_pool_replica_share(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.allowed_hosts)).await.map(Json) +} + + + + +async fn get_replicas(_token: A) -> Result>, RestError> { + T::get_replicas().await.map(Json) +} + + + + +async fn get_replica(_token: A, path: Path) -> Result, RestError> { + T::get_replica(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/replicas_api/actix/server/mod.rs b/testgen/src/autogen/apis/replicas_api/actix/server/mod.rs new file mode 100644 index 000000000..fa6cb64c2 --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/actix/server/mod.rs @@ -0,0 +1,65 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Replicas { + + + + + async fn get_node_replicas(Path(id): Path) -> Result, RestError>; + + + + async fn get_node_pool_replicas(Path(node_id, pool_id): Path) -> Result, RestError>; + + + + async fn get_node_pool_replica(Path(node_id, pool_id, replica_id): Path) -> Result>; + + + + async fn put_node_pool_replica(Path(node_id, pool_id, replica_id): Path) -> Result>; + + + + async fn del_node_pool_replica(Path(node_id, pool_id, replica_id): Path) -> Result<(), RestError>; + + + + async fn del_node_pool_replica_share(Path(node_id, pool_id, replica_id): Path) -> Result<(), RestError>; + + + + async fn put_node_pool_replica_share(Path(node_id, pool_id, replica_id): Path, Query(allowed_hosts): Query>>) -> Result>; + + + + async fn put_pool_replica(Path(pool_id, replica_id): Path) -> Result>; + + + + async fn del_pool_replica(Path(pool_id, replica_id): Path) -> Result<(), RestError>; + + + + async fn del_pool_replica_share(Path(pool_id, replica_id): Path) -> Result<(), RestError>; + + + + async fn put_pool_replica_share(Path(pool_id, replica_id): Path, Query(allowed_hosts): Query>>) -> Result>; + + + + async fn get_replicas() -> Result, RestError>; + + + + async fn get_replica(Path(id): Path) -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/replicas_api/mod.rs b/testgen/src/autogen/apis/replicas_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/replicas_api/tower/client/mod.rs b/testgen/src/autogen/apis/replicas_api/tower/client/mod.rs new file mode 100644 index 000000000..c0c7340b9 --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/tower/client/mod.rs @@ -0,0 +1,1347 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct ReplicasClient { + configuration: Arc, +} + +impl ReplicasClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for ReplicasClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Replicas: Clone + Send + Sync { + + + + + async fn get_node_replicas(&self, id: &str) -> Result>, Error>; + + + + async fn get_node_pool_replicas(&self, node_id: &str, pool_id: &str) -> Result>, Error>; + + + + async fn get_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_node_pool_replica_share(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_node_pool_replica_share(&self, allowed_hosts: Option>, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_pool_replica_share(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_pool_replica_share(&self, allowed_hosts: Option>, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_replicas(&self, ) -> Result>, Error>; + + + + async fn get_replica(&self, id: &uuid::Uuid) -> Result, Error>; + + +} + +/// Same as `Replicas` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Replicas: Clone + Send + Sync { + + + + + async fn get_node_replicas(&self, id: &str) -> Result, super::Error>; + + + + async fn get_node_pool_replicas(&self, node_id: &str, pool_id: &str) -> Result, super::Error>; + + + + async fn get_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn put_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn del_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn del_node_pool_replica_share(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn put_node_pool_replica_share(&self, allowed_hosts: Option>, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn put_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn del_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn del_pool_replica_share(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn put_pool_replica_share(&self, allowed_hosts: Option>, pool_id: &str, replica_id: &uuid::Uuid) -> Result>; + + + + async fn get_replicas(&self, ) -> Result, super::Error>; + + + + async fn get_replica(&self, id: &uuid::Uuid) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::Replicas for ReplicasClient { + + + + + async fn get_node_replicas(&self, id: &str) -> Result, Error> { + + Replicas::get_node_replicas(self, id).await.map(|r| r.into_body()) + } + + + + async fn get_node_pool_replicas(&self, node_id: &str, pool_id: &str) -> Result, Error> { + + Replicas::get_node_pool_replicas(self, node_id, pool_id).await.map(|r| r.into_body()) + } + + + + async fn get_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + Replicas::get_node_pool_replica(self, node_id, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn put_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + Replicas::put_node_pool_replica(self, node_id, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn del_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + Replicas::del_node_pool_replica(self, node_id, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn del_node_pool_replica_share(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + Replicas::del_node_pool_replica_share(self, node_id, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn put_node_pool_replica_share(&self, allowed_hosts: Option>, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + Replicas::put_node_pool_replica_share(self, allowed_hosts, node_id, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn put_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + Replicas::put_pool_replica(self, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn del_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + Replicas::del_pool_replica(self, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn del_pool_replica_share(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result<(), Error> { + + Replicas::del_pool_replica_share(self, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn put_pool_replica_share(&self, allowed_hosts: Option>, pool_id: &str, replica_id: &uuid::Uuid) -> Result> { + + Replicas::put_pool_replica_share(self, allowed_hosts, pool_id, replica_id).await.map(|r| r.into_body()) + } + + + + async fn get_replicas(&self, ) -> Result, Error> { + + Replicas::get_replicas(self, ).await.map(|r| r.into_body()) + } + + + + async fn get_replica(&self, id: &uuid::Uuid) -> Result> { + + Replicas::get_replica(self, id).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Replicas for ReplicasClient { + + + + + async fn get_node_replicas(&self, id: &str) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{id}/replicas", configuration.base_path, id=crate::apis::urlencode(id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_pool_replicas(&self, node_id: &str, pool_id: &str) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Replica = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Replica = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_node_pool_replica(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_node_pool_replica_share(&self, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_node_pool_replica_share(&self, allowed_hosts: Option>, node_id: &str, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share/nvmf", configuration.base_path, node_id=crate::apis::urlencode(node_id), pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = allowed_hosts { + match query_params { + None => Some(format!("allowed-hosts={}", local_var_str.join(","))), + Some(previous) => Some(format!("{previous}&allowed-hosts={}", local_var_str.join(","))) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: String = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Replica = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_pool_replica(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_pool_replica_share(&self, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}/share", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_pool_replica_share(&self, allowed_hosts: Option>, pool_id: &str, replica_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/pools/{pool_id}/replicas/{replica_id}/share/nvmf", configuration.base_path, pool_id=crate::apis::urlencode(pool_id), replica_id=replica_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = allowed_hosts { + match query_params { + None => Some(format!("allowed-hosts={}", local_var_str.join(","))), + Some(previous) => Some(format!("{previous}&allowed-hosts={}", local_var_str.join(","))) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: String = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_replicas(&self, ) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/replicas", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_replica(&self, id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/replicas/{id}", configuration.base_path, id=id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Replica = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/replicas_api/tower/mod.rs b/testgen/src/autogen/apis/replicas_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/replicas_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/snapshots_api/actix/client/mod.rs b/testgen/src/autogen/apis/snapshots_api/actix/client/mod.rs new file mode 100644 index 000000000..4021a3f77 --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/actix/client/mod.rs @@ -0,0 +1,508 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct SnapshotsClient { + configuration: Rc, +} + +impl SnapshotsClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Snapshots: Clone { + + + + + async fn get_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn get_volume_snapshots(&self, max_entries: isize, starting_token: Option, volume_id: &uuid::Uuid) -> Result>; + + + + async fn get_volumes_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result>; + + + + async fn del_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn get_volumes_snapshots(&self, snapshot_id: Option<&uuid::Uuid>, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl Snapshots for SnapshotsClient { + + + + + async fn get_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots/{snapshot_id}", configuration.base_path, volume_id=volume_id.to_string(), snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots/{snapshot_id}", configuration.base_path, volume_id=volume_id.to_string(), snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots/{snapshot_id}", configuration.base_path, volume_id=volume_id.to_string(), snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_volume_snapshots(&self, max_entries: isize, starting_token: Option, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + query_params.push(("max_entries", max_entries.to_string())); + + + + + + if let Some(ref local_var_str) = starting_token { + query_params.push(("starting_token", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_volumes_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/snapshots/{snapshot_id}", configuration.base_path, snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/snapshots/{snapshot_id}", configuration.base_path, snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_volumes_snapshots(&self, snapshot_id: Option<&uuid::Uuid>, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/snapshots", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = snapshot_id { + query_params.push(("snapshot_id", local_var_str.to_string())); + } + + + + + if let Some(ref local_var_str) = volume_id { + query_params.push(("volume_id", local_var_str.to_string())); + } + + + + query_params.push(("max_entries", max_entries.to_string())); + + + + + + if let Some(ref local_var_str) = starting_token { + query_params.push(("starting_token", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/snapshots_api/actix/mod.rs b/testgen/src/autogen/apis/snapshots_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/snapshots_api/actix/server/handlers.rs b/testgen/src/autogen/apis/snapshots_api/actix/server/handlers.rs new file mode 100644 index 000000000..2c95ef64e --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/actix/server/handlers.rs @@ -0,0 +1,177 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + snapshots_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Snapshots resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/volumes/{volume_id}/snapshots/{snapshot_id}") + .name("get_volume_snapshot") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_volume_snapshot::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/snapshots/{snapshot_id}") + .name("put_volume_snapshot") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume_snapshot::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/snapshots/{snapshot_id}") + .name("del_volume_snapshot") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_volume_snapshot::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/snapshots") + .name("get_volume_snapshots") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_volume_snapshots::)) + ) + + .service( + actix_web::web::resource("/volumes/snapshots/{snapshot_id}") + .name("get_volumes_snapshot") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_volumes_snapshot::)) + ) + + .service( + actix_web::web::resource("/volumes/snapshots/{snapshot_id}") + .name("del_snapshot") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_snapshot::)) + ) + + .service( + actix_web::web::resource("/volumes/snapshots") + .name("get_volumes_snapshots") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_volumes_snapshots::)) + ); + + +} + + + + + + + + + + +#[derive(serde::Deserialize)] +struct get_volume_snapshotsQueryParams { + + + #[serde(rename = "max_entries")] + pub max_entries: isize, + + + #[serde(rename = "starting_token", default, skip_serializing_if = "Option::is_none")] + pub starting_token: Option, + +} + + + + + + + +#[derive(serde::Deserialize)] +struct get_volumes_snapshotsQueryParams { + + + #[serde(rename = "snapshot_id", default, skip_serializing_if = "Option::is_none")] + pub snapshot_id: Option, + + + #[serde(rename = "volume_id", default, skip_serializing_if = "Option::is_none")] + pub volume_id: Option, + + + #[serde(rename = "max_entries")] + pub max_entries: isize, + + + #[serde(rename = "starting_token", default, skip_serializing_if = "Option::is_none")] + pub starting_token: Option, + +} + + + + + + + + +async fn get_volume_snapshot(_token: A, path: Path) -> Result, RestError> { + T::get_volume_snapshot(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_volume_snapshot(_token: A, path: Path) -> Result, RestError> { + T::put_volume_snapshot(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_volume_snapshot(_token: A, path: Path) -> Result, RestError> { + T::del_volume_snapshot(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_volume_snapshots(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::get_volume_snapshots(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.max_entries, query.starting_token)).await.map(Json) +} + + + + +async fn get_volumes_snapshot(_token: A, path: Path) -> Result, RestError> { + T::get_volumes_snapshot(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_snapshot(_token: A, path: Path) -> Result, RestError> { + T::del_snapshot(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_volumes_snapshots(_token: A, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::get_volumes_snapshots(crate::apis::actix_server::Query(query.snapshot_id, query.volume_id, query.max_entries, query.starting_token)).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/snapshots_api/actix/server/mod.rs b/testgen/src/autogen/apis/snapshots_api/actix/server/mod.rs new file mode 100644 index 000000000..bdd896917 --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/actix/server/mod.rs @@ -0,0 +1,41 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Snapshots { + + + + + async fn get_volume_snapshot(Path(volume_id, snapshot_id): Path) -> Result>; + + + + async fn put_volume_snapshot(Path(volume_id, snapshot_id): Path) -> Result>; + + + + async fn del_volume_snapshot(Path(volume_id, snapshot_id): Path) -> Result<(), RestError>; + + + + async fn get_volume_snapshots(Path(volume_id): Path, Query(max_entries, starting_token): Query>) -> Result>; + + + + async fn get_volumes_snapshot(Path(snapshot_id): Path) -> Result>; + + + + async fn del_snapshot(Path(snapshot_id): Path) -> Result<(), RestError>; + + + + async fn get_volumes_snapshots(Query(snapshot_id, volume_id, max_entries, starting_token): Query, Option, isize, Option>) -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/snapshots_api/mod.rs b/testgen/src/autogen/apis/snapshots_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/snapshots_api/tower/client/mod.rs b/testgen/src/autogen/apis/snapshots_api/tower/client/mod.rs new file mode 100644 index 000000000..c392612f6 --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/tower/client/mod.rs @@ -0,0 +1,811 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct SnapshotsClient { + configuration: Arc, +} + +impl SnapshotsClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for SnapshotsClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Snapshots: Clone + Send + Sync { + + + + + async fn get_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_volume_snapshots(&self, max_entries: isize, starting_token: Option, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_volumes_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_volumes_snapshots(&self, snapshot_id: Option<&uuid::Uuid>, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result, Error>; + + +} + +/// Same as `Snapshots` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Snapshots: Clone + Send + Sync { + + + + + async fn get_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn get_volume_snapshots(&self, max_entries: isize, starting_token: Option, volume_id: &uuid::Uuid) -> Result>; + + + + async fn get_volumes_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result>; + + + + async fn del_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn get_volumes_snapshots(&self, snapshot_id: Option<&uuid::Uuid>, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::Snapshots for SnapshotsClient { + + + + + async fn get_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result> { + + Snapshots::get_volume_snapshot(self, volume_id, snapshot_id).await.map(|r| r.into_body()) + } + + + + async fn put_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result> { + + Snapshots::put_volume_snapshot(self, volume_id, snapshot_id).await.map(|r| r.into_body()) + } + + + + async fn del_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result<(), Error> { + + Snapshots::del_volume_snapshot(self, volume_id, snapshot_id).await.map(|r| r.into_body()) + } + + + + async fn get_volume_snapshots(&self, max_entries: isize, starting_token: Option, volume_id: &uuid::Uuid) -> Result> { + + Snapshots::get_volume_snapshots(self, max_entries, starting_token, volume_id).await.map(|r| r.into_body()) + } + + + + async fn get_volumes_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result> { + + Snapshots::get_volumes_snapshot(self, snapshot_id).await.map(|r| r.into_body()) + } + + + + async fn del_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result<(), Error> { + + Snapshots::del_snapshot(self, snapshot_id).await.map(|r| r.into_body()) + } + + + + async fn get_volumes_snapshots(&self, snapshot_id: Option<&uuid::Uuid>, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result> { + + Snapshots::get_volumes_snapshots(self, snapshot_id, volume_id, max_entries, starting_token).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Snapshots for SnapshotsClient { + + + + + async fn get_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots/{snapshot_id}", configuration.base_path, volume_id=volume_id.to_string(), snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::VolumeSnapshot = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots/{snapshot_id}", configuration.base_path, volume_id=volume_id.to_string(), snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::VolumeSnapshot = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_volume_snapshot(&self, volume_id: &uuid::Uuid, snapshot_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots/{snapshot_id}", configuration.base_path, volume_id=volume_id.to_string(), snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_volume_snapshots(&self, max_entries: isize, starting_token: Option, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/snapshots", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + let query_params: Option = None; + + + let query_params = match query_params { + None => Some(format!("max_entries={}", max_entries.to_string())), + Some(previous) => Some(format!("{previous}&max_entries={}", max_entries.to_string())) + }; + + + + + + let query_params = if let Some(local_var_str) = starting_token { + match query_params { + None => Some(format!("starting_token={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&starting_token={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::VolumeSnapshots = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_volumes_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/snapshots/{snapshot_id}", configuration.base_path, snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::VolumeSnapshot = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_snapshot(&self, snapshot_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/snapshots/{snapshot_id}", configuration.base_path, snapshot_id=snapshot_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_volumes_snapshots(&self, snapshot_id: Option<&uuid::Uuid>, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/snapshots", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = snapshot_id { + match query_params { + None => Some(format!("snapshot_id={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&snapshot_id={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + + + let query_params = if let Some(local_var_str) = volume_id { + match query_params { + None => Some(format!("volume_id={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&volume_id={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + + let query_params = match query_params { + None => Some(format!("max_entries={}", max_entries.to_string())), + Some(previous) => Some(format!("{previous}&max_entries={}", max_entries.to_string())) + }; + + + + + + let query_params = if let Some(local_var_str) = starting_token { + match query_params { + None => Some(format!("starting_token={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&starting_token={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::VolumeSnapshots = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/snapshots_api/tower/mod.rs b/testgen/src/autogen/apis/snapshots_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/snapshots_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/specs_api/actix/client/mod.rs b/testgen/src/autogen/apis/specs_api/actix/client/mod.rs new file mode 100644 index 000000000..6fe4c8962 --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/actix/client/mod.rs @@ -0,0 +1,96 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct SpecsClient { + configuration: Rc, +} + +impl SpecsClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Specs: Clone { + + + + + async fn get_specs(&self, ) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl Specs for SpecsClient { + + + + + async fn get_specs(&self, ) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/specs", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/specs_api/actix/mod.rs b/testgen/src/autogen/apis/specs_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/specs_api/actix/server/handlers.rs b/testgen/src/autogen/apis/specs_api/actix/server/handlers.rs new file mode 100644 index 000000000..68c358655 --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/actix/server/handlers.rs @@ -0,0 +1,45 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + specs_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Specs resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/specs") + .name("get_specs") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_specs::)) + ); + + +} + + + + + + + + + + + +async fn get_specs(_token: A) -> Result, RestError> { + T::get_specs().await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/specs_api/actix/server/mod.rs b/testgen/src/autogen/apis/specs_api/actix/server/mod.rs new file mode 100644 index 000000000..c3fe71671 --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/actix/server/mod.rs @@ -0,0 +1,17 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Specs { + + + + + async fn get_specs() -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/specs_api/mod.rs b/testgen/src/autogen/apis/specs_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/specs_api/tower/client/mod.rs b/testgen/src/autogen/apis/specs_api/tower/client/mod.rs new file mode 100644 index 000000000..2e70f1948 --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/tower/client/mod.rs @@ -0,0 +1,157 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct SpecsClient { + configuration: Arc, +} + +impl SpecsClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for SpecsClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Specs: Clone + Send + Sync { + + + + + async fn get_specs(&self, ) -> Result, Error>; + + +} + +/// Same as `Specs` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Specs: Clone + Send + Sync { + + + + + async fn get_specs(&self, ) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::Specs for SpecsClient { + + + + + async fn get_specs(&self, ) -> Result> { + + Specs::get_specs(self, ).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Specs for SpecsClient { + + + + + async fn get_specs(&self, ) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/specs", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Specs = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/specs_api/tower/mod.rs b/testgen/src/autogen/apis/specs_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/specs_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/volumes_api/actix/client/mod.rs b/testgen/src/autogen/apis/volumes_api/actix/client/mod.rs new file mode 100644 index 000000000..d342168fa --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/actix/client/mod.rs @@ -0,0 +1,934 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct VolumesClient { + configuration: Rc, +} + +impl VolumesClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Volumes: Clone { + + + + + async fn get_volumes(&self, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result>; + + + + async fn get_volume(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume(&self, volume_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn get_rebuild_history(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_replica_count(&self, volume_id: &uuid::Uuid, replica_count: u8) -> Result>; + + + + async fn put_volume_property(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_target(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume_target(&self, force: Option, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_size(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume_shutdown_targets(&self, volume_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn put_volume_share(&self, frontend_host: Option<&str>, volume_id: &uuid::Uuid, protocol: &str) -> Result>; + + + + async fn del_share(&self, volume_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn put_snapshot_volume(&self, snapshot_id: &uuid::Uuid, volume_id: &uuid::Uuid) -> Result>; + + +} + +#[async_trait::async_trait(?Send)] +impl Volumes for VolumesClient { + + + + + async fn get_volumes(&self, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes", configuration.base_path); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = volume_id { + query_params.push(("volume_id", local_var_str.to_string())); + } + + + + query_params.push(("max_entries", max_entries.to_string())); + + + + + + if let Some(ref local_var_str) = starting_token { + query_params.push(("starting_token", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_volume(&self, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume(&self, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_volume(&self, volume_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn get_rebuild_history(&self, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/rebuild-history", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume_replica_count(&self, volume_id: &uuid::Uuid, replica_count: u8) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/replica_count/{replica_count}", configuration.base_path, volume_id=volume_id.to_string(), replica_count=replica_count.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume_property(&self, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/property", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume_target(&self, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/target", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_volume_target(&self, force: Option, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/target", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = force { + query_params.push(("force", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume_size(&self, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/size", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_volume_shutdown_targets(&self, volume_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/shutdown_targets", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_volume_share(&self, frontend_host: Option<&str>, volume_id: &uuid::Uuid, protocol: &str) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/share/{protocol}", configuration.base_path, volume_id=volume_id.to_string(), protocol=crate::apis::urlencode(protocol)); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + + if let Some(ref local_var_str) = frontend_host { + query_params.push(("frontend_host", local_var_str.to_string())); + } + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_share(&self, volume_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/volumes{volume_id}/share", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_snapshot_volume(&self, snapshot_id: &uuid::Uuid, volume_id: &uuid::Uuid) -> Result> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/snapshots/{snapshot_id}/volumes/{volume_id}", configuration.base_path, snapshot_id=snapshot_id.to_string(), volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/volumes_api/actix/mod.rs b/testgen/src/autogen/apis/volumes_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/volumes_api/actix/server/handlers.rs b/testgen/src/autogen/apis/volumes_api/actix/server/handlers.rs new file mode 100644 index 000000000..2ff5733ca --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/actix/server/handlers.rs @@ -0,0 +1,291 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + volumes_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Volumes resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/volumes") + .name("get_volumes") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_volumes::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}") + .name("get_volume") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_volume::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}") + .name("put_volume") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}") + .name("del_volume") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_volume::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/rebuild-history") + .name("get_rebuild_history") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_rebuild_history::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/replica_count/{replica_count}") + .name("put_volume_replica_count") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume_replica_count::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/property") + .name("put_volume_property") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume_property::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/target") + .name("put_volume_target") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume_target::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/target") + .name("del_volume_target") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_volume_target::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/size") + .name("put_volume_size") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume_size::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/shutdown_targets") + .name("del_volume_shutdown_targets") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_volume_shutdown_targets::)) + ) + + .service( + actix_web::web::resource("/volumes/{volume_id}/share/{protocol}") + .name("put_volume_share") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_volume_share::)) + ) + + .service( + actix_web::web::resource("/volumes{volume_id}/share") + .name("del_share") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_share::)) + ) + + .service( + actix_web::web::resource("/snapshots/{snapshot_id}/volumes/{volume_id}") + .name("put_snapshot_volume") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_snapshot_volume::)) + ); + + +} + + + + +#[derive(serde::Deserialize)] +struct get_volumesQueryParams { + + + #[serde(rename = "volume_id", default, skip_serializing_if = "Option::is_none")] + pub volume_id: Option, + + + #[serde(rename = "max_entries")] + pub max_entries: isize, + + + #[serde(rename = "starting_token", default, skip_serializing_if = "Option::is_none")] + pub starting_token: Option, + +} + + + + + + + + + + + + + + + + + +#[derive(serde::Deserialize)] +struct del_volume_targetQueryParams { + + + #[serde(rename = "force", default, skip_serializing_if = "Option::is_none")] + pub force: Option, + +} + + + + + + + +#[derive(serde::Deserialize)] +struct put_volume_shareQueryParams { + + + #[serde(rename = "frontend_host", default, skip_serializing_if = "Option::is_none")] + pub frontend_host: Option, + +} + + + + + + + + + + + + +async fn get_volumes(_token: A, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::get_volumes(crate::apis::actix_server::Query(query.volume_id, query.max_entries, query.starting_token)).await.map(Json) +} + + + + +async fn get_volume(_token: A, path: Path) -> Result, RestError> { + T::get_volume(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_volume(_token: A, path: Path) -> Result, RestError> { + T::put_volume(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_volume(_token: A, path: Path) -> Result, RestError> { + T::del_volume(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn get_rebuild_history(_token: A, path: Path) -> Result, RestError> { + T::get_rebuild_history(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_volume_replica_count(_token: A, path: Path) -> Result, RestError> { + T::put_volume_replica_count(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_volume_property(_token: A, path: Path) -> Result, RestError> { + T::put_volume_property(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_volume_target(_token: A, path: Path) -> Result, RestError> { + T::put_volume_target(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_volume_target(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::del_volume_target(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.force)).await.map(Json) +} + + + + +async fn put_volume_size(_token: A, path: Path) -> Result, RestError> { + T::put_volume_size(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn del_volume_shutdown_targets(_token: A, path: Path) -> Result, RestError> { + T::del_volume_shutdown_targets(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_volume_share(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::put_volume_share(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.frontend_host)).await.map(Json) +} + + + + +async fn del_share(_token: A, path: Path) -> Result, RestError> { + T::del_share(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_snapshot_volume(_token: A, path: Path) -> Result, RestError> { + T::put_snapshot_volume(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/volumes_api/actix/server/mod.rs b/testgen/src/autogen/apis/volumes_api/actix/server/mod.rs new file mode 100644 index 000000000..287086789 --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/actix/server/mod.rs @@ -0,0 +1,69 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Volumes { + + + + + async fn get_volumes(Query(volume_id, max_entries, starting_token): Query, isize, Option>) -> Result>; + + + + async fn get_volume(Path(volume_id): Path) -> Result>; + + + + async fn put_volume(Path(volume_id): Path) -> Result>; + + + + async fn del_volume(Path(volume_id): Path) -> Result<(), RestError>; + + + + async fn get_rebuild_history(Path(volume_id): Path) -> Result>; + + + + async fn put_volume_replica_count(Path(volume_id, replica_count): Path) -> Result>; + + + + async fn put_volume_property(Path(volume_id): Path) -> Result>; + + + + async fn put_volume_target(Path(volume_id): Path) -> Result>; + + + + async fn del_volume_target(Path(volume_id): Path, Query(force): Query>) -> Result>; + + + + async fn put_volume_size(Path(volume_id): Path) -> Result>; + + + + async fn del_volume_shutdown_targets(Path(volume_id): Path) -> Result<(), RestError>; + + + + async fn put_volume_share(Path(volume_id, protocol): Path, Query(frontend_host): Query>) -> Result>; + + + + async fn del_share(Path(volume_id): Path) -> Result<(), RestError>; + + + + async fn put_snapshot_volume(Path(snapshot_id, volume_id): Path) -> Result>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/volumes_api/mod.rs b/testgen/src/autogen/apis/volumes_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/volumes_api/tower/client/mod.rs b/testgen/src/autogen/apis/volumes_api/tower/client/mod.rs new file mode 100644 index 000000000..ead8b9b9b --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/tower/client/mod.rs @@ -0,0 +1,1482 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct VolumesClient { + configuration: Arc, +} + +impl VolumesClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for VolumesClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Volumes: Clone + Send + Sync { + + + + + async fn get_volumes(&self, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result, Error>; + + + + async fn get_volume(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_volume(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_volume(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn get_rebuild_history(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_volume_replica_count(&self, volume_id: &uuid::Uuid, replica_count: u8) -> Result, Error>; + + + + async fn put_volume_property(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_volume_target(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_volume_target(&self, force: Option, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_volume_size(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_volume_shutdown_targets(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_volume_share(&self, frontend_host: Option<&str>, volume_id: &uuid::Uuid, protocol: &str) -> Result, Error>; + + + + async fn del_share(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_snapshot_volume(&self, snapshot_id: &uuid::Uuid, volume_id: &uuid::Uuid) -> Result, Error>; + + +} + +/// Same as `Volumes` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Volumes: Clone + Send + Sync { + + + + + async fn get_volumes(&self, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result>; + + + + async fn get_volume(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume(&self, volume_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn get_rebuild_history(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_replica_count(&self, volume_id: &uuid::Uuid, replica_count: u8) -> Result>; + + + + async fn put_volume_property(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_target(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume_target(&self, force: Option, volume_id: &uuid::Uuid) -> Result>; + + + + async fn put_volume_size(&self, volume_id: &uuid::Uuid) -> Result>; + + + + async fn del_volume_shutdown_targets(&self, volume_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn put_volume_share(&self, frontend_host: Option<&str>, volume_id: &uuid::Uuid, protocol: &str) -> Result>; + + + + async fn del_share(&self, volume_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn put_snapshot_volume(&self, snapshot_id: &uuid::Uuid, volume_id: &uuid::Uuid) -> Result>; + + + } +} + +#[async_trait::async_trait] +impl direct::Volumes for VolumesClient { + + + + + async fn get_volumes(&self, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result> { + + Volumes::get_volumes(self, volume_id, max_entries, starting_token).await.map(|r| r.into_body()) + } + + + + async fn get_volume(&self, volume_id: &uuid::Uuid) -> Result> { + + Volumes::get_volume(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_volume(&self, volume_id: &uuid::Uuid) -> Result> { + + Volumes::put_volume(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn del_volume(&self, volume_id: &uuid::Uuid) -> Result<(), Error> { + + Volumes::del_volume(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn get_rebuild_history(&self, volume_id: &uuid::Uuid) -> Result> { + + Volumes::get_rebuild_history(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_volume_replica_count(&self, volume_id: &uuid::Uuid, replica_count: u8) -> Result> { + + Volumes::put_volume_replica_count(self, volume_id, replica_count).await.map(|r| r.into_body()) + } + + + + async fn put_volume_property(&self, volume_id: &uuid::Uuid) -> Result> { + + Volumes::put_volume_property(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_volume_target(&self, volume_id: &uuid::Uuid) -> Result> { + + Volumes::put_volume_target(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn del_volume_target(&self, force: Option, volume_id: &uuid::Uuid) -> Result> { + + Volumes::del_volume_target(self, force, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_volume_size(&self, volume_id: &uuid::Uuid) -> Result> { + + Volumes::put_volume_size(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn del_volume_shutdown_targets(&self, volume_id: &uuid::Uuid) -> Result<(), Error> { + + Volumes::del_volume_shutdown_targets(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_volume_share(&self, frontend_host: Option<&str>, volume_id: &uuid::Uuid, protocol: &str) -> Result> { + + Volumes::put_volume_share(self, frontend_host, volume_id, protocol).await.map(|r| r.into_body()) + } + + + + async fn del_share(&self, volume_id: &uuid::Uuid) -> Result<(), Error> { + + Volumes::del_share(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_snapshot_volume(&self, snapshot_id: &uuid::Uuid, volume_id: &uuid::Uuid) -> Result> { + + Volumes::put_snapshot_volume(self, snapshot_id, volume_id).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Volumes for VolumesClient { + + + + + async fn get_volumes(&self, volume_id: Option<&uuid::Uuid>, max_entries: isize, starting_token: Option) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes", configuration.base_path); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = volume_id { + match query_params { + None => Some(format!("volume_id={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&volume_id={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + + let query_params = match query_params { + None => Some(format!("max_entries={}", max_entries.to_string())), + Some(previous) => Some(format!("{previous}&max_entries={}", max_entries.to_string())) + }; + + + + + + let query_params = if let Some(local_var_str) = starting_token { + match query_params { + None => Some(format!("starting_token={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&starting_token={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volumes = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_volume(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_volume(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn get_rebuild_history(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/rebuild-history", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: serde_json::Value = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume_replica_count(&self, volume_id: &uuid::Uuid, replica_count: u8) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/replica_count/{replica_count}", configuration.base_path, volume_id=volume_id.to_string(), replica_count=replica_count.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume_property(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/property", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume_target(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/target", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_volume_target(&self, force: Option, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/target", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = force { + match query_params { + None => Some(format!("force={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&force={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume_size(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/size", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_volume_shutdown_targets(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/shutdown_targets", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_volume_share(&self, frontend_host: Option<&str>, volume_id: &uuid::Uuid, protocol: &str) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes/{volume_id}/share/{protocol}", configuration.base_path, volume_id=volume_id.to_string(), protocol=crate::apis::urlencode(protocol)); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + let query_params: Option = None; + + + + let query_params = if let Some(local_var_str) = frontend_host { + match query_params { + None => Some(format!("frontend_host={}", local_var_str.to_string())), + Some(previous) => Some(format!("{previous}&frontend_host={}", local_var_str.to_string())) + } + } else { + query_params + }; + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: String = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_share(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/volumes{volume_id}/share", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_snapshot_volume(&self, snapshot_id: &uuid::Uuid, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/snapshots/{snapshot_id}/volumes/{volume_id}", configuration.base_path, snapshot_id=snapshot_id.to_string(), volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: crate::models::Volume = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/volumes_api/tower/mod.rs b/testgen/src/autogen/apis/volumes_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/volumes_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/apis/watches_api/actix/client/mod.rs b/testgen/src/autogen/apis/watches_api/actix/client/mod.rs new file mode 100644 index 000000000..caa909213 --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/actix/client/mod.rs @@ -0,0 +1,236 @@ +#![allow(clippy::vec_init_then_push)] + +use crate::clients::actix::{ + configuration, Error, ResponseContent, ResponseContentUnexpected, +}; +use actix_web_opentelemetry::ClientExt; +use std::rc::Rc; + +#[derive(Clone)] +pub struct WatchesClient { + configuration: Rc, +} + +impl WatchesClient { + pub fn new(configuration: Rc) -> Self { + Self { + configuration, + } + } +} + +#[async_trait::async_trait(?Send)] +#[dyn_clonable::clonable] +pub trait Watches: Clone { + + + + + async fn get_watch_volume(&self, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn put_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), Error>; + + + + async fn del_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), Error>; + + +} + +#[async_trait::async_trait(?Send)] +impl Watches for WatchesClient { + + + + + async fn get_watch_volume(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/watches/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::GET, local_var_uri_str.as_str()); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn put_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/watches/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::PUT, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + query_params.push(("callback", callback.to_string())); + + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + + + async fn del_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), Error> { + + + let configuration = &self.configuration; + let local_var_client = &configuration.client; + + let local_var_uri_str = format!("{}/watches/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = local_var_client.request(awc::http::Method::DELETE, local_var_uri_str.as_str()); + + + let mut query_params = vec![]; + + + query_params.push(("callback", callback.to_string())); + + + + local_var_req_builder = local_var_req_builder.query(&query_params)?; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.insert_header((awc::http::header::USER_AGENT, local_var_user_agent.clone())); + } + + + + + + + + let mut local_var_resp = if configuration.trace_requests { + local_var_req_builder.trace_request().send().await + } else { + local_var_req_builder.send().await + }?; + + + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let local_var_content = local_var_resp.json::<()>().await?; + Ok(local_var_content) + + + + } else { + match local_var_resp.json::().await { + Ok(error) => Err(Error::ResponseError(ResponseContent { + status: local_var_status, + error, + })), + Err(_) => Err(Error::ResponseUnexpected(ResponseContentUnexpected { + status: local_var_status, + text: local_var_resp.json().await?, + })), + } + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/watches_api/actix/mod.rs b/testgen/src/autogen/apis/watches_api/actix/mod.rs new file mode 100644 index 000000000..97528c6de --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/actix/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix-client")] +pub mod client; +#[cfg(feature = "actix-server")] +pub mod server; \ No newline at end of file diff --git a/testgen/src/autogen/apis/watches_api/actix/server/handlers.rs b/testgen/src/autogen/apis/watches_api/actix/server/handlers.rs new file mode 100644 index 000000000..dd93b92cb --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/actix/server/handlers.rs @@ -0,0 +1,97 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::{ + actix::server::{deserialize_option_stringified_list, deserialize_stringified_list}, + apis::{ + actix_server::{Body, NoContent, RestError}, + watches_api::actix::server, + }, +}; +use actix_web::{ + web::{Json, Path, Query, ServiceConfig}, + FromRequest, HttpRequest, +}; + + +/// Configure handlers for the Watches resource +pub fn configure(cfg: &mut ServiceConfig) { + cfg + + + .service( + actix_web::web::resource("/watches/volumes/{volume_id}") + .name("get_watch_volume") + .guard(actix_web::guard::Get()) + .route(actix_web::web::get().to(get_watch_volume::)) + ) + + .service( + actix_web::web::resource("/watches/volumes/{volume_id}") + .name("put_watch_volume") + .guard(actix_web::guard::Put()) + .route(actix_web::web::put().to(put_watch_volume::)) + ) + + .service( + actix_web::web::resource("/watches/volumes/{volume_id}") + .name("del_watch_volume") + .guard(actix_web::guard::Delete()) + .route(actix_web::web::delete().to(del_watch_volume::)) + ); + + +} + + + + + + +#[derive(serde::Deserialize)] +struct put_watch_volumeQueryParams { + + + #[serde(rename = "callback")] + pub callback: String, + +} + + + +#[derive(serde::Deserialize)] +struct del_watch_volumeQueryParams { + + + #[serde(rename = "callback")] + pub callback: String, + +} + + + + + + + + +async fn get_watch_volume(_token: A, path: Path) -> Result>, RestError> { + T::get_watch_volume(crate::apis::actix_server::Path(path.into_inner())).await.map(Json) +} + + + + +async fn put_watch_volume(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::put_watch_volume(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.callback)).await.map(Json) +} + + + + +async fn del_watch_volume(_token: A, path: Path, query: Query) -> Result, RestError> { + let query = query.into_inner(); + T::del_watch_volume(crate::apis::actix_server::Path(path.into_inner()), crate::apis::actix_server::Query(query.callback)).await.map(Json) +} + + diff --git a/testgen/src/autogen/apis/watches_api/actix/server/mod.rs b/testgen/src/autogen/apis/watches_api/actix/server/mod.rs new file mode 100644 index 000000000..418540786 --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/actix/server/mod.rs @@ -0,0 +1,25 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] + +use crate::apis::actix_server::{Body, Path, Query, RestError}; +use actix_web::web::Json; + +#[async_trait::async_trait] +pub trait Watches { + + + + + async fn get_watch_volume(Path(volume_id): Path) -> Result, RestError>; + + + + async fn put_watch_volume(Path(volume_id): Path, Query(callback): Query) -> Result<(), RestError>; + + + + async fn del_watch_volume(Path(volume_id): Path, Query(callback): Query) -> Result<(), RestError>; + + +} + +pub mod handlers; \ No newline at end of file diff --git a/testgen/src/autogen/apis/watches_api/mod.rs b/testgen/src/autogen/apis/watches_api/mod.rs new file mode 100644 index 000000000..a1e0ccc37 --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/mod.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "actix")] +pub mod actix; +#[cfg(feature = "tower-hyper")] +pub mod tower; \ No newline at end of file diff --git a/testgen/src/autogen/apis/watches_api/tower/client/mod.rs b/testgen/src/autogen/apis/watches_api/tower/client/mod.rs new file mode 100644 index 000000000..1bdcbb347 --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/tower/client/mod.rs @@ -0,0 +1,379 @@ +#![allow(clippy::to_string_in_format_args)] + +use crate::clients::tower::{ + configuration, Error, RequestError, ResponseContent, ResponseContentUnexpected, ResponseError, +}; + +use hyper::service::Service; +use std::sync::Arc; +use tower::ServiceExt; + +pub struct WatchesClient { + configuration: Arc, +} + +impl WatchesClient { + pub fn new(configuration: Arc) -> Self { + Self { + configuration, + } + } +} +impl Clone for WatchesClient { + fn clone(&self) -> Self { + Self { + configuration: self.configuration.clone() + } + } +} + +#[async_trait::async_trait] +#[dyn_clonable::clonable] +pub trait Watches: Clone + Send + Sync { + + + + + async fn get_watch_volume(&self, volume_id: &uuid::Uuid) -> Result>, Error>; + + + + async fn put_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result, Error>; + + + + async fn del_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result, Error>; + + +} + +/// Same as `Watches` but it returns the result body directly. +pub mod direct { + #[async_trait::async_trait] + #[dyn_clonable::clonable] + pub trait Watches: Clone + Send + Sync { + + + + + async fn get_watch_volume(&self, volume_id: &uuid::Uuid) -> Result, super::Error>; + + + + async fn put_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), super::Error>; + + + + async fn del_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), super::Error>; + + + } +} + +#[async_trait::async_trait] +impl direct::Watches for WatchesClient { + + + + + async fn get_watch_volume(&self, volume_id: &uuid::Uuid) -> Result, Error> { + + Watches::get_watch_volume(self, volume_id).await.map(|r| r.into_body()) + } + + + + async fn put_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), Error> { + + Watches::put_watch_volume(self, callback, volume_id).await.map(|r| r.into_body()) + } + + + + async fn del_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result<(), Error> { + + Watches::del_watch_volume(self, callback, volume_id).await.map(|r| r.into_body()) + } + + +} + +#[async_trait::async_trait] +impl Watches for WatchesClient { + + + + + async fn get_watch_volume(&self, volume_id: &uuid::Uuid) -> Result>, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/watches/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::GET); + + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: Vec = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn put_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/watches/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::PUT); + + + let query_params: Option = None; + + + let query_params = match query_params { + None => Some(format!("callback={}", callback.to_string())), + Some(previous) => Some(format!("{previous}&callback={}", callback.to_string())) + }; + + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + + + async fn del_watch_volume(&self, callback: &str, volume_id: &uuid::Uuid) -> Result, Error> { + + let configuration = &self.configuration; + + let local_var_uri_str = format!("{}/watches/volumes/{volume_id}", configuration.base_path, volume_id=volume_id.to_string()); + let mut local_var_req_builder = hyper::Request::builder().method(hyper::Method::DELETE); + + + let query_params: Option = None; + + + let query_params = match query_params { + None => Some(format!("callback={}", callback.to_string())), + Some(previous) => Some(format!("{previous}&callback={}", callback.to_string())) + }; + + + + let local_var_uri_str = match query_params { + None => local_var_uri_str, + Some(params) => format!("{local_var_uri_str}?{params}") + }; + + + + + if let Some(ref local_var_user_agent) = configuration.user_agent { + local_var_req_builder = local_var_req_builder.header(hyper::header::USER_AGENT, local_var_user_agent.clone()); + } + + + + + + + + let body = hyper::Body::empty(); + + let request = local_var_req_builder.uri(local_var_uri_str).header("content-type", "application/json").body(body).map_err(RequestError::BuildRequest)?; + + let local_var_resp = { + let mut client_service = configuration.client_service.lock().await.clone(); + client_service + .ready() + .await + .map_err(RequestError::NotReady)? + .call(request) + .await + .map_err(RequestError::Request)? + }; + let local_var_status = local_var_resp.status(); + + if local_var_status.is_success() { + + + + let body = hyper::body::to_bytes(local_var_resp.into_body()).await.map_err(|e| ResponseError::PayloadError { + status: local_var_status, + error: e, + })?; + let local_var_content: () = + serde_json::from_slice(&body).map_err(|e| { + ResponseError::Unexpected(ResponseContentUnexpected { + status: local_var_status, + text: e.to_string(), + }) + })?; + Ok(ResponseContent { status: local_var_status, body: local_var_content }) + + + + } else { + match hyper::body::to_bytes(local_var_resp.into_body()).await { + Ok(body) => match serde_json::from_slice::(&body) { + Ok(error) => Err(Error::Response(ResponseError::Expected(ResponseContent { + status: local_var_status, + body: error, + }))), + Err(_) => Err(Error::Response(ResponseError::Unexpected( + ResponseContentUnexpected { + status: local_var_status, + text: String::from_utf8_lossy(&body).to_string(), + }, + ))), + }, + Err(error) => Err(Error::Response(ResponseError::PayloadError { + status: local_var_status, + error, + })), + } + + } + } + + +} \ No newline at end of file diff --git a/testgen/src/autogen/apis/watches_api/tower/mod.rs b/testgen/src/autogen/apis/watches_api/tower/mod.rs new file mode 100644 index 000000000..1b623f849 --- /dev/null +++ b/testgen/src/autogen/apis/watches_api/tower/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "tower-client")] +pub mod client; \ No newline at end of file diff --git a/testgen/src/autogen/clients/mod.rs b/testgen/src/autogen/clients/mod.rs new file mode 100644 index 000000000..3ee07f2de --- /dev/null +++ b/testgen/src/autogen/clients/mod.rs @@ -0,0 +1,9 @@ +#[cfg(feature = "actix-client")] +pub mod actix; +#[cfg(feature = "tower-client")] +pub mod tower; + +// Enable once we move to rust-2021 +// #[cfg(all(feature = "tower-client-rls", feature = "tower-client-tls"))] +// compile_error!("feature \"tower-client-rls\" and feature \"tower-client-tls\" cannot be enabled +// at the same time"); \ No newline at end of file diff --git a/testgen/src/autogen/clients/tower/body.rs b/testgen/src/autogen/clients/tower/body.rs new file mode 100644 index 000000000..a13bd7c75 --- /dev/null +++ b/testgen/src/autogen/clients/tower/body.rs @@ -0,0 +1,46 @@ +//! Kube-builder convertion from `tower_http::trace::ResponseBody` to `hyper::Body` +//! + +use std::{ + pin::Pin, + task::{Context, Poll}, +}; + +use futures::stream::Stream; +use http_body::Body; +use pin_project::pin_project; + +// Wrap `http_body::Body` to implement `Stream`. +#[pin_project] +pub struct IntoStream { + #[pin] + body: B, +} + +impl IntoStream { + pub(crate) fn new(body: B) -> Self { + Self { body } + } +} + +impl Stream for IntoStream +where + B: Body, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().body.poll_data(cx) + } +} + +pub trait BodyStreamExt: Body { + fn into_stream(self) -> IntoStream + where + Self: Sized, + { + IntoStream::new(self) + } +} + +impl BodyStreamExt for T where T: Body {} \ No newline at end of file diff --git a/testgen/src/autogen/clients/tower/configuration.rs b/testgen/src/autogen/clients/tower/configuration.rs new file mode 100644 index 000000000..c7cac2cd4 --- /dev/null +++ b/testgen/src/autogen/clients/tower/configuration.rs @@ -0,0 +1,485 @@ +#![allow(clippy::type_complexity)] +use super::body::BodyStreamExt; + +pub use hyper::{body, service::Service, Body, Request, Response, Uri}; + +use std::{sync::Arc, time::Duration}; +use tokio::sync::Mutex; +use tower::{util::BoxCloneService, Layer, ServiceExt}; + +#[cfg(feature = "tower-trace")] +use opentelemetry::global; +#[cfg(feature = "tower-trace")] +use opentelemetry_http::HeaderInjector; + +#[cfg(all(feature = "tower-client-rls", not(feature = "tower-client-tls")))] +use rustls::{ + client::{ServerCertVerified, ServerCertVerifier}, + Certificate, Error as TLSError, +}; + +use tower_http::map_response_body::MapResponseBodyLayer; +#[cfg(feature = "tower-trace")] +use tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer}; + +#[cfg(feature = "tower-trace")] +use tracing::Span; +#[cfg(feature = "tower-trace")] +use tracing_opentelemetry::OpenTelemetrySpanExt; + +/// Tower Service Error +pub type BoxedError = Box; + +/// `ConfigurationBuilder` that can be used to build a `Configuration`. +#[derive(Clone)] +pub struct ConfigurationBuilder { + /// Timeout for each HTTP Request. + timeout: Option, + /// Bearer Access Token for bearer-configured routes. + bearer_token: Option, + /// OpenTel and Tracing layer. + #[cfg(feature = "tower-trace")] + tracing_layer: bool, + certificate: Option>, + concurrency_limit: Option, +} + +impl Default for ConfigurationBuilder { + fn default() -> Self { + Self { + timeout: Some(std::time::Duration::from_secs(5)), + bearer_token: None, + #[cfg(feature = "tower-trace")] + tracing_layer: true, + certificate: None, + concurrency_limit: None, + } + } +} + +impl ConfigurationBuilder { + /// Return a new `Self`. + pub fn new() -> Self { + Self::default() + } + /// Enable/Disable a request timeout layer with the given request timeout. + pub fn with_timeout>>(mut self, timeout: O) -> Self { + self.timeout = timeout.into(); + self + } + /// Enable/Disable the given request bearer token. + pub fn with_bearer_token(mut self, bearer_token: Option) -> Self { + self.bearer_token = bearer_token; + self + } + /// Add a request concurrency limit. + pub fn with_concurrency_limit(mut self, limit: Option) -> Self { + self.concurrency_limit = limit; + self + } + /// Add a PEM-format certificate file. + pub fn with_certificate(mut self, certificate: &[u8]) -> Self { + self.certificate = Some(certificate.to_vec()); + self + } + /// Enable/Disable the telemetry and tracing layer. + #[cfg(feature = "tower-trace")] + pub fn with_tracing(mut self, tracing_layer: bool) -> Self { + self.tracing_layer = tracing_layer; + self + } + /// Build a `Configuration` from the Self parameters. + pub fn build(self, uri: hyper::Uri) -> Result { + Configuration::new( + uri.to_string().parse().map_err(Error::UriToUrl)?, + self.timeout.unwrap(), + self.bearer_token, + self.certificate.as_ref().map(|c| &c[..]), + self.tracing_layer, + self.concurrency_limit, + ) + } + /// Build a `Configuration` from the Self parameters. + pub fn build_url(self, url: url::Url) -> Result { + Configuration::new( + url, + self.timeout.unwrap_or_else(|| Duration::from_secs(5)), + self.bearer_token, + self.certificate.as_ref().map(|c| &c[..]), + self.tracing_layer, + self.concurrency_limit, + ) + } + /// Build a `Configuration` from the Self parameters. + pub fn build_with_svc( + self, + uri: hyper::Uri, + client_service: S, + ) -> Result + where + S: Service, Response = Response> + Sync + Send + Clone + 'static, + S::Future: Send + 'static, + S::Error: Into + std::fmt::Debug, + { + #[cfg(feature = "tower-trace")] + let tracing_layer = self.tracing_layer; + #[cfg(not(feature = "tower-trace"))] + let tracing_layer = false; + Configuration::new_with_client( + uri, + client_service, + self.timeout, + self.bearer_token, + tracing_layer, + self.concurrency_limit, + ) + } +} + +/// Configuration used by the `ApiClient`. +#[derive(Clone)] +pub struct Configuration { + pub base_path: hyper::Uri, + pub user_agent: Option, + pub client_service: Arc, Response, BoxedError>>>, + pub basic_auth: Option, + pub oauth_access_token: Option, + pub bearer_access_token: Option, + pub api_key: Option, +} + +/// Basic authentication. +pub type BasicAuth = (String, Option); + +/// ApiKey used for ApiKey authentication. +#[derive(Debug, Clone)] +pub struct ApiKey { + pub prefix: Option, + pub key: String, +} + +/// Configuration creation Error. +#[derive(Debug)] +pub enum Error { + Certificate, + TlsConnector, + NoTracingFeature, + UrlToUri(hyper::http::uri::InvalidUri), + UriToUrl(url::ParseError), + AddingVersionPath(hyper::http::uri::InvalidUri), +} + +impl Configuration { + /// Return a new `ConfigurationBuilder`. + pub fn builder() -> ConfigurationBuilder { + ConfigurationBuilder::new() + } + + /// New `Self` with a provided client. + pub fn new_with_client( + mut url: hyper::Uri, + client_service: S, + timeout: Option, + bearer_access_token: Option, + trace_requests: bool, + concurrency_limit: Option, + ) -> Result + where + S: Service, Response = Response> + Sync + Send + Clone + 'static, + S::Future: Send + 'static, + S::Error: Into + std::fmt::Debug, + { + #[cfg(feature = "tower-trace")] + let tracing_layer = tower::ServiceBuilder::new() + .layer( + TraceLayer::new_for_http() + .make_span_with(|request: &Request| { + tracing::info_span!( + "HTTP", + http.method = %request.method(), + http.url = %request.uri(), + http.status_code = tracing::field::Empty, + otel.name = %format!("{} {}", request.method(), request.uri()), + otel.kind = "client", + otel.status_code = tracing::field::Empty, + ) + }) + // to silence the default trace + .on_request(|request: &Request, _span: &Span| { + tracing::trace!("started {} {}", request.method(), request.uri().path()) + }) + .on_response( + |response: &Response, _latency: std::time::Duration, span: &Span| { + let status = response.status(); + span.record("http.status_code", status.as_u16()); + if status.is_client_error() || status.is_server_error() { + span.record("otel.status_code", "ERROR"); + } + }, + ) + .on_body_chunk(()) + .on_failure( + |ec: ServerErrorsFailureClass, + _latency: std::time::Duration, + span: &Span| { + span.record("otel.status_code", "ERROR"); + match ec { + ServerErrorsFailureClass::StatusCode(status) => { + span.record("http.status_code", status.as_u16()); + tracing::debug!(status=%status, "failed to issue request") + } + ServerErrorsFailureClass::Error(err) => { + tracing::debug!(error=%err, "failed to issue request") + } + } + }, + ), + ) + // injects the telemetry context in the http headers + .layer(OpenTelContext::new()) + .into_inner(); + + url = format!("{}/v0", url.to_string().trim_end_matches('/')) + .parse() + .map_err(Error::AddingVersionPath)?; + + let backend_service = tower::ServiceBuilder::new() + .option_layer(timeout.map(tower::timeout::TimeoutLayer::new)) + // .option_layer( + // bearer_access_token.map(|b| tower_http::auth::AddAuthorizationLayer::bearer(&b)), + // ) + .service(client_service); + + let service_builder = tower::ServiceBuilder::new() + .option_layer(concurrency_limit.map(tower::limit::ConcurrencyLimitLayer::new)); + + match trace_requests { + false => Ok(Self::new_with_client_inner( + url, + service_builder.service(backend_service), + bearer_access_token, + )), + true => { + #[cfg(feature = "tower-trace")] + let result = Ok(Self::new_with_client_inner( + url, + service_builder + .layer(tracing_layer) + .service(backend_service), + bearer_access_token, + )); + #[cfg(not(feature = "tower-trace"))] + let result = Err(Error::NoTracingFeature {}); + result + } + } + } + + /// New `Self`. + pub fn new( + mut url: url::Url, + timeout: std::time::Duration, + bearer_access_token: Option, + certificate: Option<&[u8]>, + trace_requests: bool, + concurrency_limit: Option, + ) -> Result { + #[cfg(all(not(feature = "tower-client-tls"), feature = "tower-client-rls"))] + let client = { + match certificate { + None => { + let mut http = hyper::client::HttpConnector::new(); + + let tls = match url.scheme() == "https" { + true => { + http.enforce_http(false); + rustls::ClientConfig::builder() + .with_safe_defaults() + .with_custom_certificate_verifier(std::sync::Arc::new( + DisableServerCertVerifier {}, + )) + .with_no_client_auth() + } + false => rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(rustls::RootCertStore::empty()) + .with_no_client_auth(), + }; + + let connector = + hyper_rustls::HttpsConnector::from((http, std::sync::Arc::new(tls))); + hyper::Client::builder().build(connector) + } + Some(bytes) => { + let mut cert_file = std::io::BufReader::new(bytes); + let mut root_store = rustls::RootCertStore::empty(); + root_store.add_parsable_certificates( + &rustls_pemfile::certs(&mut cert_file).map_err(|_| Error::Certificate)?, + ); + let config = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store) + .with_no_client_auth(); + + let mut http = hyper::client::HttpConnector::new(); + http.enforce_http(false); + let connector = + hyper_rustls::HttpsConnector::from((http, std::sync::Arc::new(config))); + url.set_scheme("https").ok(); + hyper::Client::builder().build(connector) + } + } + }; + #[cfg(feature = "tower-client-tls")] + let client = { + match certificate { + None => { + let mut http = hyper_tls::HttpsConnector::new(); + if url.scheme() == "https" { + http.https_only(true); + } + + let tls = hyper_tls::native_tls::TlsConnector::builder() + .danger_accept_invalid_certs(true) + .build() + .map_err(|_| Error::TlsConnector)?; + let tls = tokio_native_tls::TlsConnector::from(tls); + + let connector = hyper_tls::HttpsConnector::from((http, tls)); + hyper::Client::builder().build(connector) + } + Some(bytes) => { + let certificate = hyper_tls::native_tls::Certificate::from_pem(bytes) + .map_err(|_| Error::Certificate)?; + + let tls = hyper_tls::native_tls::TlsConnector::builder() + .add_root_certificate(certificate) + .danger_accept_invalid_hostnames(true) + .disable_built_in_roots(true) + .build() + .map_err(|_| Error::TlsConnector)?; + let tls = tokio_native_tls::TlsConnector::from(tls); + + let mut http = hyper_tls::HttpsConnector::new(); + http.https_only(true); + let connector = hyper_tls::HttpsConnector::from((http, tls)); + url.set_scheme("https").ok(); + hyper::Client::builder().build(connector) + } + } + }; + + let uri = url.to_string().parse().map_err(Error::UrlToUri)?; + Self::new_with_client( + uri, + client, + Some(timeout), + bearer_access_token, + trace_requests, + concurrency_limit, + ) + } + + /// New `Self` with a provided client. + pub fn new_with_client_inner( + url: hyper::Uri, + client_service: S, + bearer_access_token: Option, + ) -> Self + where + S: Service, Response = Response> + Sync + Send + Clone + 'static, + S::Future: Send + 'static, + S::Error: Into + std::fmt::Debug, + B: http_body::Body + Send + 'static, + B::Error: std::error::Error + Send + Sync + 'static, + { + // Transform response body to `hyper::Body` and use type erased error to avoid type + // parameters. + let client_service = MapResponseBodyLayer::new(|b: B| Body::wrap_stream(b.into_stream())) + .layer(client_service) + .map_err(|e| e.into()); + let client_service = Arc::new(Mutex::new(BoxCloneService::new(client_service))); + Self { + base_path: url, + user_agent: None, + client_service, + basic_auth: None, + oauth_access_token: None, + bearer_access_token, + api_key: None, + } + } +} + +/// Add OpenTelemetry Span to the Http Headers. +#[cfg(feature = "tower-trace")] +pub struct OpenTelContext {} +#[cfg(feature = "tower-trace")] +impl OpenTelContext { + fn new() -> Self { + Self {} + } +} +#[cfg(feature = "tower-trace")] +impl Layer for OpenTelContext { + type Service = OpenTelContextService; + + fn layer(&self, service: S) -> Self::Service { + OpenTelContextService::new(service) + } +} + +/// OpenTelemetry Service that injects the current span into the Http Headers. +#[cfg(feature = "tower-trace")] +#[derive(Clone)] +pub struct OpenTelContextService { + service: S, +} +#[cfg(feature = "tower-trace")] +impl OpenTelContextService { + fn new(service: S) -> Self { + Self { service } + } +} + +#[cfg(feature = "tower-trace")] +impl Service> for OpenTelContextService +where + S: Service>, +{ + type Response = S::Response; + type Error = S::Error; + type Future = S::Future; + + fn poll_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.service.poll_ready(cx) + } + + fn call(&mut self, mut request: hyper::Request) -> Self::Future { + let cx = tracing::Span::current().context(); + global::get_text_map_propagator(|propagator| { + propagator.inject_context(&cx, &mut HeaderInjector(request.headers_mut())) + }); + self.service.call(request) + } +} + +#[cfg(all(feature = "tower-client-rls", not(feature = "tower-client-tls")))] +struct DisableServerCertVerifier {} +#[cfg(all(feature = "tower-client-rls", not(feature = "tower-client-tls")))] +impl ServerCertVerifier for DisableServerCertVerifier { + fn verify_server_cert( + &self, + _end_entity: &Certificate, + _intermediates: &[Certificate], + _server_name: &rustls::ServerName, + _scts: &mut dyn Iterator, + _ocsp_response: &[u8], + _now: std::time::SystemTime, + ) -> Result { + Ok(ServerCertVerified::assertion()) + } +} \ No newline at end of file diff --git a/testgen/src/autogen/clients/tower/mod.rs b/testgen/src/autogen/clients/tower/mod.rs new file mode 100644 index 000000000..d1376e02c --- /dev/null +++ b/testgen/src/autogen/clients/tower/mod.rs @@ -0,0 +1,688 @@ +mod body; +pub mod configuration; + +use configuration::BoxedError; +pub use configuration::Configuration; +pub use hyper::{self, StatusCode, Uri}; +pub use url::Url; + +use std::{error, fmt, ops::Deref, sync::Arc}; + +#[derive(Clone)] +pub struct ApiClient { + + + + app_nodes_api: Box, + + + + block_devices_api: Box, + + + + children_api: Box, + + + + json_grpc_api: Box, + + + + nexuses_api: Box, + + + + nodes_api: Box, + + + + pools_api: Box, + + + + replicas_api: Box, + + + + snapshots_api: Box, + + + + specs_api: Box, + + + + volumes_api: Box, + + + + watches_api: Box, + + + +} + +/// Same as `ApiClient` but returns the body directly. +pub mod direct { + #[derive(Clone)] + pub struct ApiClient { + + + + app_nodes_api: Box, + + + + block_devices_api: Box, + + + + children_api: Box, + + + + json_grpc_api: Box, + + + + nexuses_api: Box, + + + + nodes_api: Box, + + + + pools_api: Box, + + + + replicas_api: Box, + + + + snapshots_api: Box, + + + + specs_api: Box, + + + + volumes_api: Box, + + + + watches_api: Box, + + + + } + + impl ApiClient { + pub fn new(configuration: super::Configuration) -> ApiClient { + let rc = super::Arc::new(configuration); + + ApiClient { + + + + + app_nodes_api: Box::new(crate::apis::app_nodes_api::tower::client::AppNodesClient::new(rc.clone())), + + + + + + + block_devices_api: Box::new(crate::apis::block_devices_api::tower::client::BlockDevicesClient::new(rc.clone())), + + + + + + + children_api: Box::new(crate::apis::children_api::tower::client::ChildrenClient::new(rc.clone())), + + + + + + + json_grpc_api: Box::new(crate::apis::json_grpc_api::tower::client::JsonGrpcClient::new(rc.clone())), + + + + + + + nexuses_api: Box::new(crate::apis::nexuses_api::tower::client::NexusesClient::new(rc.clone())), + + + + + + + nodes_api: Box::new(crate::apis::nodes_api::tower::client::NodesClient::new(rc.clone())), + + + + + + + pools_api: Box::new(crate::apis::pools_api::tower::client::PoolsClient::new(rc.clone())), + + + + + + + replicas_api: Box::new(crate::apis::replicas_api::tower::client::ReplicasClient::new(rc.clone())), + + + + + + + snapshots_api: Box::new(crate::apis::snapshots_api::tower::client::SnapshotsClient::new(rc.clone())), + + + + + + + specs_api: Box::new(crate::apis::specs_api::tower::client::SpecsClient::new(rc.clone())), + + + + + + + volumes_api: Box::new(crate::apis::volumes_api::tower::client::VolumesClient::new(rc.clone())), + + + + + + + + watches_api: Box::new(crate::apis::watches_api::tower::client::WatchesClient::new(rc)), + + + + + } + } + + + + + pub fn app_nodes_api(&self) -> &dyn crate::apis::app_nodes_api::tower::client::direct::AppNodes { + self.app_nodes_api.as_ref() + } + + + + pub fn block_devices_api(&self) -> &dyn crate::apis::block_devices_api::tower::client::direct::BlockDevices { + self.block_devices_api.as_ref() + } + + + + pub fn children_api(&self) -> &dyn crate::apis::children_api::tower::client::direct::Children { + self.children_api.as_ref() + } + + + + pub fn json_grpc_api(&self) -> &dyn crate::apis::json_grpc_api::tower::client::direct::JsonGrpc { + self.json_grpc_api.as_ref() + } + + + + pub fn nexuses_api(&self) -> &dyn crate::apis::nexuses_api::tower::client::direct::Nexuses { + self.nexuses_api.as_ref() + } + + + + pub fn nodes_api(&self) -> &dyn crate::apis::nodes_api::tower::client::direct::Nodes { + self.nodes_api.as_ref() + } + + + + pub fn pools_api(&self) -> &dyn crate::apis::pools_api::tower::client::direct::Pools { + self.pools_api.as_ref() + } + + + + pub fn replicas_api(&self) -> &dyn crate::apis::replicas_api::tower::client::direct::Replicas { + self.replicas_api.as_ref() + } + + + + pub fn snapshots_api(&self) -> &dyn crate::apis::snapshots_api::tower::client::direct::Snapshots { + self.snapshots_api.as_ref() + } + + + + pub fn specs_api(&self) -> &dyn crate::apis::specs_api::tower::client::direct::Specs { + self.specs_api.as_ref() + } + + + + pub fn volumes_api(&self) -> &dyn crate::apis::volumes_api::tower::client::direct::Volumes { + self.volumes_api.as_ref() + } + + + + pub fn watches_api(&self) -> &dyn crate::apis::watches_api::tower::client::direct::Watches { + self.watches_api.as_ref() + } + + + + } +} + +impl ApiClient { + pub fn new(configuration: Configuration) -> ApiClient { + let rc = Arc::new(configuration); + + ApiClient { + + + + + app_nodes_api: Box::new(crate::apis::app_nodes_api::tower::client::AppNodesClient::new(rc.clone())), + + + + + + + block_devices_api: Box::new(crate::apis::block_devices_api::tower::client::BlockDevicesClient::new(rc.clone())), + + + + + + + children_api: Box::new(crate::apis::children_api::tower::client::ChildrenClient::new(rc.clone())), + + + + + + + json_grpc_api: Box::new(crate::apis::json_grpc_api::tower::client::JsonGrpcClient::new(rc.clone())), + + + + + + + nexuses_api: Box::new(crate::apis::nexuses_api::tower::client::NexusesClient::new(rc.clone())), + + + + + + + nodes_api: Box::new(crate::apis::nodes_api::tower::client::NodesClient::new(rc.clone())), + + + + + + + pools_api: Box::new(crate::apis::pools_api::tower::client::PoolsClient::new(rc.clone())), + + + + + + + replicas_api: Box::new(crate::apis::replicas_api::tower::client::ReplicasClient::new(rc.clone())), + + + + + + + snapshots_api: Box::new(crate::apis::snapshots_api::tower::client::SnapshotsClient::new(rc.clone())), + + + + + + + specs_api: Box::new(crate::apis::specs_api::tower::client::SpecsClient::new(rc.clone())), + + + + + + + volumes_api: Box::new(crate::apis::volumes_api::tower::client::VolumesClient::new(rc.clone())), + + + + + + + + watches_api: Box::new(crate::apis::watches_api::tower::client::WatchesClient::new(rc)), + + + + + } + } + + + + + pub fn app_nodes_api(&self) -> &dyn crate::apis::app_nodes_api::tower::client::AppNodes { + self.app_nodes_api.as_ref() + } + + + + pub fn block_devices_api(&self) -> &dyn crate::apis::block_devices_api::tower::client::BlockDevices { + self.block_devices_api.as_ref() + } + + + + pub fn children_api(&self) -> &dyn crate::apis::children_api::tower::client::Children { + self.children_api.as_ref() + } + + + + pub fn json_grpc_api(&self) -> &dyn crate::apis::json_grpc_api::tower::client::JsonGrpc { + self.json_grpc_api.as_ref() + } + + + + pub fn nexuses_api(&self) -> &dyn crate::apis::nexuses_api::tower::client::Nexuses { + self.nexuses_api.as_ref() + } + + + + pub fn nodes_api(&self) -> &dyn crate::apis::nodes_api::tower::client::Nodes { + self.nodes_api.as_ref() + } + + + + pub fn pools_api(&self) -> &dyn crate::apis::pools_api::tower::client::Pools { + self.pools_api.as_ref() + } + + + + pub fn replicas_api(&self) -> &dyn crate::apis::replicas_api::tower::client::Replicas { + self.replicas_api.as_ref() + } + + + + pub fn snapshots_api(&self) -> &dyn crate::apis::snapshots_api::tower::client::Snapshots { + self.snapshots_api.as_ref() + } + + + + pub fn specs_api(&self) -> &dyn crate::apis::specs_api::tower::client::Specs { + self.specs_api.as_ref() + } + + + + pub fn volumes_api(&self) -> &dyn crate::apis::volumes_api::tower::client::Volumes { + self.volumes_api.as_ref() + } + + + + pub fn watches_api(&self) -> &dyn crate::apis::watches_api::tower::client::Watches { + self.watches_api.as_ref() + } + + + +} + +/// Http Response with status and body. +#[derive(Debug, Clone)] +pub struct ResponseContent { + pub(crate) status: hyper::StatusCode, + pub(crate) body: T, +} +impl ResponseContent { + /// Get the status code. + pub fn status(&self) -> hyper::StatusCode { + self.status + } + /// Get a reference to the body. + pub fn body(&self) -> &T { + &self.body + } + /// Convert self into the body. + pub fn into_body(self) -> T { + self.body + } + /// Convert ResponseContent into ResponseContent>. + pub fn with_vec_body(self) -> ResponseContent> { + ResponseContent { + status: self.status, + body: vec![self.body] + } + } +} + +/// Http Response with status and body as text (could not be coerced into the expected type). +#[derive(Debug, Clone)] +pub struct ResponseContentUnexpected { + pub(crate) status: hyper::StatusCode, + pub(crate) text: String, +} +impl ResponseContentUnexpected { + /// Get the status code. + pub fn status(&self) -> hyper::StatusCode { + self.status + } + /// Get a reference to the text. + pub fn text(&self) -> &str { + self.text.as_ref() + } +} + +/// Error type for all Requests with the various variants. +#[derive(Debug)] +pub enum Error { + Request(RequestError), + Response(ResponseError), +} +impl Error { + /// Get the request error, if that is the case. + pub fn request(&self) -> Option<&RequestError> { + match self { + Error::Request(request) => Some(request), + Error::Response(_) => None, + } + } + /// Get the response error, if that is the case. + pub fn response(&self) -> Option<&ResponseError> { + match self { + Error::Request(_) => None, + Error::Response(response) => Some(response), + } + } + /// Get the expected error, if received. + pub fn expected(&self) -> Option<&ResponseContent> { + match self { + Error::Request(_) => None, + Error::Response(response) => response.expected(), + } + } + /// Get the inner body error, if expected. + pub fn error_body(&self) -> Option<&T> { + match self { + Error::Request(_) => None, + Error::Response(response) => response.error_body(), + } + } + /// Get the response status code, if any received. + pub fn status(&self) -> Option { + self.response().map(|response| response.status()) + } +} +impl From for Error { + fn from(src: RequestError) -> Self { + Self::Request(src) + } +} +impl From> for Error { + fn from(src: ResponseError) -> Self { + Self::Response(src) + } +} +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::Request(r) => r.fmt(f), + Error::Response(r) => r.fmt(f), + } + } +} +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Error::Request(r) => r.source(), + Error::Response(r) => r.source(), + } + } +} + +/// Failed to issue the request. +#[derive(Debug)] +pub enum RequestError { + /// Failed to build the http request. + BuildRequest(hyper::http::Error), + /// Service Request call returned an error. + Request(BoxedError), + /// Service was not ready to process the request. + NotReady(BoxedError), + /// Failed to serialize request payload. + Serde(serde_json::Error), + /// Failed to encode the url path. + SerdeEncoded(serde_urlencoded::ser::Error), +} +impl fmt::Display for RequestError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + RequestError::BuildRequest(e) => ("build_request", e.to_string()), + RequestError::Request(e) => ("request", e.to_string()), + RequestError::NotReady(e) => ("not_ready", e.to_string()), + RequestError::Serde(e) => ("serde", e.to_string()), + RequestError::SerdeEncoded(e) => ("serde_encoding", e.to_string()), + }; + write!(f, "error in {module}: {e}") + } +} +impl error::Error for RequestError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(match self { + RequestError::BuildRequest(e) => e, + RequestError::Request(e) => e.deref(), + RequestError::NotReady(e) => e.deref(), + RequestError::Serde(e) => e, + RequestError::SerdeEncoded(e) => e, + }) + } +} + +/// Error type for all Requests with the various variants. +#[derive(Debug)] +pub enum ResponseError { + /// The OpenAPI call returned the "expected" OpenAPI JSON content. + Expected(ResponseContent), + /// Failed to convert the response payload to bytes. + PayloadError { + status: hyper::StatusCode, + error: hyper::Error, + }, + /// The OpenAPI call returned an "unexpected" JSON content. + Unexpected(ResponseContentUnexpected), +} +impl fmt::Display for ResponseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + ResponseError::Expected(e) => ( + "response", + format!("status code '{}', content: '{:?}'", e.status, e.body), + ), + ResponseError::PayloadError { status, error } => ( + "response", + format!("status code '{status}', error: '{error:?}'"), + ), + ResponseError::Unexpected(e) => ( + "response", + format!("status code '{}', text '{}'", e.status, e.text), + ), + }; + write!(f, "error in {module}: {e}") + } +} +impl error::Error for ResponseError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + ResponseError::Expected(_) => None, + ResponseError::PayloadError { error, .. } => Some(error), + ResponseError::Unexpected(_) => None, + } + } +} +impl ResponseError { + /// Get the inner status. + pub fn status(&self) -> StatusCode { + match self { + ResponseError::Expected(expected) => expected.status, + ResponseError::PayloadError { status, .. } => *status, + ResponseError::Unexpected(unexpected) => unexpected.status, + } + } + /// Get the expected error, if received. + pub fn expected(&self) -> Option<&ResponseContent> { + match self { + ResponseError::Expected(expected) => Some(expected), + _ => None, + } + } + /// Get the inner body error, if expected. + pub fn error_body(&self) -> Option<&T> { + match self { + ResponseError::Expected(expected) => Some(&expected.body), + _ => None, + } + } +} + +impl std::fmt::Debug for ApiClient { + fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> fmt::Result { + fmt::Result::Ok(()) + } +} \ No newline at end of file diff --git a/testgen/src/autogen/docs/apis/AppNodes.md b/testgen/src/autogen/docs/apis/AppNodes.md new file mode 100644 index 000000000..a2ddfcba5 --- /dev/null +++ b/testgen/src/autogen/docs/apis/AppNodes.md @@ -0,0 +1,140 @@ +# AppNodes + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_app_nodes**](AppNodes.md#get_app_nodes) | **Get** /app-nodes | +[**get_app_node**](AppNodes.md#get_app_node) | **Get** /app-nodes/{app_node_id} | +[**register_app_node**](AppNodes.md#register_app_node) | **Put** /app-nodes/{app_node_id} | +[**deregister_app_node**](AppNodes.md#deregister_app_node) | **Delete** /app-nodes/{app_node_id} | + + + + + +## get_app_nodes + +> crate::models::AppNodes get_app_nodes(max_entries, starting_token) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**max_entries** | **isize** | | [required] | + +**starting_token** | Option<**isize**> | | | + + +### Return type + +[**crate::models::AppNodes**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_app_node + +> crate::models::AppNode get_app_node(app_node_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**app_node_id** | **String** | | [required] | + + +### Return type + +[**crate::models::AppNode**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## register_app_node + +> () register_app_node(app_node_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**app_node_id** | **String** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## deregister_app_node + +> () deregister_app_node(app_node_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**app_node_id** | **String** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/BlockDevices.md b/testgen/src/autogen/docs/apis/BlockDevices.md new file mode 100644 index 000000000..435623329 --- /dev/null +++ b/testgen/src/autogen/docs/apis/BlockDevices.md @@ -0,0 +1,44 @@ +# BlockDevices + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_node_block_devices**](BlockDevices.md#get_node_block_devices) | **Get** /nodes/{node}/block_devices | + + + + + +## get_node_block_devices + +> Vec get_node_block_devices(all, node) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**all** | Option<**bool**> | | | + +**node** | **String** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Children.md b/testgen/src/autogen/docs/apis/Children.md new file mode 100644 index 000000000..fcb87cafb --- /dev/null +++ b/testgen/src/autogen/docs/apis/Children.md @@ -0,0 +1,286 @@ +# Children + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_nexus_children**](Children.md#get_nexus_children) | **Get** /nexuses/{nexus_id}/children | +[**get_nexus_child**](Children.md#get_nexus_child) | **Get** /nexuses/{nexus_id}/children/{child_id} | +[**put_nexus_child**](Children.md#put_nexus_child) | **Put** /nexuses/{nexus_id}/children/{child_id} | +[**del_nexus_child**](Children.md#del_nexus_child) | **Delete** /nexuses/{nexus_id}/children/{child_id} | +[**get_node_nexus_children**](Children.md#get_node_nexus_children) | **Get** /nodes/{node_id}/nexuses/{nexus_id}/children | +[**get_node_nexus_child**](Children.md#get_node_nexus_child) | **Get** /nodes/{node_id}/nexuses/{nexus_id}/children/{child_id} | +[**put_node_nexus_child**](Children.md#put_node_nexus_child) | **Put** /nodes/{node_id}/nexuses/{nexus_id}/children/{child_id} | +[**del_node_nexus_child**](Children.md#del_node_nexus_child) | **Delete** /nodes/{node_id}/nexuses/{nexus_id}/children/{child_id} | + + + + + +## get_nexus_children + +> Vec get_nexus_children(nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_nexus_child + +> crate::models::Child get_nexus_child(nexus_id, child_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**nexus_id** | **uuid::Uuid** | | [required] | + +**child_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Child**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_nexus_child + +> crate::models::Child put_nexus_child(nexus_id, child_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**nexus_id** | **uuid::Uuid** | | [required] | + +**child_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Child**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_nexus_child + +> () del_nexus_child(nexus_id, child_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**nexus_id** | **uuid::Uuid** | | [required] | + +**child_id** | **String** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_nexus_children + +> Vec get_node_nexus_children(node_id, nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_nexus_child + +> crate::models::Child get_node_nexus_child(node_id, nexus_id, child_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + +**child_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Child**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_nexus_child + +> crate::models::Child put_node_nexus_child(node_id, nexus_id, child_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + +**child_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Child**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_node_nexus_child + +> () del_node_nexus_child(node_id, nexus_id, child_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + +**child_id** | **String** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/JsonGrpc.md b/testgen/src/autogen/docs/apis/JsonGrpc.md new file mode 100644 index 000000000..904556003 --- /dev/null +++ b/testgen/src/autogen/docs/apis/JsonGrpc.md @@ -0,0 +1,44 @@ +# JsonGrpc + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**put_node_jsongrpc**](JsonGrpc.md#put_node_jsongrpc) | **Put** /nodes/{node}/jsongrpc/{method} | + + + + + +## put_node_jsongrpc + +> serde_json::Value put_node_jsongrpc(node, method) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node** | **String** | | [required] | + +**method** | **String** | | [required] | + + +### Return type + +[**serde_json::Value**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Nexuses.md b/testgen/src/autogen/docs/apis/Nexuses.md new file mode 100644 index 000000000..646aa1aa5 --- /dev/null +++ b/testgen/src/autogen/docs/apis/Nexuses.md @@ -0,0 +1,306 @@ +# Nexuses + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_nexuses**](Nexuses.md#get_nexuses) | **Get** /nexuses | +[**get_nexus**](Nexuses.md#get_nexus) | **Get** /nexuses/{nexus_id} | +[**del_nexus**](Nexuses.md#del_nexus) | **Delete** /nexuses/{nexus_id} | +[**get_node_nexuses**](Nexuses.md#get_node_nexuses) | **Get** /nodes/{id}/nexuses | +[**get_node_nexus**](Nexuses.md#get_node_nexus) | **Get** /nodes/{node_id}/nexuses/{nexus_id} | +[**put_node_nexus**](Nexuses.md#put_node_nexus) | **Put** /nodes/{node_id}/nexuses/{nexus_id} | +[**del_node_nexus**](Nexuses.md#del_node_nexus) | **Delete** /nodes/{node_id}/nexuses/{nexus_id} | +[**del_node_nexus_share**](Nexuses.md#del_node_nexus_share) | **Delete** /nodes/{node_id}/nexuses/{nexus_id}/share | +[**put_node_nexus_share**](Nexuses.md#put_node_nexus_share) | **Put** /nodes/{node_id}/nexuses/{nexus_id}/share/{protocol} | + + + + + +## get_nexuses + +> Vec get_nexuses() + + +### Parameters + +This endpoint does not need any parameter. + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_nexus + +> crate::models::Nexus get_nexus(nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Nexus**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_nexus + +> () del_nexus(nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_nexuses + +> Vec get_node_nexuses(id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_nexus + +> crate::models::Nexus get_node_nexus(node_id, nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Nexus**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_nexus + +> crate::models::Nexus put_node_nexus(node_id, nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Nexus**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_node_nexus + +> () del_node_nexus(node_id, nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_node_nexus_share + +> () del_node_nexus_share(node_id, nexus_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_nexus_share + +> String put_node_nexus_share(node_id, nexus_id, protocol) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**nexus_id** | **uuid::Uuid** | | [required] | + +**protocol** | [**Protocol**](.md) | | [required] | + + +### Return type + +[**String**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Nodes.md b/testgen/src/autogen/docs/apis/Nodes.md new file mode 100644 index 000000000..78b51a1f9 --- /dev/null +++ b/testgen/src/autogen/docs/apis/Nodes.md @@ -0,0 +1,248 @@ +# Nodes + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_nodes**](Nodes.md#get_nodes) | **Get** /nodes | +[**get_node**](Nodes.md#get_node) | **Get** /nodes/{id} | +[**put_node_cordon**](Nodes.md#put_node_cordon) | **Put** /nodes/{id}/cordon/{label} | +[**delete_node_cordon**](Nodes.md#delete_node_cordon) | **Delete** /nodes/{id}/cordon/{label} | +[**put_node_drain**](Nodes.md#put_node_drain) | **Put** /nodes/{id}/drain/{label} | +[**put_node_label**](Nodes.md#put_node_label) | **Put** /nodes/{id}/label/{key}={value} | +[**delete_node_label**](Nodes.md#delete_node_label) | **Delete** /nodes/{id}/label/{key} | + + + + + +## get_nodes + +> Vec get_nodes(node_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | Option<**String**> | | | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node + +> crate::models::Node get_node(id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + + +### Return type + +[**crate::models::Node**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_cordon + +> crate::models::Node put_node_cordon(id, label) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + +**label** | **String** | | [required] | + + +### Return type + +[**crate::models::Node**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## delete_node_cordon + +> crate::models::Node delete_node_cordon(id, label) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + +**label** | **String** | | [required] | + + +### Return type + +[**crate::models::Node**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_drain + +> crate::models::Node put_node_drain(id, label) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + +**label** | **String** | | [required] | + + +### Return type + +[**crate::models::Node**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_label + +> crate::models::Node put_node_label(overwrite, id, key, value) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**overwrite** | Option<**bool**> | | | + +**id** | **String** | | [required] | + +**key** | **String** | | [required] | + +**value** | **String** | | [required] | + + +### Return type + +[**crate::models::Node**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## delete_node_label + +> crate::models::Node delete_node_label(id, key) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + +**key** | **String** | | [required] | + + +### Return type + +[**crate::models::Node**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Pools.md b/testgen/src/autogen/docs/apis/Pools.md new file mode 100644 index 000000000..3976b5efc --- /dev/null +++ b/testgen/src/autogen/docs/apis/Pools.md @@ -0,0 +1,236 @@ +# Pools + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_node_pools**](Pools.md#get_node_pools) | **Get** /nodes/{id}/pools | +[**get_node_pool**](Pools.md#get_node_pool) | **Get** /nodes/{node_id}/pools/{pool_id} | +[**put_node_pool**](Pools.md#put_node_pool) | **Put** /nodes/{node_id}/pools/{pool_id} | +[**del_node_pool**](Pools.md#del_node_pool) | **Delete** /nodes/{node_id}/pools/{pool_id} | +[**get_pools**](Pools.md#get_pools) | **Get** /pools | +[**get_pool**](Pools.md#get_pool) | **Get** /pools/{pool_id} | +[**del_pool**](Pools.md#del_pool) | **Delete** /pools/{pool_id} | + + + + + +## get_node_pools + +> Vec get_node_pools(id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_pool + +> crate::models::Pool get_node_pool(node_id, pool_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Pool**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_pool + +> crate::models::Pool put_node_pool(node_id, pool_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Pool**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_node_pool + +> () del_node_pool(node_id, pool_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_pools + +> Vec get_pools() + + +### Parameters + +This endpoint does not need any parameter. + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_pool + +> crate::models::Pool get_pool(pool_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**pool_id** | **String** | | [required] | + + +### Return type + +[**crate::models::Pool**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_pool + +> () del_pool(pool_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**pool_id** | **String** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Replicas.md b/testgen/src/autogen/docs/apis/Replicas.md new file mode 100644 index 000000000..96dc30b7b --- /dev/null +++ b/testgen/src/autogen/docs/apis/Replicas.md @@ -0,0 +1,456 @@ +# Replicas + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_node_replicas**](Replicas.md#get_node_replicas) | **Get** /nodes/{id}/replicas | +[**get_node_pool_replicas**](Replicas.md#get_node_pool_replicas) | **Get** /nodes/{node_id}/pools/{pool_id}/replicas | +[**get_node_pool_replica**](Replicas.md#get_node_pool_replica) | **Get** /nodes/{node_id}/pools/{pool_id}/replicas/{replica_id} | +[**put_node_pool_replica**](Replicas.md#put_node_pool_replica) | **Put** /nodes/{node_id}/pools/{pool_id}/replicas/{replica_id} | +[**del_node_pool_replica**](Replicas.md#del_node_pool_replica) | **Delete** /nodes/{node_id}/pools/{pool_id}/replicas/{replica_id} | +[**del_node_pool_replica_share**](Replicas.md#del_node_pool_replica_share) | **Delete** /nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share | +[**put_node_pool_replica_share**](Replicas.md#put_node_pool_replica_share) | **Put** /nodes/{node_id}/pools/{pool_id}/replicas/{replica_id}/share/nvmf | +[**put_pool_replica**](Replicas.md#put_pool_replica) | **Put** /pools/{pool_id}/replicas/{replica_id} | +[**del_pool_replica**](Replicas.md#del_pool_replica) | **Delete** /pools/{pool_id}/replicas/{replica_id} | +[**del_pool_replica_share**](Replicas.md#del_pool_replica_share) | **Delete** /pools/{pool_id}/replicas/{replica_id}/share | +[**put_pool_replica_share**](Replicas.md#put_pool_replica_share) | **Put** /pools/{pool_id}/replicas/{replica_id}/share/nvmf | +[**get_replicas**](Replicas.md#get_replicas) | **Get** /replicas | +[**get_replica**](Replicas.md#get_replica) | **Get** /replicas/{id} | + + + + + +## get_node_replicas + +> Vec get_node_replicas(id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **String** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_pool_replicas + +> Vec get_node_pool_replicas(node_id, pool_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_node_pool_replica + +> crate::models::Replica get_node_pool_replica(node_id, pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Replica**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_pool_replica + +> crate::models::Replica put_node_pool_replica(node_id, pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Replica**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_node_pool_replica + +> () del_node_pool_replica(node_id, pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_node_pool_replica_share + +> () del_node_pool_replica_share(node_id, pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_node_pool_replica_share + +> String put_node_pool_replica_share(allowed_hosts, node_id, pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**allowed_hosts** | Option<[**Vec**](.md)> | | | + +**node_id** | **String** | | [required] | + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**String**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_pool_replica + +> crate::models::Replica put_pool_replica(pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Replica**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_pool_replica + +> () del_pool_replica(pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_pool_replica_share + +> () del_pool_replica_share(pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_pool_replica_share + +> String put_pool_replica_share(allowed_hosts, pool_id, replica_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**allowed_hosts** | Option<[**Vec**](.md)> | | | + +**pool_id** | **String** | | [required] | + +**replica_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**String**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_replicas + +> Vec get_replicas() + + +### Parameters + +This endpoint does not need any parameter. + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_replica + +> crate::models::Replica get_replica(id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Replica**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Snapshots.md b/testgen/src/autogen/docs/apis/Snapshots.md new file mode 100644 index 000000000..1a1274bef --- /dev/null +++ b/testgen/src/autogen/docs/apis/Snapshots.md @@ -0,0 +1,250 @@ +# Snapshots + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_volume_snapshot**](Snapshots.md#get_volume_snapshot) | **Get** /volumes/{volume_id}/snapshots/{snapshot_id} | +[**put_volume_snapshot**](Snapshots.md#put_volume_snapshot) | **Put** /volumes/{volume_id}/snapshots/{snapshot_id} | +[**del_volume_snapshot**](Snapshots.md#del_volume_snapshot) | **Delete** /volumes/{volume_id}/snapshots/{snapshot_id} | +[**get_volume_snapshots**](Snapshots.md#get_volume_snapshots) | **Get** /volumes/{volume_id}/snapshots | +[**get_volumes_snapshot**](Snapshots.md#get_volumes_snapshot) | **Get** /volumes/snapshots/{snapshot_id} | +[**del_snapshot**](Snapshots.md#del_snapshot) | **Delete** /volumes/snapshots/{snapshot_id} | +[**get_volumes_snapshots**](Snapshots.md#get_volumes_snapshots) | **Get** /volumes/snapshots | + + + + + +## get_volume_snapshot + +> crate::models::VolumeSnapshot get_volume_snapshot(volume_id, snapshot_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + +**snapshot_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::VolumeSnapshot**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume_snapshot + +> crate::models::VolumeSnapshot put_volume_snapshot(volume_id, snapshot_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + +**snapshot_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::VolumeSnapshot**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_volume_snapshot + +> () del_volume_snapshot(volume_id, snapshot_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + +**snapshot_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_volume_snapshots + +> crate::models::VolumeSnapshots get_volume_snapshots(max_entries, starting_token, volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**max_entries** | **isize** | | [required] | + +**starting_token** | Option<**isize**> | | | + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::VolumeSnapshots**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_volumes_snapshot + +> crate::models::VolumeSnapshot get_volumes_snapshot(snapshot_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**snapshot_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::VolumeSnapshot**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_snapshot + +> () del_snapshot(snapshot_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**snapshot_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_volumes_snapshots + +> crate::models::VolumeSnapshots get_volumes_snapshots(snapshot_id, volume_id, max_entries, starting_token) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**snapshot_id** | Option<**uuid::Uuid**> | | | + +**volume_id** | Option<**uuid::Uuid**> | | | + +**max_entries** | **isize** | | [required] | + +**starting_token** | Option<**isize**> | | | + + +### Return type + +[**crate::models::VolumeSnapshots**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Specs.md b/testgen/src/autogen/docs/apis/Specs.md new file mode 100644 index 000000000..7ac9665e3 --- /dev/null +++ b/testgen/src/autogen/docs/apis/Specs.md @@ -0,0 +1,38 @@ +# Specs + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_specs**](Specs.md#get_specs) | **Get** /specs | + + + + + +## get_specs + +> crate::models::Specs get_specs() + + +### Parameters + +This endpoint does not need any parameter. + + +### Return type + +[**crate::models::Specs**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Volumes.md b/testgen/src/autogen/docs/apis/Volumes.md new file mode 100644 index 000000000..18acc8a34 --- /dev/null +++ b/testgen/src/autogen/docs/apis/Volumes.md @@ -0,0 +1,472 @@ +# Volumes + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_volumes**](Volumes.md#get_volumes) | **Get** /volumes | +[**get_volume**](Volumes.md#get_volume) | **Get** /volumes/{volume_id} | +[**put_volume**](Volumes.md#put_volume) | **Put** /volumes/{volume_id} | +[**del_volume**](Volumes.md#del_volume) | **Delete** /volumes/{volume_id} | +[**get_rebuild_history**](Volumes.md#get_rebuild_history) | **Get** /volumes/{volume_id}/rebuild-history | +[**put_volume_replica_count**](Volumes.md#put_volume_replica_count) | **Put** /volumes/{volume_id}/replica_count/{replica_count} | +[**put_volume_property**](Volumes.md#put_volume_property) | **Put** /volumes/{volume_id}/property | +[**put_volume_target**](Volumes.md#put_volume_target) | **Put** /volumes/{volume_id}/target | +[**del_volume_target**](Volumes.md#del_volume_target) | **Delete** /volumes/{volume_id}/target | +[**put_volume_size**](Volumes.md#put_volume_size) | **Put** /volumes/{volume_id}/size | +[**del_volume_shutdown_targets**](Volumes.md#del_volume_shutdown_targets) | **Delete** /volumes/{volume_id}/shutdown_targets | +[**put_volume_share**](Volumes.md#put_volume_share) | **Put** /volumes/{volume_id}/share/{protocol} | +[**del_share**](Volumes.md#del_share) | **Delete** /volumes{volume_id}/share | +[**put_snapshot_volume**](Volumes.md#put_snapshot_volume) | **Put** /snapshots/{snapshot_id}/volumes/{volume_id} | + + + + + +## get_volumes + +> crate::models::Volumes get_volumes(volume_id, max_entries, starting_token) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | Option<**uuid::Uuid**> | | | + +**max_entries** | **isize** | | [required] | + +**starting_token** | Option<**isize**> | | | + + +### Return type + +[**crate::models::Volumes**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_volume + +> crate::models::Volume get_volume(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume + +> crate::models::Volume put_volume(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_volume + +> () del_volume(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## get_rebuild_history + +> serde_json::Value get_rebuild_history(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**serde_json::Value**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume_replica_count + +> crate::models::Volume put_volume_replica_count(volume_id, replica_count) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + +**replica_count** | **u8** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume_property + +> crate::models::Volume put_volume_property(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume_target + +> crate::models::Volume put_volume_target(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_volume_target + +> crate::models::Volume del_volume_target(force, volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**force** | Option<**bool**> | | | + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume_size + +> crate::models::Volume put_volume_size(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_volume_shutdown_targets + +> () del_volume_shutdown_targets(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_volume_share + +> String put_volume_share(frontend_host, volume_id, protocol) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**frontend_host** | Option<**String**> | | | + +**volume_id** | **uuid::Uuid** | | [required] | + +**protocol** | [**Protocol**](.md) | | [required] | + + +### Return type + +[**String**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_share + +> () del_share(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_snapshot_volume + +> crate::models::Volume put_snapshot_volume(snapshot_id, volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**snapshot_id** | **uuid::Uuid** | | [required] | + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**crate::models::Volume**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/apis/Watches.md b/testgen/src/autogen/docs/apis/Watches.md new file mode 100644 index 000000000..588dca40d --- /dev/null +++ b/testgen/src/autogen/docs/apis/Watches.md @@ -0,0 +1,110 @@ +# Watches + +All URIs are relative to ** + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_watch_volume**](Watches.md#get_watch_volume) | **Get** /watches/volumes/{volume_id} | +[**put_watch_volume**](Watches.md#put_watch_volume) | **Put** /watches/volumes/{volume_id} | +[**del_watch_volume**](Watches.md#del_watch_volume) | **Delete** /watches/volumes/{volume_id} | + + + + + +## get_watch_volume + +> Vec get_watch_volume(volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**Vec**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## put_watch_volume + +> () put_watch_volume(callback, volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**callback** | **String** | | [required] | + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + + +## del_watch_volume + +> () del_watch_volume(callback, volume_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- + +**callback** | **String** | | [required] | + +**volume_id** | **uuid::Uuid** | | [required] | + + +### Return type + +[**()**](.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + diff --git a/testgen/src/autogen/docs/models/AffinityGroup.md b/testgen/src/autogen/docs/models/AffinityGroup.md new file mode 100644 index 000000000..011c745a5 --- /dev/null +++ b/testgen/src/autogen/docs/models/AffinityGroup.md @@ -0,0 +1,11 @@ +# AffinityGroup + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | Identification of the Affinity Group. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/AppNode.md b/testgen/src/autogen/docs/models/AppNode.md new file mode 100644 index 000000000..073ca3ca5 --- /dev/null +++ b/testgen/src/autogen/docs/models/AppNode.md @@ -0,0 +1,13 @@ +# AppNode + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | App node identifier. | +**spec** | [**crate::models::AppNodeSpec**](.md) | App node attributes. | +**state** | Option<[**crate::models::AppNodeState**](.md)> | Deemed state of the app node. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/AppNodeSpec.md b/testgen/src/autogen/docs/models/AppNodeSpec.md new file mode 100644 index 000000000..46074e303 --- /dev/null +++ b/testgen/src/autogen/docs/models/AppNodeSpec.md @@ -0,0 +1,13 @@ +# AppNodeSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | App node identifier. | +**endpoint** | **String** | gRPC server endpoint of the app node. | +**labels** | Option<[**::std::collections::HashMap**](.md)> | Labels to be set on the app node. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/AppNodeState.md b/testgen/src/autogen/docs/models/AppNodeState.md new file mode 100644 index 000000000..258dac417 --- /dev/null +++ b/testgen/src/autogen/docs/models/AppNodeState.md @@ -0,0 +1,13 @@ +# AppNodeState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | App node identifier. | +**endpoint** | **String** | gRPC server endpoint of the app node. | +**status** | [**Status**](.md) | Deemed Status of the app node. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/AppNodes.md b/testgen/src/autogen/docs/models/AppNodes.md new file mode 100644 index 000000000..fac5336d9 --- /dev/null +++ b/testgen/src/autogen/docs/models/AppNodes.md @@ -0,0 +1,12 @@ +# AppNodes + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**entries** | [**Vec**](.md) | | +**next_token** | Option<**isize**> | | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/BlockDevice.md b/testgen/src/autogen/docs/models/BlockDevice.md new file mode 100644 index 000000000..ae202c222 --- /dev/null +++ b/testgen/src/autogen/docs/models/BlockDevice.md @@ -0,0 +1,23 @@ +# BlockDevice + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**available** | **bool** | identifies if device is available for use (ie. is not \"currently\" in use) | +**connection_type** | **String** | the type of bus through which the device is connected to the system | +**devlinks** | [**Vec**](.md) | list of udev generated symlinks by which device may be identified | +**devmajor** | **i32** | major device number | +**devminor** | **i32** | minor device number | +**devname** | **String** | entry in /dev associated with device | +**devpath** | **String** | official device path | +**devtype** | **String** | currently \"disk\" or \"partition\" | +**filesystem** | Option<[**crate::models::BlockDeviceFilesystem**](.md)> | filesystem information in case where a filesystem is present | [optional] +**is_rotational** | Option<**bool**> | indicates whether the device is rotational or non-rotational | [optional] +**model** | **String** | device model - useful for identifying devices | +**partition** | Option<[**crate::models::BlockDevicePartition**](.md)> | partition information in case where device represents a partition | [optional] +**size** | **u64** | size of device in (512 byte) blocks | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/BlockDeviceFilesystem.md b/testgen/src/autogen/docs/models/BlockDeviceFilesystem.md new file mode 100644 index 000000000..d44346235 --- /dev/null +++ b/testgen/src/autogen/docs/models/BlockDeviceFilesystem.md @@ -0,0 +1,14 @@ +# BlockDeviceFilesystem + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**fstype** | **String** | filesystem type: ext3, ntfs, ... | +**label** | **String** | volume label | +**mountpoint** | **String** | path where filesystem is currently mounted | +**uuid** | **String** | UUID identifying the volume (filesystem) | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/BlockDevicePartition.md b/testgen/src/autogen/docs/models/BlockDevicePartition.md new file mode 100644 index 000000000..764efe489 --- /dev/null +++ b/testgen/src/autogen/docs/models/BlockDevicePartition.md @@ -0,0 +1,16 @@ +# BlockDevicePartition + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **String** | partition name | +**number** | **i32** | partition number | +**parent** | **String** | devname of parent device to which this partition belongs | +**scheme** | **String** | partition scheme: gpt, dos, ... | +**typeid** | **String** | partition type identifier | +**uuid** | **String** | UUID identifying partition | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Child.md b/testgen/src/autogen/docs/models/Child.md new file mode 100644 index 000000000..b8eca56cb --- /dev/null +++ b/testgen/src/autogen/docs/models/Child.md @@ -0,0 +1,14 @@ +# Child + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**rebuild_progress** | Option<**usize**> | current rebuild progress (%) | [optional] +**state** | [**crate::models::ChildState**](.md) | State of a Nexus Child | +**state_reason** | Option<[**crate::models::ChildStateReason**](.md)> | Reason for the state of a Nexus Child | [optional] +**uri** | **String** | uri of the child device | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ChildState.md b/testgen/src/autogen/docs/models/ChildState.md new file mode 100644 index 000000000..affe70ac3 --- /dev/null +++ b/testgen/src/autogen/docs/models/ChildState.md @@ -0,0 +1,10 @@ +# ChildState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ChildStateReason.md b/testgen/src/autogen/docs/models/ChildStateReason.md new file mode 100644 index 000000000..01ecd8e6c --- /dev/null +++ b/testgen/src/autogen/docs/models/ChildStateReason.md @@ -0,0 +1,10 @@ +# ChildStateReason + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/CordonDrainState.md b/testgen/src/autogen/docs/models/CordonDrainState.md new file mode 100644 index 000000000..425d828be --- /dev/null +++ b/testgen/src/autogen/docs/models/CordonDrainState.md @@ -0,0 +1,13 @@ +# CordonDrainState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**cordonedstate** | Option<[**crate::models::CordonedState**](.md)> | The item is cordoned | [optional] +**drainingstate** | Option<[**crate::models::DrainState**](.md)> | The item is draining | [optional] +**drainedstate** | Option<[**crate::models::DrainState**](.md)> | The item is draining | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/CordonedState.md b/testgen/src/autogen/docs/models/CordonedState.md new file mode 100644 index 000000000..0f5d56a59 --- /dev/null +++ b/testgen/src/autogen/docs/models/CordonedState.md @@ -0,0 +1,11 @@ +# CordonedState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**cordonlabels** | [**Vec**](.md) | | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/CreateNexusBody.md b/testgen/src/autogen/docs/models/CreateNexusBody.md new file mode 100644 index 000000000..547163ecc --- /dev/null +++ b/testgen/src/autogen/docs/models/CreateNexusBody.md @@ -0,0 +1,12 @@ +# CreateNexusBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**children** | [**Vec**](.md) | replica can be iscsi and nvmf remote targets or a local spdk bdev (i.e. bdev:///name-of-the-bdev). uris to the targets we connect to | +**size** | **u64** | size of the device in bytes | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/CreatePoolBody.md b/testgen/src/autogen/docs/models/CreatePoolBody.md new file mode 100644 index 000000000..69765d24a --- /dev/null +++ b/testgen/src/autogen/docs/models/CreatePoolBody.md @@ -0,0 +1,12 @@ +# CreatePoolBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**disks** | [**Vec**](.md) | disk device paths or URIs to be claimed by the pool | +**labels** | Option<[**::std::collections::HashMap**](.md)> | labels to be set on the pools | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/CreateReplicaBody.md b/testgen/src/autogen/docs/models/CreateReplicaBody.md new file mode 100644 index 000000000..c7f753136 --- /dev/null +++ b/testgen/src/autogen/docs/models/CreateReplicaBody.md @@ -0,0 +1,14 @@ +# CreateReplicaBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**share** | Option<[**crate::models::ReplicaShareProtocol**](.md)> | Replica Share Protocol | [optional] +**allowed_hosts** | Option<[**Vec**](.md)> | | [optional] +**size** | **u64** | size of the replica in bytes | +**thin** | **bool** | thin provisioning | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/CreateVolumeBody.md b/testgen/src/autogen/docs/models/CreateVolumeBody.md new file mode 100644 index 000000000..45a34eb2a --- /dev/null +++ b/testgen/src/autogen/docs/models/CreateVolumeBody.md @@ -0,0 +1,18 @@ +# CreateVolumeBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**policy** | [**crate::models::VolumePolicy**](.md) | Volume policy used to determine if and how to replace a replica | +**replicas** | **u8** | number of storage replicas | +**size** | **u64** | size of the volume in bytes | +**thin** | **bool** | flag indicating whether or not the volume is thin provisioned | +**topology** | Option<[**crate::models::Topology**](.md)> | node and pool topology for volumes | [optional] +**labels** | Option<[**::std::collections::HashMap**](.md)> | Optionally used to store custom volume information | [optional] +**affinity_group** | Option<[**crate::models::AffinityGroup**](.md)> | Affinity Group related information. | [optional] +**max_snapshots** | Option<**u32**> | Max Snapshots limit per volume. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/DrainState.md b/testgen/src/autogen/docs/models/DrainState.md new file mode 100644 index 000000000..da317323d --- /dev/null +++ b/testgen/src/autogen/docs/models/DrainState.md @@ -0,0 +1,12 @@ +# DrainState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**cordonlabels** | [**Vec**](.md) | | +**drainlabels** | [**Vec**](.md) | | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ExplicitNodeTopology.md b/testgen/src/autogen/docs/models/ExplicitNodeTopology.md new file mode 100644 index 000000000..2b84abe0e --- /dev/null +++ b/testgen/src/autogen/docs/models/ExplicitNodeTopology.md @@ -0,0 +1,12 @@ +# ExplicitNodeTopology + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**allowed_nodes** | [**Vec**](.md) | replicas can only be placed on these nodes | +**preferred_nodes** | [**Vec**](.md) | preferred nodes to place the replicas | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/LabelledTopology.md b/testgen/src/autogen/docs/models/LabelledTopology.md new file mode 100644 index 000000000..fe244c01e --- /dev/null +++ b/testgen/src/autogen/docs/models/LabelledTopology.md @@ -0,0 +1,13 @@ +# LabelledTopology + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**exclusion** | [**::std::collections::HashMap**](.md) | Excludes resources with the same $label name, eg: \"Zone\" would not allow for resources with the same \"Zone\" value to be used for a certain operation, eg: A node with \"Zone: A\" would not be paired up with a node with \"Zone: A\", but it could be paired up with a node with \"Zone: B\" exclusive label NAME in the form \"NAME\", and not \"NAME: VALUE\" | +**inclusion** | [**::std::collections::HashMap**](.md) | Includes resources with the same $label or $label:$value eg: if label is \"Zone: A\": A resource with \"Zone: A\" would be paired up with a resource with \"Zone: A\", but not with a resource with \"Zone: B\" if label is \"Zone\": A resource with \"Zone: A\" would be paired up with a resource with \"Zone: B\", but not with a resource with \"OtherLabel: B\" inclusive label key value in the form \"NAME: VALUE\" | +**affinitykey** | [**Vec**](.md) | This feature includes resources with identical $label keys. For example, if the affinity key is set to \"Zone\": Initially, a resource that matches the label is selected, example \"Zone: A\". Subsequently, all other resources must match the given label \"Zone: A\", effectively adding this requirement as an inclusion label. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Nexus.md b/testgen/src/autogen/docs/models/Nexus.md new file mode 100644 index 000000000..9d2e77e27 --- /dev/null +++ b/testgen/src/autogen/docs/models/Nexus.md @@ -0,0 +1,18 @@ +# Nexus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**children** | [**Vec**](.md) | Array of Nexus Children | +**device_uri** | **String** | URI of the device for the volume (missing if not published). Missing property and empty string are treated the same. | +**node** | **String** | id of the io-engine instance | +**rebuilds** | **u32** | total number of rebuild tasks | +**protocol** | [**crate::models::Protocol**](.md) | Common Protocol | +**size** | **u64** | size of the volume in bytes | +**state** | [**crate::models::NexusState**](.md) | State of the Nexus | +**uuid** | **uuid::Uuid** | uuid of the nexus | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NexusShareProtocol.md b/testgen/src/autogen/docs/models/NexusShareProtocol.md new file mode 100644 index 000000000..612325f2f --- /dev/null +++ b/testgen/src/autogen/docs/models/NexusShareProtocol.md @@ -0,0 +1,10 @@ +# NexusShareProtocol + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NexusSpec.md b/testgen/src/autogen/docs/models/NexusSpec.md new file mode 100644 index 000000000..17f0994b8 --- /dev/null +++ b/testgen/src/autogen/docs/models/NexusSpec.md @@ -0,0 +1,19 @@ +# NexusSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**children** | [**Vec**](.md) | List of children. | +**managed** | **bool** | Managed by our control plane | +**node** | **String** | Node where the nexus should live. | +**operation** | Option<[**crate::models::NexusSpecOperation**](.md)> | Record of the operation in progress | [optional] +**owner** | Option<**uuid::Uuid**> | Volume which owns this nexus, if any | [optional] +**share** | [**crate::models::Protocol**](.md) | Common Protocol | +**size** | **u64** | Size of the nexus. | +**status** | [**crate::models::SpecStatus**](.md) | Common base state for a resource | +**uuid** | **uuid::Uuid** | Nexus Id | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NexusSpecOperation.md b/testgen/src/autogen/docs/models/NexusSpecOperation.md new file mode 100644 index 000000000..3cc00afbf --- /dev/null +++ b/testgen/src/autogen/docs/models/NexusSpecOperation.md @@ -0,0 +1,12 @@ +# NexusSpecOperation + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**operation** | [**Operation**](.md) | Record of the operation | +**result** | Option<**bool**> | Result of the operation | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NexusState.md b/testgen/src/autogen/docs/models/NexusState.md new file mode 100644 index 000000000..d1103df9c --- /dev/null +++ b/testgen/src/autogen/docs/models/NexusState.md @@ -0,0 +1,10 @@ +# NexusState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Node.md b/testgen/src/autogen/docs/models/Node.md new file mode 100644 index 000000000..f2d972777 --- /dev/null +++ b/testgen/src/autogen/docs/models/Node.md @@ -0,0 +1,13 @@ +# Node + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | storage node identifier | +**spec** | Option<[**crate::models::NodeSpec**](.md)> | Node spec | [optional] +**state** | Option<[**crate::models::NodeState**](.md)> | io-engine storage node information | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NodeAccessInfo.md b/testgen/src/autogen/docs/models/NodeAccessInfo.md new file mode 100644 index 000000000..3b1fdc435 --- /dev/null +++ b/testgen/src/autogen/docs/models/NodeAccessInfo.md @@ -0,0 +1,12 @@ +# NodeAccessInfo + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **String** | The nodename of the node. | +**nqn** | **String** | The Nvme Nqn of the node\'s initiator. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NodeSpec.md b/testgen/src/autogen/docs/models/NodeSpec.md new file mode 100644 index 000000000..fd9ab2c68 --- /dev/null +++ b/testgen/src/autogen/docs/models/NodeSpec.md @@ -0,0 +1,15 @@ +# NodeSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**grpc_endpoint** | **String** | gRPC endpoint of the io-engine instance | +**id** | **String** | storage node identifier | +**labels** | Option<[**::std::collections::HashMap**](.md)> | labels to be set on the node | [optional] +**cordondrainstate** | Option<[**crate::models::CordonDrainState**](.md)> | the drain state | [optional] +**node_nqn** | Option<**String**> | NVMe Qualified Names (NQNs) are used to uniquely describe a host or NVM subsystem for the purposes of identification and authentication | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NodeState.md b/testgen/src/autogen/docs/models/NodeState.md new file mode 100644 index 000000000..cfe06903a --- /dev/null +++ b/testgen/src/autogen/docs/models/NodeState.md @@ -0,0 +1,14 @@ +# NodeState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**grpc_endpoint** | **String** | gRPC endpoint of the io-engine instance | +**id** | **String** | storage node identifier | +**status** | [**crate::models::NodeStatus**](.md) | deemed state of the node | +**node_nqn** | Option<**String**> | NVMe Qualified Names (NQNs) are used to uniquely describe a host or NVM subsystem for the purposes of identification and authentication | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NodeStatus.md b/testgen/src/autogen/docs/models/NodeStatus.md new file mode 100644 index 000000000..ad0b3763a --- /dev/null +++ b/testgen/src/autogen/docs/models/NodeStatus.md @@ -0,0 +1,10 @@ +# NodeStatus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/NodeTopology.md b/testgen/src/autogen/docs/models/NodeTopology.md new file mode 100644 index 000000000..31acbf529 --- /dev/null +++ b/testgen/src/autogen/docs/models/NodeTopology.md @@ -0,0 +1,12 @@ +# NodeTopology + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**explicit** | Option<[**crate::models::ExplicitNodeTopology**](.md)> | volume topology, explicitly selected | [optional] +**labelled** | Option<[**crate::models::LabelledTopology**](.md)> | volume topology definition through labels | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/OfflineReplicaSnapshotState.md b/testgen/src/autogen/docs/models/OfflineReplicaSnapshotState.md new file mode 100644 index 000000000..4aa352b5d --- /dev/null +++ b/testgen/src/autogen/docs/models/OfflineReplicaSnapshotState.md @@ -0,0 +1,14 @@ +# OfflineReplicaSnapshotState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uuid** | **uuid::Uuid** | | +**source_id** | **uuid::Uuid** | | +**pool_id** | **String** | storage pool identifier | +**pool_uuid** | **uuid::Uuid** | storage pool unique identifier | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/OnlineReplicaSnapshotState.md b/testgen/src/autogen/docs/models/OnlineReplicaSnapshotState.md new file mode 100644 index 000000000..842a2d2c6 --- /dev/null +++ b/testgen/src/autogen/docs/models/OnlineReplicaSnapshotState.md @@ -0,0 +1,18 @@ +# OnlineReplicaSnapshotState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uuid** | **uuid::Uuid** | | +**source_id** | **uuid::Uuid** | | +**pool_id** | **String** | storage pool identifier | +**pool_uuid** | **uuid::Uuid** | storage pool unique identifier | +**timestamp** | **String** | Timestamp when the replica snapshot is taken on the storage system. | +**size** | **u64** | Replica snapshot size. | +**allocated_size** | **u64** | Runtime size in bytes of the snapshot. Equal to the volume allocation at the time of the snapshot creation. It may grow larger if any of its predecessors are deleted. | +**predecessor_alloc_size** | **u64** | Total allocated size of all the snapshot predecessors. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Pool.md b/testgen/src/autogen/docs/models/Pool.md new file mode 100644 index 000000000..159b5dd18 --- /dev/null +++ b/testgen/src/autogen/docs/models/Pool.md @@ -0,0 +1,13 @@ +# Pool + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | storage pool identifier | +**spec** | Option<[**crate::models::PoolSpec**](.md)> | User specification of a pool. | [optional] +**state** | Option<[**crate::models::PoolState**](.md)> | State of a pool, as reported by io-engine | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/PoolSpec.md b/testgen/src/autogen/docs/models/PoolSpec.md new file mode 100644 index 000000000..961f961fb --- /dev/null +++ b/testgen/src/autogen/docs/models/PoolSpec.md @@ -0,0 +1,15 @@ +# PoolSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**disks** | [**Vec**](.md) | absolute disk paths claimed by the pool | +**id** | **String** | storage pool identifier | +**labels** | Option<[**::std::collections::HashMap**](.md)> | labels to be set on the pools | [optional] +**node** | **String** | storage node identifier | +**status** | [**crate::models::SpecStatus**](.md) | Common base state for a resource | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/PoolState.md b/testgen/src/autogen/docs/models/PoolState.md new file mode 100644 index 000000000..c915995c3 --- /dev/null +++ b/testgen/src/autogen/docs/models/PoolState.md @@ -0,0 +1,17 @@ +# PoolState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**capacity** | **u64** | size of the pool in bytes | +**disks** | [**Vec**](.md) | absolute disk paths claimed by the pool | +**id** | **String** | storage pool identifier | +**node** | **String** | storage node identifier | +**status** | [**crate::models::PoolStatus**](.md) | current status of the pool | +**used** | **u64** | used bytes from the pool | +**committed** | Option<**u64**> | accrued size of all replicas contained in this pool | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/PoolStatus.md b/testgen/src/autogen/docs/models/PoolStatus.md new file mode 100644 index 000000000..d0317632c --- /dev/null +++ b/testgen/src/autogen/docs/models/PoolStatus.md @@ -0,0 +1,10 @@ +# PoolStatus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/PoolTopology.md b/testgen/src/autogen/docs/models/PoolTopology.md new file mode 100644 index 000000000..398c45114 --- /dev/null +++ b/testgen/src/autogen/docs/models/PoolTopology.md @@ -0,0 +1,11 @@ +# PoolTopology + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**labelled** | Option<[**crate::models::LabelledTopology**](.md)> | volume pool topology definition through labels | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Protocol.md b/testgen/src/autogen/docs/models/Protocol.md new file mode 100644 index 000000000..3eea538e0 --- /dev/null +++ b/testgen/src/autogen/docs/models/Protocol.md @@ -0,0 +1,10 @@ +# Protocol + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/PublishVolumeBody.md b/testgen/src/autogen/docs/models/PublishVolumeBody.md new file mode 100644 index 000000000..4032b01d7 --- /dev/null +++ b/testgen/src/autogen/docs/models/PublishVolumeBody.md @@ -0,0 +1,16 @@ +# PublishVolumeBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**publish_context** | [**::std::collections::HashMap**](.md) | Controller Volume Publish context | +**reuse_existing** | Option<**bool**> | Allows reusing of the current target. | [optional] +**node** | Option<[**String**](.md)> | The node where the target will reside in. It may be moved elsewhere during volume republish. | [optional] +**protocol** | [**crate::models::VolumeShareProtocol**](.md) | The protocol used to connect to the front-end node. | +**republish** | Option<**bool**> | Allows republishing the volume on the node by shutting down the existing target first. | [optional] +**frontend_node** | Option<**String**> | The node where the front-end workload resides. If the workload moves then the volume must be republished. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/RebuildJobState.md b/testgen/src/autogen/docs/models/RebuildJobState.md new file mode 100644 index 000000000..f4847b99c --- /dev/null +++ b/testgen/src/autogen/docs/models/RebuildJobState.md @@ -0,0 +1,10 @@ +# RebuildJobState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/RebuildRecord.md b/testgen/src/autogen/docs/models/RebuildRecord.md new file mode 100644 index 000000000..dbb5f2108 --- /dev/null +++ b/testgen/src/autogen/docs/models/RebuildRecord.md @@ -0,0 +1,21 @@ +# RebuildRecord + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**child_uri** | **String** | Uri of the rebuilding child | +**src_uri** | **String** | Uri of source child for rebuild job | +**rebuild_job_state** | [**crate::models::RebuildJobState**](.md) | State of the rebuild job | +**blocks_total** | **u64** | Total blocks to rebuild | +**blocks_recovered** | **u64** | Number of blocks processed | +**blocks_transferred** | **u64** | Number of blocks to transferred | +**blocks_remaining** | **u64** | Number of blocks remaining | +**block_size** | **u64** | Size of each block in the task | +**is_partial** | **bool** | True means its Partial rebuild job. If false, its Full rebuild job | +**start_time** | **String** | Start time of the rebuild job (UTC) | +**end_time** | **String** | End time of the rebuild job (UTC) | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/RegisterAppNode.md b/testgen/src/autogen/docs/models/RegisterAppNode.md new file mode 100644 index 000000000..d607b2de6 --- /dev/null +++ b/testgen/src/autogen/docs/models/RegisterAppNode.md @@ -0,0 +1,12 @@ +# RegisterAppNode + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**endpoint** | **String** | gRPC server endpoint of the app node. | +**labels** | Option<[**::std::collections::HashMap**](.md)> | Labels to be set on the app node. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Replica.md b/testgen/src/autogen/docs/models/Replica.md new file mode 100644 index 000000000..22aef7e23 --- /dev/null +++ b/testgen/src/autogen/docs/models/Replica.md @@ -0,0 +1,22 @@ +# Replica + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**node** | **String** | storage node identifier | +**pool** | **String** | storage pool identifier | +**pool_uuid** | Option<**uuid::Uuid**> | storage pool unique identifier | [optional] +**share** | [**crate::models::Protocol**](.md) | Common Protocol | +**size** | **u64** | size of the replica in bytes | +**space** | Option<[**crate::models::ReplicaSpaceUsage**](.md)> | Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. | [optional] +**state** | [**crate::models::ReplicaState**](.md) | state of the replica | +**thin** | **bool** | thin provisioning | +**uri** | **String** | uri usable by nexus to access it | +**uuid** | **uuid::Uuid** | uuid of the replica | +**allowed_hosts** | Option<[**Vec**](.md)> | NQNs of hosts allowed to connect to this replica | [optional] +**kind** | [**crate::models::ReplicaKind**](.md) | Type of replica, example regular or snapshot. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaKind.md b/testgen/src/autogen/docs/models/ReplicaKind.md new file mode 100644 index 000000000..c12864b3f --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaKind.md @@ -0,0 +1,10 @@ +# ReplicaKind + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaShareProtocol.md b/testgen/src/autogen/docs/models/ReplicaShareProtocol.md new file mode 100644 index 000000000..7ac1a6082 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaShareProtocol.md @@ -0,0 +1,10 @@ +# ReplicaShareProtocol + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSnapshot.md b/testgen/src/autogen/docs/models/ReplicaSnapshot.md new file mode 100644 index 000000000..3503e2970 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSnapshot.md @@ -0,0 +1,13 @@ +# ReplicaSnapshot + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uuid** | **uuid::Uuid** | | +**source_id** | **uuid::Uuid** | | +**status** | [**crate::models::SpecStatus**](.md) | Common base state for a resource | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSnapshotState.md b/testgen/src/autogen/docs/models/ReplicaSnapshotState.md new file mode 100644 index 000000000..07a911a20 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSnapshotState.md @@ -0,0 +1,12 @@ +# ReplicaSnapshotState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**online** | Option<[**crate::models::OnlineReplicaSnapshotState**](.md)> | Online ReplicaSnapshotState representation. | [optional] +**offline** | Option<[**crate::models::OfflineReplicaSnapshotState**](.md)> | Offline ReplicaSnapshotState representation. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSnapshotStatus.md b/testgen/src/autogen/docs/models/ReplicaSnapshotStatus.md new file mode 100644 index 000000000..c851c726a --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSnapshotStatus.md @@ -0,0 +1,10 @@ +# ReplicaSnapshotStatus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSpaceUsage.md b/testgen/src/autogen/docs/models/ReplicaSpaceUsage.md new file mode 100644 index 000000000..15e728492 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSpaceUsage.md @@ -0,0 +1,17 @@ +# ReplicaSpaceUsage + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**capacity_bytes** | **u64** | Replica capacity in bytes. | +**allocated_bytes** | **u64** | Amount of actually allocated disk space for this replica in bytes. | +**allocated_bytes_snapshots** | **u64** | Amount of actually allocated disk space for this replica\'s snapshots in bytes. | +**allocated_bytes_all_snapshots** | Option<**u64**> | Amount of actually allocated disk space for this replica\'s snapshots and its predecessors in bytes. For a restored/cloned replica this includes snapshots from the parent source. | [optional] +**cluster_size** | **u64** | Cluster size in bytes. | +**clusters** | **u64** | Total number of clusters. | +**allocated_clusters** | **u64** | Number of actually used clusters. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSpec.md b/testgen/src/autogen/docs/models/ReplicaSpec.md new file mode 100644 index 000000000..37af98b8d --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSpec.md @@ -0,0 +1,21 @@ +# ReplicaSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**managed** | **bool** | Managed by our control plane | +**operation** | Option<[**crate::models::ReplicaSpecOperation**](.md)> | Record of the operation in progress | [optional] +**owners** | [**crate::models::ReplicaSpecOwners**](.md) | Owner Resource | +**pool** | **String** | The pool that the replica should live on. | +**pool_uuid** | Option<**uuid::Uuid**> | storage pool unique identifier | [optional] +**share** | [**crate::models::Protocol**](.md) | Common Protocol | +**size** | **u64** | The size that the replica should be. | +**status** | [**crate::models::SpecStatus**](.md) | Common base state for a resource | +**thin** | **bool** | Thin provisioning. | +**uuid** | **uuid::Uuid** | uuid of the replica | +**kind** | Option<[**crate::models::ReplicaKind**](.md)> | Type of replica, example regular or snapshot. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSpecOperation.md b/testgen/src/autogen/docs/models/ReplicaSpecOperation.md new file mode 100644 index 000000000..f08a778a5 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSpecOperation.md @@ -0,0 +1,12 @@ +# ReplicaSpecOperation + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**operation** | [**Operation**](.md) | Record of the operation | +**result** | Option<**bool**> | Result of the operation | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaSpecOwners.md b/testgen/src/autogen/docs/models/ReplicaSpecOwners.md new file mode 100644 index 000000000..80fdac1a5 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaSpecOwners.md @@ -0,0 +1,12 @@ +# ReplicaSpecOwners + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nexuses** | [**Vec**](.md) | | +**volume** | Option<**uuid::Uuid**> | | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaState.md b/testgen/src/autogen/docs/models/ReplicaState.md new file mode 100644 index 000000000..fdc2ebfbe --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaState.md @@ -0,0 +1,10 @@ +# ReplicaState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaTopology.md b/testgen/src/autogen/docs/models/ReplicaTopology.md new file mode 100644 index 000000000..ce292c91c --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaTopology.md @@ -0,0 +1,17 @@ +# ReplicaTopology + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**node** | Option<**String**> | storage node identifier | [optional] +**pool** | Option<**String**> | storage pool identifier | [optional] +**state** | [**crate::models::ReplicaState**](.md) | state of the replica | +**child_status** | Option<[**crate::models::ChildState**](.md)> | State of a Nexus Child | [optional] +**child_status_reason** | Option<[**crate::models::ChildStateReason**](.md)> | Reason for the state of a Nexus Child | [optional] +**usage** | Option<[**crate::models::ReplicaUsage**](.md)> | Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. | [optional] +**rebuild_progress** | Option<**usize**> | current rebuild progress (%) | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ReplicaUsage.md b/testgen/src/autogen/docs/models/ReplicaUsage.md new file mode 100644 index 000000000..dd6642046 --- /dev/null +++ b/testgen/src/autogen/docs/models/ReplicaUsage.md @@ -0,0 +1,14 @@ +# ReplicaUsage + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**capacity** | **u64** | Replica capacity in bytes. | +**allocated** | **u64** | Amount of actually allocated disk space for this replica in bytes. | +**allocated_snapshots** | **u64** | Amount of actually allocated disk space for this replica\'s snapshots in bytes. | +**allocated_all_snapshots** | **u64** | Amount of actually allocated disk space for this replica\'s snapshots and its predecessors in bytes. For a restored/cloned replica this includes snapshots from the parent source. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/ResizeVolumeBody.md b/testgen/src/autogen/docs/models/ResizeVolumeBody.md new file mode 100644 index 000000000..1c776327f --- /dev/null +++ b/testgen/src/autogen/docs/models/ResizeVolumeBody.md @@ -0,0 +1,11 @@ +# ResizeVolumeBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**size** | **u64** | New required size of the volume in bytes | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/RestJsonError.md b/testgen/src/autogen/docs/models/RestJsonError.md new file mode 100644 index 000000000..30d93f00f --- /dev/null +++ b/testgen/src/autogen/docs/models/RestJsonError.md @@ -0,0 +1,13 @@ +# RestJsonError + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**details** | **String** | detailed error information | +**message** | **String** | last reported error information | +**kind** | [**Kind**](.md) | error kind | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/RestWatch.md b/testgen/src/autogen/docs/models/RestWatch.md new file mode 100644 index 000000000..597bc6532 --- /dev/null +++ b/testgen/src/autogen/docs/models/RestWatch.md @@ -0,0 +1,12 @@ +# RestWatch + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**callback** | **String** | callback used to notify the watch of a change | +**resource** | **String** | id of the resource to watch on | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/SetVolumePropertyBody.md b/testgen/src/autogen/docs/models/SetVolumePropertyBody.md new file mode 100644 index 000000000..f1c9d3fe6 --- /dev/null +++ b/testgen/src/autogen/docs/models/SetVolumePropertyBody.md @@ -0,0 +1,11 @@ +# SetVolumePropertyBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**max_snapshots** | Option<**u32**> | Max Snapshots limit per volume. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/SnapshotAsSource.md b/testgen/src/autogen/docs/models/SnapshotAsSource.md new file mode 100644 index 000000000..1eb1810f3 --- /dev/null +++ b/testgen/src/autogen/docs/models/SnapshotAsSource.md @@ -0,0 +1,12 @@ +# SnapshotAsSource + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**snapshot** | **uuid::Uuid** | | +**volume** | **uuid::Uuid** | | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/SpecStatus.md b/testgen/src/autogen/docs/models/SpecStatus.md new file mode 100644 index 000000000..8f047646b --- /dev/null +++ b/testgen/src/autogen/docs/models/SpecStatus.md @@ -0,0 +1,10 @@ +# SpecStatus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Specs.md b/testgen/src/autogen/docs/models/Specs.md new file mode 100644 index 000000000..4429f6205 --- /dev/null +++ b/testgen/src/autogen/docs/models/Specs.md @@ -0,0 +1,14 @@ +# Specs + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nexuses** | [**Vec**](.md) | Nexus Specs | +**pools** | [**Vec**](.md) | Pool Specs | +**replicas** | [**Vec**](.md) | Replica Specs | +**volumes** | [**Vec**](.md) | Volume Specs | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Topology.md b/testgen/src/autogen/docs/models/Topology.md new file mode 100644 index 000000000..fc0aff511 --- /dev/null +++ b/testgen/src/autogen/docs/models/Topology.md @@ -0,0 +1,12 @@ +# Topology + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**node_topology** | Option<[**crate::models::NodeTopology**](.md)> | Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. | [optional] +**pool_topology** | Option<[**crate::models::PoolTopology**](.md)> | Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Volume.md b/testgen/src/autogen/docs/models/Volume.md new file mode 100644 index 000000000..f72e82b66 --- /dev/null +++ b/testgen/src/autogen/docs/models/Volume.md @@ -0,0 +1,12 @@ +# Volume + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**spec** | [**crate::models::VolumeSpec**](.md) | User specification of a volume. | +**state** | [**crate::models::VolumeState**](.md) | Runtime state of the volume | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeContentSource.md b/testgen/src/autogen/docs/models/VolumeContentSource.md new file mode 100644 index 000000000..87b9352ef --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeContentSource.md @@ -0,0 +1,11 @@ +# VolumeContentSource + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**snapshot** | Option<[**crate::models::SnapshotAsSource**](.md)> | The snapshot source for the volume content. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumePolicy.md b/testgen/src/autogen/docs/models/VolumePolicy.md new file mode 100644 index 000000000..1efdbffc2 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumePolicy.md @@ -0,0 +1,11 @@ +# VolumePolicy + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**self_heal** | **bool** | If true the control plane will attempt to heal the volume by itself | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeShareProtocol.md b/testgen/src/autogen/docs/models/VolumeShareProtocol.md new file mode 100644 index 000000000..260711659 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeShareProtocol.md @@ -0,0 +1,10 @@ +# VolumeShareProtocol + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSnapshot.md b/testgen/src/autogen/docs/models/VolumeSnapshot.md new file mode 100644 index 000000000..2d9cdc143 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSnapshot.md @@ -0,0 +1,12 @@ +# VolumeSnapshot + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**definition** | [**crate::models::VolumeSnapshotDefinition**](.md) | Volume Snapshot Metadata and Spec information. | +**state** | [**crate::models::VolumeSnapshotState**](.md) | Volume Snapshot State information. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSnapshotDefinition.md b/testgen/src/autogen/docs/models/VolumeSnapshotDefinition.md new file mode 100644 index 000000000..eaf140660 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSnapshotDefinition.md @@ -0,0 +1,12 @@ +# VolumeSnapshotDefinition + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**metadata** | [**crate::models::VolumeSnapshotMetadata**](.md) | Volume Snapshot Metadata information. | +**spec** | [**crate::models::VolumeSnapshotSpec**](.md) | Volume Snapshot Spec information. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSnapshotMetadata.md b/testgen/src/autogen/docs/models/VolumeSnapshotMetadata.md new file mode 100644 index 000000000..6db671028 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSnapshotMetadata.md @@ -0,0 +1,19 @@ +# VolumeSnapshotMetadata + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**status** | [**crate::models::SpecStatus**](.md) | Common base state for a resource | +**timestamp** | Option<**String**> | Timestamp when snapshot is taken on the storage system. | [optional] +**size** | **u64** | Size in bytes of the snapshot (which is equivalent to its source size). | +**spec_size** | **u64** | Spec size in bytes of the snapshot (which is equivalent to its source spec size). | +**total_allocated_size** | **u64** | Size in bytes taken by the snapshot and its predecessors. | +**txn_id** | **String** | | +**transactions** | [**::std::collections::HashMap>**](.md) | | +**num_restores** | **u32** | Number of restores done from this snapshot. | +**num_snapshot_replicas** | **u32** | Number of snapshot replicas for a volumesnapshot. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSnapshotSpec.md b/testgen/src/autogen/docs/models/VolumeSnapshotSpec.md new file mode 100644 index 000000000..4ab8818d9 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSnapshotSpec.md @@ -0,0 +1,12 @@ +# VolumeSnapshotSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uuid** | **uuid::Uuid** | | +**source_volume** | **uuid::Uuid** | | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSnapshotState.md b/testgen/src/autogen/docs/models/VolumeSnapshotState.md new file mode 100644 index 000000000..f0fd0f190 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSnapshotState.md @@ -0,0 +1,16 @@ +# VolumeSnapshotState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uuid** | **uuid::Uuid** | | +**allocated_size** | **u64** | Runtime size in bytes of the snapshot. Equal to the volume allocation at the time of the snapshot creation. It may grow larger if any of its predecessors are deleted. | +**source_volume** | **uuid::Uuid** | | +**timestamp** | Option<**String**> | Timestamp when snapshot is taken on the storage system. | [optional] +**ready_as_source** | **bool** | Indicates if a snapshot is ready to be used as a new volume source. | +**replica_snapshots** | [**Vec**](.md) | List of individual ReplicaSnapshotStates. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSnapshots.md b/testgen/src/autogen/docs/models/VolumeSnapshots.md new file mode 100644 index 000000000..17f70da93 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSnapshots.md @@ -0,0 +1,12 @@ +# VolumeSnapshots + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**entries** | [**Vec**](.md) | | +**next_token** | Option<**isize**> | | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSpec.md b/testgen/src/autogen/docs/models/VolumeSpec.md new file mode 100644 index 000000000..96376990a --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSpec.md @@ -0,0 +1,25 @@ +# VolumeSpec + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**labels** | Option<[**::std::collections::HashMap**](.md)> | Optionally used to store custom volume information | [optional] +**num_replicas** | **u8** | Number of children the volume should have. | +**operation** | Option<[**crate::models::VolumeSpecOperation**](.md)> | Record of the operation in progress | [optional] +**size** | **u64** | Size that the volume should be. | +**status** | [**crate::models::SpecStatus**](.md) | Common base state for a resource | +**target** | Option<[**crate::models::VolumeTarget**](.md)> | Specification of a volume target | [optional] +**uuid** | **uuid::Uuid** | Volume Id | +**topology** | Option<[**crate::models::Topology**](.md)> | node and pool topology for volumes | [optional] +**policy** | [**crate::models::VolumePolicy**](.md) | Volume policy used to determine if and how to replace a replica | +**thin** | **bool** | Thin provisioning flag. | +**as_thin** | Option<**bool**> | Volume converted to thin provisioned. | [optional] +**affinity_group** | Option<[**crate::models::AffinityGroup**](.md)> | Affinity Group related information. | [optional] +**content_source** | Option<[**crate::models::VolumeContentSource**](.md)> | Volume Content Source i.e the snapshot or the volume. | [optional] +**num_snapshots** | **u32** | Number of snapshots taken on this volume. | +**max_snapshots** | Option<**u32**> | Max snapshots to limit per volume. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeSpecOperation.md b/testgen/src/autogen/docs/models/VolumeSpecOperation.md new file mode 100644 index 000000000..ccacc2767 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeSpecOperation.md @@ -0,0 +1,12 @@ +# VolumeSpecOperation + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**operation** | [**Operation**](.md) | Record of the operation | +**result** | Option<**bool**> | Result of the operation | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeState.md b/testgen/src/autogen/docs/models/VolumeState.md new file mode 100644 index 000000000..27363e40e --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeState.md @@ -0,0 +1,16 @@ +# VolumeState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**target** | Option<[**crate::models::Nexus**](.md)> | target exposed via a Nexus | [optional] +**size** | **u64** | size of the volume in bytes | +**status** | [**crate::models::VolumeStatus**](.md) | current volume status | +**uuid** | **uuid::Uuid** | name of the volume | +**replica_topology** | [**::std::collections::HashMap**](.md) | replica topology information | +**usage** | Option<[**crate::models::VolumeUsage**](.md)> | Volume space usage | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeStatus.md b/testgen/src/autogen/docs/models/VolumeStatus.md new file mode 100644 index 000000000..1dd8b1a9d --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeStatus.md @@ -0,0 +1,10 @@ +# VolumeStatus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeTarget.md b/testgen/src/autogen/docs/models/VolumeTarget.md new file mode 100644 index 000000000..1e0ab0ca8 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeTarget.md @@ -0,0 +1,13 @@ +# VolumeTarget + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**node** | **String** | The node where front-end IO will be sent to | +**protocol** | Option<[**crate::models::VolumeShareProtocol**](.md)> | Volume Share Protocol | [optional] +**frontend_nodes** | Option<[**Vec**](.md)> | The nodes where the front-end workload resides. If the workload moves then the volume must be republished. | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/VolumeUsage.md b/testgen/src/autogen/docs/models/VolumeUsage.md new file mode 100644 index 000000000..b19603eb6 --- /dev/null +++ b/testgen/src/autogen/docs/models/VolumeUsage.md @@ -0,0 +1,18 @@ +# VolumeUsage + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**capacity** | **u64** | Capacity of the volume in bytes. | +**allocated** | **u64** | -| Allocated size in bytes, related the largest healthy replica, including snapshots. For example, if a volume has 2 replicas, each with 1MiB allocated space, then this field will be 1MiB. | +**allocated_replica** | **u64** | -| Allocated size in bytes, related to the largest healthy replica, excluding snapshots. | +**allocated_snapshots** | **u64** | -| Allocated size in bytes, related the healthy replica with the highest snapshot usage. | +**allocated_all_snapshots** | **u64** | -| For a restored/cloned volume, allocated size in bytes, related to the healthy replica with largest parent snapshot allocation. | +**total_allocated** | **u64** | -| Allocated size in bytes, accrued from all the replicas, including snapshots. For example, if a volume has 2 replicas, each with 1MiB allocated space, then this field will be 2MiB. | +**total_allocated_replicas** | [**serde_json::Value**](.md) | -| Allocated size in bytes, accrued from all the replicas, excluding snapshots. | +**total_allocated_snapshots** | **u64** | -| Allocated size in bytes, accrued from all the replica\'s snapshots. | + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/Volumes.md b/testgen/src/autogen/docs/models/Volumes.md new file mode 100644 index 000000000..058ad52e6 --- /dev/null +++ b/testgen/src/autogen/docs/models/Volumes.md @@ -0,0 +1,12 @@ +# Volumes + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**entries** | [**Vec**](.md) | | +**next_token** | Option<**isize**> | | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/docs/models/WatchCallback.md b/testgen/src/autogen/docs/models/WatchCallback.md new file mode 100644 index 000000000..6982b34f7 --- /dev/null +++ b/testgen/src/autogen/docs/models/WatchCallback.md @@ -0,0 +1,11 @@ +# WatchCallback + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uri** | Option<**String**> | | [optional] + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/testgen/src/autogen/mod.rs b/testgen/src/autogen/mod.rs new file mode 100644 index 000000000..2ad74474f --- /dev/null +++ b/testgen/src/autogen/mod.rs @@ -0,0 +1,24 @@ +#[macro_use] +extern crate serde_derive; + +extern crate serde; +extern crate serde_json; +extern crate url; + +pub mod apis; +pub mod models; +pub mod clients; + +#[cfg(feature = "tower-hyper")] +pub mod tower { + pub use crate::clients::tower as client; +} + +#[cfg(feature = "actix")] +pub mod actix { + #[cfg(feature = "actix-client")] + pub use crate::clients::actix as client; + + #[cfg(feature = "actix-server")] + pub use crate::apis::actix_server as server; +} \ No newline at end of file diff --git a/testgen/src/autogen/models/affinity_group.rs b/testgen/src/autogen/models/affinity_group.rs new file mode 100644 index 000000000..40b09e6ad --- /dev/null +++ b/testgen/src/autogen/models/affinity_group.rs @@ -0,0 +1,52 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// AffinityGroup : Affinity Group related information. + + + + + + + + +/// Affinity Group related information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct AffinityGroup { + + /// Identification of the Affinity Group. + #[serde(default, rename = "id")] + pub id: String, + +} + +impl AffinityGroup { + /// AffinityGroup using only the required fields + pub fn new(id: impl Into) -> AffinityGroup { + AffinityGroup { + id: id.into(), + + } + } + /// AffinityGroup using all fields + pub fn new_all(id: impl Into) -> AffinityGroup { + AffinityGroup { + id: id.into(), + + } + } +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/app_node.rs b/testgen/src/autogen/models/app_node.rs new file mode 100644 index 000000000..db2a36762 --- /dev/null +++ b/testgen/src/autogen/models/app_node.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// AppNode : Represents an application node, which connects to the target node via a share protocol (eg: nvmf). + + + + + + + + +/// Represents an application node, which connects to the target node via a share protocol (eg: nvmf). + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct AppNode { + + /// App node identifier. + #[serde(default, rename = "id")] + pub id: String, + + /// App node attributes. + #[serde(default, rename = "spec")] + pub spec: crate::models::AppNodeSpec, + + /// Deemed state of the app node. + #[serde(default, rename = "state", skip_serializing_if = "Option::is_none")] + pub state: Option, + +} + +impl AppNode { + /// AppNode using only the required fields + pub fn new(id: impl Into, spec: impl Into) -> AppNode { + AppNode { + id: id.into(), + spec: spec.into(), + state: None, + + } + } + /// AppNode using all fields + pub fn new_all(id: impl Into, spec: impl Into, state: impl Into>) -> AppNode { + AppNode { + id: id.into(), + spec: spec.into(), + state: state.into(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/app_node_spec.rs b/testgen/src/autogen/models/app_node_spec.rs new file mode 100644 index 000000000..5a0f52aa5 --- /dev/null +++ b/testgen/src/autogen/models/app_node_spec.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// AppNodeSpec : App node attributes. + + + + + + + + +/// App node attributes. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct AppNodeSpec { + + /// App node identifier. + #[serde(default, rename = "id")] + pub id: String, + + /// gRPC server endpoint of the app node. + #[serde(default, rename = "endpoint")] + pub endpoint: String, + + /// Labels to be set on the app node. + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + +} + +impl AppNodeSpec { + /// AppNodeSpec using only the required fields + pub fn new(id: impl Into, endpoint: impl Into) -> AppNodeSpec { + AppNodeSpec { + id: id.into(), + endpoint: endpoint.into(), + labels: None, + + } + } + /// AppNodeSpec using all fields + pub fn new_all(id: impl Into, endpoint: impl Into, labels: impl Into>>) -> AppNodeSpec { + AppNodeSpec { + id: id.into(), + endpoint: endpoint.into(), + labels: labels.into(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/app_node_state.rs b/testgen/src/autogen/models/app_node_state.rs new file mode 100644 index 000000000..6b516996a --- /dev/null +++ b/testgen/src/autogen/models/app_node_state.rs @@ -0,0 +1,89 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// AppNodeState : Deemed state of the app node. + + + + + + + + +/// Deemed state of the app node. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct AppNodeState { + + /// App node identifier. + #[serde(default, rename = "id")] + pub id: String, + + /// gRPC server endpoint of the app node. + #[serde(default, rename = "endpoint")] + pub endpoint: String, + + /// Deemed Status of the app node. + #[serde(default, rename = "status")] + pub status: Status, + +} + +impl AppNodeState { + /// AppNodeState using only the required fields + pub fn new(id: impl Into, endpoint: impl Into, status: impl Into) -> AppNodeState { + AppNodeState { + id: id.into(), + endpoint: endpoint.into(), + status: status.into(), + + } + } + /// AppNodeState using all fields + pub fn new_all(id: impl Into, endpoint: impl Into, status: impl Into) -> AppNodeState { + AppNodeState { + id: id.into(), + endpoint: endpoint.into(), + status: status.into(), + + } + } +} + + + + + + + + + + + + +/// Deemed Status of the app node. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum Status { + + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Offline")] + Offline, + + +} + +impl Default for Status { + fn default() -> Self { + Self::Online + } +} + + + + diff --git a/testgen/src/autogen/models/app_nodes.rs b/testgen/src/autogen/models/app_nodes.rs new file mode 100644 index 000000000..158661d76 --- /dev/null +++ b/testgen/src/autogen/models/app_nodes.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// AppNodes : Array of app nodes plus the next token for subsequent get requests when using pagination. + + + + + + + + +/// Array of app nodes plus the next token for subsequent get requests when using pagination. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct AppNodes { + + + #[serde(default, rename = "entries")] + pub entries: Vec, + + + #[serde(default, rename = "next_token", skip_serializing_if = "Option::is_none")] + pub next_token: Option, + +} + +impl AppNodes { + /// AppNodes using only the required fields + pub fn new(entries: impl IntoVec) -> AppNodes { + AppNodes { + entries: entries.into_vec(), + next_token: None, + + } + } + /// AppNodes using all fields + pub fn new_all(entries: impl IntoVec, next_token: impl Into>) -> AppNodes { + AppNodes { + entries: entries.into_vec(), + next_token: next_token.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/block_device.rs b/testgen/src/autogen/models/block_device.rs new file mode 100644 index 000000000..866fc16e0 --- /dev/null +++ b/testgen/src/autogen/models/block_device.rs @@ -0,0 +1,148 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// BlockDevice : Block device information + + + + + + + + +/// Block device information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct BlockDevice { + + /// identifies if device is available for use (ie. is not \"currently\" in use) + #[serde(default, rename = "available")] + pub available: bool, + + /// the type of bus through which the device is connected to the system + #[serde(default, rename = "connection_type")] + pub connection_type: String, + + /// list of udev generated symlinks by which device may be identified + #[serde(default, rename = "devlinks")] + pub devlinks: Vec, + + /// major device number + #[serde(default, rename = "devmajor")] + pub devmajor: i32, + + /// minor device number + #[serde(default, rename = "devminor")] + pub devminor: i32, + + /// entry in /dev associated with device + #[serde(default, rename = "devname")] + pub devname: String, + + /// official device path + #[serde(default, rename = "devpath")] + pub devpath: String, + + /// currently \"disk\" or \"partition\" + #[serde(default, rename = "devtype")] + pub devtype: String, + + /// filesystem information in case where a filesystem is present + #[serde(default, rename = "filesystem", skip_serializing_if = "Option::is_none")] + pub filesystem: Option, + + /// indicates whether the device is rotational or non-rotational + #[serde(default, rename = "is_rotational", skip_serializing_if = "Option::is_none")] + pub is_rotational: Option, + + /// device model - useful for identifying devices + #[serde(default, rename = "model")] + pub model: String, + + /// partition information in case where device represents a partition + #[serde(default, rename = "partition", skip_serializing_if = "Option::is_none")] + pub partition: Option, + + /// size of device in (512 byte) blocks + #[serde(default, rename = "size")] + pub size: u64, + +} + +impl BlockDevice { + /// BlockDevice using only the required fields + pub fn new(available: impl Into, connection_type: impl Into, devlinks: impl IntoVec, devmajor: impl Into, devminor: impl Into, devname: impl Into, devpath: impl Into, devtype: impl Into, model: impl Into, size: impl Into) -> BlockDevice { + BlockDevice { + available: available.into(), + connection_type: connection_type.into(), + devlinks: devlinks.into_vec(), + devmajor: devmajor.into(), + devminor: devminor.into(), + devname: devname.into(), + devpath: devpath.into(), + devtype: devtype.into(), + filesystem: None, + is_rotational: None, + model: model.into(), + partition: None, + size: size.into(), + + } + } + /// BlockDevice using all fields + pub fn new_all(available: impl Into, connection_type: impl Into, devlinks: impl IntoVec, devmajor: impl Into, devminor: impl Into, devname: impl Into, devpath: impl Into, devtype: impl Into, filesystem: impl Into>, is_rotational: impl Into>, model: impl Into, partition: impl Into>, size: impl Into) -> BlockDevice { + BlockDevice { + available: available.into(), + connection_type: connection_type.into(), + devlinks: devlinks.into_vec(), + devmajor: devmajor.into(), + devminor: devminor.into(), + devname: devname.into(), + devpath: devpath.into(), + devtype: devtype.into(), + filesystem: filesystem.into(), + is_rotational: is_rotational.into(), + model: model.into(), + partition: partition.into(), + size: size.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/block_device_filesystem.rs b/testgen/src/autogen/models/block_device_filesystem.rs new file mode 100644 index 000000000..dd6da59d1 --- /dev/null +++ b/testgen/src/autogen/models/block_device_filesystem.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// BlockDeviceFilesystem : filesystem information in case where a filesystem is present + + + + + + + + +/// filesystem information in case where a filesystem is present + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct BlockDeviceFilesystem { + + /// filesystem type: ext3, ntfs, ... + #[serde(default, rename = "fstype")] + pub fstype: String, + + /// volume label + #[serde(default, rename = "label")] + pub label: String, + + /// path where filesystem is currently mounted + #[serde(default, rename = "mountpoint")] + pub mountpoint: String, + + /// UUID identifying the volume (filesystem) + #[serde(default, rename = "uuid")] + pub uuid: String, + +} + +impl BlockDeviceFilesystem { + /// BlockDeviceFilesystem using only the required fields + pub fn new(fstype: impl Into, label: impl Into, mountpoint: impl Into, uuid: impl Into) -> BlockDeviceFilesystem { + BlockDeviceFilesystem { + fstype: fstype.into(), + label: label.into(), + mountpoint: mountpoint.into(), + uuid: uuid.into(), + + } + } + /// BlockDeviceFilesystem using all fields + pub fn new_all(fstype: impl Into, label: impl Into, mountpoint: impl Into, uuid: impl Into) -> BlockDeviceFilesystem { + BlockDeviceFilesystem { + fstype: fstype.into(), + label: label.into(), + mountpoint: mountpoint.into(), + uuid: uuid.into(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/block_device_partition.rs b/testgen/src/autogen/models/block_device_partition.rs new file mode 100644 index 000000000..b53bd4897 --- /dev/null +++ b/testgen/src/autogen/models/block_device_partition.rs @@ -0,0 +1,92 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// BlockDevicePartition : partition information in case where device represents a partition + + + + + + + + +/// partition information in case where device represents a partition + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct BlockDevicePartition { + + /// partition name + #[serde(default, rename = "name")] + pub name: String, + + /// partition number + #[serde(default, rename = "number")] + pub number: i32, + + /// devname of parent device to which this partition belongs + #[serde(default, rename = "parent")] + pub parent: String, + + /// partition scheme: gpt, dos, ... + #[serde(default, rename = "scheme")] + pub scheme: String, + + /// partition type identifier + #[serde(default, rename = "typeid")] + pub typeid: String, + + /// UUID identifying partition + #[serde(default, rename = "uuid")] + pub uuid: String, + +} + +impl BlockDevicePartition { + /// BlockDevicePartition using only the required fields + pub fn new(name: impl Into, number: impl Into, parent: impl Into, scheme: impl Into, typeid: impl Into, uuid: impl Into) -> BlockDevicePartition { + BlockDevicePartition { + name: name.into(), + number: number.into(), + parent: parent.into(), + scheme: scheme.into(), + typeid: typeid.into(), + uuid: uuid.into(), + + } + } + /// BlockDevicePartition using all fields + pub fn new_all(name: impl Into, number: impl Into, parent: impl Into, scheme: impl Into, typeid: impl Into, uuid: impl Into) -> BlockDevicePartition { + BlockDevicePartition { + name: name.into(), + number: number.into(), + parent: parent.into(), + scheme: scheme.into(), + typeid: typeid.into(), + uuid: uuid.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/child.rs b/testgen/src/autogen/models/child.rs new file mode 100644 index 000000000..cdaf80b22 --- /dev/null +++ b/testgen/src/autogen/models/child.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Child : Child information + + + + + + + + +/// Child information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Child { + + /// current rebuild progress (%) + #[serde(default, rename = "rebuildProgress", skip_serializing_if = "Option::is_none")] + pub rebuild_progress: Option, + + /// State of a Nexus Child + #[serde(default, rename = "state")] + pub state: crate::models::ChildState, + + /// Reason for the state of a Nexus Child + #[serde(default, rename = "state_reason", skip_serializing_if = "Option::is_none")] + pub state_reason: Option, + + /// uri of the child device + #[serde(default, rename = "uri")] + pub uri: String, + +} + +impl Child { + /// Child using only the required fields + pub fn new(state: impl Into, uri: impl Into) -> Child { + Child { + rebuild_progress: None, + state: state.into(), + state_reason: None, + uri: uri.into(), + + } + } + /// Child using all fields + pub fn new_all(rebuild_progress: impl Into>, state: impl Into, state_reason: impl Into>, uri: impl Into) -> Child { + Child { + rebuild_progress: rebuild_progress.into(), + state: state.into(), + state_reason: state_reason.into(), + uri: uri.into(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/child_state.rs b/testgen/src/autogen/models/child_state.rs new file mode 100644 index 000000000..2ada9d8a0 --- /dev/null +++ b/testgen/src/autogen/models/child_state.rs @@ -0,0 +1,61 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ChildState : State of a Nexus Child + + + +/// State of a Nexus Child +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum ChildState { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Degraded")] + Degraded, + + #[serde(rename = "Faulted")] + Faulted, + +} + +impl ToString for ChildState { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Degraded => String::from("Degraded"), + + Self::Faulted => String::from("Faulted"), + + + } + } +} + +impl Default for ChildState { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/child_state_reason.rs b/testgen/src/autogen/models/child_state_reason.rs new file mode 100644 index 000000000..7ac9ec63d --- /dev/null +++ b/testgen/src/autogen/models/child_state_reason.rs @@ -0,0 +1,46 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ChildStateReason : Reason for the state of a Nexus Child + + + +/// Reason for the state of a Nexus Child +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum ChildStateReason { + + + #[serde(rename = "OutOfSpace")] + OutOfSpace, + +} + +impl ToString for ChildStateReason { + fn to_string(&self) -> String { + match self { + + + Self::OutOfSpace => String::from("OutOfSpace"), + + + } + } +} + +impl Default for ChildStateReason { + fn default() -> Self { + Self::OutOfSpace + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/cordon_drain_state.rs b/testgen/src/autogen/models/cordon_drain_state.rs new file mode 100644 index 000000000..03e3c322a --- /dev/null +++ b/testgen/src/autogen/models/cordon_drain_state.rs @@ -0,0 +1,49 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// CordonDrainState : The drain state + + + + + + + + +/// The drain state + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum CordonDrainState { + + /// The item is cordoned + #[serde(rename = "cordonedstate")] + cordonedstate(crate::models::CordonedState), + + /// The item is draining + #[serde(rename = "drainingstate")] + drainingstate(crate::models::DrainState), + + /// The item is draining + #[serde(rename = "drainedstate")] + drainedstate(crate::models::DrainState), + +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/cordoned_state.rs b/testgen/src/autogen/models/cordoned_state.rs new file mode 100644 index 000000000..694f7bbae --- /dev/null +++ b/testgen/src/autogen/models/cordoned_state.rs @@ -0,0 +1,52 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// CordonedState : The item is cordoned + + + + + + + + +/// The item is cordoned + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct CordonedState { + + + #[serde(default, rename = "cordonlabels")] + pub cordonlabels: Vec, + +} + +impl CordonedState { + /// CordonedState using only the required fields + pub fn new(cordonlabels: impl IntoVec) -> CordonedState { + CordonedState { + cordonlabels: cordonlabels.into_vec(), + + } + } + /// CordonedState using all fields + pub fn new_all(cordonlabels: impl IntoVec) -> CordonedState { + CordonedState { + cordonlabels: cordonlabels.into_vec(), + + } + } +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/create_nexus_body.rs b/testgen/src/autogen/models/create_nexus_body.rs new file mode 100644 index 000000000..4e3101dbe --- /dev/null +++ b/testgen/src/autogen/models/create_nexus_body.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// CreateNexusBody : Create Nexus Body + + + + + + + + +/// Create Nexus Body + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct CreateNexusBody { + + /// replica can be iscsi and nvmf remote targets or a local spdk bdev (i.e. bdev:///name-of-the-bdev). uris to the targets we connect to + #[serde(default, rename = "children")] + pub children: Vec, + + /// size of the device in bytes + #[serde(default, rename = "size")] + pub size: u64, + +} + +impl CreateNexusBody { + /// CreateNexusBody using only the required fields + pub fn new(children: impl IntoVec, size: impl Into) -> CreateNexusBody { + CreateNexusBody { + children: children.into_vec(), + size: size.into(), + + } + } + /// CreateNexusBody using all fields + pub fn new_all(children: impl IntoVec, size: impl Into) -> CreateNexusBody { + CreateNexusBody { + children: children.into_vec(), + size: size.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/create_pool_body.rs b/testgen/src/autogen/models/create_pool_body.rs new file mode 100644 index 000000000..5c2994a34 --- /dev/null +++ b/testgen/src/autogen/models/create_pool_body.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// CreatePoolBody : Create Pool Body + + + + + + + + +/// Create Pool Body + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct CreatePoolBody { + + /// disk device paths or URIs to be claimed by the pool + #[serde(default, rename = "disks")] + pub disks: Vec, + + /// labels to be set on the pools + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + +} + +impl CreatePoolBody { + /// CreatePoolBody using only the required fields + pub fn new(disks: impl IntoVec) -> CreatePoolBody { + CreatePoolBody { + disks: disks.into_vec(), + labels: None, + + } + } + /// CreatePoolBody using all fields + pub fn new_all(disks: impl IntoVec, labels: impl Into>>) -> CreatePoolBody { + CreatePoolBody { + disks: disks.into_vec(), + labels: labels.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/create_replica_body.rs b/testgen/src/autogen/models/create_replica_body.rs new file mode 100644 index 000000000..44cc320fa --- /dev/null +++ b/testgen/src/autogen/models/create_replica_body.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// CreateReplicaBody : Create Replica Body + + + + + + + + +/// Create Replica Body + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct CreateReplicaBody { + + /// Replica Share Protocol + #[serde(default, rename = "share", skip_serializing_if = "Option::is_none")] + pub share: Option, + + + #[serde(default, rename = "allowed-hosts", skip_serializing_if = "Option::is_none")] + pub allowed_hosts: Option>, + + /// size of the replica in bytes + #[serde(default, rename = "size")] + pub size: u64, + + /// thin provisioning + #[serde(default, rename = "thin")] + pub thin: bool, + +} + +impl CreateReplicaBody { + /// CreateReplicaBody using only the required fields + pub fn new(size: impl Into, thin: impl Into) -> CreateReplicaBody { + CreateReplicaBody { + share: None, + allowed_hosts: None, + size: size.into(), + thin: thin.into(), + + } + } + /// CreateReplicaBody using all fields + pub fn new_all(share: impl Into>, allowed_hosts: impl IntoOptVec, size: impl Into, thin: impl Into) -> CreateReplicaBody { + CreateReplicaBody { + share: share.into(), + allowed_hosts: allowed_hosts.into_opt_vec(), + size: size.into(), + thin: thin.into(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/create_volume_body.rs b/testgen/src/autogen/models/create_volume_body.rs new file mode 100644 index 000000000..d173442e2 --- /dev/null +++ b/testgen/src/autogen/models/create_volume_body.rs @@ -0,0 +1,108 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// CreateVolumeBody : Create Volume Body + + + + + + + + +/// Create Volume Body + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct CreateVolumeBody { + + /// Volume policy used to determine if and how to replace a replica + #[serde(default, rename = "policy")] + pub policy: crate::models::VolumePolicy, + + /// number of storage replicas + #[serde(default, rename = "replicas")] + pub replicas: u8, + + /// size of the volume in bytes + #[serde(default, rename = "size")] + pub size: u64, + + /// flag indicating whether or not the volume is thin provisioned + #[serde(default, rename = "thin")] + pub thin: bool, + + /// node and pool topology for volumes + #[serde(default, rename = "topology", skip_serializing_if = "Option::is_none")] + pub topology: Option, + + /// Optionally used to store custom volume information + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + + /// Affinity Group related information. + #[serde(default, rename = "affinity_group", skip_serializing_if = "Option::is_none")] + pub affinity_group: Option, + + /// Max Snapshots limit per volume. + #[serde(default, rename = "max_snapshots", skip_serializing_if = "Option::is_none")] + pub max_snapshots: Option, + +} + +impl CreateVolumeBody { + /// CreateVolumeBody using only the required fields + pub fn new(policy: impl Into, replicas: impl Into, size: impl Into, thin: impl Into) -> CreateVolumeBody { + CreateVolumeBody { + policy: policy.into(), + replicas: replicas.into(), + size: size.into(), + thin: thin.into(), + topology: None, + labels: None, + affinity_group: None, + max_snapshots: None, + + } + } + /// CreateVolumeBody using all fields + pub fn new_all(policy: impl Into, replicas: impl Into, size: impl Into, thin: impl Into, topology: impl Into>, labels: impl Into>>, affinity_group: impl Into>, max_snapshots: impl Into>) -> CreateVolumeBody { + CreateVolumeBody { + policy: policy.into(), + replicas: replicas.into(), + size: size.into(), + thin: thin.into(), + topology: topology.into(), + labels: labels.into(), + affinity_group: affinity_group.into(), + max_snapshots: max_snapshots.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/drain_state.rs b/testgen/src/autogen/models/drain_state.rs new file mode 100644 index 000000000..9b6c098e0 --- /dev/null +++ b/testgen/src/autogen/models/drain_state.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// DrainState : The item is draining + + + + + + + + +/// The item is draining + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct DrainState { + + + #[serde(default, rename = "cordonlabels")] + pub cordonlabels: Vec, + + + #[serde(default, rename = "drainlabels")] + pub drainlabels: Vec, + +} + +impl DrainState { + /// DrainState using only the required fields + pub fn new(cordonlabels: impl IntoVec, drainlabels: impl IntoVec) -> DrainState { + DrainState { + cordonlabels: cordonlabels.into_vec(), + drainlabels: drainlabels.into_vec(), + + } + } + /// DrainState using all fields + pub fn new_all(cordonlabels: impl IntoVec, drainlabels: impl IntoVec) -> DrainState { + DrainState { + cordonlabels: cordonlabels.into_vec(), + drainlabels: drainlabels.into_vec(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/explicit_node_topology.rs b/testgen/src/autogen/models/explicit_node_topology.rs new file mode 100644 index 000000000..32dfab530 --- /dev/null +++ b/testgen/src/autogen/models/explicit_node_topology.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ExplicitNodeTopology : volume topology, explicitly selected + + + + + + + + +/// volume topology, explicitly selected + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ExplicitNodeTopology { + + /// replicas can only be placed on these nodes + #[serde(default, rename = "allowed_nodes")] + pub allowed_nodes: Vec, + + /// preferred nodes to place the replicas + #[serde(default, rename = "preferred_nodes")] + pub preferred_nodes: Vec, + +} + +impl ExplicitNodeTopology { + /// ExplicitNodeTopology using only the required fields + pub fn new(allowed_nodes: impl IntoVec, preferred_nodes: impl IntoVec) -> ExplicitNodeTopology { + ExplicitNodeTopology { + allowed_nodes: allowed_nodes.into_vec(), + preferred_nodes: preferred_nodes.into_vec(), + + } + } + /// ExplicitNodeTopology using all fields + pub fn new_all(allowed_nodes: impl IntoVec, preferred_nodes: impl IntoVec) -> ExplicitNodeTopology { + ExplicitNodeTopology { + allowed_nodes: allowed_nodes.into_vec(), + preferred_nodes: preferred_nodes.into_vec(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/labelled_topology.rs b/testgen/src/autogen/models/labelled_topology.rs new file mode 100644 index 000000000..0edd48042 --- /dev/null +++ b/testgen/src/autogen/models/labelled_topology.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// LabelledTopology : labelled topology + + + + + + + + +/// labelled topology + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct LabelledTopology { + + /// Excludes resources with the same $label name, eg: \"Zone\" would not allow for resources with the same \"Zone\" value to be used for a certain operation, eg: A node with \"Zone: A\" would not be paired up with a node with \"Zone: A\", but it could be paired up with a node with \"Zone: B\" exclusive label NAME in the form \"NAME\", and not \"NAME: VALUE\" + #[serde(default, rename = "exclusion")] + pub exclusion: ::std::collections::HashMap, + + /// Includes resources with the same $label or $label:$value eg: if label is \"Zone: A\": A resource with \"Zone: A\" would be paired up with a resource with \"Zone: A\", but not with a resource with \"Zone: B\" if label is \"Zone\": A resource with \"Zone: A\" would be paired up with a resource with \"Zone: B\", but not with a resource with \"OtherLabel: B\" inclusive label key value in the form \"NAME: VALUE\" + #[serde(default, rename = "inclusion")] + pub inclusion: ::std::collections::HashMap, + + /// This feature includes resources with identical $label keys. For example, if the affinity key is set to \"Zone\": Initially, a resource that matches the label is selected, example \"Zone: A\". Subsequently, all other resources must match the given label \"Zone: A\", effectively adding this requirement as an inclusion label. + #[serde(default, rename = "affinitykey")] + pub affinitykey: Vec, + +} + +impl LabelledTopology { + /// LabelledTopology using only the required fields + pub fn new(exclusion: impl Into<::std::collections::HashMap>, inclusion: impl Into<::std::collections::HashMap>, affinitykey: impl IntoVec) -> LabelledTopology { + LabelledTopology { + exclusion: exclusion.into(), + inclusion: inclusion.into(), + affinitykey: affinitykey.into_vec(), + + } + } + /// LabelledTopology using all fields + pub fn new_all(exclusion: impl Into<::std::collections::HashMap>, inclusion: impl Into<::std::collections::HashMap>, affinitykey: impl IntoVec) -> LabelledTopology { + LabelledTopology { + exclusion: exclusion.into(), + inclusion: inclusion.into(), + affinitykey: affinitykey.into_vec(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/mod.rs b/testgen/src/autogen/models/mod.rs new file mode 100644 index 000000000..24f0eb4eb --- /dev/null +++ b/testgen/src/autogen/models/mod.rs @@ -0,0 +1,248 @@ + + +pub mod affinity_group; +pub use self::affinity_group::AffinityGroup; + +pub mod app_node; +pub use self::app_node::AppNode; + +pub mod app_node_spec; +pub use self::app_node_spec::AppNodeSpec; + +pub mod app_node_state; +pub use self::app_node_state::AppNodeState; + +pub mod app_nodes; +pub use self::app_nodes::AppNodes; + +pub mod block_device; +pub use self::block_device::BlockDevice; + +pub mod block_device_filesystem; +pub use self::block_device_filesystem::BlockDeviceFilesystem; + +pub mod block_device_partition; +pub use self::block_device_partition::BlockDevicePartition; + +pub mod child; +pub use self::child::Child; + +pub mod child_state; +pub use self::child_state::ChildState; + +pub mod child_state_reason; +pub use self::child_state_reason::ChildStateReason; + +pub mod cordon_drain_state; +pub use self::cordon_drain_state::CordonDrainState; + +pub mod cordoned_state; +pub use self::cordoned_state::CordonedState; + +pub mod create_nexus_body; +pub use self::create_nexus_body::CreateNexusBody; + +pub mod create_pool_body; +pub use self::create_pool_body::CreatePoolBody; + +pub mod create_replica_body; +pub use self::create_replica_body::CreateReplicaBody; + +pub mod create_volume_body; +pub use self::create_volume_body::CreateVolumeBody; + +pub mod drain_state; +pub use self::drain_state::DrainState; + +pub mod explicit_node_topology; +pub use self::explicit_node_topology::ExplicitNodeTopology; + +pub mod labelled_topology; +pub use self::labelled_topology::LabelledTopology; + +pub mod nexus; +pub use self::nexus::Nexus; + +pub mod nexus_share_protocol; +pub use self::nexus_share_protocol::NexusShareProtocol; + +pub mod nexus_spec; +pub use self::nexus_spec::NexusSpec; + +pub mod nexus_spec_operation; +pub use self::nexus_spec_operation::NexusSpecOperation; + +pub mod nexus_state; +pub use self::nexus_state::NexusState; + +pub mod node; +pub use self::node::Node; + +pub mod node_access_info; +pub use self::node_access_info::NodeAccessInfo; + +pub mod node_spec; +pub use self::node_spec::NodeSpec; + +pub mod node_state; +pub use self::node_state::NodeState; + +pub mod node_status; +pub use self::node_status::NodeStatus; + +pub mod node_topology; +pub use self::node_topology::NodeTopology; + +pub mod offline_replica_snapshot_state; +pub use self::offline_replica_snapshot_state::OfflineReplicaSnapshotState; + +pub mod online_replica_snapshot_state; +pub use self::online_replica_snapshot_state::OnlineReplicaSnapshotState; + +pub mod pool; +pub use self::pool::Pool; + +pub mod pool_spec; +pub use self::pool_spec::PoolSpec; + +pub mod pool_state; +pub use self::pool_state::PoolState; + +pub mod pool_status; +pub use self::pool_status::PoolStatus; + +pub mod pool_topology; +pub use self::pool_topology::PoolTopology; + +pub mod protocol; +pub use self::protocol::Protocol; + +pub mod publish_volume_body; +pub use self::publish_volume_body::PublishVolumeBody; + +pub mod rebuild_job_state; +pub use self::rebuild_job_state::RebuildJobState; + +pub mod rebuild_record; +pub use self::rebuild_record::RebuildRecord; + +pub mod register_app_node; +pub use self::register_app_node::RegisterAppNode; + +pub mod replica; +pub use self::replica::Replica; + +pub mod replica_kind; +pub use self::replica_kind::ReplicaKind; + +pub mod replica_share_protocol; +pub use self::replica_share_protocol::ReplicaShareProtocol; + +pub mod replica_snapshot; +pub use self::replica_snapshot::ReplicaSnapshot; + +pub mod replica_snapshot_state; +pub use self::replica_snapshot_state::ReplicaSnapshotState; + +pub mod replica_snapshot_status; +pub use self::replica_snapshot_status::ReplicaSnapshotStatus; + +pub mod replica_space_usage; +pub use self::replica_space_usage::ReplicaSpaceUsage; + +pub mod replica_spec; +pub use self::replica_spec::ReplicaSpec; + +pub mod replica_spec_operation; +pub use self::replica_spec_operation::ReplicaSpecOperation; + +pub mod replica_spec_owners; +pub use self::replica_spec_owners::ReplicaSpecOwners; + +pub mod replica_state; +pub use self::replica_state::ReplicaState; + +pub mod replica_topology; +pub use self::replica_topology::ReplicaTopology; + +pub mod replica_usage; +pub use self::replica_usage::ReplicaUsage; + +pub mod resize_volume_body; +pub use self::resize_volume_body::ResizeVolumeBody; + +pub mod rest_json_error; +pub use self::rest_json_error::RestJsonError; + +pub mod rest_watch; +pub use self::rest_watch::RestWatch; + +pub mod set_volume_property_body; +pub use self::set_volume_property_body::SetVolumePropertyBody; + +pub mod snapshot_as_source; +pub use self::snapshot_as_source::SnapshotAsSource; + +pub mod spec_status; +pub use self::spec_status::SpecStatus; + +pub mod specs; +pub use self::specs::Specs; + +pub mod topology; +pub use self::topology::Topology; + +pub mod volume; +pub use self::volume::Volume; + +pub mod volume_content_source; +pub use self::volume_content_source::VolumeContentSource; + +pub mod volume_policy; +pub use self::volume_policy::VolumePolicy; + +pub mod volume_share_protocol; +pub use self::volume_share_protocol::VolumeShareProtocol; + +pub mod volume_snapshot; +pub use self::volume_snapshot::VolumeSnapshot; + +pub mod volume_snapshot_definition; +pub use self::volume_snapshot_definition::VolumeSnapshotDefinition; + +pub mod volume_snapshot_metadata; +pub use self::volume_snapshot_metadata::VolumeSnapshotMetadata; + +pub mod volume_snapshot_spec; +pub use self::volume_snapshot_spec::VolumeSnapshotSpec; + +pub mod volume_snapshot_state; +pub use self::volume_snapshot_state::VolumeSnapshotState; + +pub mod volume_snapshots; +pub use self::volume_snapshots::VolumeSnapshots; + +pub mod volume_spec; +pub use self::volume_spec::VolumeSpec; + +pub mod volume_spec_operation; +pub use self::volume_spec_operation::VolumeSpecOperation; + +pub mod volume_state; +pub use self::volume_state::VolumeState; + +pub mod volume_status; +pub use self::volume_status::VolumeStatus; + +pub mod volume_target; +pub use self::volume_target::VolumeTarget; + +pub mod volume_usage; +pub use self::volume_usage::VolumeUsage; + +pub mod volumes; +pub use self::volumes::Volumes; + +pub mod watch_callback; +pub use self::watch_callback::WatchCallback; + diff --git a/testgen/src/autogen/models/nexus.rs b/testgen/src/autogen/models/nexus.rs new file mode 100644 index 000000000..9db749990 --- /dev/null +++ b/testgen/src/autogen/models/nexus.rs @@ -0,0 +1,108 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Nexus : Nexus information + + + + + + + + +/// Nexus information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Nexus { + + /// Array of Nexus Children + #[serde(default, rename = "children")] + pub children: Vec, + + /// URI of the device for the volume (missing if not published). Missing property and empty string are treated the same. + #[serde(default, rename = "deviceUri")] + pub device_uri: String, + + /// id of the io-engine instance + #[serde(default, rename = "node")] + pub node: String, + + /// total number of rebuild tasks + #[serde(default, rename = "rebuilds")] + pub rebuilds: u32, + + /// Common Protocol + #[serde(default, rename = "protocol")] + pub protocol: crate::models::Protocol, + + /// size of the volume in bytes + #[serde(default, rename = "size")] + pub size: u64, + + /// State of the Nexus + #[serde(default, rename = "state")] + pub state: crate::models::NexusState, + + /// uuid of the nexus + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + +} + +impl Nexus { + /// Nexus using only the required fields + pub fn new(children: impl IntoVec, device_uri: impl Into, node: impl Into, rebuilds: impl Into, protocol: impl Into, size: impl Into, state: impl Into, uuid: impl Into) -> Nexus { + Nexus { + children: children.into_vec(), + device_uri: device_uri.into(), + node: node.into(), + rebuilds: rebuilds.into(), + protocol: protocol.into(), + size: size.into(), + state: state.into(), + uuid: uuid.into(), + + } + } + /// Nexus using all fields + pub fn new_all(children: impl IntoVec, device_uri: impl Into, node: impl Into, rebuilds: impl Into, protocol: impl Into, size: impl Into, state: impl Into, uuid: impl Into) -> Nexus { + Nexus { + children: children.into_vec(), + device_uri: device_uri.into(), + node: node.into(), + rebuilds: rebuilds.into(), + protocol: protocol.into(), + size: size.into(), + state: state.into(), + uuid: uuid.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/nexus_share_protocol.rs b/testgen/src/autogen/models/nexus_share_protocol.rs new file mode 100644 index 000000000..dbd26cad0 --- /dev/null +++ b/testgen/src/autogen/models/nexus_share_protocol.rs @@ -0,0 +1,51 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NexusShareProtocol : Nexus Share Protocol + + + +/// Nexus Share Protocol +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum NexusShareProtocol { + + + #[serde(rename = "nvmf")] + Nvmf, + + #[serde(rename = "iscsi")] + Iscsi, + +} + +impl ToString for NexusShareProtocol { + fn to_string(&self) -> String { + match self { + + + Self::Nvmf => String::from("nvmf"), + + Self::Iscsi => String::from("iscsi"), + + + } + } +} + +impl Default for NexusShareProtocol { + fn default() -> Self { + Self::Nvmf + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/nexus_spec.rs b/testgen/src/autogen/models/nexus_spec.rs new file mode 100644 index 000000000..dd03e0d3d --- /dev/null +++ b/testgen/src/autogen/models/nexus_spec.rs @@ -0,0 +1,116 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NexusSpec : User specification of a nexus. + + + + + + + + +/// User specification of a nexus. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct NexusSpec { + + /// List of children. + #[serde(default, rename = "children")] + pub children: Vec, + + /// Managed by our control plane + #[serde(default, rename = "managed")] + pub managed: bool, + + /// Node where the nexus should live. + #[serde(default, rename = "node")] + pub node: String, + + /// Record of the operation in progress + #[serde(default, rename = "operation", skip_serializing_if = "Option::is_none")] + pub operation: Option, + + /// Volume which owns this nexus, if any + #[serde(default, rename = "owner", skip_serializing_if = "Option::is_none")] + pub owner: Option, + + /// Common Protocol + #[serde(default, rename = "share")] + pub share: crate::models::Protocol, + + /// Size of the nexus. + #[serde(default, rename = "size")] + pub size: u64, + + /// Common base state for a resource + #[serde(default, rename = "status")] + pub status: crate::models::SpecStatus, + + /// Nexus Id + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + +} + +impl NexusSpec { + /// NexusSpec using only the required fields + pub fn new(children: impl IntoVec, managed: impl Into, node: impl Into, share: impl Into, size: impl Into, status: impl Into, uuid: impl Into) -> NexusSpec { + NexusSpec { + children: children.into_vec(), + managed: managed.into(), + node: node.into(), + operation: None, + owner: None, + share: share.into(), + size: size.into(), + status: status.into(), + uuid: uuid.into(), + + } + } + /// NexusSpec using all fields + pub fn new_all(children: impl IntoVec, managed: impl Into, node: impl Into, operation: impl Into>, owner: impl Into>, share: impl Into, size: impl Into, status: impl Into, uuid: impl Into) -> NexusSpec { + NexusSpec { + children: children.into_vec(), + managed: managed.into(), + node: node.into(), + operation: operation.into(), + owner: owner.into(), + share: share.into(), + size: size.into(), + status: status.into(), + uuid: uuid.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/nexus_spec_operation.rs b/testgen/src/autogen/models/nexus_spec_operation.rs new file mode 100644 index 000000000..31abf3077 --- /dev/null +++ b/testgen/src/autogen/models/nexus_spec_operation.rs @@ -0,0 +1,96 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NexusSpecOperation : Record of the operation in progress + + + + + + + + +/// Record of the operation in progress + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct NexusSpecOperation { + + /// Record of the operation + #[serde(default, rename = "operation")] + pub operation: Operation, + + /// Result of the operation + #[serde(default, rename = "result", skip_serializing_if = "Option::is_none")] + pub result: Option, + +} + +impl NexusSpecOperation { + /// NexusSpecOperation using only the required fields + pub fn new(operation: impl Into) -> NexusSpecOperation { + NexusSpecOperation { + operation: operation.into(), + result: None, + + } + } + /// NexusSpecOperation using all fields + pub fn new_all(operation: impl Into, result: impl Into>) -> NexusSpecOperation { + NexusSpecOperation { + operation: operation.into(), + result: result.into(), + + } + } +} + + + + + + + + +/// Record of the operation +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum Operation { + + + #[serde(rename = "Create")] + Create, + + #[serde(rename = "Destroy")] + Destroy, + + #[serde(rename = "Share")] + Share, + + #[serde(rename = "Unshare")] + Unshare, + + #[serde(rename = "AddChild")] + AddChild, + + #[serde(rename = "RemoveChild")] + RemoveChild, + + #[serde(rename = "Shutdown")] + Shutdown, + + +} + +impl Default for Operation { + fn default() -> Self { + Self::Create + } +} + + + + + + diff --git a/testgen/src/autogen/models/nexus_state.rs b/testgen/src/autogen/models/nexus_state.rs new file mode 100644 index 000000000..0131c6e20 --- /dev/null +++ b/testgen/src/autogen/models/nexus_state.rs @@ -0,0 +1,71 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NexusState : State of the Nexus + + + +/// State of the Nexus +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum NexusState { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Degraded")] + Degraded, + + #[serde(rename = "Faulted")] + Faulted, + + #[serde(rename = "ShuttingDown")] + ShuttingDown, + + #[serde(rename = "Shutdown")] + Shutdown, + +} + +impl ToString for NexusState { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Degraded => String::from("Degraded"), + + Self::Faulted => String::from("Faulted"), + + Self::ShuttingDown => String::from("ShuttingDown"), + + Self::Shutdown => String::from("Shutdown"), + + + } + } +} + +impl Default for NexusState { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/node.rs b/testgen/src/autogen/models/node.rs new file mode 100644 index 000000000..4bbe4c302 --- /dev/null +++ b/testgen/src/autogen/models/node.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Node : io-engine storage node information + + + + + + + + +/// io-engine storage node information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Node { + + /// storage node identifier + #[serde(default, rename = "id")] + pub id: String, + + /// Node spec + #[serde(default, rename = "spec", skip_serializing_if = "Option::is_none")] + pub spec: Option, + + /// io-engine storage node information + #[serde(default, rename = "state", skip_serializing_if = "Option::is_none")] + pub state: Option, + +} + +impl Node { + /// Node using only the required fields + pub fn new(id: impl Into) -> Node { + Node { + id: id.into(), + spec: None, + state: None, + + } + } + /// Node using all fields + pub fn new_all(id: impl Into, spec: impl Into>, state: impl Into>) -> Node { + Node { + id: id.into(), + spec: spec.into(), + state: state.into(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/node_access_info.rs b/testgen/src/autogen/models/node_access_info.rs new file mode 100644 index 000000000..68de674b1 --- /dev/null +++ b/testgen/src/autogen/models/node_access_info.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NodeAccessInfo : Frontend Node access information. + + + + + + + + +/// Frontend Node access information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct NodeAccessInfo { + + /// The nodename of the node. + #[serde(default, rename = "name")] + pub name: String, + + /// The Nvme Nqn of the node\'s initiator. + #[serde(default, rename = "nqn")] + pub nqn: String, + +} + +impl NodeAccessInfo { + /// NodeAccessInfo using only the required fields + pub fn new(name: impl Into, nqn: impl Into) -> NodeAccessInfo { + NodeAccessInfo { + name: name.into(), + nqn: nqn.into(), + + } + } + /// NodeAccessInfo using all fields + pub fn new_all(name: impl Into, nqn: impl Into) -> NodeAccessInfo { + NodeAccessInfo { + name: name.into(), + nqn: nqn.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/node_spec.rs b/testgen/src/autogen/models/node_spec.rs new file mode 100644 index 000000000..4b3f0c528 --- /dev/null +++ b/testgen/src/autogen/models/node_spec.rs @@ -0,0 +1,84 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NodeSpec : Node spec + + + + + + + + +/// Node spec + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct NodeSpec { + + /// gRPC endpoint of the io-engine instance + #[serde(default, rename = "grpcEndpoint")] + pub grpc_endpoint: String, + + /// storage node identifier + #[serde(default, rename = "id")] + pub id: String, + + /// labels to be set on the node + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + + /// the drain state + #[serde(default, rename = "cordondrainstate", skip_serializing_if = "Option::is_none")] + pub cordondrainstate: Option, + + /// NVMe Qualified Names (NQNs) are used to uniquely describe a host or NVM subsystem for the purposes of identification and authentication + #[serde(default, rename = "node_nqn", skip_serializing_if = "Option::is_none")] + pub node_nqn: Option, + +} + +impl NodeSpec { + /// NodeSpec using only the required fields + pub fn new(grpc_endpoint: impl Into, id: impl Into) -> NodeSpec { + NodeSpec { + grpc_endpoint: grpc_endpoint.into(), + id: id.into(), + labels: None, + cordondrainstate: None, + node_nqn: None, + + } + } + /// NodeSpec using all fields + pub fn new_all(grpc_endpoint: impl Into, id: impl Into, labels: impl Into>>, cordondrainstate: impl Into>, node_nqn: impl Into>) -> NodeSpec { + NodeSpec { + grpc_endpoint: grpc_endpoint.into(), + id: id.into(), + labels: labels.into(), + cordondrainstate: cordondrainstate.into(), + node_nqn: node_nqn.into(), + + } + } +} + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/node_state.rs b/testgen/src/autogen/models/node_state.rs new file mode 100644 index 000000000..ad645cc1b --- /dev/null +++ b/testgen/src/autogen/models/node_state.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NodeState : io-engine storage node information + + + + + + + + +/// io-engine storage node information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct NodeState { + + /// gRPC endpoint of the io-engine instance + #[serde(default, rename = "grpcEndpoint")] + pub grpc_endpoint: String, + + /// storage node identifier + #[serde(default, rename = "id")] + pub id: String, + + /// deemed state of the node + #[serde(default, rename = "status")] + pub status: crate::models::NodeStatus, + + /// NVMe Qualified Names (NQNs) are used to uniquely describe a host or NVM subsystem for the purposes of identification and authentication + #[serde(default, rename = "node_nqn", skip_serializing_if = "Option::is_none")] + pub node_nqn: Option, + +} + +impl NodeState { + /// NodeState using only the required fields + pub fn new(grpc_endpoint: impl Into, id: impl Into, status: impl Into) -> NodeState { + NodeState { + grpc_endpoint: grpc_endpoint.into(), + id: id.into(), + status: status.into(), + node_nqn: None, + + } + } + /// NodeState using all fields + pub fn new_all(grpc_endpoint: impl Into, id: impl Into, status: impl Into, node_nqn: impl Into>) -> NodeState { + NodeState { + grpc_endpoint: grpc_endpoint.into(), + id: id.into(), + status: status.into(), + node_nqn: node_nqn.into(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/node_status.rs b/testgen/src/autogen/models/node_status.rs new file mode 100644 index 000000000..bb549891b --- /dev/null +++ b/testgen/src/autogen/models/node_status.rs @@ -0,0 +1,56 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NodeStatus : deemed state of the node + + + +/// deemed state of the node +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum NodeStatus { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Offline")] + Offline, + +} + +impl ToString for NodeStatus { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Offline => String::from("Offline"), + + + } + } +} + +impl Default for NodeStatus { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/node_topology.rs b/testgen/src/autogen/models/node_topology.rs new file mode 100644 index 000000000..803e819fa --- /dev/null +++ b/testgen/src/autogen/models/node_topology.rs @@ -0,0 +1,43 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// NodeTopology : Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. + + + + + + + + +/// Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum NodeTopology { + + /// volume topology, explicitly selected + #[serde(rename = "explicit")] + explicit(crate::models::ExplicitNodeTopology), + + /// volume topology definition through labels + #[serde(rename = "labelled")] + labelled(crate::models::LabelledTopology), + +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/offline_replica_snapshot_state.rs b/testgen/src/autogen/models/offline_replica_snapshot_state.rs new file mode 100644 index 000000000..600524f77 --- /dev/null +++ b/testgen/src/autogen/models/offline_replica_snapshot_state.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// OfflineReplicaSnapshotState : Offline ReplicaSnapshotState representation. + + + + + + + + +/// Offline ReplicaSnapshotState representation. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct OfflineReplicaSnapshotState { + + + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + + #[serde(default, rename = "source_id")] + pub source_id: uuid::Uuid, + + /// storage pool identifier + #[serde(default, rename = "pool_id")] + pub pool_id: String, + + /// storage pool unique identifier + #[serde(default, rename = "pool_uuid")] + pub pool_uuid: uuid::Uuid, + +} + +impl OfflineReplicaSnapshotState { + /// OfflineReplicaSnapshotState using only the required fields + pub fn new(uuid: impl Into, source_id: impl Into, pool_id: impl Into, pool_uuid: impl Into) -> OfflineReplicaSnapshotState { + OfflineReplicaSnapshotState { + uuid: uuid.into(), + source_id: source_id.into(), + pool_id: pool_id.into(), + pool_uuid: pool_uuid.into(), + + } + } + /// OfflineReplicaSnapshotState using all fields + pub fn new_all(uuid: impl Into, source_id: impl Into, pool_id: impl Into, pool_uuid: impl Into) -> OfflineReplicaSnapshotState { + OfflineReplicaSnapshotState { + uuid: uuid.into(), + source_id: source_id.into(), + pool_id: pool_id.into(), + pool_uuid: pool_uuid.into(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/online_replica_snapshot_state.rs b/testgen/src/autogen/models/online_replica_snapshot_state.rs new file mode 100644 index 000000000..3c4ccf87f --- /dev/null +++ b/testgen/src/autogen/models/online_replica_snapshot_state.rs @@ -0,0 +1,108 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// OnlineReplicaSnapshotState : Online ReplicaSnapshotState representation. + + + + + + + + +/// Online ReplicaSnapshotState representation. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct OnlineReplicaSnapshotState { + + + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + + #[serde(default, rename = "source_id")] + pub source_id: uuid::Uuid, + + /// storage pool identifier + #[serde(default, rename = "pool_id")] + pub pool_id: String, + + /// storage pool unique identifier + #[serde(default, rename = "pool_uuid")] + pub pool_uuid: uuid::Uuid, + + /// Timestamp when the replica snapshot is taken on the storage system. + #[serde(default, rename = "timestamp")] + pub timestamp: String, + + /// Replica snapshot size. + #[serde(default, rename = "size")] + pub size: u64, + + /// Runtime size in bytes of the snapshot. Equal to the volume allocation at the time of the snapshot creation. It may grow larger if any of its predecessors are deleted. + #[serde(default, rename = "allocated_size")] + pub allocated_size: u64, + + /// Total allocated size of all the snapshot predecessors. + #[serde(default, rename = "predecessor_alloc_size")] + pub predecessor_alloc_size: u64, + +} + +impl OnlineReplicaSnapshotState { + /// OnlineReplicaSnapshotState using only the required fields + pub fn new(uuid: impl Into, source_id: impl Into, pool_id: impl Into, pool_uuid: impl Into, timestamp: impl Into, size: impl Into, allocated_size: impl Into, predecessor_alloc_size: impl Into) -> OnlineReplicaSnapshotState { + OnlineReplicaSnapshotState { + uuid: uuid.into(), + source_id: source_id.into(), + pool_id: pool_id.into(), + pool_uuid: pool_uuid.into(), + timestamp: timestamp.into(), + size: size.into(), + allocated_size: allocated_size.into(), + predecessor_alloc_size: predecessor_alloc_size.into(), + + } + } + /// OnlineReplicaSnapshotState using all fields + pub fn new_all(uuid: impl Into, source_id: impl Into, pool_id: impl Into, pool_uuid: impl Into, timestamp: impl Into, size: impl Into, allocated_size: impl Into, predecessor_alloc_size: impl Into) -> OnlineReplicaSnapshotState { + OnlineReplicaSnapshotState { + uuid: uuid.into(), + source_id: source_id.into(), + pool_id: pool_id.into(), + pool_uuid: pool_uuid.into(), + timestamp: timestamp.into(), + size: size.into(), + allocated_size: allocated_size.into(), + predecessor_alloc_size: predecessor_alloc_size.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/pool.rs b/testgen/src/autogen/models/pool.rs new file mode 100644 index 000000000..cc4b2c776 --- /dev/null +++ b/testgen/src/autogen/models/pool.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Pool : Pool object, comprised of a spec and a state + + + + + + + + +/// Pool object, comprised of a spec and a state + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Pool { + + /// storage pool identifier + #[serde(default, rename = "id")] + pub id: String, + + /// User specification of a pool. + #[serde(default, rename = "spec", skip_serializing_if = "Option::is_none")] + pub spec: Option, + + /// State of a pool, as reported by io-engine + #[serde(default, rename = "state", skip_serializing_if = "Option::is_none")] + pub state: Option, + +} + +impl Pool { + /// Pool using only the required fields + pub fn new(id: impl Into) -> Pool { + Pool { + id: id.into(), + spec: None, + state: None, + + } + } + /// Pool using all fields + pub fn new_all(id: impl Into, spec: impl Into>, state: impl Into>) -> Pool { + Pool { + id: id.into(), + spec: spec.into(), + state: state.into(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/pool_spec.rs b/testgen/src/autogen/models/pool_spec.rs new file mode 100644 index 000000000..934840901 --- /dev/null +++ b/testgen/src/autogen/models/pool_spec.rs @@ -0,0 +1,84 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// PoolSpec : User specification of a pool. + + + + + + + + +/// User specification of a pool. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct PoolSpec { + + /// absolute disk paths claimed by the pool + #[serde(default, rename = "disks")] + pub disks: Vec, + + /// storage pool identifier + #[serde(default, rename = "id")] + pub id: String, + + /// labels to be set on the pools + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + + /// storage node identifier + #[serde(default, rename = "node")] + pub node: String, + + /// Common base state for a resource + #[serde(default, rename = "status")] + pub status: crate::models::SpecStatus, + +} + +impl PoolSpec { + /// PoolSpec using only the required fields + pub fn new(disks: impl IntoVec, id: impl Into, node: impl Into, status: impl Into) -> PoolSpec { + PoolSpec { + disks: disks.into_vec(), + id: id.into(), + labels: None, + node: node.into(), + status: status.into(), + + } + } + /// PoolSpec using all fields + pub fn new_all(disks: impl IntoVec, id: impl Into, labels: impl Into>>, node: impl Into, status: impl Into) -> PoolSpec { + PoolSpec { + disks: disks.into_vec(), + id: id.into(), + labels: labels.into(), + node: node.into(), + status: status.into(), + + } + } +} + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/pool_state.rs b/testgen/src/autogen/models/pool_state.rs new file mode 100644 index 000000000..4a135ecc6 --- /dev/null +++ b/testgen/src/autogen/models/pool_state.rs @@ -0,0 +1,100 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// PoolState : State of a pool, as reported by io-engine + + + + + + + + +/// State of a pool, as reported by io-engine + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct PoolState { + + /// size of the pool in bytes + #[serde(default, rename = "capacity")] + pub capacity: u64, + + /// absolute disk paths claimed by the pool + #[serde(default, rename = "disks")] + pub disks: Vec, + + /// storage pool identifier + #[serde(default, rename = "id")] + pub id: String, + + /// storage node identifier + #[serde(default, rename = "node")] + pub node: String, + + /// current status of the pool + #[serde(default, rename = "status")] + pub status: crate::models::PoolStatus, + + /// used bytes from the pool + #[serde(default, rename = "used")] + pub used: u64, + + /// accrued size of all replicas contained in this pool + #[serde(default, rename = "committed", skip_serializing_if = "Option::is_none")] + pub committed: Option, + +} + +impl PoolState { + /// PoolState using only the required fields + pub fn new(capacity: impl Into, disks: impl IntoVec, id: impl Into, node: impl Into, status: impl Into, used: impl Into) -> PoolState { + PoolState { + capacity: capacity.into(), + disks: disks.into_vec(), + id: id.into(), + node: node.into(), + status: status.into(), + used: used.into(), + committed: None, + + } + } + /// PoolState using all fields + pub fn new_all(capacity: impl Into, disks: impl IntoVec, id: impl Into, node: impl Into, status: impl Into, used: impl Into, committed: impl Into>) -> PoolState { + PoolState { + capacity: capacity.into(), + disks: disks.into_vec(), + id: id.into(), + node: node.into(), + status: status.into(), + used: used.into(), + committed: committed.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/pool_status.rs b/testgen/src/autogen/models/pool_status.rs new file mode 100644 index 000000000..d105e2309 --- /dev/null +++ b/testgen/src/autogen/models/pool_status.rs @@ -0,0 +1,61 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// PoolStatus : current status of the pool + + + +/// current status of the pool +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum PoolStatus { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Degraded")] + Degraded, + + #[serde(rename = "Faulted")] + Faulted, + +} + +impl ToString for PoolStatus { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Degraded => String::from("Degraded"), + + Self::Faulted => String::from("Faulted"), + + + } + } +} + +impl Default for PoolStatus { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/pool_topology.rs b/testgen/src/autogen/models/pool_topology.rs new file mode 100644 index 000000000..838cea3ad --- /dev/null +++ b/testgen/src/autogen/models/pool_topology.rs @@ -0,0 +1,37 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// PoolTopology : Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. + + + + + + + + +/// Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum PoolTopology { + + /// volume pool topology definition through labels + #[serde(rename = "labelled")] + labelled(crate::models::LabelledTopology), + +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/protocol.rs b/testgen/src/autogen/models/protocol.rs new file mode 100644 index 000000000..95cc46b69 --- /dev/null +++ b/testgen/src/autogen/models/protocol.rs @@ -0,0 +1,61 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Protocol : Common Protocol + + + +/// Common Protocol +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum Protocol { + + + #[serde(rename = "none")] + None, + + #[serde(rename = "nvmf")] + Nvmf, + + #[serde(rename = "iscsi")] + Iscsi, + + #[serde(rename = "nbd")] + Nbd, + +} + +impl ToString for Protocol { + fn to_string(&self) -> String { + match self { + + + Self::None => String::from("none"), + + Self::Nvmf => String::from("nvmf"), + + Self::Iscsi => String::from("iscsi"), + + Self::Nbd => String::from("nbd"), + + + } + } +} + +impl Default for Protocol { + fn default() -> Self { + Self::None + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/publish_volume_body.rs b/testgen/src/autogen/models/publish_volume_body.rs new file mode 100644 index 000000000..624efc1a5 --- /dev/null +++ b/testgen/src/autogen/models/publish_volume_body.rs @@ -0,0 +1,92 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// PublishVolumeBody : Publish Volume Body + + + + + + + + +/// Publish Volume Body + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct PublishVolumeBody { + + /// Controller Volume Publish context + #[serde(default, rename = "publish_context")] + pub publish_context: ::std::collections::HashMap, + + /// Allows reusing of the current target. + #[serde(default, rename = "reuse_existing", skip_serializing_if = "Option::is_none")] + pub reuse_existing: Option, + + /// The node where the target will reside in. It may be moved elsewhere during volume republish. + #[serde(default, rename = "node", skip_serializing_if = "Option::is_none")] + pub node: Option, + + /// The protocol used to connect to the front-end node. + #[serde(default, rename = "protocol")] + pub protocol: crate::models::VolumeShareProtocol, + + /// Allows republishing the volume on the node by shutting down the existing target first. + #[serde(default, rename = "republish", skip_serializing_if = "Option::is_none")] + pub republish: Option, + + /// The node where the front-end workload resides. If the workload moves then the volume must be republished. + #[serde(default, rename = "frontend_node", skip_serializing_if = "Option::is_none")] + pub frontend_node: Option, + +} + +impl PublishVolumeBody { + /// PublishVolumeBody using only the required fields + pub fn new(publish_context: impl Into<::std::collections::HashMap>, protocol: impl Into) -> PublishVolumeBody { + PublishVolumeBody { + publish_context: publish_context.into(), + reuse_existing: None, + node: None, + protocol: protocol.into(), + republish: None, + frontend_node: None, + + } + } + /// PublishVolumeBody using all fields + pub fn new_all(publish_context: impl Into<::std::collections::HashMap>, reuse_existing: impl Into>, node: impl Into>, protocol: impl Into, republish: impl Into>, frontend_node: impl Into>) -> PublishVolumeBody { + PublishVolumeBody { + publish_context: publish_context.into(), + reuse_existing: reuse_existing.into(), + node: node.into(), + protocol: protocol.into(), + republish: republish.into(), + frontend_node: frontend_node.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/rebuild_job_state.rs b/testgen/src/autogen/models/rebuild_job_state.rs new file mode 100644 index 000000000..9b81821a3 --- /dev/null +++ b/testgen/src/autogen/models/rebuild_job_state.rs @@ -0,0 +1,71 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// RebuildJobState : State of the rebuild job + + + +/// State of the rebuild job +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum RebuildJobState { + + + #[serde(rename = "Init")] + Init, + + #[serde(rename = "Rebuilding")] + Rebuilding, + + #[serde(rename = "Stopped")] + Stopped, + + #[serde(rename = "Paused")] + Paused, + + #[serde(rename = "Failed")] + Failed, + + #[serde(rename = "Completed")] + Completed, + +} + +impl ToString for RebuildJobState { + fn to_string(&self) -> String { + match self { + + + Self::Init => String::from("Init"), + + Self::Rebuilding => String::from("Rebuilding"), + + Self::Stopped => String::from("Stopped"), + + Self::Paused => String::from("Paused"), + + Self::Failed => String::from("Failed"), + + Self::Completed => String::from("Completed"), + + + } + } +} + +impl Default for RebuildJobState { + fn default() -> Self { + Self::Init + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/rebuild_record.rs b/testgen/src/autogen/models/rebuild_record.rs new file mode 100644 index 000000000..9295df6e8 --- /dev/null +++ b/testgen/src/autogen/models/rebuild_record.rs @@ -0,0 +1,132 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// RebuildRecord : Rebuild record of a Child + + + + + + + + +/// Rebuild record of a Child + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct RebuildRecord { + + /// Uri of the rebuilding child + #[serde(default, rename = "childUri")] + pub child_uri: String, + + /// Uri of source child for rebuild job + #[serde(default, rename = "srcUri")] + pub src_uri: String, + + /// State of the rebuild job + #[serde(default, rename = "rebuildJobState")] + pub rebuild_job_state: crate::models::RebuildJobState, + + /// Total blocks to rebuild + #[serde(default, rename = "blocksTotal")] + pub blocks_total: u64, + + /// Number of blocks processed + #[serde(default, rename = "blocksRecovered")] + pub blocks_recovered: u64, + + /// Number of blocks to transferred + #[serde(default, rename = "blocksTransferred")] + pub blocks_transferred: u64, + + /// Number of blocks remaining + #[serde(default, rename = "blocksRemaining")] + pub blocks_remaining: u64, + + /// Size of each block in the task + #[serde(default, rename = "blockSize")] + pub block_size: u64, + + /// True means its Partial rebuild job. If false, its Full rebuild job + #[serde(default, rename = "isPartial")] + pub is_partial: bool, + + /// Start time of the rebuild job (UTC) + #[serde(default, rename = "startTime")] + pub start_time: String, + + /// End time of the rebuild job (UTC) + #[serde(default, rename = "endTime")] + pub end_time: String, + +} + +impl RebuildRecord { + /// RebuildRecord using only the required fields + pub fn new(child_uri: impl Into, src_uri: impl Into, rebuild_job_state: impl Into, blocks_total: impl Into, blocks_recovered: impl Into, blocks_transferred: impl Into, blocks_remaining: impl Into, block_size: impl Into, is_partial: impl Into, start_time: impl Into, end_time: impl Into) -> RebuildRecord { + RebuildRecord { + child_uri: child_uri.into(), + src_uri: src_uri.into(), + rebuild_job_state: rebuild_job_state.into(), + blocks_total: blocks_total.into(), + blocks_recovered: blocks_recovered.into(), + blocks_transferred: blocks_transferred.into(), + blocks_remaining: blocks_remaining.into(), + block_size: block_size.into(), + is_partial: is_partial.into(), + start_time: start_time.into(), + end_time: end_time.into(), + + } + } + /// RebuildRecord using all fields + pub fn new_all(child_uri: impl Into, src_uri: impl Into, rebuild_job_state: impl Into, blocks_total: impl Into, blocks_recovered: impl Into, blocks_transferred: impl Into, blocks_remaining: impl Into, block_size: impl Into, is_partial: impl Into, start_time: impl Into, end_time: impl Into) -> RebuildRecord { + RebuildRecord { + child_uri: child_uri.into(), + src_uri: src_uri.into(), + rebuild_job_state: rebuild_job_state.into(), + blocks_total: blocks_total.into(), + blocks_recovered: blocks_recovered.into(), + blocks_transferred: blocks_transferred.into(), + blocks_remaining: blocks_remaining.into(), + block_size: block_size.into(), + is_partial: is_partial.into(), + start_time: start_time.into(), + end_time: end_time.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/register_app_node.rs b/testgen/src/autogen/models/register_app_node.rs new file mode 100644 index 000000000..4098ff4c1 --- /dev/null +++ b/testgen/src/autogen/models/register_app_node.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + + + + + + + + + + + + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct RegisterAppNode { + + /// gRPC server endpoint of the app node. + #[serde(default, rename = "endpoint")] + pub endpoint: String, + + /// Labels to be set on the app node. + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + +} + +impl RegisterAppNode { + /// RegisterAppNode using only the required fields + pub fn new(endpoint: impl Into) -> RegisterAppNode { + RegisterAppNode { + endpoint: endpoint.into(), + labels: None, + + } + } + /// RegisterAppNode using all fields + pub fn new_all(endpoint: impl Into, labels: impl Into>>) -> RegisterAppNode { + RegisterAppNode { + endpoint: endpoint.into(), + labels: labels.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica.rs b/testgen/src/autogen/models/replica.rs new file mode 100644 index 000000000..05e2fd29c --- /dev/null +++ b/testgen/src/autogen/models/replica.rs @@ -0,0 +1,140 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Replica : Replica information + + + + + + + + +/// Replica information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Replica { + + /// storage node identifier + #[serde(default, rename = "node")] + pub node: String, + + /// storage pool identifier + #[serde(default, rename = "pool")] + pub pool: String, + + /// storage pool unique identifier + #[serde(default, rename = "poolUuid", skip_serializing_if = "Option::is_none")] + pub pool_uuid: Option, + + /// Common Protocol + #[serde(default, rename = "share")] + pub share: crate::models::Protocol, + + /// size of the replica in bytes + #[serde(default, rename = "size")] + pub size: u64, + + /// Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. + #[serde(default, rename = "space", skip_serializing_if = "Option::is_none")] + pub space: Option, + + /// state of the replica + #[serde(default, rename = "state")] + pub state: crate::models::ReplicaState, + + /// thin provisioning + #[serde(default, rename = "thin")] + pub thin: bool, + + /// uri usable by nexus to access it + #[serde(default, rename = "uri")] + pub uri: String, + + /// uuid of the replica + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + /// NQNs of hosts allowed to connect to this replica + #[serde(default, rename = "allowed-hosts", skip_serializing_if = "Option::is_none")] + pub allowed_hosts: Option>, + + /// Type of replica, example regular or snapshot. + #[serde(default, rename = "kind")] + pub kind: crate::models::ReplicaKind, + +} + +impl Replica { + /// Replica using only the required fields + pub fn new(node: impl Into, pool: impl Into, share: impl Into, size: impl Into, state: impl Into, thin: impl Into, uri: impl Into, uuid: impl Into, kind: impl Into) -> Replica { + Replica { + node: node.into(), + pool: pool.into(), + pool_uuid: None, + share: share.into(), + size: size.into(), + space: None, + state: state.into(), + thin: thin.into(), + uri: uri.into(), + uuid: uuid.into(), + allowed_hosts: None, + kind: kind.into(), + + } + } + /// Replica using all fields + pub fn new_all(node: impl Into, pool: impl Into, pool_uuid: impl Into>, share: impl Into, size: impl Into, space: impl Into>, state: impl Into, thin: impl Into, uri: impl Into, uuid: impl Into, allowed_hosts: impl IntoOptVec, kind: impl Into) -> Replica { + Replica { + node: node.into(), + pool: pool.into(), + pool_uuid: pool_uuid.into(), + share: share.into(), + size: size.into(), + space: space.into(), + state: state.into(), + thin: thin.into(), + uri: uri.into(), + uuid: uuid.into(), + allowed_hosts: allowed_hosts.into_opt_vec(), + kind: kind.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_kind.rs b/testgen/src/autogen/models/replica_kind.rs new file mode 100644 index 000000000..16da8128a --- /dev/null +++ b/testgen/src/autogen/models/replica_kind.rs @@ -0,0 +1,56 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaKind : Type of replica, example regular or snapshot. + + + +/// Type of replica, example regular or snapshot. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum ReplicaKind { + + + #[serde(rename = "Regular")] + Regular, + + #[serde(rename = "Snapshot")] + Snapshot, + + #[serde(rename = "SnapshotClone")] + SnapshotClone, + +} + +impl ToString for ReplicaKind { + fn to_string(&self) -> String { + match self { + + + Self::Regular => String::from("Regular"), + + Self::Snapshot => String::from("Snapshot"), + + Self::SnapshotClone => String::from("SnapshotClone"), + + + } + } +} + +impl Default for ReplicaKind { + fn default() -> Self { + Self::Regular + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_share_protocol.rs b/testgen/src/autogen/models/replica_share_protocol.rs new file mode 100644 index 000000000..05e40de7e --- /dev/null +++ b/testgen/src/autogen/models/replica_share_protocol.rs @@ -0,0 +1,46 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaShareProtocol : Replica Share Protocol + + + +/// Replica Share Protocol +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum ReplicaShareProtocol { + + + #[serde(rename = "nvmf")] + Nvmf, + +} + +impl ToString for ReplicaShareProtocol { + fn to_string(&self) -> String { + match self { + + + Self::Nvmf => String::from("nvmf"), + + + } + } +} + +impl Default for ReplicaShareProtocol { + fn default() -> Self { + Self::Nvmf + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_snapshot.rs b/testgen/src/autogen/models/replica_snapshot.rs new file mode 100644 index 000000000..8e2cc6094 --- /dev/null +++ b/testgen/src/autogen/models/replica_snapshot.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSnapshot : Replica Snapshot information. + + + + + + + + +/// Replica Snapshot information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaSnapshot { + + + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + + #[serde(default, rename = "source_id")] + pub source_id: uuid::Uuid, + + /// Common base state for a resource + #[serde(default, rename = "status")] + pub status: crate::models::SpecStatus, + +} + +impl ReplicaSnapshot { + /// ReplicaSnapshot using only the required fields + pub fn new(uuid: impl Into, source_id: impl Into, status: impl Into) -> ReplicaSnapshot { + ReplicaSnapshot { + uuid: uuid.into(), + source_id: source_id.into(), + status: status.into(), + + } + } + /// ReplicaSnapshot using all fields + pub fn new_all(uuid: impl Into, source_id: impl Into, status: impl Into) -> ReplicaSnapshot { + ReplicaSnapshot { + uuid: uuid.into(), + source_id: source_id.into(), + status: status.into(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_snapshot_state.rs b/testgen/src/autogen/models/replica_snapshot_state.rs new file mode 100644 index 000000000..f8f965b55 --- /dev/null +++ b/testgen/src/autogen/models/replica_snapshot_state.rs @@ -0,0 +1,43 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSnapshotState : Replica Snapshot state information. + + + + + + + + +/// Replica Snapshot state information. + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum ReplicaSnapshotState { + + /// Online ReplicaSnapshotState representation. + #[serde(rename = "online")] + online(crate::models::OnlineReplicaSnapshotState), + + /// Offline ReplicaSnapshotState representation. + #[serde(rename = "offline")] + offline(crate::models::OfflineReplicaSnapshotState), + +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_snapshot_status.rs b/testgen/src/autogen/models/replica_snapshot_status.rs new file mode 100644 index 000000000..f1cdb8937 --- /dev/null +++ b/testgen/src/autogen/models/replica_snapshot_status.rs @@ -0,0 +1,56 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSnapshotStatus : Current ReplicaSnapshot status + + + +/// Current ReplicaSnapshot status +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum ReplicaSnapshotStatus { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Offline")] + Offline, + +} + +impl ToString for ReplicaSnapshotStatus { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Offline => String::from("Offline"), + + + } + } +} + +impl Default for ReplicaSnapshotStatus { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_space_usage.rs b/testgen/src/autogen/models/replica_space_usage.rs new file mode 100644 index 000000000..72e878572 --- /dev/null +++ b/testgen/src/autogen/models/replica_space_usage.rs @@ -0,0 +1,100 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSpaceUsage : Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. + + + + + + + + +/// Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaSpaceUsage { + + /// Replica capacity in bytes. + #[serde(default, rename = "capacity_bytes")] + pub capacity_bytes: u64, + + /// Amount of actually allocated disk space for this replica in bytes. + #[serde(default, rename = "allocated_bytes")] + pub allocated_bytes: u64, + + /// Amount of actually allocated disk space for this replica\'s snapshots in bytes. + #[serde(default, rename = "allocated_bytes_snapshots")] + pub allocated_bytes_snapshots: u64, + + /// Amount of actually allocated disk space for this replica\'s snapshots and its predecessors in bytes. For a restored/cloned replica this includes snapshots from the parent source. + #[serde(default, rename = "allocated_bytes_all_snapshots", skip_serializing_if = "Option::is_none")] + pub allocated_bytes_all_snapshots: Option, + + /// Cluster size in bytes. + #[serde(default, rename = "cluster_size")] + pub cluster_size: u64, + + /// Total number of clusters. + #[serde(default, rename = "clusters")] + pub clusters: u64, + + /// Number of actually used clusters. + #[serde(default, rename = "allocated_clusters")] + pub allocated_clusters: u64, + +} + +impl ReplicaSpaceUsage { + /// ReplicaSpaceUsage using only the required fields + pub fn new(capacity_bytes: impl Into, allocated_bytes: impl Into, allocated_bytes_snapshots: impl Into, cluster_size: impl Into, clusters: impl Into, allocated_clusters: impl Into) -> ReplicaSpaceUsage { + ReplicaSpaceUsage { + capacity_bytes: capacity_bytes.into(), + allocated_bytes: allocated_bytes.into(), + allocated_bytes_snapshots: allocated_bytes_snapshots.into(), + allocated_bytes_all_snapshots: None, + cluster_size: cluster_size.into(), + clusters: clusters.into(), + allocated_clusters: allocated_clusters.into(), + + } + } + /// ReplicaSpaceUsage using all fields + pub fn new_all(capacity_bytes: impl Into, allocated_bytes: impl Into, allocated_bytes_snapshots: impl Into, allocated_bytes_all_snapshots: impl Into>, cluster_size: impl Into, clusters: impl Into, allocated_clusters: impl Into) -> ReplicaSpaceUsage { + ReplicaSpaceUsage { + capacity_bytes: capacity_bytes.into(), + allocated_bytes: allocated_bytes.into(), + allocated_bytes_snapshots: allocated_bytes_snapshots.into(), + allocated_bytes_all_snapshots: allocated_bytes_all_snapshots.into(), + cluster_size: cluster_size.into(), + clusters: clusters.into(), + allocated_clusters: allocated_clusters.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_spec.rs b/testgen/src/autogen/models/replica_spec.rs new file mode 100644 index 000000000..144a49123 --- /dev/null +++ b/testgen/src/autogen/models/replica_spec.rs @@ -0,0 +1,132 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSpec : User specification of a replica. + + + + + + + + +/// User specification of a replica. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaSpec { + + /// Managed by our control plane + #[serde(default, rename = "managed")] + pub managed: bool, + + /// Record of the operation in progress + #[serde(default, rename = "operation", skip_serializing_if = "Option::is_none")] + pub operation: Option, + + /// Owner Resource + #[serde(default, rename = "owners")] + pub owners: crate::models::ReplicaSpecOwners, + + /// The pool that the replica should live on. + #[serde(default, rename = "pool")] + pub pool: String, + + /// storage pool unique identifier + #[serde(default, rename = "poolUuid", skip_serializing_if = "Option::is_none")] + pub pool_uuid: Option, + + /// Common Protocol + #[serde(default, rename = "share")] + pub share: crate::models::Protocol, + + /// The size that the replica should be. + #[serde(default, rename = "size")] + pub size: u64, + + /// Common base state for a resource + #[serde(default, rename = "status")] + pub status: crate::models::SpecStatus, + + /// Thin provisioning. + #[serde(default, rename = "thin")] + pub thin: bool, + + /// uuid of the replica + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + /// Type of replica, example regular or snapshot. + #[serde(default, rename = "kind", skip_serializing_if = "Option::is_none")] + pub kind: Option, + +} + +impl ReplicaSpec { + /// ReplicaSpec using only the required fields + pub fn new(managed: impl Into, owners: impl Into, pool: impl Into, share: impl Into, size: impl Into, status: impl Into, thin: impl Into, uuid: impl Into) -> ReplicaSpec { + ReplicaSpec { + managed: managed.into(), + operation: None, + owners: owners.into(), + pool: pool.into(), + pool_uuid: None, + share: share.into(), + size: size.into(), + status: status.into(), + thin: thin.into(), + uuid: uuid.into(), + kind: None, + + } + } + /// ReplicaSpec using all fields + pub fn new_all(managed: impl Into, operation: impl Into>, owners: impl Into, pool: impl Into, pool_uuid: impl Into>, share: impl Into, size: impl Into, status: impl Into, thin: impl Into, uuid: impl Into, kind: impl Into>) -> ReplicaSpec { + ReplicaSpec { + managed: managed.into(), + operation: operation.into(), + owners: owners.into(), + pool: pool.into(), + pool_uuid: pool_uuid.into(), + share: share.into(), + size: size.into(), + status: status.into(), + thin: thin.into(), + uuid: uuid.into(), + kind: kind.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_spec_operation.rs b/testgen/src/autogen/models/replica_spec_operation.rs new file mode 100644 index 000000000..1879e5e7c --- /dev/null +++ b/testgen/src/autogen/models/replica_spec_operation.rs @@ -0,0 +1,87 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSpecOperation : Record of the operation in progress + + + + + + + + +/// Record of the operation in progress + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaSpecOperation { + + /// Record of the operation + #[serde(default, rename = "operation")] + pub operation: Operation, + + /// Result of the operation + #[serde(default, rename = "result", skip_serializing_if = "Option::is_none")] + pub result: Option, + +} + +impl ReplicaSpecOperation { + /// ReplicaSpecOperation using only the required fields + pub fn new(operation: impl Into) -> ReplicaSpecOperation { + ReplicaSpecOperation { + operation: operation.into(), + result: None, + + } + } + /// ReplicaSpecOperation using all fields + pub fn new_all(operation: impl Into, result: impl Into>) -> ReplicaSpecOperation { + ReplicaSpecOperation { + operation: operation.into(), + result: result.into(), + + } + } +} + + + + + + + + +/// Record of the operation +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum Operation { + + + #[serde(rename = "Create")] + Create, + + #[serde(rename = "Destroy")] + Destroy, + + #[serde(rename = "Share")] + Share, + + #[serde(rename = "Unshare")] + Unshare, + + +} + +impl Default for Operation { + fn default() -> Self { + Self::Create + } +} + + + + + + diff --git a/testgen/src/autogen/models/replica_spec_owners.rs b/testgen/src/autogen/models/replica_spec_owners.rs new file mode 100644 index 000000000..0520a97f7 --- /dev/null +++ b/testgen/src/autogen/models/replica_spec_owners.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaSpecOwners : Owner Resource + + + + + + + + +/// Owner Resource + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaSpecOwners { + + + #[serde(default, rename = "nexuses")] + pub nexuses: Vec, + + + #[serde(default, rename = "volume", skip_serializing_if = "Option::is_none")] + pub volume: Option, + +} + +impl ReplicaSpecOwners { + /// ReplicaSpecOwners using only the required fields + pub fn new(nexuses: impl IntoVec) -> ReplicaSpecOwners { + ReplicaSpecOwners { + nexuses: nexuses.into_vec(), + volume: None, + + } + } + /// ReplicaSpecOwners using all fields + pub fn new_all(nexuses: impl IntoVec, volume: impl Into>) -> ReplicaSpecOwners { + ReplicaSpecOwners { + nexuses: nexuses.into_vec(), + volume: volume.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_state.rs b/testgen/src/autogen/models/replica_state.rs new file mode 100644 index 000000000..26bbfcbef --- /dev/null +++ b/testgen/src/autogen/models/replica_state.rs @@ -0,0 +1,61 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaState : state of the replica + + + +/// state of the replica +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum ReplicaState { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Degraded")] + Degraded, + + #[serde(rename = "Faulted")] + Faulted, + +} + +impl ToString for ReplicaState { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Degraded => String::from("Degraded"), + + Self::Faulted => String::from("Faulted"), + + + } + } +} + +impl Default for ReplicaState { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_topology.rs b/testgen/src/autogen/models/replica_topology.rs new file mode 100644 index 000000000..18eab1dca --- /dev/null +++ b/testgen/src/autogen/models/replica_topology.rs @@ -0,0 +1,100 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaTopology : Volume Replica information. + + + + + + + + +/// Volume Replica information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaTopology { + + /// storage node identifier + #[serde(default, rename = "node", skip_serializing_if = "Option::is_none")] + pub node: Option, + + /// storage pool identifier + #[serde(default, rename = "pool", skip_serializing_if = "Option::is_none")] + pub pool: Option, + + /// state of the replica + #[serde(default, rename = "state")] + pub state: crate::models::ReplicaState, + + /// State of a Nexus Child + #[serde(default, rename = "child-status", skip_serializing_if = "Option::is_none")] + pub child_status: Option, + + /// Reason for the state of a Nexus Child + #[serde(default, rename = "child-status-reason", skip_serializing_if = "Option::is_none")] + pub child_status_reason: Option, + + /// Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. + #[serde(default, rename = "usage", skip_serializing_if = "Option::is_none")] + pub usage: Option, + + /// current rebuild progress (%) + #[serde(default, rename = "rebuild-progress", skip_serializing_if = "Option::is_none")] + pub rebuild_progress: Option, + +} + +impl ReplicaTopology { + /// ReplicaTopology using only the required fields + pub fn new(state: impl Into) -> ReplicaTopology { + ReplicaTopology { + node: None, + pool: None, + state: state.into(), + child_status: None, + child_status_reason: None, + usage: None, + rebuild_progress: None, + + } + } + /// ReplicaTopology using all fields + pub fn new_all(node: impl Into>, pool: impl Into>, state: impl Into, child_status: impl Into>, child_status_reason: impl Into>, usage: impl Into>, rebuild_progress: impl Into>) -> ReplicaTopology { + ReplicaTopology { + node: node.into(), + pool: pool.into(), + state: state.into(), + child_status: child_status.into(), + child_status_reason: child_status_reason.into(), + usage: usage.into(), + rebuild_progress: rebuild_progress.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/replica_usage.rs b/testgen/src/autogen/models/replica_usage.rs new file mode 100644 index 000000000..47fce787d --- /dev/null +++ b/testgen/src/autogen/models/replica_usage.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ReplicaUsage : Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. + + + + + + + + +/// Replica space usage information. Useful for capacity management, eg: figure out how much of a thin-provisioned replica is allocated. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ReplicaUsage { + + /// Replica capacity in bytes. + #[serde(default, rename = "capacity")] + pub capacity: u64, + + /// Amount of actually allocated disk space for this replica in bytes. + #[serde(default, rename = "allocated")] + pub allocated: u64, + + /// Amount of actually allocated disk space for this replica\'s snapshots in bytes. + #[serde(default, rename = "allocated_snapshots")] + pub allocated_snapshots: u64, + + /// Amount of actually allocated disk space for this replica\'s snapshots and its predecessors in bytes. For a restored/cloned replica this includes snapshots from the parent source. + #[serde(default, rename = "allocated_all_snapshots")] + pub allocated_all_snapshots: u64, + +} + +impl ReplicaUsage { + /// ReplicaUsage using only the required fields + pub fn new(capacity: impl Into, allocated: impl Into, allocated_snapshots: impl Into, allocated_all_snapshots: impl Into) -> ReplicaUsage { + ReplicaUsage { + capacity: capacity.into(), + allocated: allocated.into(), + allocated_snapshots: allocated_snapshots.into(), + allocated_all_snapshots: allocated_all_snapshots.into(), + + } + } + /// ReplicaUsage using all fields + pub fn new_all(capacity: impl Into, allocated: impl Into, allocated_snapshots: impl Into, allocated_all_snapshots: impl Into) -> ReplicaUsage { + ReplicaUsage { + capacity: capacity.into(), + allocated: allocated.into(), + allocated_snapshots: allocated_snapshots.into(), + allocated_all_snapshots: allocated_all_snapshots.into(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/resize_volume_body.rs b/testgen/src/autogen/models/resize_volume_body.rs new file mode 100644 index 000000000..6e0a8955a --- /dev/null +++ b/testgen/src/autogen/models/resize_volume_body.rs @@ -0,0 +1,52 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// ResizeVolumeBody : Resize Volume Body + + + + + + + + +/// Resize Volume Body + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct ResizeVolumeBody { + + /// New required size of the volume in bytes + #[serde(default, rename = "size")] + pub size: u64, + +} + +impl ResizeVolumeBody { + /// ResizeVolumeBody using only the required fields + pub fn new(size: impl Into) -> ResizeVolumeBody { + ResizeVolumeBody { + size: size.into(), + + } + } + /// ResizeVolumeBody using all fields + pub fn new_all(size: impl Into) -> ResizeVolumeBody { + ResizeVolumeBody { + size: size.into(), + + } + } +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/rest_json_error.rs b/testgen/src/autogen/models/rest_json_error.rs new file mode 100644 index 000000000..27c0ca064 --- /dev/null +++ b/testgen/src/autogen/models/rest_json_error.rs @@ -0,0 +1,161 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// RestJsonError : Rest Json Error format + + + + + + + + +/// Rest Json Error format + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct RestJsonError { + + /// detailed error information + #[serde(default, rename = "details")] + pub details: String, + + /// last reported error information + #[serde(default, rename = "message")] + pub message: String, + + /// error kind + #[serde(default, rename = "kind")] + pub kind: Kind, + +} + +impl RestJsonError { + /// RestJsonError using only the required fields + pub fn new(details: impl Into, message: impl Into, kind: impl Into) -> RestJsonError { + RestJsonError { + details: details.into(), + message: message.into(), + kind: kind.into(), + + } + } + /// RestJsonError using all fields + pub fn new_all(details: impl Into, message: impl Into, kind: impl Into) -> RestJsonError { + RestJsonError { + details: details.into(), + message: message.into(), + kind: kind.into(), + + } + } +} + + + + + + + + + + + + +/// error kind +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum Kind { + + + #[serde(rename = "Timeout")] + Timeout, + + #[serde(rename = "Deserialize")] + Deserialize, + + #[serde(rename = "Internal")] + Internal, + + #[serde(rename = "InvalidArgument")] + InvalidArgument, + + #[serde(rename = "DeadlineExceeded")] + DeadlineExceeded, + + #[serde(rename = "NotFound")] + NotFound, + + #[serde(rename = "AlreadyExists")] + AlreadyExists, + + #[serde(rename = "PermissionDenied")] + PermissionDenied, + + #[serde(rename = "ResourceExhausted")] + ResourceExhausted, + + #[serde(rename = "FailedPrecondition")] + FailedPrecondition, + + #[serde(rename = "NotShared")] + NotShared, + + #[serde(rename = "NotPublished")] + NotPublished, + + #[serde(rename = "AlreadyPublished")] + AlreadyPublished, + + #[serde(rename = "AlreadyShared")] + AlreadyShared, + + #[serde(rename = "Aborted")] + Aborted, + + #[serde(rename = "OutOfRange")] + OutOfRange, + + #[serde(rename = "Unimplemented")] + Unimplemented, + + #[serde(rename = "Unavailable")] + Unavailable, + + #[serde(rename = "Unauthenticated")] + Unauthenticated, + + #[serde(rename = "Unauthorized")] + Unauthorized, + + #[serde(rename = "Conflict")] + Conflict, + + #[serde(rename = "FailedPersist")] + FailedPersist, + + #[serde(rename = "Deleting")] + Deleting, + + #[serde(rename = "InUse")] + InUse, + + #[serde(rename = "CapacityLimitExceeded")] + CapacityLimitExceeded, + + #[serde(rename = "NotAcceptable")] + NotAcceptable, + + +} + +impl Default for Kind { + fn default() -> Self { + Self::Timeout + } +} + + + + diff --git a/testgen/src/autogen/models/rest_watch.rs b/testgen/src/autogen/models/rest_watch.rs new file mode 100644 index 000000000..9ac0b07b3 --- /dev/null +++ b/testgen/src/autogen/models/rest_watch.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// RestWatch : Watch Resource in the store + + + + + + + + +/// Watch Resource in the store + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct RestWatch { + + /// callback used to notify the watch of a change + #[serde(default, rename = "callback")] + pub callback: String, + + /// id of the resource to watch on + #[serde(default, rename = "resource")] + pub resource: String, + +} + +impl RestWatch { + /// RestWatch using only the required fields + pub fn new(callback: impl Into, resource: impl Into) -> RestWatch { + RestWatch { + callback: callback.into(), + resource: resource.into(), + + } + } + /// RestWatch using all fields + pub fn new_all(callback: impl Into, resource: impl Into) -> RestWatch { + RestWatch { + callback: callback.into(), + resource: resource.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/set_volume_property_body.rs b/testgen/src/autogen/models/set_volume_property_body.rs new file mode 100644 index 000000000..0a93321ae --- /dev/null +++ b/testgen/src/autogen/models/set_volume_property_body.rs @@ -0,0 +1,37 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// SetVolumePropertyBody : Set Volume Properties Body + + + + + + + + +/// Set Volume Properties Body + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum SetVolumePropertyBody { + + /// Max Snapshots limit per volume. + #[serde(rename = "max_snapshots")] + max_snapshots(u32), + +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/snapshot_as_source.rs b/testgen/src/autogen/models/snapshot_as_source.rs new file mode 100644 index 000000000..b6e955da1 --- /dev/null +++ b/testgen/src/autogen/models/snapshot_as_source.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// SnapshotAsSource : The snapshot source for the volume content. + + + + + + + + +/// The snapshot source for the volume content. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct SnapshotAsSource { + + + #[serde(default, rename = "snapshot")] + pub snapshot: uuid::Uuid, + + + #[serde(default, rename = "volume")] + pub volume: uuid::Uuid, + +} + +impl SnapshotAsSource { + /// SnapshotAsSource using only the required fields + pub fn new(snapshot: impl Into, volume: impl Into) -> SnapshotAsSource { + SnapshotAsSource { + snapshot: snapshot.into(), + volume: volume.into(), + + } + } + /// SnapshotAsSource using all fields + pub fn new_all(snapshot: impl Into, volume: impl Into) -> SnapshotAsSource { + SnapshotAsSource { + snapshot: snapshot.into(), + volume: volume.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/spec_status.rs b/testgen/src/autogen/models/spec_status.rs new file mode 100644 index 000000000..9e08b183f --- /dev/null +++ b/testgen/src/autogen/models/spec_status.rs @@ -0,0 +1,61 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// SpecStatus : Common base state for a resource + + + +/// Common base state for a resource +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum SpecStatus { + + + #[serde(rename = "Creating")] + Creating, + + #[serde(rename = "Created")] + Created, + + #[serde(rename = "Deleting")] + Deleting, + + #[serde(rename = "Deleted")] + Deleted, + +} + +impl ToString for SpecStatus { + fn to_string(&self) -> String { + match self { + + + Self::Creating => String::from("Creating"), + + Self::Created => String::from("Created"), + + Self::Deleting => String::from("Deleting"), + + Self::Deleted => String::from("Deleted"), + + + } + } +} + +impl Default for SpecStatus { + fn default() -> Self { + Self::Creating + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/specs.rs b/testgen/src/autogen/models/specs.rs new file mode 100644 index 000000000..67b7bbe17 --- /dev/null +++ b/testgen/src/autogen/models/specs.rs @@ -0,0 +1,76 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Specs : Specs detailing the requested configuration of the objects. + + + + + + + + +/// Specs detailing the requested configuration of the objects. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Specs { + + /// Nexus Specs + #[serde(default, rename = "nexuses")] + pub nexuses: Vec, + + /// Pool Specs + #[serde(default, rename = "pools")] + pub pools: Vec, + + /// Replica Specs + #[serde(default, rename = "replicas")] + pub replicas: Vec, + + /// Volume Specs + #[serde(default, rename = "volumes")] + pub volumes: Vec, + +} + +impl Specs { + /// Specs using only the required fields + pub fn new(nexuses: impl IntoVec, pools: impl IntoVec, replicas: impl IntoVec, volumes: impl IntoVec) -> Specs { + Specs { + nexuses: nexuses.into_vec(), + pools: pools.into_vec(), + replicas: replicas.into_vec(), + volumes: volumes.into_vec(), + + } + } + /// Specs using all fields + pub fn new_all(nexuses: impl IntoVec, pools: impl IntoVec, replicas: impl IntoVec, volumes: impl IntoVec) -> Specs { + Specs { + nexuses: nexuses.into_vec(), + pools: pools.into_vec(), + replicas: replicas.into_vec(), + volumes: volumes.into_vec(), + + } + } +} + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/topology.rs b/testgen/src/autogen/models/topology.rs new file mode 100644 index 000000000..c4350fa3f --- /dev/null +++ b/testgen/src/autogen/models/topology.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Topology : node and pool topology for volumes + + + + + + + + +/// node and pool topology for volumes + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Topology { + + /// Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. + #[serde(default, rename = "node_topology", skip_serializing_if = "Option::is_none")] + pub node_topology: Option, + + /// Used to determine how to place/distribute the data during volume creation and replica replacement. If left empty then the control plane will select from all available resources. + #[serde(default, rename = "pool_topology", skip_serializing_if = "Option::is_none")] + pub pool_topology: Option, + +} + +impl Topology { + /// Topology using only the required fields + pub fn new() -> Topology { + Topology { + node_topology: None, + pool_topology: None, + + } + } + /// Topology using all fields + pub fn new_all(node_topology: impl Into>, pool_topology: impl Into>) -> Topology { + Topology { + node_topology: node_topology.into(), + pool_topology: pool_topology.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume.rs b/testgen/src/autogen/models/volume.rs new file mode 100644 index 000000000..5e3dd68c1 --- /dev/null +++ b/testgen/src/autogen/models/volume.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Volume : Volumes Volume information + + + + + + + + +/// Volumes Volume information + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Volume { + + /// User specification of a volume. + #[serde(default, rename = "spec")] + pub spec: crate::models::VolumeSpec, + + /// Runtime state of the volume + #[serde(default, rename = "state")] + pub state: crate::models::VolumeState, + +} + +impl Volume { + /// Volume using only the required fields + pub fn new(spec: impl Into, state: impl Into) -> Volume { + Volume { + spec: spec.into(), + state: state.into(), + + } + } + /// Volume using all fields + pub fn new_all(spec: impl Into, state: impl Into) -> Volume { + Volume { + spec: spec.into(), + state: state.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_content_source.rs b/testgen/src/autogen/models/volume_content_source.rs new file mode 100644 index 000000000..834e1779f --- /dev/null +++ b/testgen/src/autogen/models/volume_content_source.rs @@ -0,0 +1,37 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeContentSource : Volume Content Source i.e the snapshot or the volume. + + + + + + + + +/// Volume Content Source i.e the snapshot or the volume. + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum VolumeContentSource { + + /// The snapshot source for the volume content. + #[serde(rename = "snapshot")] + snapshot(crate::models::SnapshotAsSource), + +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_policy.rs b/testgen/src/autogen/models/volume_policy.rs new file mode 100644 index 000000000..abcaec7cb --- /dev/null +++ b/testgen/src/autogen/models/volume_policy.rs @@ -0,0 +1,52 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumePolicy : Volume policy used to determine if and how to replace a replica + + + + + + + + +/// Volume policy used to determine if and how to replace a replica + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumePolicy { + + /// If true the control plane will attempt to heal the volume by itself + #[serde(default, rename = "self_heal")] + pub self_heal: bool, + +} + +impl VolumePolicy { + /// VolumePolicy using only the required fields + pub fn new(self_heal: impl Into) -> VolumePolicy { + VolumePolicy { + self_heal: self_heal.into(), + + } + } + /// VolumePolicy using all fields + pub fn new_all(self_heal: impl Into) -> VolumePolicy { + VolumePolicy { + self_heal: self_heal.into(), + + } + } +} + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_share_protocol.rs b/testgen/src/autogen/models/volume_share_protocol.rs new file mode 100644 index 000000000..11ac1dbbc --- /dev/null +++ b/testgen/src/autogen/models/volume_share_protocol.rs @@ -0,0 +1,51 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeShareProtocol : Volume Share Protocol + + + +/// Volume Share Protocol +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum VolumeShareProtocol { + + + #[serde(rename = "nvmf")] + Nvmf, + + #[serde(rename = "iscsi")] + Iscsi, + +} + +impl ToString for VolumeShareProtocol { + fn to_string(&self) -> String { + match self { + + + Self::Nvmf => String::from("nvmf"), + + Self::Iscsi => String::from("iscsi"), + + + } + } +} + +impl Default for VolumeShareProtocol { + fn default() -> Self { + Self::Nvmf + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_snapshot.rs b/testgen/src/autogen/models/volume_snapshot.rs new file mode 100644 index 000000000..314b78a4b --- /dev/null +++ b/testgen/src/autogen/models/volume_snapshot.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSnapshot : Volume Snapshot Information. + + + + + + + + +/// Volume Snapshot Information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSnapshot { + + /// Volume Snapshot Metadata and Spec information. + #[serde(default, rename = "definition")] + pub definition: crate::models::VolumeSnapshotDefinition, + + /// Volume Snapshot State information. + #[serde(default, rename = "state")] + pub state: crate::models::VolumeSnapshotState, + +} + +impl VolumeSnapshot { + /// VolumeSnapshot using only the required fields + pub fn new(definition: impl Into, state: impl Into) -> VolumeSnapshot { + VolumeSnapshot { + definition: definition.into(), + state: state.into(), + + } + } + /// VolumeSnapshot using all fields + pub fn new_all(definition: impl Into, state: impl Into) -> VolumeSnapshot { + VolumeSnapshot { + definition: definition.into(), + state: state.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_snapshot_definition.rs b/testgen/src/autogen/models/volume_snapshot_definition.rs new file mode 100644 index 000000000..235aaae37 --- /dev/null +++ b/testgen/src/autogen/models/volume_snapshot_definition.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSnapshotDefinition : Volume Snapshot Metadata and Spec information. + + + + + + + + +/// Volume Snapshot Metadata and Spec information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSnapshotDefinition { + + /// Volume Snapshot Metadata information. + #[serde(default, rename = "metadata")] + pub metadata: crate::models::VolumeSnapshotMetadata, + + /// Volume Snapshot Spec information. + #[serde(default, rename = "spec")] + pub spec: crate::models::VolumeSnapshotSpec, + +} + +impl VolumeSnapshotDefinition { + /// VolumeSnapshotDefinition using only the required fields + pub fn new(metadata: impl Into, spec: impl Into) -> VolumeSnapshotDefinition { + VolumeSnapshotDefinition { + metadata: metadata.into(), + spec: spec.into(), + + } + } + /// VolumeSnapshotDefinition using all fields + pub fn new_all(metadata: impl Into, spec: impl Into) -> VolumeSnapshotDefinition { + VolumeSnapshotDefinition { + metadata: metadata.into(), + spec: spec.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_snapshot_metadata.rs b/testgen/src/autogen/models/volume_snapshot_metadata.rs new file mode 100644 index 000000000..ac49dfb34 --- /dev/null +++ b/testgen/src/autogen/models/volume_snapshot_metadata.rs @@ -0,0 +1,116 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSnapshotMetadata : Volume Snapshot Metadata information. + + + + + + + + +/// Volume Snapshot Metadata information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSnapshotMetadata { + + /// Common base state for a resource + #[serde(default, rename = "status")] + pub status: crate::models::SpecStatus, + + /// Timestamp when snapshot is taken on the storage system. + #[serde(default, rename = "timestamp", skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + + /// Size in bytes of the snapshot (which is equivalent to its source size). + #[serde(default, rename = "size")] + pub size: u64, + + /// Spec size in bytes of the snapshot (which is equivalent to its source spec size). + #[serde(default, rename = "spec_size")] + pub spec_size: u64, + + /// Size in bytes taken by the snapshot and its predecessors. + #[serde(default, rename = "total_allocated_size")] + pub total_allocated_size: u64, + + + #[serde(default, rename = "txn_id")] + pub txn_id: String, + + + #[serde(default, rename = "transactions")] + pub transactions: ::std::collections::HashMap>, + + /// Number of restores done from this snapshot. + #[serde(default, rename = "num_restores")] + pub num_restores: u32, + + /// Number of snapshot replicas for a volumesnapshot. + #[serde(default, rename = "num_snapshot_replicas")] + pub num_snapshot_replicas: u32, + +} + +impl VolumeSnapshotMetadata { + /// VolumeSnapshotMetadata using only the required fields + pub fn new(status: impl Into, size: impl Into, spec_size: impl Into, total_allocated_size: impl Into, txn_id: impl Into, transactions: impl Into<::std::collections::HashMap>>, num_restores: impl Into, num_snapshot_replicas: impl Into) -> VolumeSnapshotMetadata { + VolumeSnapshotMetadata { + status: status.into(), + timestamp: None, + size: size.into(), + spec_size: spec_size.into(), + total_allocated_size: total_allocated_size.into(), + txn_id: txn_id.into(), + transactions: transactions.into(), + num_restores: num_restores.into(), + num_snapshot_replicas: num_snapshot_replicas.into(), + + } + } + /// VolumeSnapshotMetadata using all fields + pub fn new_all(status: impl Into, timestamp: impl Into>, size: impl Into, spec_size: impl Into, total_allocated_size: impl Into, txn_id: impl Into, transactions: impl Into<::std::collections::HashMap>>, num_restores: impl Into, num_snapshot_replicas: impl Into) -> VolumeSnapshotMetadata { + VolumeSnapshotMetadata { + status: status.into(), + timestamp: timestamp.into(), + size: size.into(), + spec_size: spec_size.into(), + total_allocated_size: total_allocated_size.into(), + txn_id: txn_id.into(), + transactions: transactions.into(), + num_restores: num_restores.into(), + num_snapshot_replicas: num_snapshot_replicas.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_snapshot_spec.rs b/testgen/src/autogen/models/volume_snapshot_spec.rs new file mode 100644 index 000000000..a9c8f324a --- /dev/null +++ b/testgen/src/autogen/models/volume_snapshot_spec.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSnapshotSpec : Volume Snapshot Spec information. + + + + + + + + +/// Volume Snapshot Spec information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSnapshotSpec { + + + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + + #[serde(default, rename = "source_volume")] + pub source_volume: uuid::Uuid, + +} + +impl VolumeSnapshotSpec { + /// VolumeSnapshotSpec using only the required fields + pub fn new(uuid: impl Into, source_volume: impl Into) -> VolumeSnapshotSpec { + VolumeSnapshotSpec { + uuid: uuid.into(), + source_volume: source_volume.into(), + + } + } + /// VolumeSnapshotSpec using all fields + pub fn new_all(uuid: impl Into, source_volume: impl Into) -> VolumeSnapshotSpec { + VolumeSnapshotSpec { + uuid: uuid.into(), + source_volume: source_volume.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_snapshot_state.rs b/testgen/src/autogen/models/volume_snapshot_state.rs new file mode 100644 index 000000000..85971b4fd --- /dev/null +++ b/testgen/src/autogen/models/volume_snapshot_state.rs @@ -0,0 +1,92 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSnapshotState : Volume Snapshot State information. + + + + + + + + +/// Volume Snapshot State information. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSnapshotState { + + + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + /// Runtime size in bytes of the snapshot. Equal to the volume allocation at the time of the snapshot creation. It may grow larger if any of its predecessors are deleted. + #[serde(default, rename = "allocated_size")] + pub allocated_size: u64, + + + #[serde(default, rename = "source_volume")] + pub source_volume: uuid::Uuid, + + /// Timestamp when snapshot is taken on the storage system. + #[serde(default, rename = "timestamp", skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + + /// Indicates if a snapshot is ready to be used as a new volume source. + #[serde(default, rename = "ready_as_source")] + pub ready_as_source: bool, + + /// List of individual ReplicaSnapshotStates. + #[serde(default, rename = "replica_snapshots")] + pub replica_snapshots: Vec, + +} + +impl VolumeSnapshotState { + /// VolumeSnapshotState using only the required fields + pub fn new(uuid: impl Into, allocated_size: impl Into, source_volume: impl Into, ready_as_source: impl Into, replica_snapshots: impl IntoVec) -> VolumeSnapshotState { + VolumeSnapshotState { + uuid: uuid.into(), + allocated_size: allocated_size.into(), + source_volume: source_volume.into(), + timestamp: None, + ready_as_source: ready_as_source.into(), + replica_snapshots: replica_snapshots.into_vec(), + + } + } + /// VolumeSnapshotState using all fields + pub fn new_all(uuid: impl Into, allocated_size: impl Into, source_volume: impl Into, timestamp: impl Into>, ready_as_source: impl Into, replica_snapshots: impl IntoVec) -> VolumeSnapshotState { + VolumeSnapshotState { + uuid: uuid.into(), + allocated_size: allocated_size.into(), + source_volume: source_volume.into(), + timestamp: timestamp.into(), + ready_as_source: ready_as_source.into(), + replica_snapshots: replica_snapshots.into_vec(), + + } + } +} + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_snapshots.rs b/testgen/src/autogen/models/volume_snapshots.rs new file mode 100644 index 000000000..0e766fec7 --- /dev/null +++ b/testgen/src/autogen/models/volume_snapshots.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSnapshots : Array of volume snapshots plus the next token for subsequent get requests when using pagination. + + + + + + + + +/// Array of volume snapshots plus the next token for subsequent get requests when using pagination. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSnapshots { + + + #[serde(default, rename = "entries")] + pub entries: Vec, + + + #[serde(default, rename = "next_token", skip_serializing_if = "Option::is_none")] + pub next_token: Option, + +} + +impl VolumeSnapshots { + /// VolumeSnapshots using only the required fields + pub fn new(entries: impl IntoVec) -> VolumeSnapshots { + VolumeSnapshots { + entries: entries.into_vec(), + next_token: None, + + } + } + /// VolumeSnapshots using all fields + pub fn new_all(entries: impl IntoVec, next_token: impl Into>) -> VolumeSnapshots { + VolumeSnapshots { + entries: entries.into_vec(), + next_token: next_token.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_spec.rs b/testgen/src/autogen/models/volume_spec.rs new file mode 100644 index 000000000..e966b68b7 --- /dev/null +++ b/testgen/src/autogen/models/volume_spec.rs @@ -0,0 +1,164 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSpec : User specification of a volume. + + + + + + + + +/// User specification of a volume. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSpec { + + /// Optionally used to store custom volume information + #[serde(default, rename = "labels", skip_serializing_if = "Option::is_none")] + pub labels: Option<::std::collections::HashMap>, + + /// Number of children the volume should have. + #[serde(default, rename = "num_replicas")] + pub num_replicas: u8, + + /// Record of the operation in progress + #[serde(default, rename = "operation", skip_serializing_if = "Option::is_none")] + pub operation: Option, + + /// Size that the volume should be. + #[serde(default, rename = "size")] + pub size: u64, + + /// Common base state for a resource + #[serde(default, rename = "status")] + pub status: crate::models::SpecStatus, + + /// Specification of a volume target + #[serde(default, rename = "target", skip_serializing_if = "Option::is_none")] + pub target: Option, + + /// Volume Id + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + /// node and pool topology for volumes + #[serde(default, rename = "topology", skip_serializing_if = "Option::is_none")] + pub topology: Option, + + /// Volume policy used to determine if and how to replace a replica + #[serde(default, rename = "policy")] + pub policy: crate::models::VolumePolicy, + + /// Thin provisioning flag. + #[serde(default, rename = "thin")] + pub thin: bool, + + /// Volume converted to thin provisioned. + #[serde(default, rename = "as_thin", skip_serializing_if = "Option::is_none")] + pub as_thin: Option, + + /// Affinity Group related information. + #[serde(default, rename = "affinity_group", skip_serializing_if = "Option::is_none")] + pub affinity_group: Option, + + /// Volume Content Source i.e the snapshot or the volume. + #[serde(default, rename = "content_source", skip_serializing_if = "Option::is_none")] + pub content_source: Option, + + /// Number of snapshots taken on this volume. + #[serde(default, rename = "num_snapshots")] + pub num_snapshots: u32, + + /// Max snapshots to limit per volume. + #[serde(default, rename = "max_snapshots", skip_serializing_if = "Option::is_none")] + pub max_snapshots: Option, + +} + +impl VolumeSpec { + /// VolumeSpec using only the required fields + pub fn new(num_replicas: impl Into, size: impl Into, status: impl Into, uuid: impl Into, policy: impl Into, thin: impl Into, num_snapshots: impl Into) -> VolumeSpec { + VolumeSpec { + labels: None, + num_replicas: num_replicas.into(), + operation: None, + size: size.into(), + status: status.into(), + target: None, + uuid: uuid.into(), + topology: None, + policy: policy.into(), + thin: thin.into(), + as_thin: None, + affinity_group: None, + content_source: None, + num_snapshots: num_snapshots.into(), + max_snapshots: None, + + } + } + /// VolumeSpec using all fields + pub fn new_all(labels: impl Into>>, num_replicas: impl Into, operation: impl Into>, size: impl Into, status: impl Into, target: impl Into>, uuid: impl Into, topology: impl Into>, policy: impl Into, thin: impl Into, as_thin: impl Into>, affinity_group: impl Into>, content_source: impl Into>, num_snapshots: impl Into, max_snapshots: impl Into>) -> VolumeSpec { + VolumeSpec { + labels: labels.into(), + num_replicas: num_replicas.into(), + operation: operation.into(), + size: size.into(), + status: status.into(), + target: target.into(), + uuid: uuid.into(), + topology: topology.into(), + policy: policy.into(), + thin: thin.into(), + as_thin: as_thin.into(), + affinity_group: affinity_group.into(), + content_source: content_source.into(), + num_snapshots: num_snapshots.into(), + max_snapshots: max_snapshots.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_spec_operation.rs b/testgen/src/autogen/models/volume_spec_operation.rs new file mode 100644 index 000000000..426c20069 --- /dev/null +++ b/testgen/src/autogen/models/volume_spec_operation.rs @@ -0,0 +1,114 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeSpecOperation : Record of the operation in progress + + + + + + + + +/// Record of the operation in progress + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeSpecOperation { + + /// Record of the operation + #[serde(default, rename = "operation")] + pub operation: Operation, + + /// Result of the operation + #[serde(default, rename = "result", skip_serializing_if = "Option::is_none")] + pub result: Option, + +} + +impl VolumeSpecOperation { + /// VolumeSpecOperation using only the required fields + pub fn new(operation: impl Into) -> VolumeSpecOperation { + VolumeSpecOperation { + operation: operation.into(), + result: None, + + } + } + /// VolumeSpecOperation using all fields + pub fn new_all(operation: impl Into, result: impl Into>) -> VolumeSpecOperation { + VolumeSpecOperation { + operation: operation.into(), + result: result.into(), + + } + } +} + + + + + + + + +/// Record of the operation +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum Operation { + + + #[serde(rename = "Create")] + Create, + + #[serde(rename = "Destroy")] + Destroy, + + #[serde(rename = "Share")] + Share, + + #[serde(rename = "Unshare")] + Unshare, + + #[serde(rename = "SetReplica")] + SetReplica, + + #[serde(rename = "RemoveUnusedReplica")] + RemoveUnusedReplica, + + #[serde(rename = "Publish")] + Publish, + + #[serde(rename = "Republish")] + Republish, + + #[serde(rename = "Unpublish")] + Unpublish, + + #[serde(rename = "CreateSnapshot")] + CreateSnapshot, + + #[serde(rename = "DestroySnapshot")] + DestroySnapshot, + + #[serde(rename = "Resize")] + Resize, + + #[serde(rename = "SetVolumeProperty")] + SetVolumeProperty, + + +} + +impl Default for Operation { + fn default() -> Self { + Self::Create + } +} + + + + + + diff --git a/testgen/src/autogen/models/volume_state.rs b/testgen/src/autogen/models/volume_state.rs new file mode 100644 index 000000000..f3cb92650 --- /dev/null +++ b/testgen/src/autogen/models/volume_state.rs @@ -0,0 +1,92 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeState : Runtime state of the volume + + + + + + + + +/// Runtime state of the volume + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeState { + + /// target exposed via a Nexus + #[serde(default, rename = "target", skip_serializing_if = "Option::is_none")] + pub target: Option, + + /// size of the volume in bytes + #[serde(default, rename = "size")] + pub size: u64, + + /// current volume status + #[serde(default, rename = "status")] + pub status: crate::models::VolumeStatus, + + /// name of the volume + #[serde(default, rename = "uuid")] + pub uuid: uuid::Uuid, + + /// replica topology information + #[serde(default, rename = "replica_topology")] + pub replica_topology: ::std::collections::HashMap, + + /// Volume space usage + #[serde(default, rename = "usage", skip_serializing_if = "Option::is_none")] + pub usage: Option, + +} + +impl VolumeState { + /// VolumeState using only the required fields + pub fn new(size: impl Into, status: impl Into, uuid: impl Into, replica_topology: impl Into<::std::collections::HashMap>) -> VolumeState { + VolumeState { + target: None, + size: size.into(), + status: status.into(), + uuid: uuid.into(), + replica_topology: replica_topology.into(), + usage: None, + + } + } + /// VolumeState using all fields + pub fn new_all(target: impl Into>, size: impl Into, status: impl Into, uuid: impl Into, replica_topology: impl Into<::std::collections::HashMap>, usage: impl Into>) -> VolumeState { + VolumeState { + target: target.into(), + size: size.into(), + status: status.into(), + uuid: uuid.into(), + replica_topology: replica_topology.into(), + usage: usage.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_status.rs b/testgen/src/autogen/models/volume_status.rs new file mode 100644 index 000000000..f045fb712 --- /dev/null +++ b/testgen/src/autogen/models/volume_status.rs @@ -0,0 +1,66 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeStatus : current volume status + + + +/// current volume status +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub enum VolumeStatus { + + + #[serde(rename = "Unknown")] + Unknown, + + #[serde(rename = "Online")] + Online, + + #[serde(rename = "Degraded")] + Degraded, + + #[serde(rename = "Faulted")] + Faulted, + + #[serde(rename = "Shutdown")] + Shutdown, + +} + +impl ToString for VolumeStatus { + fn to_string(&self) -> String { + match self { + + + Self::Unknown => String::from("Unknown"), + + Self::Online => String::from("Online"), + + Self::Degraded => String::from("Degraded"), + + Self::Faulted => String::from("Faulted"), + + Self::Shutdown => String::from("Shutdown"), + + + } + } +} + +impl Default for VolumeStatus { + fn default() -> Self { + Self::Unknown + } +} + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_target.rs b/testgen/src/autogen/models/volume_target.rs new file mode 100644 index 000000000..57ae5526f --- /dev/null +++ b/testgen/src/autogen/models/volume_target.rs @@ -0,0 +1,68 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeTarget : Specification of a volume target + + + + + + + + +/// Specification of a volume target + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeTarget { + + /// The node where front-end IO will be sent to + #[serde(default, rename = "node")] + pub node: String, + + /// Volume Share Protocol + #[serde(default, rename = "protocol", skip_serializing_if = "Option::is_none")] + pub protocol: Option, + + /// The nodes where the front-end workload resides. If the workload moves then the volume must be republished. + #[serde(default, rename = "frontend_nodes", skip_serializing_if = "Option::is_none")] + pub frontend_nodes: Option>, + +} + +impl VolumeTarget { + /// VolumeTarget using only the required fields + pub fn new(node: impl Into) -> VolumeTarget { + VolumeTarget { + node: node.into(), + protocol: None, + frontend_nodes: None, + + } + } + /// VolumeTarget using all fields + pub fn new_all(node: impl Into, protocol: impl Into>, frontend_nodes: impl IntoOptVec) -> VolumeTarget { + VolumeTarget { + node: node.into(), + protocol: protocol.into(), + frontend_nodes: frontend_nodes.into_opt_vec(), + + } + } +} + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volume_usage.rs b/testgen/src/autogen/models/volume_usage.rs new file mode 100644 index 000000000..7bebe2612 --- /dev/null +++ b/testgen/src/autogen/models/volume_usage.rs @@ -0,0 +1,108 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// VolumeUsage : Volume space usage + + + + + + + + +/// Volume space usage + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct VolumeUsage { + + /// Capacity of the volume in bytes. + #[serde(default, rename = "capacity")] + pub capacity: u64, + + /// -| Allocated size in bytes, related the largest healthy replica, including snapshots. For example, if a volume has 2 replicas, each with 1MiB allocated space, then this field will be 1MiB. + #[serde(default, rename = "allocated")] + pub allocated: u64, + + /// -| Allocated size in bytes, related to the largest healthy replica, excluding snapshots. + #[serde(default, rename = "allocated_replica")] + pub allocated_replica: u64, + + /// -| Allocated size in bytes, related the healthy replica with the highest snapshot usage. + #[serde(default, rename = "allocated_snapshots")] + pub allocated_snapshots: u64, + + /// -| For a restored/cloned volume, allocated size in bytes, related to the healthy replica with largest parent snapshot allocation. + #[serde(default, rename = "allocated_all_snapshots")] + pub allocated_all_snapshots: u64, + + /// -| Allocated size in bytes, accrued from all the replicas, including snapshots. For example, if a volume has 2 replicas, each with 1MiB allocated space, then this field will be 2MiB. + #[serde(default, rename = "total_allocated")] + pub total_allocated: u64, + + /// -| Allocated size in bytes, accrued from all the replicas, excluding snapshots. + #[serde(default, rename = "total_allocated_replicas")] + pub total_allocated_replicas: serde_json::Value, + + /// -| Allocated size in bytes, accrued from all the replica\'s snapshots. + #[serde(default, rename = "total_allocated_snapshots")] + pub total_allocated_snapshots: u64, + +} + +impl VolumeUsage { + /// VolumeUsage using only the required fields + pub fn new(capacity: impl Into, allocated: impl Into, allocated_replica: impl Into, allocated_snapshots: impl Into, allocated_all_snapshots: impl Into, total_allocated: impl Into, total_allocated_replicas: impl Into, total_allocated_snapshots: impl Into) -> VolumeUsage { + VolumeUsage { + capacity: capacity.into(), + allocated: allocated.into(), + allocated_replica: allocated_replica.into(), + allocated_snapshots: allocated_snapshots.into(), + allocated_all_snapshots: allocated_all_snapshots.into(), + total_allocated: total_allocated.into(), + total_allocated_replicas: total_allocated_replicas.into(), + total_allocated_snapshots: total_allocated_snapshots.into(), + + } + } + /// VolumeUsage using all fields + pub fn new_all(capacity: impl Into, allocated: impl Into, allocated_replica: impl Into, allocated_snapshots: impl Into, allocated_all_snapshots: impl Into, total_allocated: impl Into, total_allocated_replicas: impl Into, total_allocated_snapshots: impl Into) -> VolumeUsage { + VolumeUsage { + capacity: capacity.into(), + allocated: allocated.into(), + allocated_replica: allocated_replica.into(), + allocated_snapshots: allocated_snapshots.into(), + allocated_all_snapshots: allocated_all_snapshots.into(), + total_allocated: total_allocated.into(), + total_allocated_replicas: total_allocated_replicas.into(), + total_allocated_snapshots: total_allocated_snapshots.into(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/volumes.rs b/testgen/src/autogen/models/volumes.rs new file mode 100644 index 000000000..f65210268 --- /dev/null +++ b/testgen/src/autogen/models/volumes.rs @@ -0,0 +1,60 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// Volumes : Array of volumes plus the next token for subsequent get requests when using pagination. + + + + + + + + +/// Array of volumes plus the next token for subsequent get requests when using pagination. + +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Volumes { + + + #[serde(default, rename = "entries")] + pub entries: Vec, + + + #[serde(default, rename = "next_token", skip_serializing_if = "Option::is_none")] + pub next_token: Option, + +} + +impl Volumes { + /// Volumes using only the required fields + pub fn new(entries: impl IntoVec) -> Volumes { + Volumes { + entries: entries.into_vec(), + next_token: None, + + } + } + /// Volumes using all fields + pub fn new_all(entries: impl IntoVec, next_token: impl Into>) -> Volumes { + Volumes { + entries: entries.into_vec(), + next_token: next_token.into(), + + } + } +} + + + + + + + + + + + + diff --git a/testgen/src/autogen/models/watch_callback.rs b/testgen/src/autogen/models/watch_callback.rs new file mode 100644 index 000000000..afb910e44 --- /dev/null +++ b/testgen/src/autogen/models/watch_callback.rs @@ -0,0 +1,37 @@ +#![allow(clippy::too_many_arguments, clippy::new_without_default, non_camel_case_types, unused_imports)] + +use crate::apis::{IntoOptVec, IntoVec}; + + + +/// WatchCallback : Watch Callbacks + + + + + + + + +/// Watch Callbacks + + + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum WatchCallback { + + + #[serde(rename = "uri")] + uri(String), + +} + + + + + + + + + + From b917e8a26759888f91ced9e77bec54753c05e360 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Mon, 21 Oct 2024 00:52:23 +0100 Subject: [PATCH 2/4] fix: exit with error on failure paperclip cli main was not exiting with error code. Signed-off-by: Tiago Castro --- src/bin/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/main.rs b/src/bin/main.rs index a34426542..5cf59d54e 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -152,5 +152,6 @@ fn main() { env_logger::init(); if let Err(e) = parse_args_and_run() { eprintln!("{}", e); + std::process::exit(1); } } From 8bb90b76c7e8d0a14c4aca8edf231986247edf66 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Mon, 21 Oct 2024 00:53:01 +0100 Subject: [PATCH 3/4] ci: add release publish workflow On a new published release, build and upload the cli's as static binaries in a tar file. Signed-off-by: Tiago Castro --- .github/workflows/release.yml | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..7cfe673e7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Publish Bins +on: + release: + types: [published] +jobs: + paperclip-bins: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-musl + - os: ubuntu-latest + target: aarch64-unknown-linux-musl + - os: macos-14 + target: x86_64-apple-darwin + - os: macos-13 + target: aarch64-apple-darwin + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + - name: Build + uses: actions-rs/cargo@v1 + with: + use-cross: true + command: build + args: --bins --verbose --release --features "cli" -p paperclip -p paperclip-ng --target ${{ matrix.target }} + - name: Archive + shell: bash + run: | + tar -czf paperclip-${{ matrix.target }}.tar.gz LICENSE-APACHE LICENSE-MIT -C ./target/${{ matrix.target }}/release/ paperclip paperclip-ng + - name: Publish + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release upload "${{ github.event.release.tag_name }}" --clobber *.tar.gz \ No newline at end of file From 0a32d58630488f2d7e5aa7b0581f99438c4b8ee5 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Mon, 21 Oct 2024 01:21:40 +0100 Subject: [PATCH 4/4] chore: prepare for 0.9.3 release with cli-ng 0.1.0 Signed-off-by: Tiago Castro --- CHANGELOG.md | 4 ++++ Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ca4c2c0a..5fdf2ebf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.9.3] - 2024-10-21 +### Added +- Experimental openapiv3 cli codegen. [PR#506](https://github.com/paperclip-rs/paperclip/pull/506) + ## [0.9.2] - 2024-10-13 ### Fixed - Switch to pro-macro-error2. [PR#545](https://github.com/paperclip-rs/paperclip/pull/545) diff --git a/Cargo.toml b/Cargo.toml index 2f2902439..84367f588 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "paperclip" -version = "0.9.2" +version = "0.9.3" edition = "2018" description = "OpenAPI tooling library for type-safe compile-time checked HTTP APIs" documentation = "https://paperclip-rs.github.io/paperclip/paperclip"