1use crate::types::{OutputKey, StackId, StackIdentifier, StackName};
2
3pub(crate) async fn try_load_stack<T: StackIdentifier>(
4 cloudformation: &aws_sdk_cloudformation::client::Client,
5 stack_identifier: &T,
6) -> Option<aws_sdk_cloudformation::types::Stack> {
7 let response = cloudformation
8 .describe_stacks()
9 .stack_name(stack_identifier.as_str())
10 .send()
11 .await;
12
13 match response {
14 Ok(output) => output.stacks.unwrap().first().cloned(),
15 Err(error) => {
16 let service_error = error.into_service_error();
17 let meta = service_error.meta();
18 let expected_message =
19 format!("Stack with id {} does not exist", stack_identifier.as_str());
20
21 match meta.code() {
22 Some("ValidationError") if meta.message() == Some(&expected_message) => None,
24 _ => panic!("unexpected service error: {service_error:#?}"),
25 }
26 }
27 }
28}
29
30pub async fn load_stack<T: StackIdentifier>(
31 cloudformation: &aws_sdk_cloudformation::client::Client,
32 stack_identifier: &T,
33) -> aws_sdk_cloudformation::types::Stack {
34 try_load_stack(cloudformation, stack_identifier)
35 .await
36 .unwrap_or_else(|| panic!("stack: {stack_identifier:#?} does not exist!"))
37}
38
39pub(crate) async fn load_stack_id(
40 cloudformation: &aws_sdk_cloudformation::client::Client,
41 stack_name: &StackName,
42) -> StackId {
43 StackId(
44 load_stack(cloudformation, &stack_name)
45 .await
46 .stack_id
47 .unwrap(),
48 )
49}
50
51pub async fn read_stack_output<T: StackIdentifier>(
52 cloudformation: &aws_sdk_cloudformation::client::Client,
53 stack_identifier: &T,
54 output_key: &OutputKey,
55) -> String {
56 log::info!("Reading stack output, stack: {stack_identifier} output: {output_key}");
57
58 load_stack(cloudformation, stack_identifier)
59 .await
60 .outputs()
61 .iter()
62 .find(|output| output.output_key().unwrap() == output_key.0)
63 .unwrap_or_else(|| {
64 panic!(
65 "stack: {:#?} missing output: {}",
66 stack_identifier, output_key.0
67 )
68 })
69 .output_value()
70 .unwrap()
71 .to_string()
72}
73
74#[must_use]
75pub fn fetch_stack_output(
76 stack: &aws_sdk_cloudformation::types::Stack,
77 output_key: &OutputKey,
78) -> String {
79 stack
80 .outputs()
81 .iter()
82 .find(|output| output.output_key().unwrap() == output_key.0)
83 .unwrap_or_else(|| {
84 panic!(
85 "stack: {} missing output: {}",
86 stack.stack_name.as_ref().unwrap(),
87 output_key.0
88 )
89 })
90 .output_value()
91 .unwrap()
92 .to_string()
93}