diff --git a/proxmox-notify/src/api/gotify.rs b/proxmox-notify/src/api/gotify.rs index 98ff255d..a93a0244 100644 --- a/proxmox-notify/src/api/gotify.rs +++ b/proxmox-notify/src/api/gotify.rs @@ -136,7 +136,7 @@ pub fn update_endpoint( pub fn delete_gotify_endpoint(config: &mut Config, name: &str) -> Result<(), HttpError> { // Check if the endpoint exists let _ = get_endpoint(config, name)?; - super::ensure_unused(config, name)?; + super::ensure_safe_to_delete(config, name)?; remove_private_config_entry(config, name)?; config.config.sections.remove(name); diff --git a/proxmox-notify/src/api/mod.rs b/proxmox-notify/src/api/mod.rs index 762d448a..7cc25939 100644 --- a/proxmox-notify/src/api/mod.rs +++ b/proxmox-notify/src/api/mod.rs @@ -1,9 +1,10 @@ -use serde::Serialize; use std::collections::HashSet; +use serde::{Deserialize, Serialize}; + use proxmox_http_error::HttpError; -use crate::Config; +use crate::{Config, Origin}; pub mod common; #[cfg(feature = "gotify")] @@ -111,7 +112,20 @@ fn get_referrers(config: &Config, entity: &str) -> Result, HttpE Ok(referrers) } -fn ensure_unused(config: &Config, entity: &str) -> Result<(), HttpError> { +fn ensure_safe_to_delete(config: &Config, entity: &str) -> Result<(), HttpError> { + if let Some(entity_config) = config.config.sections.get(entity) { + if let Ok(origin) = Origin::deserialize(&entity_config.1["origin"]) { + // Built-ins are never actually removed, only reset to their default + // It is thus safe to do the reset if another entity depends + // on it + if origin == Origin::Builtin || origin == Origin::ModifiedBuiltin { + return Ok(()); + } + } + } else { + http_bail!(NOT_FOUND, "entity '{entity}' does not exist"); + } + let referrers = get_referrers(config, entity)?; if !referrers.is_empty() { @@ -191,25 +205,15 @@ mod test_helpers { } } -#[cfg(all(test, gotify, sendmail))] +#[cfg(all(test, feature = "gotify", feature = "sendmail"))] mod tests { use super::*; use crate::endpoints::gotify::{GotifyConfig, GotifyPrivateConfig}; use crate::endpoints::sendmail::SendmailConfig; - use crate::filter::FilterConfig; - use crate::group::GroupConfig; + use crate::matcher::MatcherConfig; fn prepare_config() -> Result { - let mut config = super::test_helpers::empty_config(); - - matcher::add_matcher( - &mut config, - &MatcherConfig { - name: "matcher".to_string(), - target: Some(vec!["sendmail".to_string(), "gotify".to_string()]) - ..Default::default(), - }, - )?; + let mut config = test_helpers::empty_config(); sendmail::add_endpoint( &mut config, @@ -220,6 +224,16 @@ mod tests { }, )?; + sendmail::add_endpoint( + &mut config, + &SendmailConfig { + name: "builtin".to_string(), + mailto: Some(vec!["foo@example.com".to_string()]), + origin: Some(Origin::Builtin), + ..Default::default() + }, + )?; + gotify::add_endpoint( &mut config, &GotifyConfig { @@ -233,6 +247,19 @@ mod tests { }, )?; + matcher::add_matcher( + &mut config, + &MatcherConfig { + name: "matcher".to_string(), + target: Some(vec![ + "sendmail".to_string(), + "gotify".to_string(), + "builtin".to_string(), + ]), + ..Default::default() + }, + )?; + Ok(config) } @@ -245,6 +272,7 @@ mod tests { HashSet::from([ "matcher".to_string(), "sendmail".to_string(), + "builtin".to_string(), "gotify".to_string() ]) ); @@ -268,12 +296,17 @@ mod tests { } #[test] - fn test_ensure_unused() { + fn test_ensure_safe_to_delete() { let config = prepare_config().unwrap(); - assert!(ensure_unused(&config, "gotify").is_err()); - assert!(ensure_unused(&config, "sendmail").is_err()); - assert!(ensure_unused(&config, "matcher").is_ok()); + assert!(ensure_safe_to_delete(&config, "gotify").is_err()); + assert!(ensure_safe_to_delete(&config, "sendmail").is_err()); + assert!(ensure_safe_to_delete(&config, "matcher").is_ok()); + + // built-ins are always safe to delete, since there is no way to actually + // delete them... they will only be reset to their default settings and + // will thus continue to exist + assert!(ensure_safe_to_delete(&config, "builtin").is_ok()); } #[test] @@ -281,7 +314,7 @@ mod tests { let config = prepare_config().unwrap(); assert!(ensure_unique(&config, "sendmail").is_err()); - assert!(ensure_unique(&config, "group").is_err()); + assert!(ensure_unique(&config, "matcher").is_err()); assert!(ensure_unique(&config, "new").is_ok()); } @@ -289,6 +322,6 @@ mod tests { fn test_ensure_endpoints_exist() { let config = prepare_config().unwrap(); - assert!(ensure_endpoints_exist(&config, &vec!["sendmail", "gotify"]).is_ok()); + assert!(ensure_endpoints_exist(&config, &["sendmail", "gotify", "builtin"]).is_ok()); } } diff --git a/proxmox-notify/src/api/sendmail.rs b/proxmox-notify/src/api/sendmail.rs index 0f401787..e9115051 100644 --- a/proxmox-notify/src/api/sendmail.rs +++ b/proxmox-notify/src/api/sendmail.rs @@ -144,7 +144,7 @@ pub fn update_endpoint( pub fn delete_endpoint(config: &mut Config, name: &str) -> Result<(), HttpError> { // Check if the endpoint exists let _ = get_endpoint(config, name)?; - super::ensure_unused(config, name)?; + super::ensure_safe_to_delete(config, name)?; config.config.sections.remove(name); diff --git a/proxmox-notify/src/api/smtp.rs b/proxmox-notify/src/api/smtp.rs index 14b301c3..6bd0c4bf 100644 --- a/proxmox-notify/src/api/smtp.rs +++ b/proxmox-notify/src/api/smtp.rs @@ -192,7 +192,7 @@ pub fn update_endpoint( pub fn delete_endpoint(config: &mut Config, name: &str) -> Result<(), HttpError> { // Check if the endpoint exists let _ = get_endpoint(config, name)?; - super::ensure_unused(config, name)?; + super::ensure_safe_to_delete(config, name)?; super::remove_private_config_entry(config, name)?; config.config.sections.remove(name);