diff options
author | Alex Auvolat <alex@adnab.me> | 2021-12-07 17:05:25 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2021-12-07 17:05:25 +0100 |
commit | bb77e7c459a624bb2b4ea043145fd6ea75771105 (patch) | |
tree | 70d31e76a9eb2d6b925627c775804cd4ad42e4b7 /src/cert_store.rs | |
parent | ccb4e87658f622edbd57cc2b5a058c969643bfe2 (diff) | |
download | tricot-bb77e7c459a624bb2b4ea043145fd6ea75771105.tar.gz tricot-bb77e7c459a624bb2b4ea043145fd6ea75771105.zip |
Locking to avoid flooding Let's encrypt
Diffstat (limited to 'src/cert_store.rs')
-rw-r--r-- | src/cert_store.rs | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/cert_store.rs b/src/cert_store.rs index 1b1a478..a58288c 100644 --- a/src/cert_store.rs +++ b/src/cert_store.rs @@ -13,7 +13,7 @@ use acme_micro::{Directory, DirectoryUrl}; use rustls::sign::CertifiedKey; use crate::cert::{Cert, CertSer}; -use crate::consul::Consul; +use crate::consul::*; use crate::proxy_config::ProxyConfig; pub struct CertStore { @@ -86,6 +86,30 @@ impl CertStore { pub async fn renew_cert(self: &Arc<Self>, domain: &str) -> Result<Arc<Cert>> { info!("Renewing certificate for {}", domain); + // ---- Acquire lock ---- + + let lock_path = format!("renew_lock/{}", domain); + let lock_name = format!("tricot/renew:{}@{}", domain, self.consul.local_node.clone()); + let session = self + .consul + .create_session(&ConsulSessionRequest { + name: lock_name.clone(), + node: Some(self.consul.local_node.clone()), + lock_delay: Some("30s".into()), + ttl: Some("1m".into()), + behavior: Some("delete".into()), + }) + .await?; + if !self + .consul + .acquire(&lock_path, lock_name.clone().into(), &session) + .await? + { + bail!("Lock is already taken, not renewing for now."); + } + + // ---- Do let's encrypt stuff ---- + let dir = Directory::from_url(DirectoryUrl::LetsEncrypt)?; let contact = vec!["mailto:alex@adnab.me".to_string()]; @@ -149,6 +173,7 @@ impl CertStore { self.consul .kv_put_json(&format!("certs/{}", domain), &certser) .await?; + self.consul.release(&lock_path, "".into(), &session).await?; let cert = Arc::new(Cert::new(certser)?); self.certs |