Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
/// Hold an alert back, as Alertmanager's silences and inhibit rules do:
/// during its component's maintenance if its kind is one maintenance mutes,
/// or while an alert that inhibits it fires on the same component. The whole
/// policy is checked every time, so a mistake in it fails loudly rather than
/// silently never muting. The caller passes `condition && !muted` to
/// monitor.alert-state.
///
/// # Panics
/// Panics on an empty kind, an empty maintenance kind, or an inhibition with
/// an empty side or the same kind on both sides.
pub fn mute_alert(kind: &str, under_maintenance: bool, firing_kinds: &[String], policy: &MutePolicy) -> AlertMute {
if kind.is_empty() {
panic!("kind must not be empty");
}
for k in &policy.maintenance {
if k.is_empty() {
panic!("maintenance kinds must not be empty");
}
}
for rule in &policy.inhibit {
if rule.source.is_empty() {
panic!("inhibition source must not be empty");
}
if rule.target.is_empty() {
panic!("inhibition target must not be empty");
}
if rule.source == rule.target {
panic!("an alert kind cannot inhibit itself: {}", rule.source);
}
}
if under_maintenance && policy.maintenance.iter().any(|k| k == kind) {
return AlertMute { muted: true, reason: Some("maintenance".to_string()), by: None };
}
for rule in &policy.inhibit {
// source != target, so an alert listed among firing_kinds never inhibits itself.
if rule.target == kind && firing_kinds.iter().any(|k| *k == rule.source) {
return AlertMute { muted: true, reason: Some("inhibited".to_string()), by: Some(rule.source.clone()) };
}
}
AlertMute { muted: false, reason: None, by: None }
}
fn strings(v: &Value) -> Vec<String> {
v.as_arr().iter().map(|s| s.as_str().to_string()).collect()
}
pub fn mute_policy_from_value(v: &Value) -> MutePolicy {
MutePolicy {
maintenance: strings(v.get("maintenance")),
inhibit: v
.get("inhibit")
.as_arr()
.iter()
.map(|r| Inhibition { source: r.get("source").as_str().to_string(), target: r.get("target").as_str().to_string() })
.collect(),
}
}
pub fn alert_mute_to_value(m: &AlertMute) -> Value {
Value::obj(vec![
("muted", Value::Bool(m.muted)),
("reason", match &m.reason { Some(s) => Value::str(s), None => Value::Null }),
("by", match &m.by { Some(s) => Value::str(s), None => Value::Null }),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
let under_maintenance = match &args[1] {
Value::Bool(b) => *b,
_ => panic!("underMaintenance must be true or false"),
};
alert_mute_to_value(&mute_alert(args[0].as_str(), under_maintenance, &strings(&args[2]), &mute_policy_from_value(&args[3])))
}