feat: warmup memory store when starting

This commit is contained in:
Quentin 2023-08-08 18:04:21 +02:00
parent 3999723308
commit 48a421a3b6
Signed by untrusted user: quentin
GPG key ID: E9602264D639FF68
2 changed files with 69 additions and 9 deletions

View file

@ -145,6 +145,47 @@ impl CertStore {
self.gen_self_signed_certificate(domain) self.gen_self_signed_certificate(domain)
} }
pub async fn warmup_memory_store(self: &Arc<Self>) -> Result<()> {
let consul_certs = self
.consul
.kv_get_prefix("certs/", None)
.await?
.into_inner();
trace!(
"Fetched {} certificate entries from Consul",
consul_certs.len()
);
let mut loaded_certs: usize = 0;
for (domain, cert) in consul_certs {
let certser: CertSer = match serde_json::from_slice(&cert) {
Ok(cs) => cs,
Err(e) => {
warn!("Could not deserialize CertSer for {domain}: {e}");
continue;
}
};
let cert = match Cert::new(certser) {
Ok(c) => c,
Err(e) => {
warn!("Could not create Cert from CertSer for domain {domain}: {e}");
continue;
}
};
self.certs
.write()
.unwrap()
.insert(domain.to_string(), Arc::new(cert));
debug!("({domain}) Certificate loaded from Consul to the Memory Store");
loaded_certs += 1;
}
info!("Memory store warmed up with {loaded_certs} certificates");
Ok(())
}
pub async fn check_cert(self: &Arc<Self>, domain: &str) -> Result<()> { pub async fn check_cert(self: &Arc<Self>, domain: &str) -> Result<()> {
// First, try locally. // First, try locally.
{ {
@ -162,16 +203,23 @@ impl CertStore {
.kv_get_json::<CertSer>(&format!("certs/{}", domain)) .kv_get_json::<CertSer>(&format!("certs/{}", domain))
.await? .await?
{ {
if let Ok(cert) = Cert::new(consul_cert) { match Cert::new(consul_cert) {
Ok(cert) => {
let cert = Arc::new(cert); let cert = Arc::new(cert);
self.certs self.certs
.write() .write()
.unwrap() .unwrap()
.insert(domain.to_string(), cert.clone()); .insert(domain.to_string(), cert.clone());
debug!("({domain}) Certificate loaded from Consul to the Memory Store");
if !cert.is_old() { if !cert.is_old() {
return Ok(()); return Ok(());
} }
} }
Err(e) => {
warn!("Could not create Cert from CertSer for domain {domain}: {e}");
}
};
} }
// Third, ask from Let's Encrypt // Third, ask from Let's Encrypt

View file

@ -101,6 +101,12 @@ struct Opt {
default_value = "text/html,text/plain,text/css,text/javascript,text/xml,application/javascript,application/json,application/xml,image/svg+xml,font/ttf" default_value = "text/html,text/plain,text/css,text/javascript,text/xml,application/javascript,application/json,application/xml,image/svg+xml,font/ttf"
)] )]
pub compress_mime_types: String, pub compress_mime_types: String,
#[structopt(
long = "warmup-cert-memory-store",
env = "TRICOT_WARMUP_CERT_MEMORY_STORE"
)]
pub warmup_cert_memory_store: bool,
} }
#[tokio::main(flavor = "multi_thread", worker_threads = 10)] #[tokio::main(flavor = "multi_thread", worker_threads = 10)]
@ -154,6 +160,12 @@ async fn main() {
opt.letsencrypt_email.clone(), opt.letsencrypt_email.clone(),
exit_on_err.clone(), exit_on_err.clone(),
); );
if opt.warmup_cert_memory_store {
match cert_store.warmup_memory_store().await {
Err(e) => error!("An error occured while warming up the certificate memory store with Consul data, continue without caching: {e}"),
_ => (),
};
}
let metrics_task = tokio::spawn( let metrics_task = tokio::spawn(
metrics_server metrics_server