Signed-off-by: Lukas Wagner <l.wag...@proxmox.com> --- proxmox-notify/src/api/filter.rs | 1 + proxmox-notify/src/api/gotify.rs | 1 + proxmox-notify/src/api/mod.rs | 113 ++++++++++++++++++++++++++--- proxmox-notify/src/api/sendmail.rs | 1 + 4 files changed, 106 insertions(+), 10 deletions(-)
diff --git a/proxmox-notify/src/api/filter.rs b/proxmox-notify/src/api/filter.rs index 3fcff6b9..824f802d 100644 --- a/proxmox-notify/src/api/filter.rs +++ b/proxmox-notify/src/api/filter.rs @@ -115,6 +115,7 @@ pub fn update_filter( pub fn delete_filter(config: &mut Config, name: &str) -> Result<(), ApiError> { // Check if the filter exists let _ = get_filter(config, name)?; + super::ensure_unused(config, name)?; config.config.sections.remove(name); diff --git a/proxmox-notify/src/api/gotify.rs b/proxmox-notify/src/api/gotify.rs index d6f33064..5c4db4be 100644 --- a/proxmox-notify/src/api/gotify.rs +++ b/proxmox-notify/src/api/gotify.rs @@ -145,6 +145,7 @@ pub fn update_endpoint( pub fn delete_gotify_endpoint(config: &mut Config, name: &str) -> Result<(), ApiError> { // Check if the endpoint exists let _ = get_endpoint(config, name)?; + super::ensure_unused(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 d8a44bf2..81c182c7 100644 --- a/proxmox-notify/src/api/mod.rs +++ b/proxmox-notify/src/api/mod.rs @@ -102,6 +102,59 @@ fn endpoint_exists(config: &Config, name: &str) -> bool { exists } +fn get_referrers(config: &Config, entity: &str) -> Result<HashSet<String>, ApiError> { + let mut referrers = HashSet::new(); + + for group in group::get_groups(config)? { + for endpoint in group.endpoint { + if endpoint == entity { + referrers.insert(group.name.clone()); + } + } + + if let Some(filter) = group.filter { + if filter == entity { + referrers.insert(group.name); + } + } + } + + #[cfg(feature = "sendmail")] + for endpoint in sendmail::get_endpoints(config)? { + if let Some(filter) = endpoint.filter { + if filter == entity { + referrers.insert(endpoint.name); + } + } + } + + #[cfg(feature = "gotify")] + for endpoint in gotify::get_endpoints(config)? { + if let Some(filter) = endpoint.filter { + if filter == entity { + referrers.insert(endpoint.name); + } + } + } + + Ok(referrers) +} + +fn ensure_unused(config: &Config, entity: &str) -> Result<(), ApiError> { + let referrers = get_referrers(config, entity)?; + + if !referrers.is_empty() { + let used_by = referrers.into_iter().collect::<Vec<_>>().join(", "); + + return Err(ApiError::bad_request( + format!("cannot delete '{entity}', referenced by: {used_by}"), + None, + )); + } + + Ok(()) +} + fn get_referenced_entities(config: &Config, entity: &str) -> HashSet<String> { let mut to_expand = HashSet::new(); let mut expanded = HashSet::new(); @@ -161,8 +214,7 @@ mod tests { use crate::filter::FilterConfig; use crate::group::GroupConfig; - #[test] - fn test_get_referenced_entities() { + fn prepare_config() -> Result<Config, ApiError> { let mut config = super::test_helpers::empty_config(); filter::add_filter( @@ -171,8 +223,7 @@ mod tests { name: "filter".to_string(), ..Default::default() }, - ) - .unwrap(); + )?; sendmail::add_endpoint( &mut config, @@ -182,8 +233,7 @@ mod tests { filter: Some("filter".to_string()), ..Default::default() }, - ) - .unwrap(); + )?; gotify::add_endpoint( &mut config, @@ -197,8 +247,7 @@ mod tests { name: "gotify".to_string(), token: "foo".to_string(), }, - ) - .unwrap(); + )?; group::add_group( &mut config, @@ -208,8 +257,14 @@ mod tests { filter: Some("filter".to_string()), ..Default::default() }, - ) - .unwrap(); + )?; + + Ok(config) + } + + #[test] + fn test_get_referenced_entities() { + let config = prepare_config().unwrap(); assert_eq!( get_referenced_entities(&config, "filter"), @@ -233,4 +288,42 @@ mod tests { ]) ); } + + #[test] + fn test_get_referrers_for_entity() -> Result<(), ApiError> { + let config = prepare_config().unwrap(); + + assert_eq!( + get_referrers(&config, "filter")?, + HashSet::from([ + "gotify".to_string(), + "sendmail".to_string(), + "group".to_string() + ]) + ); + + assert_eq!( + get_referrers(&config, "sendmail")?, + HashSet::from(["group".to_string()]) + ); + + assert_eq!( + get_referrers(&config, "gotify")?, + HashSet::from(["group".to_string()]) + ); + + assert!(get_referrers(&config, "group")?.is_empty(),); + + Ok(()) + } + + #[test] + fn test_ensure_unused() { + let config = prepare_config().unwrap(); + + assert!(ensure_unused(&config, "filter").is_err()); + assert!(ensure_unused(&config, "gotify").is_err()); + assert!(ensure_unused(&config, "sendmail").is_err()); + assert!(ensure_unused(&config, "group").is_ok()); + } } diff --git a/proxmox-notify/src/api/sendmail.rs b/proxmox-notify/src/api/sendmail.rs index 070ed6e7..bf225f29 100644 --- a/proxmox-notify/src/api/sendmail.rs +++ b/proxmox-notify/src/api/sendmail.rs @@ -147,6 +147,7 @@ pub fn update_endpoint( pub fn delete_endpoint(config: &mut Config, name: &str) -> Result<(), ApiError> { // Check if the endpoint exists let _ = get_endpoint(config, name)?; + super::ensure_unused(config, name)?; config.config.sections.remove(name); -- 2.39.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel