Skip to main content

rusticity_term/cw/
alarms.rs

1use crate::common::translate_column;
2use crate::common::{ColumnId, UTC_TIMESTAMP_WIDTH};
3use std::collections::HashMap;
4
5pub fn init(i18n: &mut HashMap<String, String>) {
6    for col in [
7        AlarmColumn::Name,
8        AlarmColumn::State,
9        AlarmColumn::LastStateUpdate,
10        AlarmColumn::Description,
11        AlarmColumn::Conditions,
12        AlarmColumn::Actions,
13        AlarmColumn::StateDetails,
14        AlarmColumn::MetricName,
15        AlarmColumn::Namespace,
16        AlarmColumn::Statistic,
17        AlarmColumn::Period,
18        AlarmColumn::Resource,
19        AlarmColumn::Dimensions,
20        AlarmColumn::Expression,
21        AlarmColumn::Type,
22        AlarmColumn::CrossAccount,
23    ] {
24        i18n.entry(col.id().to_string())
25            .or_insert_with(|| col.default_name().to_string());
26    }
27}
28
29#[derive(Debug, Clone)]
30pub struct Alarm {
31    pub name: String,
32    pub state: String,
33    pub state_updated_timestamp: String,
34    pub description: String,
35    pub metric_name: String,
36    pub namespace: String,
37    pub statistic: String,
38    pub period: u32,
39    pub comparison_operator: String,
40    pub threshold: f64,
41    pub actions_enabled: bool,
42    pub state_reason: String,
43    pub resource: String,
44    pub dimensions: String,
45    pub expression: String,
46    pub alarm_type: String,
47    pub cross_account: String,
48}
49
50#[derive(Debug, Clone, Copy, PartialEq)]
51pub enum AlarmColumn {
52    Name,
53    State,
54    LastStateUpdate,
55    Description,
56    Conditions,
57    Actions,
58    StateDetails,
59    MetricName,
60    Namespace,
61    Statistic,
62    Period,
63    Resource,
64    Dimensions,
65    Expression,
66    Type,
67    CrossAccount,
68}
69
70impl AlarmColumn {
71    const ID_NAME: &'static str = "column.cw.alarm.name";
72    const ID_STATE: &'static str = "column.cw.alarm.state";
73    const ID_LAST_STATE_UPDATE: &'static str = "column.cw.alarm.last_state_update";
74    const ID_DESCRIPTION: &'static str = "column.cw.alarm.description";
75    const ID_CONDITIONS: &'static str = "column.cw.alarm.conditions";
76    const ID_ACTIONS: &'static str = "column.cw.alarm.actions";
77    const ID_STATE_DETAILS: &'static str = "column.cw.alarm.state_details";
78    const ID_METRIC_NAME: &'static str = "column.cw.alarm.metric_name";
79    const ID_NAMESPACE: &'static str = "column.cw.alarm.namespace";
80    const ID_STATISTIC: &'static str = "column.cw.alarm.statistic";
81    const ID_PERIOD: &'static str = "column.cw.alarm.period";
82    const ID_RESOURCE: &'static str = "column.cw.alarm.resource";
83    const ID_DIMENSIONS: &'static str = "column.cw.alarm.dimensions";
84    const ID_EXPRESSION: &'static str = "column.cw.alarm.expression";
85    const ID_TYPE: &'static str = "column.cw.alarm.type";
86    const ID_CROSS_ACCOUNT: &'static str = "column.cw.alarm.cross_account";
87
88    pub const fn id(&self) -> &'static str {
89        match self {
90            AlarmColumn::Name => Self::ID_NAME,
91            AlarmColumn::State => Self::ID_STATE,
92            AlarmColumn::LastStateUpdate => Self::ID_LAST_STATE_UPDATE,
93            AlarmColumn::Description => Self::ID_DESCRIPTION,
94            AlarmColumn::Conditions => Self::ID_CONDITIONS,
95            AlarmColumn::Actions => Self::ID_ACTIONS,
96            AlarmColumn::StateDetails => Self::ID_STATE_DETAILS,
97            AlarmColumn::MetricName => Self::ID_METRIC_NAME,
98            AlarmColumn::Namespace => Self::ID_NAMESPACE,
99            AlarmColumn::Statistic => Self::ID_STATISTIC,
100            AlarmColumn::Period => Self::ID_PERIOD,
101            AlarmColumn::Resource => Self::ID_RESOURCE,
102            AlarmColumn::Dimensions => Self::ID_DIMENSIONS,
103            AlarmColumn::Expression => Self::ID_EXPRESSION,
104            AlarmColumn::Type => Self::ID_TYPE,
105            AlarmColumn::CrossAccount => Self::ID_CROSS_ACCOUNT,
106        }
107    }
108
109    pub const fn default_name(&self) -> &'static str {
110        match self {
111            AlarmColumn::Name => "Name",
112            AlarmColumn::State => "State",
113            AlarmColumn::LastStateUpdate => "Last state update",
114            AlarmColumn::Description => "Description",
115            AlarmColumn::Conditions => "Conditions",
116            AlarmColumn::Actions => "Actions",
117            AlarmColumn::StateDetails => "State details",
118            AlarmColumn::MetricName => "Metric name",
119            AlarmColumn::Namespace => "Namespace",
120            AlarmColumn::Statistic => "Statistic",
121            AlarmColumn::Period => "Period",
122            AlarmColumn::Resource => "Resource",
123            AlarmColumn::Dimensions => "Dimensions",
124            AlarmColumn::Expression => "Expression",
125            AlarmColumn::Type => "Type",
126            AlarmColumn::CrossAccount => "Cross-account",
127        }
128    }
129
130    pub fn name(&self) -> String {
131        translate_column(self.id(), self.default_name())
132    }
133
134    pub fn width(&self) -> u16 {
135        match self {
136            AlarmColumn::Name => 30,
137            AlarmColumn::State => 15,
138            AlarmColumn::LastStateUpdate => UTC_TIMESTAMP_WIDTH,
139            AlarmColumn::Description => 40,
140            AlarmColumn::Conditions => 30,
141            AlarmColumn::Actions => 20,
142            AlarmColumn::StateDetails => 30,
143            AlarmColumn::MetricName => 25,
144            AlarmColumn::Namespace => 20,
145            AlarmColumn::Statistic => 15,
146            AlarmColumn::Period => 10,
147            AlarmColumn::Resource => 25,
148            AlarmColumn::Dimensions => 25,
149            AlarmColumn::Expression => 30,
150            AlarmColumn::Type => 15,
151            AlarmColumn::CrossAccount => 15,
152        }
153    }
154
155    pub fn from_id(id: &str) -> Option<Self> {
156        match id {
157            Self::ID_NAME => Some(AlarmColumn::Name),
158            Self::ID_STATE => Some(AlarmColumn::State),
159            Self::ID_LAST_STATE_UPDATE => Some(AlarmColumn::LastStateUpdate),
160            Self::ID_DESCRIPTION => Some(AlarmColumn::Description),
161            Self::ID_CONDITIONS => Some(AlarmColumn::Conditions),
162            Self::ID_ACTIONS => Some(AlarmColumn::Actions),
163            Self::ID_STATE_DETAILS => Some(AlarmColumn::StateDetails),
164            Self::ID_METRIC_NAME => Some(AlarmColumn::MetricName),
165            Self::ID_NAMESPACE => Some(AlarmColumn::Namespace),
166            Self::ID_STATISTIC => Some(AlarmColumn::Statistic),
167            Self::ID_PERIOD => Some(AlarmColumn::Period),
168            Self::ID_RESOURCE => Some(AlarmColumn::Resource),
169            Self::ID_DIMENSIONS => Some(AlarmColumn::Dimensions),
170            Self::ID_EXPRESSION => Some(AlarmColumn::Expression),
171            Self::ID_TYPE => Some(AlarmColumn::Type),
172            Self::ID_CROSS_ACCOUNT => Some(AlarmColumn::CrossAccount),
173            _ => None,
174        }
175    }
176
177    pub fn all() -> [AlarmColumn; 16] {
178        [
179            AlarmColumn::Name,
180            AlarmColumn::State,
181            AlarmColumn::LastStateUpdate,
182            AlarmColumn::Description,
183            AlarmColumn::Conditions,
184            AlarmColumn::Actions,
185            AlarmColumn::StateDetails,
186            AlarmColumn::MetricName,
187            AlarmColumn::Namespace,
188            AlarmColumn::Statistic,
189            AlarmColumn::Period,
190            AlarmColumn::Resource,
191            AlarmColumn::Dimensions,
192            AlarmColumn::Expression,
193            AlarmColumn::Type,
194            AlarmColumn::CrossAccount,
195        ]
196    }
197
198    pub fn ids() -> Vec<ColumnId> {
199        Self::all().iter().map(|c| c.id()).collect()
200    }
201}
202
203pub fn console_url(
204    region: &str,
205    view_mode: &str,
206    page_size: usize,
207    sort_col: &str,
208    sort_dir: &str,
209) -> String {
210    format!(
211        "https://{}.console.aws.amazon.com/cloudwatch/home?region={}#alarmsV2:alarms/{}/{}?~(sortingColumn~'{}~sortingDirection~'{})",
212        region, region, view_mode, page_size, sort_col, sort_dir
213    )
214}
215
216#[cfg(test)]
217mod tests {
218    use super::*;
219
220    #[test]
221    fn test_column_ids_have_correct_prefix() {
222        for col in AlarmColumn::all() {
223            assert!(
224                col.id().starts_with("column.cw.alarm."),
225                "AlarmColumn ID '{}' should start with 'column.cw.alarm.'",
226                col.id()
227            );
228        }
229    }
230}