1use aws_sdk_cloudformation::Client;
2use rusty_cdk_core::wrappers::StringWithOnlyAlphaNumericsAndHyphens;
3use std::error::Error;
4use std::fmt::{Display, Formatter};
5use std::process::exit;
6use std::time::Duration;
7use aws_sdk_cloudformation::types::StackStatus;
8use tokio::time::sleep;
9use crate::util::{get_stack_status, load_config};
10
11#[derive(Debug)]
12pub enum DestroyError {
13 StackDeleteError(String),
14 UnknownError(String),
15}
16
17impl Error for DestroyError {}
18
19impl Display for DestroyError {
20 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21 match self {
22 DestroyError::StackDeleteError(_) => f.write_str("unable to delete stack"),
23 DestroyError::UnknownError(_) => f.write_str("unknown error"),
24 }
25 }
26}
27
28pub async fn destroy(name: StringWithOnlyAlphaNumericsAndHyphens) {
30 let name = name.0;
31 let config = load_config().await;
32 let cloudformation_client = Client::new(&config);
33
34 match destroy_stack(&name, &cloudformation_client).await {
35 Ok(()) => {},
36 Err(e) => {
37 eprintln!("{:?}", e);
38 exit(1);
39 }
40 }
41
42 loop {
43 let status = get_stack_status(&name, &cloudformation_client).await;
44
45 if let Some(status) = status {
46 match status {
47 StackStatus::DeleteComplete => {
48 println!("destroy completed successfully!");
49 exit(0);
50 }
51 StackStatus::DeleteInProgress => {
52 println!("destroying...");
53 }
54 StackStatus::DeleteFailed => {
55 println!("destroy failed");
56 exit(1);
57 }
58 _ => {
59 println!("encountered unexpected cloudformation status: {status}");
60 exit(1);
61 }
62 }
63 } else {
64 println!("destroy completed successfully!");
66 exit(0);
67 }
68
69 sleep(Duration::from_secs(10)).await;
70 }
71}
72
73pub async fn destroy_with_result(name: StringWithOnlyAlphaNumericsAndHyphens) -> Result<(), DestroyError> {
77 let name = name.0;
78 let config = load_config().await;
79 let cloudformation_client = Client::new(&config);
80
81 destroy_stack(&name, &cloudformation_client).await?;
82
83 loop {
84 let status = get_stack_status(&name, &cloudformation_client).await;
85
86 if let Some(status) = status {
87 match status {
88 StackStatus::DeleteComplete => {
89 return Ok(())
90 }
91 StackStatus::DeleteInProgress => {}
92 StackStatus::DeleteFailed => {
93 return Err(DestroyError::StackDeleteError(format!("{status}")));
94 }
95 _ => {
96 return Err(DestroyError::UnknownError(format!("{status}")));
97 }
98 }
99 } else {
100 return Ok(())
102 }
103
104 sleep(Duration::from_secs(10)).await;
105 }
106}
107
108async fn destroy_stack(name: &String, cloudformation_client: &Client) -> Result<(), DestroyError> {
109 let delete_result = cloudformation_client
110 .delete_stack()
111 .stack_name(name)
112 .send()
113 .await;
114 match delete_result {
115 Ok(_) => Ok(()),
116 Err(e) => Err(DestroyError::StackDeleteError(e.to_string()))
117 }
118}