Do cert syncing within domain manager

This commit is contained in:
Brian Picciano 2023-08-02 19:59:05 +02:00
parent 96b38f2c97
commit 337f3c9cef
3 changed files with 52 additions and 110 deletions

View File

@ -149,11 +149,6 @@ pub trait Manager: Sync + Send {
path: &str,
) -> Result<util::BoxByteStream, GetFileError>;
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(())
})
}

View File

@ -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

View File

@ -105,47 +105,3 @@ pub async fn listen_https(
graceful.await.or_unexpected()
}
pub async fn cert_refresher(
service: sync::Arc<service::http::Service>,
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(),)
});
}
}
}