From 9e733dae48cae337f7e02c4437106646417f6fb7 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 29 Oct 2020 12:07:46 +0100 Subject: [PATCH] send sync job status emails --- src/api2/pull.rs | 15 ++++++-- src/config/sync.rs | 2 +- src/server/email_notifications.rs | 61 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/api2/pull.rs b/src/api2/pull.rs index 441701a5..dd49b6ef 100644 --- a/src/api2/pull.rs +++ b/src/api2/pull.rs @@ -75,6 +75,8 @@ pub fn do_sync_job( let job_id = job.jobname().to_string(); let worker_type = job.jobtype().to_string(); + let email = crate::server::lookup_user_email(userid); + let upid_str = WorkerTask::spawn( &worker_type, Some(job.jobname().to_string()), @@ -85,6 +87,7 @@ pub fn do_sync_job( job.start(&worker.upid().to_string())?; let worker2 = worker.clone(); + let sync_job2 = sync_job.clone(); let worker_future = async move { @@ -107,12 +110,12 @@ pub fn do_sync_job( let mut abort_future = worker2.abort_future().map(|_| Err(format_err!("sync aborted"))); - let res = select!{ + let result = select!{ worker = worker_future.fuse() => worker, abort = abort_future => abort, }; - let status = worker2.create_state(&res); + let status = worker2.create_state(&result); match job.finish(status) { Ok(_) => {}, @@ -121,7 +124,13 @@ pub fn do_sync_job( } } - res + if let Some(email) = email { + if let Err(err) = crate::server::send_sync_status(&email, &sync_job2, &result) { + eprintln!("send sync notification failed: {}", err); + } + } + + result })?; Ok(upid_str) diff --git a/src/config/sync.rs b/src/config/sync.rs index c35f4f25..92ccb6fe 100644 --- a/src/config/sync.rs +++ b/src/config/sync.rs @@ -51,7 +51,7 @@ lazy_static! { } )] #[serde(rename_all="kebab-case")] -#[derive(Serialize,Deserialize)] +#[derive(Serialize,Deserialize,Clone)] /// Sync Job pub struct SyncJobConfig { pub id: String, diff --git a/src/server/email_notifications.rs b/src/server/email_notifications.rs index 4362b2b9..069dd98c 100644 --- a/src/server/email_notifications.rs +++ b/src/server/email_notifications.rs @@ -7,6 +7,7 @@ use proxmox::tools::email::sendmail; use crate::{ config::verify::VerificationJobConfig, + config::sync::SyncJobConfig, api2::types::{ Userid, GarbageCollectionStatus, @@ -68,6 +69,28 @@ Verification failed on these snapshots: "###; +const SYNC_OK_TEMPLATE: &str = r###" + +Job ID: {{job.id}} +Datastore: {{job.store}} +Remote: {{job.remote}} +Remote Store: {{job.remote-store}} + +Synchronization successful. + +"###; + +const SYNC_ERR_TEMPLATE: &str = r###" + +Job ID: {{job.id}} +Datastore: {{job.store}} +Remote: {{job.remote}} +Remote Store: {{job.remote-store}} + +Synchronization failed: {{error}} + +"###; + lazy_static::lazy_static!{ static ref HANDLEBARS: Handlebars<'static> = { @@ -84,6 +107,9 @@ lazy_static::lazy_static!{ hb.register_template_string("verify_ok_template", VERIFY_OK_TEMPLATE).unwrap(); hb.register_template_string("verify_err_template", VERIFY_ERR_TEMPLATE).unwrap(); + hb.register_template_string("sync_ok_template", SYNC_OK_TEMPLATE).unwrap(); + hb.register_template_string("sync_err_template", SYNC_ERR_TEMPLATE).unwrap(); + hb }; } @@ -200,6 +226,41 @@ pub fn send_verify_status( Ok(()) } +pub fn send_sync_status( + email: &str, + job: &SyncJobConfig, + result: &Result<(), Error>, +) -> Result<(), Error> { + + let text = match result { + Ok(()) => { + let data = json!({ "job": job }); + HANDLEBARS.render("sync_ok_template", &data)? + } + Err(err) => { + let data = json!({ "job": job, "error": err.to_string() }); + HANDLEBARS.render("sync_err_template", &data)? + } + }; + + let subject = match result { + Ok(()) => format!( + "Sync remote '{}' datastore '{}' successful", + job.remote, + job.remote_store, + ), + Err(_) => format!( + "Sync remote '{}' datastore '{}' failed", + job.remote, + job.remote_store, + ), + }; + + send_job_status_mail(email, &subject, &text)?; + + Ok(()) +} + /// Lookup users email address /// /// For "backup@pam", this returns the address from "root@pam".