Compare commits

...

2 commits

Author SHA1 Message Date
Armaël Guéneau c8854fcbd4 cargo fmt 2024-04-15 23:15:08 +02:00
Armaël Guéneau 8bc9126264 tweak duration formatting in logs 2024-04-15 23:14:32 +02:00

View file

@ -3,8 +3,8 @@ use eyre::{eyre, OptionExt, WrapErr};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::{fmt,env};
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use std::{env, fmt};
const RESTIC_ALARM_BUCKET: &str = "restic-alarm-state"; const RESTIC_ALARM_BUCKET: &str = "restic-alarm-state";
const RESTIC_ALARM_STATE_FILE: &str = "state.toml"; const RESTIC_ALARM_STATE_FILE: &str = "state.toml";
@ -18,23 +18,27 @@ struct SmtpConfig {
impl SmtpConfig { impl SmtpConfig {
fn mailer(&self) -> Result<lettre::SmtpTransport, lettre::transport::smtp::Error> { fn mailer(&self) -> Result<lettre::SmtpTransport, lettre::transport::smtp::Error> {
use lettre::SmtpTransport;
use lettre::transport::smtp::authentication::Credentials; use lettre::transport::smtp::authentication::Credentials;
use lettre::SmtpTransport;
Ok(SmtpTransport::relay(&self.address)? Ok(SmtpTransport::relay(&self.address)?
.credentials(Credentials::new( .credentials(Credentials::new(
self.username.to_owned(), self.username.to_owned(),
self.password.to_owned(), self.password.to_owned(),
)) ))
.build()) .build())
} }
async fn from_env() -> eyre::Result<SmtpConfig> { async fn from_env() -> eyre::Result<SmtpConfig> {
let address = env::var("SMTP_ADDRESS")?; let address = env::var("SMTP_ADDRESS")?;
let username = env::var("SMTP_USERNAME")?; let username = env::var("SMTP_USERNAME")?;
let password = env::var("SMTP_PASSWORD")?; let password = env::var("SMTP_PASSWORD")?;
let smtp = SmtpConfig { address, username, password }; let smtp = SmtpConfig {
if ! smtp.mailer()?.test_connection()? { address,
return Err(eyre!("Unable to contact the SMTP relay")) username,
password,
};
if !smtp.mailer()?.test_connection()? {
return Err(eyre!("Unable to contact the SMTP relay"));
} }
Ok(smtp) Ok(smtp)
} }
@ -89,15 +93,17 @@ impl fmt::Display for AlertStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let days = |d: Duration| d.as_secs() / (3600 * 24); let days = |d: Duration| d.as_secs() / (3600 * 24);
let hours = |d: Duration| (d.as_secs() / 3600) % 24; let hours = |d: Duration| (d.as_secs() / 3600) % 24;
let minutes = |d: Duration| (d.as_secs() / 60) % 60;
write!( write!(
f, f,
"{}: inactivity: {} days, {} hours, last_alert: {}", "{}: inactivity: {}d{}h{}m, last_alert: {}",
(if self.alert { "ALERT" } else { "no alert" }), (if self.alert { "ALERT" } else { "no alert" }),
days(self.inactivity), days(self.inactivity),
hours(self.inactivity), hours(self.inactivity),
minutes(self.inactivity),
match self.last_alert { match self.last_alert {
None => "none".to_owned(), None => "none".to_owned(),
Some(d) => format!("{} days, {} hours", days(d), hours(d)), Some(d) => format!("{}d{}h{}m", days(d), hours(d), minutes(d)),
} }
) )
} }
@ -275,7 +281,12 @@ struct RepoInfo {
// (e.g. if it fails to parse). // (e.g. if it fails to parse).
// So the error must not be propagated to the toplevel, which would abort the // So the error must not be propagated to the toplevel, which would abort the
// alert for remaining repositories; it should instead just be reported/logged. // alert for remaining repositories; it should instead just be reported/logged.
async fn check_repo(smtp: &SmtpConfig, client: &s3::Client, state: &mut State, repo: &str) -> eyre::Result<RepoInfo> { async fn check_repo(
smtp: &SmtpConfig,
client: &s3::Client,
state: &mut State,
repo: &str,
) -> eyre::Result<RepoInfo> {
let config = read_repo_config(client, repo).await?; let config = read_repo_config(client, repo).await?;
let alert_status = if let Some(inactivity) = repo_last_snapshot(client, repo).await? { let alert_status = if let Some(inactivity) = repo_last_snapshot(client, repo).await? {
let last_alert = state.last_alert(repo); let last_alert = state.last_alert(repo);