1use crate::config::AwsConfig;
2use anyhow::Result;
3
4pub struct AlarmsClient {
5 config: AwsConfig,
6}
7
8impl AlarmsClient {
9 pub fn new(config: AwsConfig) -> Self {
10 Self { config }
11 }
12
13 pub async fn list_alarms(
14 &self,
15 ) -> Result<
16 Vec<(
17 String,
18 String,
19 String,
20 String,
21 String,
22 String,
23 String,
24 u32,
25 String,
26 f64,
27 bool,
28 String,
29 String,
30 String,
31 String,
32 String,
33 String,
34 )>,
35 > {
36 let client = self.config.cloudwatch_client().await;
37
38 let resp = client.describe_alarms().send().await?;
39
40 let mut alarms = Vec::new();
41
42 for alarm in resp.metric_alarms() {
43 let name = alarm.alarm_name().unwrap_or("").to_string();
44 let state = alarm
45 .state_value()
46 .map(|s| s.as_str())
47 .unwrap_or("INSUFFICIENT_DATA")
48 .to_string();
49 let state_updated = alarm
50 .state_updated_timestamp()
51 .map(|t| {
52 let dt = chrono::DateTime::parse_from_rfc3339(&t.to_string())
53 .unwrap_or_else(|_| chrono::Utc::now().into());
54 dt.format("%Y-%m-%d %H:%M:%S").to_string()
55 })
56 .unwrap_or_default();
57 let description = alarm.alarm_description().unwrap_or("").to_string();
58 let metric_name = alarm.metric_name().unwrap_or("").to_string();
59 let namespace = alarm.namespace().unwrap_or("").to_string();
60 let statistic = alarm
61 .statistic()
62 .map(|s| s.as_str())
63 .unwrap_or("")
64 .to_string();
65 let period = alarm.period().unwrap_or(0) as u32;
66 let comparison = alarm
67 .comparison_operator()
68 .map(|c| c.as_str())
69 .unwrap_or("")
70 .to_string();
71 let threshold = alarm.threshold().unwrap_or(0.0);
72 let actions_enabled = alarm.actions_enabled().unwrap_or(false);
73 let state_reason = alarm.state_reason().unwrap_or("").to_string();
74
75 let resource = alarm
76 .dimensions()
77 .iter()
78 .map(|d| format!("{}={}", d.name().unwrap_or(""), d.value().unwrap_or("")))
79 .collect::<Vec<_>>()
80 .join(", ");
81
82 let dimensions = resource.clone();
83 let expression = if !alarm.metrics().is_empty() {
84 "Expression".to_string()
85 } else {
86 String::new()
87 };
88 let alarm_type = if !alarm.metrics().is_empty() {
89 "Metric math"
90 } else {
91 "Metric"
92 }
93 .to_string();
94 let cross_account = "".to_string();
95
96 alarms.push((
97 name,
98 state,
99 state_updated,
100 description,
101 metric_name,
102 namespace,
103 statistic,
104 period,
105 comparison,
106 threshold,
107 actions_enabled,
108 state_reason,
109 resource,
110 dimensions,
111 expression,
112 alarm_type,
113 cross_account,
114 ));
115 }
116
117 Ok(alarms)
118 }
119}