server: notifications: send verify notifications via notification system

If the `notification-mode` parameter is set to `legacy-sendmail`, then
we still use the new infrastructure, but don't consider the
notification config and use a hard-coded sendmail endpoint directly.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
Tested-by: Gabriel Goller <g.goller@proxmox.com>
Reviewed-by: Gabriel Goller <g.goller@proxmox.com>
Tested-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Lukas Wagner 2024-04-23 13:52:08 +02:00 committed by Thomas Lamprecht
parent 3ca03c051f
commit 2432775ce8
8 changed files with 62 additions and 69 deletions

View File

@ -52,3 +52,7 @@ usr/share/proxmox-backup/templates/default/prune-ok-subject.txt.hbs
usr/share/proxmox-backup/templates/default/test-body.txt.hbs
usr/share/proxmox-backup/templates/default/test-body.html.hbs
usr/share/proxmox-backup/templates/default/test-subject.txt.hbs
usr/share/proxmox-backup/templates/default/verify-err-body.txt.hbs
usr/share/proxmox-backup/templates/default/verify-ok-body.txt.hbs
usr/share/proxmox-backup/templates/default/verify-err-subject.txt.hbs
usr/share/proxmox-backup/templates/default/verify-ok-subject.txt.hbs

View File

@ -23,38 +23,6 @@ use proxmox_notify::{Endpoint, Notification, Severity};
const SPOOL_DIR: &str = concatcp!(pbs_buildcfg::PROXMOX_BACKUP_STATE_DIR, "/notifications");
const VERIFY_OK_TEMPLATE: &str = r###"
Job ID: {{job.id}}
Datastore: {{job.store}}
Verification successful.
Please visit the web interface for further details:
<https://{{fqdn}}:{{port}}/#DataStore-{{job.store}}>
"###;
const VERIFY_ERR_TEMPLATE: &str = r###"
Job ID: {{job.id}}
Datastore: {{job.store}}
Verification failed on these snapshots/groups:
{{#each errors}}
{{this~}}
{{/each}}
Please visit the web interface for further details:
<https://{{fqdn}}:{{port}}/#pbsServerAdministration:tasks>
"###;
const SYNC_OK_TEMPLATE: &str = r###"
Job ID: {{job.id}}
@ -189,9 +157,6 @@ lazy_static::lazy_static! {
hb.set_strict_mode(true);
hb.register_escape_fn(handlebars::no_escape);
hb.register_template_string("verify_ok_template", VERIFY_OK_TEMPLATE)?;
hb.register_template_string("verify_err_template", VERIFY_ERR_TEMPLATE)?;
hb.register_template_string("sync_ok_template", SYNC_OK_TEMPLATE)?;
hb.register_template_string("sync_err_template", SYNC_ERR_TEMPLATE)?;
@ -417,8 +382,6 @@ pub fn send_gc_status(
}
pub fn send_verify_status(
email: &str,
notify: DatastoreNotify,
job: VerificationJobConfig,
result: &Result<Vec<String>, Error>,
) -> Result<(), Error> {
@ -429,39 +392,45 @@ pub fn send_verify_status(
"port": port,
});
let mut result_is_ok = false;
let text = match result {
Ok(errors) if errors.is_empty() => {
result_is_ok = true;
HANDLEBARS.render("verify_ok_template", &data)?
}
let (template, severity) = match result {
Ok(errors) if errors.is_empty() => ("verify-ok", Severity::Info),
Ok(errors) => {
data["errors"] = json!(errors);
HANDLEBARS.render("verify_err_template", &data)?
("verify-err", Severity::Error)
}
Err(_) => {
// aborted job - do not send any email
// aborted job - do not send any notification
return Ok(());
}
};
match notify.verify {
None => { /* send notifications by default */ }
Some(notify) => {
if notify == Notify::Never || (result_is_ok && notify == Notify::Error) {
let metadata = HashMap::from([
("job-id".into(), job.id.clone()),
("datastore".into(), job.store.clone()),
("hostname".into(), proxmox_sys::nodename().into()),
("type".into(), "verify".into()),
]);
let notification = Notification::from_template(severity, template, data, metadata);
let (email, notify, mode) = lookup_datastore_notify_settings(&job.store);
match mode {
NotificationMode::LegacySendmail => {
let notify = notify.verify.unwrap_or(Notify::Always);
if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) {
return Ok(());
}
if let Some(email) = email {
send_sendmail_legacy_notification(notification, &email)?;
}
}
NotificationMode::NotificationSystem => {
send_notification(notification)?;
}
}
let subject = match result {
Ok(errors) if errors.is_empty() => format!("Verify Datastore '{}' successful", job.store),
_ => format!("Verify Datastore '{}' failed", job.store),
};
send_job_status_mail(email, &subject, &text)?;
Ok(())
}
@ -758,9 +727,6 @@ pub fn lookup_datastore_notify_settings(
#[test]
fn test_template_register() {
assert!(HANDLEBARS.has_template("verify_ok_template"));
assert!(HANDLEBARS.has_template("verify_err_template"));
assert!(HANDLEBARS.has_template("sync_ok_template"));
assert!(HANDLEBARS.has_template("sync_err_template"));

View File

@ -23,9 +23,6 @@ pub fn do_verification_job(
let outdated_after = verification_job.outdated_after;
let ignore_verified_snapshots = verification_job.ignore_verified.unwrap_or(true);
let (email, notify, _) =
crate::server::lookup_datastore_notify_settings(&verification_job.store);
// FIXME encode namespace here for filter/ACL check?
let job_id = format!("{}:{}", &verification_job.store, job.jobname());
let worker_type = job.jobtype().to_string();
@ -79,12 +76,8 @@ pub fn do_verification_job(
eprintln!("could not finish job state for {}: {}", job.jobtype(), err);
}
if let Some(email) = email {
if let Err(err) =
crate::server::send_verify_status(&email, notify, verification_job, &result)
{
eprintln!("send verify notification failed: {}", err);
}
if let Err(err) = crate::server::send_verify_status(verification_job, &result) {
eprintln!("send verify notification failed: {err}");
}
job_result

View File

@ -12,6 +12,10 @@ NOTIFICATION_TEMPLATES= \
default/test-body.txt.hbs \
default/test-body.html.hbs \
default/test-subject.txt.hbs \
default/verify-err-body.txt.hbs \
default/verify-ok-body.txt.hbs \
default/verify-err-subject.txt.hbs \
default/verify-ok-subject.txt.hbs \
all:

View File

@ -0,0 +1,14 @@
Job ID: {{job.id}}
Datastore: {{job.store}}
Verification failed on these snapshots/groups:
{{#each errors}}
{{this~}}
{{/each}}
Please visit the web interface for further details:
<https://{{fqdn}}:{{port}}/#pbsServerAdministration:tasks>

View File

@ -0,0 +1 @@
Verify Datastore '{{ job.store }}' failed

View File

@ -0,0 +1,10 @@
Job ID: {{job.id}}
Datastore: {{job.store}}
Verification successful.
Please visit the web interface for further details:
<https://{{fqdn}}:{{port}}/#DataStore-{{job.store}}>

View File

@ -0,0 +1 @@
Verify Datastore '{{ job.store }}' successful