[pve-devel] [PATCH v4 proxmox 22/69] notify: on deletion, check if a filter/endp. is still used by anything
Lukas Wagner
l.wagner at proxmox.com
Thu Jul 20 16:31:49 CEST 2023
Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
Notes:
Changes since v3:
- get_referrers: minor stylistic touchups
proxmox-notify/src/api/filter.rs | 1 +
proxmox-notify/src/api/gotify.rs | 1 +
proxmox-notify/src/api/mod.rs | 111 ++++++++++++++++++++++++++---
proxmox-notify/src/api/sendmail.rs | 1 +
4 files changed, 104 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 1d9aaca7..e064b607 100644
--- a/proxmox-notify/src/api/mod.rs
+++ b/proxmox-notify/src/api/mod.rs
@@ -102,6 +102,57 @@ 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)? {
+ if group.endpoint.iter().any(|endpoint| 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 +212,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 +221,7 @@ mod tests {
name: "filter".to_string(),
..Default::default()
},
- )
- .unwrap();
+ )?;
sendmail::add_endpoint(
&mut config,
@@ -182,8 +231,7 @@ mod tests {
filter: Some("filter".to_string()),
..Default::default()
},
- )
- .unwrap();
+ )?;
gotify::add_endpoint(
&mut config,
@@ -197,8 +245,7 @@ mod tests {
name: "gotify".to_string(),
token: "foo".to_string(),
},
- )
- .unwrap();
+ )?;
group::add_group(
&mut config,
@@ -208,8 +255,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 +286,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
More information about the pve-devel
mailing list