[pve-devel] [PATCH v4 proxmox 21/69] notify: api: allow to query entities referenced by filter/target
Lukas Wagner
l.wagner at proxmox.com
Thu Jul 20 16:31:48 CEST 2023
Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
Notes:
Changes since v3:
- Removed unneeded drain() call
proxmox-notify/src/api/common.rs | 11 +++
proxmox-notify/src/api/mod.rs | 125 +++++++++++++++++++++++++++++++
2 files changed, 136 insertions(+)
diff --git a/proxmox-notify/src/api/common.rs b/proxmox-notify/src/api/common.rs
index 518caa8f..48761fbb 100644
--- a/proxmox-notify/src/api/common.rs
+++ b/proxmox-notify/src/api/common.rs
@@ -42,3 +42,14 @@ pub fn test_target(config: &Config, endpoint: &str) -> Result<(), ApiError> {
Ok(())
}
+
+/// Return all entities (targets, groups, filters) that are linked to the entity.
+/// For instance, if a group 'grp1' contains the targets 'a', 'b' and 'c',
+/// where grp1 has 'filter1' and 'a' has 'filter2' as filters, then
+/// the result for 'grp1' would be [grp1, a, b, c, filter1, filter2].
+/// The result will always contain the entity that was passed as a parameter.
+/// If the entity does not exist, the result will only contain the entity.
+pub fn get_referenced_entities(config: &Config, entity: &str) -> Result<Vec<String>, ApiError> {
+ let entities = super::get_referenced_entities(config, entity);
+ Ok(Vec::from_iter(entities.into_iter()))
+}
diff --git a/proxmox-notify/src/api/mod.rs b/proxmox-notify/src/api/mod.rs
index 12811baf..1d9aaca7 100644
--- a/proxmox-notify/src/api/mod.rs
+++ b/proxmox-notify/src/api/mod.rs
@@ -1,3 +1,4 @@
+use std::collections::HashSet;
use std::error::Error as StdError;
use std::fmt::Display;
@@ -101,6 +102,48 @@ fn endpoint_exists(config: &Config, name: &str) -> bool {
exists
}
+fn get_referenced_entities(config: &Config, entity: &str) -> HashSet<String> {
+ let mut to_expand = HashSet::new();
+ let mut expanded = HashSet::new();
+ to_expand.insert(entity.to_string());
+
+ let expand = |entities: &HashSet<String>| -> HashSet<String> {
+ let mut new = HashSet::new();
+
+ for entity in entities {
+ if let Ok(group) = group::get_group(config, entity) {
+ for target in group.endpoint {
+ new.insert(target.clone());
+ }
+ }
+
+ #[cfg(feature = "sendmail")]
+ if let Ok(target) = sendmail::get_endpoint(config, entity) {
+ if let Some(filter) = target.filter {
+ new.insert(filter.clone());
+ }
+ }
+
+ #[cfg(feature = "gotify")]
+ if let Ok(target) = gotify::get_endpoint(config, entity) {
+ if let Some(filter) = target.filter {
+ new.insert(filter.clone());
+ }
+ }
+ }
+
+ new
+ };
+
+ while !to_expand.is_empty() {
+ let new = expand(&to_expand);
+ expanded.extend(to_expand);
+ to_expand = new;
+ }
+
+ expanded
+}
+
#[cfg(test)]
mod test_helpers {
use crate::Config;
@@ -109,3 +152,85 @@ mod test_helpers {
Config::new("", "").unwrap()
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::endpoints::gotify::{GotifyConfig, GotifyPrivateConfig};
+ use crate::endpoints::sendmail::SendmailConfig;
+ use crate::filter::FilterConfig;
+ use crate::group::GroupConfig;
+
+ #[test]
+ fn test_get_referenced_entities() {
+ let mut config = super::test_helpers::empty_config();
+
+ filter::add_filter(
+ &mut config,
+ &FilterConfig {
+ name: "filter".to_string(),
+ ..Default::default()
+ },
+ )
+ .unwrap();
+
+ sendmail::add_endpoint(
+ &mut config,
+ &SendmailConfig {
+ name: "sendmail".to_string(),
+ mailto: Some(vec!["foo at example.com".to_string()]),
+ filter: Some("filter".to_string()),
+ ..Default::default()
+ },
+ )
+ .unwrap();
+
+ gotify::add_endpoint(
+ &mut config,
+ &GotifyConfig {
+ name: "gotify".to_string(),
+ server: "localhost".to_string(),
+ filter: Some("filter".to_string()),
+ ..Default::default()
+ },
+ &GotifyPrivateConfig {
+ name: "gotify".to_string(),
+ token: "foo".to_string(),
+ },
+ )
+ .unwrap();
+
+ group::add_group(
+ &mut config,
+ &GroupConfig {
+ name: "group".to_string(),
+ endpoint: vec!["gotify".to_string(), "sendmail".to_string()],
+ filter: Some("filter".to_string()),
+ ..Default::default()
+ },
+ )
+ .unwrap();
+
+ assert_eq!(
+ get_referenced_entities(&config, "filter"),
+ HashSet::from(["filter".to_string()])
+ );
+ assert_eq!(
+ get_referenced_entities(&config, "sendmail"),
+ HashSet::from(["filter".to_string(), "sendmail".to_string()])
+ );
+ assert_eq!(
+ get_referenced_entities(&config, "gotify"),
+ HashSet::from(["filter".to_string(), "gotify".to_string()])
+ );
+ assert_eq!(
+ get_referenced_entities(&config, "group"),
+ HashSet::from([
+ "filter".to_string(),
+ "gotify".to_string(),
+ "sendmail".to_string(),
+ "group".to_string()
+ ])
+ );
+ }
+}
--
2.39.2
More information about the pve-devel
mailing list