config: make notify a property string
For example "gc=never,verify=always,sync=error".
This commit is contained in:
parent
9e45e03aef
commit
c26c9390ff
|
@ -5,6 +5,7 @@ use serde_json::Value;
|
||||||
use ::serde::{Deserialize, Serialize};
|
use ::serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use proxmox::api::{api, Router, RpcEnvironment, Permission};
|
use proxmox::api::{api, Router, RpcEnvironment, Permission};
|
||||||
|
use proxmox::api::schema::parse_property_string;
|
||||||
use proxmox::tools::fs::open_file_locked;
|
use proxmox::tools::fs::open_file_locked;
|
||||||
|
|
||||||
use crate::api2::types::*;
|
use crate::api2::types::*;
|
||||||
|
@ -74,7 +75,7 @@ pub fn list_datastores(
|
||||||
},
|
},
|
||||||
"notify": {
|
"notify": {
|
||||||
optional: true,
|
optional: true,
|
||||||
type: Notify,
|
schema: DATASTORE_NOTIFY_STRING_SCHEMA,
|
||||||
},
|
},
|
||||||
"gc-schedule": {
|
"gc-schedule": {
|
||||||
optional: true,
|
optional: true,
|
||||||
|
@ -218,7 +219,7 @@ pub enum DeletableProperty {
|
||||||
},
|
},
|
||||||
"notify": {
|
"notify": {
|
||||||
optional: true,
|
optional: true,
|
||||||
type: Notify,
|
schema: DATASTORE_NOTIFY_STRING_SCHEMA,
|
||||||
},
|
},
|
||||||
"gc-schedule": {
|
"gc-schedule": {
|
||||||
optional: true,
|
optional: true,
|
||||||
|
@ -282,7 +283,7 @@ pub fn update_datastore(
|
||||||
keep_weekly: Option<u64>,
|
keep_weekly: Option<u64>,
|
||||||
keep_monthly: Option<u64>,
|
keep_monthly: Option<u64>,
|
||||||
keep_yearly: Option<u64>,
|
keep_yearly: Option<u64>,
|
||||||
notify: Option<Notify>,
|
notify: Option<String>,
|
||||||
notify_user: Option<Userid>,
|
notify_user: Option<Userid>,
|
||||||
delete: Option<Vec<DeletableProperty>>,
|
delete: Option<Vec<DeletableProperty>>,
|
||||||
digest: Option<String>,
|
digest: Option<String>,
|
||||||
|
@ -346,7 +347,15 @@ pub fn update_datastore(
|
||||||
if keep_monthly.is_some() { data.keep_monthly = keep_monthly; }
|
if keep_monthly.is_some() { data.keep_monthly = keep_monthly; }
|
||||||
if keep_yearly.is_some() { data.keep_yearly = keep_yearly; }
|
if keep_yearly.is_some() { data.keep_yearly = keep_yearly; }
|
||||||
|
|
||||||
if notify.is_some() { data.notify = notify; }
|
if let Some(notify_str) = notify {
|
||||||
|
let value = parse_property_string(¬ify_str, &DatastoreNotify::API_SCHEMA)?;
|
||||||
|
let notify: DatastoreNotify = serde_json::from_value(value)?;
|
||||||
|
if let DatastoreNotify { gc: None, verify: None, sync: None } = notify {
|
||||||
|
data.notify = None;
|
||||||
|
} else {
|
||||||
|
data.notify = Some(notify_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
if notify_user.is_some() { data.notify_user = notify_user; }
|
if notify_user.is_some() { data.notify_user = notify_user; }
|
||||||
|
|
||||||
config.set_data(&name, "datastore", &data)?;
|
config.set_data(&name, "datastore", &data)?;
|
||||||
|
|
|
@ -1167,3 +1167,35 @@ pub enum Notify {
|
||||||
/// Send notifications for failed jobs only
|
/// Send notifications for failed jobs only
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
properties: {
|
||||||
|
gc: {
|
||||||
|
type: Notify,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
verify: {
|
||||||
|
type: Notify,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
sync: {
|
||||||
|
type: Notify,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
/// Datastore notify settings
|
||||||
|
pub struct DatastoreNotify {
|
||||||
|
/// Garbage collection settings
|
||||||
|
pub gc: Option<Notify>,
|
||||||
|
/// Verify job setting
|
||||||
|
pub verify: Option<Notify>,
|
||||||
|
/// Sync job setting
|
||||||
|
pub sync: Option<Notify>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const DATASTORE_NOTIFY_STRING_SCHEMA: Schema = StringSchema::new(
|
||||||
|
"Datastore notification setting")
|
||||||
|
.format(&ApiStringFormat::PropertyString(&DatastoreNotify::API_SCHEMA))
|
||||||
|
.schema();
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub const DIR_NAME_SCHEMA: Schema = StringSchema::new("Directory name").schema()
|
||||||
},
|
},
|
||||||
"notify": {
|
"notify": {
|
||||||
optional: true,
|
optional: true,
|
||||||
type: Notify,
|
schema: DATASTORE_NOTIFY_STRING_SCHEMA,
|
||||||
},
|
},
|
||||||
comment: {
|
comment: {
|
||||||
optional: true,
|
optional: true,
|
||||||
|
@ -114,7 +114,7 @@ pub struct DataStoreConfig {
|
||||||
pub notify_user: Option<Userid>,
|
pub notify_user: Option<Userid>,
|
||||||
/// Send notification only for job errors
|
/// Send notification only for job errors
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub notify: Option<Notify>,
|
pub notify: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init() -> SectionConfig {
|
fn init() -> SectionConfig {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use serde_json::json;
|
||||||
use handlebars::{Handlebars, Helper, Context, RenderError, RenderContext, Output, HelperResult};
|
use handlebars::{Handlebars, Helper, Context, RenderError, RenderContext, Output, HelperResult};
|
||||||
|
|
||||||
use proxmox::tools::email::sendmail;
|
use proxmox::tools::email::sendmail;
|
||||||
|
use proxmox::api::schema::parse_property_string;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::datastore::DataStoreConfig,
|
config::datastore::DataStoreConfig,
|
||||||
|
@ -14,6 +15,7 @@ use crate::{
|
||||||
GarbageCollectionStatus,
|
GarbageCollectionStatus,
|
||||||
Userid,
|
Userid,
|
||||||
Notify,
|
Notify,
|
||||||
|
DatastoreNotify,
|
||||||
},
|
},
|
||||||
tools::format::HumanByte,
|
tools::format::HumanByte,
|
||||||
};
|
};
|
||||||
|
@ -190,15 +192,20 @@ fn send_job_status_mail(
|
||||||
|
|
||||||
pub fn send_gc_status(
|
pub fn send_gc_status(
|
||||||
email: &str,
|
email: &str,
|
||||||
notify: Notify,
|
notify: DatastoreNotify,
|
||||||
datastore: &str,
|
datastore: &str,
|
||||||
status: &GarbageCollectionStatus,
|
status: &GarbageCollectionStatus,
|
||||||
result: &Result<(), Error>,
|
result: &Result<(), Error>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
|
match notify.gc {
|
||||||
|
None => { /* send notifications by default */ },
|
||||||
|
Some(notify) => {
|
||||||
if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) {
|
if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (fqdn, port) = get_server_url();
|
let (fqdn, port) = get_server_url();
|
||||||
let mut data = json!({
|
let mut data = json!({
|
||||||
|
@ -244,15 +251,11 @@ pub fn send_gc_status(
|
||||||
|
|
||||||
pub fn send_verify_status(
|
pub fn send_verify_status(
|
||||||
email: &str,
|
email: &str,
|
||||||
notify: Notify,
|
notify: DatastoreNotify,
|
||||||
job: VerificationJobConfig,
|
job: VerificationJobConfig,
|
||||||
result: &Result<Vec<String>, Error>,
|
result: &Result<Vec<String>, Error>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let (fqdn, port) = get_server_url();
|
let (fqdn, port) = get_server_url();
|
||||||
let mut data = json!({
|
let mut data = json!({
|
||||||
"job": job,
|
"job": job,
|
||||||
|
@ -260,8 +263,11 @@ pub fn send_verify_status(
|
||||||
"port": port,
|
"port": port,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut result_is_ok = false;
|
||||||
|
|
||||||
let text = match result {
|
let text = match result {
|
||||||
Ok(errors) if errors.is_empty() => {
|
Ok(errors) if errors.is_empty() => {
|
||||||
|
result_is_ok = true;
|
||||||
HANDLEBARS.render("verify_ok_template", &data)?
|
HANDLEBARS.render("verify_ok_template", &data)?
|
||||||
}
|
}
|
||||||
Ok(errors) => {
|
Ok(errors) => {
|
||||||
|
@ -274,6 +280,15 @@ pub fn send_verify_status(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match notify.verify {
|
||||||
|
None => { /* send notifications by default */ },
|
||||||
|
Some(notify) => {
|
||||||
|
if notify == Notify::Never || (result_is_ok && notify == Notify::Error) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let subject = match result {
|
let subject = match result {
|
||||||
Ok(errors) if errors.is_empty() => format!(
|
Ok(errors) if errors.is_empty() => format!(
|
||||||
"Verify Datastore '{}' successful",
|
"Verify Datastore '{}' successful",
|
||||||
|
@ -292,14 +307,19 @@ pub fn send_verify_status(
|
||||||
|
|
||||||
pub fn send_sync_status(
|
pub fn send_sync_status(
|
||||||
email: &str,
|
email: &str,
|
||||||
notify: Notify,
|
notify: DatastoreNotify,
|
||||||
job: &SyncJobConfig,
|
job: &SyncJobConfig,
|
||||||
result: &Result<(), Error>,
|
result: &Result<(), Error>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
|
match notify.sync {
|
||||||
|
None => { /* send notifications by default */ },
|
||||||
|
Some(notify) => {
|
||||||
if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) {
|
if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (fqdn, port) = get_server_url();
|
let (fqdn, port) = get_server_url();
|
||||||
let mut data = json!({
|
let mut data = json!({
|
||||||
|
@ -399,11 +419,12 @@ fn lookup_user_email(userid: &Userid) -> Option<String> {
|
||||||
/// Lookup Datastore notify settings
|
/// Lookup Datastore notify settings
|
||||||
pub fn lookup_datastore_notify_settings(
|
pub fn lookup_datastore_notify_settings(
|
||||||
store: &str,
|
store: &str,
|
||||||
) -> (Option<String>, Notify) {
|
) -> (Option<String>, DatastoreNotify) {
|
||||||
|
|
||||||
let mut notify = Notify::Always;
|
|
||||||
let mut email = None;
|
let mut email = None;
|
||||||
|
|
||||||
|
let notify = DatastoreNotify { gc: None, verify: None, sync: None };
|
||||||
|
|
||||||
let (config, _digest) = match crate::config::datastore::config() {
|
let (config, _digest) = match crate::config::datastore::config() {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(_) => return (email, notify),
|
Err(_) => return (email, notify),
|
||||||
|
@ -419,8 +440,12 @@ pub fn lookup_datastore_notify_settings(
|
||||||
None => lookup_user_email(Userid::backup_userid()),
|
None => lookup_user_email(Userid::backup_userid()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(value) = config.notify {
|
let notify_str = config.notify.unwrap_or(String::new());
|
||||||
notify = value;
|
|
||||||
|
if let Ok(value) = parse_property_string(¬ify_str, &DatastoreNotify::API_SCHEMA) {
|
||||||
|
if let Ok(notify) = serde_json::from_value(value) {
|
||||||
|
return (email, notify);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(email, notify)
|
(email, notify)
|
||||||
|
|
Loading…
Reference in New Issue