diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a5460..848dc13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Man pages. - The project can now be built and installed using `make`. +- The post-operation hooks now have access to the `is_success` template variable. ### Changed - Unknown configuration fields are no longer tolerated. diff --git a/acmed/src/certificate.rs b/acmed/src/certificate.rs index 28a2e4e..9637c3c 100644 --- a/acmed/src/certificate.rs +++ b/acmed/src/certificate.rs @@ -164,7 +164,7 @@ impl Certificate { hooks::call(data, &self.hooks, hook_type) } - pub fn call_post_operation_hooks(&self, status: &str) -> Result<(), Error> { + pub fn call_post_operation_hooks(&self, status: &str, is_success: bool) -> Result<(), Error> { let domains = self .domains .iter() @@ -174,6 +174,7 @@ impl Certificate { domains, algorithm: self.algo.to_string(), status: status.to_string(), + is_success, }; hooks::call(&hook_data, &self.hooks, HookType::PostOperation)?; Ok(()) diff --git a/acmed/src/hooks.rs b/acmed/src/hooks.rs index 64f097d..de067f8 100644 --- a/acmed/src/hooks.rs +++ b/acmed/src/hooks.rs @@ -14,6 +14,7 @@ pub struct PostOperationHookData { pub domains: Vec, pub algorithm: String, pub status: String, + pub is_success: bool, } #[derive(Serialize)] diff --git a/acmed/src/main_event_loop.rs b/acmed/src/main_event_loop.rs index d13001a..73bcdd3 100644 --- a/acmed/src/main_event_loop.rs +++ b/acmed/src/main_event_loop.rs @@ -57,20 +57,21 @@ impl MainEventLoop { match crt.should_renew() { Ok(sr) => { if sr { - let status = match request_certificate(crt, &self.root_certs) { - Ok(_) => "Success.".to_string(), - Err(e) => { - let msg = format!( - "Unable to renew the {} certificate for {}: {}", - crt.algo, - crt.domains.first().unwrap().0, - e - ); - warn!("{}", msg); - format!("Failed: {}", msg) - } - }; - match crt.call_post_operation_hooks(&status) { + let (status, is_success) = + match request_certificate(crt, &self.root_certs) { + Ok(_) => ("Success.".to_string(), true), + Err(e) => { + let msg = format!( + "Unable to renew the {} certificate for {}: {}", + crt.algo, + crt.domains.first().unwrap().0, + e + ); + warn!("{}", msg); + (format!("Failed: {}", msg), false) + } + }; + match crt.call_post_operation_hooks(&status, is_success) { Ok(_) => {} Err(e) => { let msg = format!( diff --git a/man/en/acmed.toml.5 b/man/en/acmed.toml.5 index 149a844..72b0bfd 100644 --- a/man/en/acmed.toml.5 +++ b/man/en/acmed.toml.5 @@ -317,9 +317,9 @@ Array containing the domain names included in the requested certificate. .It Cm algorithm Ar string Name of the algorithm used in the certificate. .It Cm status Ar string -Status of request. Is set to -.Dq Success. -in case the operation succeeded, in an error description otherwise. +Human-readable status. If the certificate request failed, it contains the error description. +.It Cm is_success Ar boolean +True if the certificate request is successful. .El .El .Sh FILES @@ -432,9 +432,9 @@ args = [ "-f", "noreply.certs@example.net", "contact@example.net" ] -stdin = """Subject: Certificate renewal alert for {{domains.[0]}} +stdin = """Subject: Certificate renewal {{#if is_success}}succeeded{{else}}failed{{/if}} for {{domains.[0]}} -The following certificate has been renewed. +The following certificate has {{#unless is_success}}*not* {{/if}}been renewed. domains: {{#each domains}}{{#if @index}}, {{/if}}{{this}}{{/each}} algorithm: {{algorithm}} status: {{status}}"""