openstack_cli_compute/v2/migration/
get.rs1use clap::Args;
23use eyre::OptionExt;
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 openstack_sdk::api::QueryAsync;
32use openstack_sdk::api::compute::v2::migration::get;
33use openstack_sdk::api::find_by_name;
34use openstack_sdk::api::identity::v3::project::find as find_project;
35use openstack_sdk::api::identity::v3::user::find as find_user;
36use openstack_types::compute::v2::migration::response;
37use tracing::warn;
38
39#[derive(Args)]
52#[command(about = "List Migrations")]
53pub struct MigrationCommand {
54 #[command(flatten)]
56 query: QueryParameters,
57
58 #[command(flatten)]
60 path: PathParameters,
61}
62
63#[derive(Args)]
65struct QueryParameters {
66 #[arg(help_heading = "Query parameters", long)]
67 changes_before: Option<String>,
68
69 #[arg(help_heading = "Query parameters", long)]
70 changes_since: Option<String>,
71
72 #[arg(help_heading = "Query parameters", long)]
73 hidden: Option<String>,
74
75 #[arg(help_heading = "Query parameters", long)]
76 host: Option<String>,
77
78 #[arg(help_heading = "Query parameters", long)]
79 instance_uuid: Option<String>,
80
81 #[arg(
86 help_heading = "Query parameters",
87 long("page-size"),
88 visible_alias("limit")
89 )]
90 limit: Option<u32>,
91
92 #[arg(help_heading = "Query parameters", long)]
96 marker: Option<String>,
97
98 #[arg(help_heading = "Query parameters", long)]
99 migration_type: Option<String>,
100
101 #[command(flatten)]
103 project: ProjectInput,
104
105 #[arg(help_heading = "Query parameters", long)]
106 source_compute: Option<String>,
107
108 #[arg(help_heading = "Query parameters", long)]
109 status: Option<String>,
110
111 #[command(flatten)]
113 user: UserInput,
114}
115
116#[derive(Args)]
118#[group(required = false, multiple = false)]
119struct ProjectInput {
120 #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_NAME")]
122 project_name: Option<String>,
123 #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_ID")]
125 project_id: Option<String>,
126 #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
128 current_project: bool,
129}
130
131#[derive(Args)]
133#[group(required = false, multiple = false)]
134struct UserInput {
135 #[arg(long, help_heading = "Path parameters", value_name = "USER_NAME")]
137 user_name: Option<String>,
138 #[arg(long, help_heading = "Path parameters", value_name = "USER_ID")]
140 user_id: Option<String>,
141 #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
143 current_user: bool,
144}
145
146#[derive(Args)]
148struct PathParameters {}
149
150impl MigrationCommand {
151 pub async fn take_action<C: CliArgs>(
153 &self,
154 parsed_args: &C,
155 client: &mut AsyncOpenStack,
156 ) -> Result<(), OpenStackCliError> {
157 info!("Get Migration");
158
159 let op = OutputProcessor::from_args(parsed_args, Some("compute.migration"), Some("get"));
160 op.validate_args(parsed_args)?;
161
162 let mut ep_builder = get::Request::builder();
163
164 if let Some(val) = &self.query.changes_before {
166 ep_builder.changes_before(val);
167 }
168 if let Some(val) = &self.query.changes_since {
169 ep_builder.changes_since(val);
170 }
171 if let Some(val) = &self.query.hidden {
172 ep_builder.hidden(val);
173 }
174 if let Some(val) = &self.query.host {
175 ep_builder.host(val);
176 }
177 if let Some(val) = &self.query.instance_uuid {
178 ep_builder.instance_uuid(val);
179 }
180 if let Some(val) = &self.query.limit {
181 ep_builder.limit(*val);
182 }
183 if let Some(val) = &self.query.marker {
184 ep_builder.marker(val);
185 }
186 if let Some(val) = &self.query.migration_type {
187 ep_builder.migration_type(val);
188 }
189 if let Some(id) = &self.query.project.project_id {
190 ep_builder.project_id(id);
192 } else if let Some(name) = &self.query.project.project_name {
193 let mut sub_find_builder = find_project::Request::builder();
195 warn!(
196 "Querying project by name (because of `--project-name` parameter passed) may not be definite. This may fail in which case parameter `--project-id` should be used instead."
197 );
198
199 sub_find_builder.id(name);
200 let find_ep = sub_find_builder
201 .build()
202 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
203 let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
204 match find_data.get("id") {
206 Some(val) => match val.as_str() {
207 Some(id_str) => {
208 ep_builder.project_id(id_str.to_owned());
209 }
210 None => {
211 return Err(OpenStackCliError::ResourceAttributeNotString(
212 serde_json::to_string(&val)?,
213 ));
214 }
215 },
216 None => {
217 return Err(OpenStackCliError::ResourceAttributeMissing(
218 "id".to_string(),
219 ));
220 }
221 };
222 } else if self.query.project.current_project {
223 ep_builder.project_id(
224 client
225 .get_auth_info()
226 .ok_or_eyre("Cannot determine current authentication information")?
227 .token
228 .user
229 .id,
230 );
231 }
232 if let Some(val) = &self.query.source_compute {
233 ep_builder.source_compute(val);
234 }
235 if let Some(val) = &self.query.status {
236 ep_builder.status(val);
237 }
238 if let Some(id) = &self.query.user.user_id {
239 ep_builder.user_id(id);
241 } else if let Some(name) = &self.query.user.user_name {
242 let mut sub_find_builder = find_user::Request::builder();
244 warn!(
245 "Querying user by name (because of `--user-name` parameter passed) may not be definite. This may fail in which case parameter `--user-id` should be used instead."
246 );
247
248 sub_find_builder.id(name);
249 let find_ep = sub_find_builder
250 .build()
251 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
252 let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
253 match find_data.get("id") {
255 Some(val) => match val.as_str() {
256 Some(id_str) => {
257 ep_builder.user_id(id_str.to_owned());
258 }
259 None => {
260 return Err(OpenStackCliError::ResourceAttributeNotString(
261 serde_json::to_string(&val)?,
262 ));
263 }
264 },
265 None => {
266 return Err(OpenStackCliError::ResourceAttributeMissing(
267 "id".to_string(),
268 ));
269 }
270 };
271 } else if self.query.user.current_user {
272 ep_builder.user_id(
273 client
274 .get_auth_info()
275 .ok_or_eyre("Cannot determine current authentication information")?
276 .token
277 .user
278 .id,
279 );
280 }
281
282 let ep = ep_builder
283 .build()
284 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
285
286 let data: Vec<serde_json::Value> = ep.query_async(client).await?;
287 op.output_list::<response::get_20::MigrationResponse>(data.clone())
288 .or_else(|_| op.output_list::<response::get_223::MigrationResponse>(data.clone()))
289 .or_else(|_| op.output_list::<response::get_259::MigrationResponse>(data.clone()))
290 .or_else(|_| op.output_list::<response::get_280::MigrationResponse>(data.clone()))?;
291 op.show_command_hint()?;
293 Ok(())
294 }
295}