Skip to main content

rusty_cdk/
diff.rs

1use aws_sdk_cloudformation::Client;
2use rusty_cdk_core::stack::{Stack, StackDiff};
3use rusty_cdk_core::wrappers::StringWithOnlyAlphaNumericsAndHyphens;
4use crate::util::{get_existing_template, load_config};
5
6/// Creates a diff that will show what ids are being added / removed to an existing stack, as well as showing ids that remain without being added or removed.
7/// Currently, the diff does not show modifications to resources.
8/// 
9/// # Parameters
10///
11/// * `name` - The existing CloudFormation stack name
12/// * `stack` - The new stack
13/// * `print_progress` - Print progress updates to standard out
14///
15/// # AWS Credentials
16///
17/// This function requires valid AWS credentials.
18/// The AWS credentials must have permissions for:
19/// - `cloudformation:DescribeStacks`
20/// - `cloudformation:GetTemplate`
21pub async fn diff(name: StringWithOnlyAlphaNumericsAndHyphens, stack: Stack) -> Result<String, String> {
22    let config = load_config(false).await;
23    let cloudformation_client = Client::new(&config);
24
25    match get_existing_template(&cloudformation_client, &name.0).await {
26        None => {
27            Err(format!("could not find existing stack with name {}", name.0))
28        }
29        Some(existing) => {
30            let diff = stack.get_diff(&existing);
31
32            match diff {
33                Ok(diff) => {
34                    let StackDiff { new_ids, unchanged_ids, ids_to_be_removed} = diff;
35                    let output = format!("- added ids: {}\n- removed ids: {}\n- ids that stay: {}", print_ids(new_ids), print_ids(ids_to_be_removed), print_ids(unchanged_ids));
36                    Ok(output)
37                }
38                Err(e) => {
39                    Err(e)
40                }
41            }
42        }
43    }
44}
45
46fn print_ids(ids: Vec<(String, String)>) -> String {
47    if ids.is_empty() {
48        "(none)".to_string()
49    } else {
50        ids.into_iter().map(|v| format!("{} (resource {})", v.0, v.1)).collect::<Vec<_>>().join(", ")
51    }
52}