Skip to main content

rusty_cdk/
destroy.rs

1use crate::util::{get_stack_status, load_config};
2use aws_sdk_cloudformation::types::StackStatus;
3use aws_sdk_cloudformation::Client;
4use rusty_cdk_core::wrappers::StringWithOnlyAlphaNumericsAndHyphens;
5use std::error::Error;
6use std::fmt::{Display, Formatter};
7use std::process::exit;
8use std::time::Duration;
9use tokio::time::sleep;
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
28/// Destroy a deployed stack
29pub async fn destroy(name: StringWithOnlyAlphaNumericsAndHyphens) {
30    match destroy_with_result(name, true).await {
31        Ok(()) => println!("destroy completed successfully!"),
32        Err(e) => {
33            eprintln!("{:?}", e);
34            exit(1);
35        }
36    }
37}
38
39/// Destroy a deployed stack
40///
41/// It returns a `Result`. In case of error, a `DestroyError` is returned.
42pub async fn destroy_with_result(name: StringWithOnlyAlphaNumericsAndHyphens, print_progress: bool) -> Result<(), DestroyError> {
43    let name = name.0;
44    let config = load_config(false).await;
45    let cloudformation_client = Client::new(&config);
46
47    destroy_stack(&name, &cloudformation_client).await?;
48
49    loop {
50        let status = get_stack_status(&name, &cloudformation_client).await;
51
52        if let Some(status) = status {
53            match status {
54                StackStatus::DeleteComplete => return Ok(()),
55                StackStatus::DeleteInProgress => {
56                    if print_progress {
57                        println!("destroying...");
58                    }
59                }
60                StackStatus::DeleteFailed => {
61                    return Err(DestroyError::StackDeleteError(format!("{status}")));
62                }
63                _ => {
64                    return Err(DestroyError::UnknownError(format!("{status}")));
65                }
66            }
67        } else {
68            // no status, so stack should be gone
69            return Ok(());
70        }
71
72        sleep(Duration::from_secs(10)).await;
73    }
74}
75
76async fn destroy_stack(name: &String, cloudformation_client: &Client) -> Result<(), DestroyError> {
77    let delete_result = cloudformation_client.delete_stack().stack_name(name).send().await;
78    match delete_result {
79        Ok(_) => Ok(()),
80        Err(e) => Err(DestroyError::StackDeleteError(e.to_string())),
81    }
82}