use std::collections::BTreeMap;
use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AlertState {
Firing,
Resolved,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RenderSource {
Schema,
Structural,
KeyOnly,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct AlertTransition {
pub origin: String,
pub producer: String,
pub alert_key: String,
pub alert_ref: String,
pub state: AlertState,
pub severity: Option<String>,
pub rule: Option<String>,
pub labels: BTreeMap<String, String>,
pub summary: Option<String>,
pub timestamp: Option<String>,
pub at: String,
pub rendering: RenderSource,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn alert_transition_json_shape_is_pinned() {
let mut labels = BTreeMap::new();
labels.insert("port".to_string(), "eth0".to_string());
let t = AlertTransition {
origin: "h-3fa9c2d41b7e".into(),
producer: "netlink".into(),
alert_key: "a659f813308ad1da".into(),
alert_ref: "h-3fa9c2d41b7e.netlink.a659f813308ad1da".into(),
state: AlertState::Firing,
severity: Some("warning".into()),
rule: Some("link_down".into()),
labels,
summary: Some("eth0 is down".into()),
timestamp: None,
at: "2026-09-06T00:00:00Z".into(),
rendering: RenderSource::Schema,
};
assert_eq!(
serde_json::to_value(&t).unwrap(),
serde_json::json!({
"origin": "h-3fa9c2d41b7e",
"producer": "netlink",
"alert_key": "a659f813308ad1da",
"alert_ref": "h-3fa9c2d41b7e.netlink.a659f813308ad1da",
"state": "firing",
"severity": "warning",
"rule": "link_down",
"labels": {"port": "eth0"},
"summary": "eth0 is down",
"timestamp": null,
"at": "2026-09-06T00:00:00Z",
"rendering": "schema",
})
);
let resolved = AlertTransition {
state: AlertState::Resolved,
severity: None,
rule: None,
labels: BTreeMap::new(),
summary: None,
rendering: RenderSource::KeyOnly,
..t
};
let json = serde_json::to_value(&resolved).unwrap();
assert_eq!(json["state"], "resolved");
assert_eq!(json["rendering"], "key_only");
assert_eq!(json["labels"], serde_json::json!({}));
assert_eq!(json["severity"], serde_json::Value::Null);
}
}