aboutsummaryrefslogtreecommitdiff
path: root/src/cert_store.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2021-12-07 17:05:25 +0100
committerAlex Auvolat <alex@adnab.me>2021-12-07 17:05:25 +0100
commitbb77e7c459a624bb2b4ea043145fd6ea75771105 (patch)
tree70d31e76a9eb2d6b925627c775804cd4ad42e4b7 /src/cert_store.rs
parentccb4e87658f622edbd57cc2b5a058c969643bfe2 (diff)
downloadtricot-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.rs27
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