all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher
@ 2024-01-10  9:31 Lukas Wagner
  2024-01-10  9:31 ` [pve-devel] [PATCH proxmox v2 2/2] notify: add separate context for unit-tests Lukas Wagner
  2024-01-10 11:37 ` [pve-devel] applied-series: [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher Wolfgang Bumiller
  0 siblings, 2 replies; 3+ messages in thread
From: Lukas Wagner @ 2024-01-10  9:31 UTC (permalink / raw)
  To: pve-devel

In the 'delete'-handler targets, we check if a
target is still referenced by a matcher - if it is, we return an
error. For built-in targets, this is actually not necessary, since
'deleting' a built-in only resets it to its default settings - it will
continue to exist after that.
The user could easily trigger this if 'mail-to-root', which is
referenced by 'default-matcher' is modified and then reset to its
defaults: An error is shown, the built-in target is not reset.

This commit disables this check if it is a built-in target.

Renamed the helper 'ensure_unused' to 'ensure_safe_to_delete' in the
process.

Also fixed the tests in api::test - they were never executed due to a
faulty #[cfg] directive.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---

Changes since v1:
  - Simplify deserialization of 'origin' in 
    ensure_safe_to_delete (thx @ Wolfgang 🙏)
  - Reworded commit message slightly

 proxmox-notify/src/api/gotify.rs   |  2 +-
 proxmox-notify/src/api/mod.rs      | 71 ++++++++++++++++++++++--------
 proxmox-notify/src/api/sendmail.rs |  2 +-
 proxmox-notify/src/api/smtp.rs     |  2 +-
 4 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/proxmox-notify/src/api/gotify.rs b/proxmox-notify/src/api/gotify.rs
index 98ff255..a93a024 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 762d448..7cc2593 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<HashSet<String>, 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,31 +205,31 @@ 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<Config, HttpError> {
-        let mut config = super::test_helpers::empty_config();
+        let mut config = test_helpers::empty_config();
 
-        matcher::add_matcher(
+        sendmail::add_endpoint(
             &mut config,
-            &MatcherConfig {
-                name: "matcher".to_string(),
-                target: Some(vec!["sendmail".to_string(), "gotify".to_string()])
-                    ..Default::default(),
+            &SendmailConfig {
+                name: "sendmail".to_string(),
+                mailto: Some(vec!["foo@example.com".to_string()]),
+                ..Default::default()
             },
         )?;
 
         sendmail::add_endpoint(
             &mut config,
             &SendmailConfig {
-                name: "sendmail".to_string(),
+                name: "builtin".to_string(),
                 mailto: Some(vec!["foo@example.com".to_string()]),
+                origin: Some(Origin::Builtin),
                 ..Default::default()
             },
         )?;
@@ -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 0f40178..e911505 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 14b301c..6bd0c4b 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);
-- 
2.39.2




^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pve-devel] [PATCH proxmox v2 2/2] notify: add separate context for unit-tests
  2024-01-10  9:31 [pve-devel] [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher Lukas Wagner
@ 2024-01-10  9:31 ` Lukas Wagner
  2024-01-10 11:37 ` [pve-devel] applied-series: [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher Wolfgang Bumiller
  1 sibling, 0 replies; 3+ messages in thread
From: Lukas Wagner @ 2024-01-10  9:31 UTC (permalink / raw)
  To: pve-devel

... as using PVEContext for tests is brittle and annoying for some
tests.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
 proxmox-notify/src/context/mod.rs  | 10 +++++-----
 proxmox-notify/src/context/test.rs | 26 ++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 5 deletions(-)
 create mode 100644 proxmox-notify/src/context/test.rs

diff --git a/proxmox-notify/src/context/mod.rs b/proxmox-notify/src/context/mod.rs
index b419641..cc68603 100644
--- a/proxmox-notify/src/context/mod.rs
+++ b/proxmox-notify/src/context/mod.rs
@@ -7,6 +7,8 @@ pub mod common;
 pub mod pbs;
 #[cfg(feature = "pve-context")]
 pub mod pve;
+#[cfg(test)]
+mod test;
 
 /// Product-specific context
 pub trait Context: Send + Sync + Debug {
@@ -22,12 +24,10 @@ pub trait Context: Send + Sync + Debug {
     fn default_config(&self) -> &'static str;
 }
 
-#[cfg(not(feature = "pve-context"))]
+#[cfg(not(test))]
 static CONTEXT: Mutex<Option<&'static dyn Context>> = Mutex::new(None);
-// The test unfortunately require context...
-// TODO: Check if we can make this nicer...
-#[cfg(feature = "pve-context")]
-static CONTEXT: Mutex<Option<&'static dyn Context>> = Mutex::new(Some(&pve::PVE_CONTEXT));
+#[cfg(test)]
+static CONTEXT: Mutex<Option<&'static dyn Context>> = Mutex::new(Some(&test::TestContext));
 
 /// Set the product-specific context
 pub fn set_context(context: &'static dyn Context) {
diff --git a/proxmox-notify/src/context/test.rs b/proxmox-notify/src/context/test.rs
new file mode 100644
index 0000000..61f794a
--- /dev/null
+++ b/proxmox-notify/src/context/test.rs
@@ -0,0 +1,26 @@
+use crate::context::Context;
+
+#[derive(Debug)]
+pub struct TestContext;
+
+impl Context for TestContext {
+    fn lookup_email_for_user(&self, _user: &str) -> Option<String> {
+        Some("test@example.com".into())
+    }
+
+    fn default_sendmail_author(&self) -> String {
+        "Proxmox VE".into()
+    }
+
+    fn default_sendmail_from(&self) -> String {
+        "root".into()
+    }
+
+    fn http_proxy_config(&self) -> Option<String> {
+        None
+    }
+
+    fn default_config(&self) -> &'static str {
+        ""
+    }
+}
-- 
2.39.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pve-devel] applied-series: [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher
  2024-01-10  9:31 [pve-devel] [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher Lukas Wagner
  2024-01-10  9:31 ` [pve-devel] [PATCH proxmox v2 2/2] notify: add separate context for unit-tests Lukas Wagner
@ 2024-01-10 11:37 ` Wolfgang Bumiller
  1 sibling, 0 replies; 3+ messages in thread
From: Wolfgang Bumiller @ 2024-01-10 11:37 UTC (permalink / raw)
  To: Lukas Wagner; +Cc: pve-devel

applied both patches, thanks




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-10 11:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-10  9:31 [pve-devel] [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher Lukas Wagner
2024-01-10  9:31 ` [pve-devel] [PATCH proxmox v2 2/2] notify: add separate context for unit-tests Lukas Wagner
2024-01-10 11:37 ` [pve-devel] applied-series: [PATCH proxmox v2 1/2] notify: api: allow resetting built-in targets if used by a matcher Wolfgang Bumiller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal