From 337f3c9cef1e4221e7f89092d745dc8b8a9c7e94 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Wed, 2 Aug 2023 19:59:05 +0200 Subject: [PATCH] Do cert syncing within domain manager --- src/domain/manager.rs | 117 +++++++++++++++++--------------------- src/service/http.rs | 1 - src/service/http/tasks.rs | 44 -------------- 3 files changed, 52 insertions(+), 110 deletions(-) diff --git a/src/domain/manager.rs b/src/domain/manager.rs index 74bf725..9b2fa0c 100644 --- a/src/domain/manager.rs +++ b/src/domain/manager.rs @@ -149,11 +149,6 @@ pub trait Manager: Sync + Send { path: &str, ) -> Result; - fn sync_https_cert<'mgr>( - &'mgr self, - domain: domain::Name, - ) -> util::BoxFuture<'mgr, Result<(), unexpected::Error>>; - fn sync_with_settings<'mgr>( &'mgr self, domain: domain::Name, @@ -207,7 +202,7 @@ impl ManagerImpl { task_stack.push_spawn(|canceller| { let manager = manager.clone(); async move { - manager.sync_origins(canceller).await; + manager.sync_all_domains(canceller).await; Ok(()) } }); @@ -215,45 +210,13 @@ impl ManagerImpl { manager } - async fn sync_origins_once(&self) { - match self.domain_store.all_domains() { - Ok(domains) => domains, - Err(err) => { - log::error!("Error fetching all domains: {err}"); - return; - } - } - .into_iter() - .for_each(|domain| { - log::info!("Syncing domain {}", &domain); + async fn sync_domain_certs_and_origin( + &self, + domain: &domain::Name, + settings: &domain::Settings, + ) -> Result<(), SyncWithSettingsError> { + self.origin_store.sync(&settings.origin_descr)?; - let settings = match self.domain_store.get(&domain) { - Ok(settings) => settings, - Err(err) => { - log::error!("Error syncing {domain}: {err}"); - return; - } - }; - - let descr = &settings.settings.origin_descr; - - if let Err(err) = self.origin_store.sync(descr) { - log::error!("Failed to sync origin for {domain}, origin:{descr:?}: {err}") - } - }); - } - - async fn sync_origins(&self, canceller: CancellationToken) { - let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(20 * 60)); - loop { - tokio::select! { - _ = interval.tick() => self.sync_origins_once().await, - _ = canceller.cancelled() => return, - } - } - } - - fn sync_gemini_cert(&self, domain: &domain::Name) -> unexpected::Result<()> { if let Some(ref gemini_store) = self.gemini_store { if let Some(_) = gemini_store.get_certificate(domain).or_unexpected()? { return Ok(()); @@ -267,8 +230,51 @@ impl ManagerImpl { gemini_store.set_certificate(domain, pkey, cert)?; } + if let Some(ref acme_manager) = self.acme_manager { + acme_manager.sync_domain(domain.clone()).await?; + } + Ok(()) } + + async fn sync_all_domains_once(&self) { + let domains = match self.domain_store.all_domains() { + Ok(domains) => domains, + Err(err) => { + log::error!("Error fetching all domains: {err}"); + return; + } + } + .into_iter(); + + for domain in domains { + log::info!("Syncing domain {}", &domain); + + let get_res = match self.domain_store.get(&domain) { + Ok(get_res) => get_res, + Err(err) => { + log::error!("Error syncing {domain}: {err}"); + return; + } + }; + + let settings = get_res.settings; + + if let Err(err) = self.sync_domain_certs_and_origin(&domain, &settings).await { + log::error!("Failed to sync settings for {domain}, settings:{settings:?}: {err}",) + } + } + } + + async fn sync_all_domains(&self, canceller: CancellationToken) { + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(20 * 60)); + loop { + tokio::select! { + _ = canceller.cancelled() => return, + _ = interval.tick() => self.sync_all_domains_once().await, + } + } + } } impl Manager for ManagerImpl { @@ -292,19 +298,6 @@ impl Manager for ManagerImpl { Ok(f) } - fn sync_https_cert<'mgr>( - &'mgr self, - domain: domain::Name, - ) -> util::BoxFuture<'mgr, Result<(), unexpected::Error>> { - Box::pin(async move { - if let Some(ref acme_manager) = self.acme_manager { - acme_manager.sync_domain(domain.clone()).await?; - } - - Ok(()) - }) - } - fn sync_with_settings<'mgr>( &'mgr self, domain: domain::Name, @@ -316,15 +309,9 @@ impl Manager for ManagerImpl { .or_unexpected_while("calculating config hash")?; self.domain_checker.check_domain(&domain, &hash).await?; - - self.origin_store.sync(&settings.origin_descr)?; - + self.sync_domain_certs_and_origin(&domain, &settings) + .await?; self.domain_store.set(&domain, &settings)?; - - self.sync_gemini_cert(&domain)?; - - self.sync_https_cert(domain).await?; - Ok(()) }) } diff --git a/src/service/http.rs b/src/service/http.rs index 7605f44..25bd6a5 100644 --- a/src/service/http.rs +++ b/src/service/http.rs @@ -75,7 +75,6 @@ impl Service { if https_enabled { task_stack.push_spawn(|canceller| tasks::listen_https(service.clone(), canceller)); - task_stack.push_spawn(|canceller| tasks::cert_refresher(service.clone(), canceller)); } service diff --git a/src/service/http/tasks.rs b/src/service/http/tasks.rs index 0e40ab3..2fb7328 100644 --- a/src/service/http/tasks.rs +++ b/src/service/http/tasks.rs @@ -105,47 +105,3 @@ pub async fn listen_https( graceful.await.or_unexpected() } - -pub async fn cert_refresher( - service: sync::Arc, - canceller: CancellationToken, -) -> Result<(), unexpected::Error> { - use tokio::time; - - let domain_manager = service.domain_manager.clone(); - let primary_domain = service.config.primary_domain.clone(); - let mut interval = time::interval(time::Duration::from_secs(60 * 60)); - - loop { - tokio::select! { - _ = interval.tick() => (), - _ = canceller.cancelled() => return Ok(()), - } - - _ = domain_manager - .sync_https_cert(primary_domain.clone()) - .await - .inspect_err(|err| { - log::error!( - "Error while getting cert for {}: {err}", - primary_domain.as_str() - ) - }); - - let domains_iter = domain_manager.all_domains(); - - if let Err(err) = domains_iter { - log::error!("Got error calling all_domains: {err}"); - continue; - } - - for domain in domains_iter.unwrap().into_iter() { - let _ = domain_manager - .sync_https_cert(domain.clone()) - .await - .inspect_err(|err| { - log::error!("Error while getting cert for {}: {err}", domain.as_str(),) - }); - } - } -}