openstack_cli_network/v2/port/binding/
create.rs1use clap::Args;
23use eyre::WrapErr;
24use tracing::info;
25
26use openstack_cli_core::cli::CliArgs;
27use openstack_cli_core::error::OpenStackCliError;
28use openstack_cli_core::output::OutputProcessor;
29use openstack_sdk::AsyncOpenStack;
30
31use clap::ValueEnum;
32use openstack_cli_core::common::parse_key_val;
33use openstack_sdk::api::QueryAsync;
34use openstack_sdk::api::network::v2::port::binding::create;
35use openstack_types::network::v2::port::binding::response;
36use serde_json::Value;
37
38#[derive(Args)]
40pub struct BindingCommand {
41 #[command(flatten)]
43 query: QueryParameters,
44
45 #[command(flatten)]
47 path: PathParameters,
48
49 #[command(flatten)]
50 binding: Binding,
51}
52
53#[derive(Args)]
55struct QueryParameters {}
56
57#[derive(Args)]
59struct PathParameters {
60 #[arg(
62 help_heading = "Path parameters",
63 id = "path_param_port_id",
64 value_name = "PORT_ID"
65 )]
66 port_id: String,
67}
68
69#[derive(Clone, Eq, Ord, PartialEq, PartialOrd, ValueEnum)]
70enum VnicType {
71 AcceleratorDirect,
72 AcceleratorDirectPhysical,
73 Baremetal,
74 Direct,
75 DirectPhysical,
76 Macvtap,
77 Normal,
78 RemoteManaged,
79 SmartNic,
80 Vdpa,
81 VirtioForwarder,
82}
83
84#[derive(Args, Clone)]
86struct Binding {
87 #[arg(help_heading = "Body parameters", long)]
88 host: Option<String>,
89
90 #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, Value>)]
91 profile: Option<Vec<(String, Value)>>,
92
93 #[arg(help_heading = "Body parameters", long)]
94 project_id: Option<String>,
95
96 #[arg(help_heading = "Body parameters", long)]
97 vnic_type: Option<VnicType>,
98}
99
100impl BindingCommand {
101 pub async fn take_action<C: CliArgs>(
103 &self,
104 parsed_args: &C,
105 client: &mut AsyncOpenStack,
106 ) -> Result<(), OpenStackCliError> {
107 info!("Create Binding");
108
109 let op =
110 OutputProcessor::from_args(parsed_args, Some("network.port/binding"), Some("create"));
111 op.validate_args(parsed_args)?;
112
113 let mut ep_builder = create::Request::builder();
114
115 ep_builder.port_id(&self.path.port_id);
116
117 let args = &self.binding;
120 let mut binding_builder = create::BindingBuilder::default();
121 if let Some(val) = &args.host {
122 binding_builder.host(val);
123 }
124
125 if let Some(val) = &args.profile {
126 binding_builder.profile(val.iter().cloned());
127 }
128
129 if let Some(val) = &args.project_id {
130 binding_builder.project_id(val);
131 }
132
133 if let Some(val) = &args.vnic_type {
134 let tmp = match val {
135 VnicType::AcceleratorDirect => create::VnicType::AcceleratorDirect,
136 VnicType::AcceleratorDirectPhysical => create::VnicType::AcceleratorDirectPhysical,
137 VnicType::Baremetal => create::VnicType::Baremetal,
138 VnicType::Direct => create::VnicType::Direct,
139 VnicType::DirectPhysical => create::VnicType::DirectPhysical,
140 VnicType::Macvtap => create::VnicType::Macvtap,
141 VnicType::Normal => create::VnicType::Normal,
142 VnicType::RemoteManaged => create::VnicType::RemoteManaged,
143 VnicType::SmartNic => create::VnicType::SmartNic,
144 VnicType::Vdpa => create::VnicType::Vdpa,
145 VnicType::VirtioForwarder => create::VnicType::VirtioForwarder,
146 };
147 binding_builder.vnic_type(tmp);
148 }
149
150 ep_builder.binding(
151 binding_builder
152 .build()
153 .wrap_err("error preparing the request data")?,
154 );
155
156 let ep = ep_builder
157 .build()
158 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
159
160 let data: serde_json::Value = ep.query_async(client).await?;
161
162 op.output_single::<response::create::BindingResponse>(data.clone())?;
163 op.show_command_hint()?;
165 Ok(())
166 }
167}