proxmox/proxmox-notify/src/context/mod.rs
Alexander Zeidler 684ffacdf9 fix #6143: notify: allow overriding notification templates
Previously, notification templates could be modified by the user, but
these were overwritten again with installing newer package versions of
pve-manager and proxmox-backup.

Now override templates can be created cluster-wide in the path
“/etc/{pve,proxmox-backup}/notification-templates/{namespace}”, which
are used with priority. The folder structure has to be created and
populated manually (e.g. /etc/pve/notification-templates/default).

If override templates are not existing or their rendering fails, the
vendor templates in
"/usr/share/{pve-manager,proxmox-backup}/templates/default/" are used.

Sequence: [override html -> vendor html ->] override txt -> vendor txt

An error is only returned if none of the template candidates could be
used. Using an override template gets not logged.

Signed-off-by: Alexander Zeidler <a.zeidler@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Link: https://lore.proxmox.com/20250321133341.151340-1-a.zeidler@proxmox.com
2025-04-08 12:25:32 +02:00

54 lines
1.8 KiB
Rust

use std::fmt::Debug;
use std::sync::Mutex;
use crate::renderer::TemplateSource;
use crate::Error;
#[cfg(any(feature = "pve-context", feature = "pbs-context"))]
pub mod common;
#[cfg(feature = "pbs-context")]
pub mod pbs;
#[cfg(feature = "pve-context")]
pub mod pve;
#[cfg(test)]
mod test;
/// Product-specific context
pub trait Context: Send + Sync + Debug {
/// Look up a user's email address from users.cfg
fn lookup_email_for_user(&self, user: &str) -> Option<String>;
/// Default mail author for mail-based targets
fn default_sendmail_author(&self) -> String;
/// Default from address for sendmail-based targets
fn default_sendmail_from(&self) -> String;
/// Proxy configuration for the current node
fn http_proxy_config(&self) -> Option<String>;
/// Return default config for built-in targets/matchers.
fn default_config(&self) -> &'static str;
/// Return the path of `filename` from `source` and a certain (optional) `namespace`
fn lookup_template(
&self,
filename: &str,
namespace: Option<&str>,
source: TemplateSource,
) -> Result<Option<String>, Error>;
}
#[cfg(not(test))]
static CONTEXT: Mutex<Option<&'static dyn Context>> = Mutex::new(None);
#[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) {
*CONTEXT.lock().unwrap() = Some(context);
}
/// Get product-specific context.
///
/// Panics if the context has not been set yet.
#[allow(unused)] // context is not used if all endpoint features are disabled
pub(crate) fn context() -> &'static dyn Context {
(*CONTEXT.lock().unwrap()).expect("context for proxmox-notify has not been set yet")
}