wip: implementing api

This commit is contained in:
Jun Kurihara 2024-07-17 17:06:37 +09:00
commit 9e79a481c6
No known key found for this signature in database
GPG key ID: D992B3E3DE1DED23
7 changed files with 155 additions and 48 deletions

View file

@ -7,7 +7,7 @@ use rpxy_lib::{AppConfig, AppConfigList, ProxyConfig};
use rustc_hash::FxHashMap as HashMap;
#[cfg(feature = "acme")]
use rpxy_acme::{AcmeContexts, ACME_DIR_URL, ACME_REGISTRY_PATH};
use rpxy_acme::{AcmeManager, ACME_DIR_URL, ACME_REGISTRY_PATH};
/// Parsed options
pub struct Opts {
@ -157,12 +157,14 @@ pub async fn build_cert_manager(
/* ----------------------- */
#[cfg(feature = "acme")]
/// Build acme manager and dummy cert and key as initial states if not exists
/// TODO: CURRENTLY NOT IMPLEMENTED, UNDER DESIGNING
pub async fn build_acme_manager(config: &ConfigToml) -> Result<(), anyhow::Error> {
/// Build acme manager
pub async fn build_acme_manager(
config: &ConfigToml,
runtime_handle: tokio::runtime::Handle,
) -> Result<Option<AcmeManager>, anyhow::Error> {
let acme_option = config.experimental.as_ref().and_then(|v| v.acme.clone());
if acme_option.is_none() {
return Ok(());
return Ok(None);
}
let acme_option = acme_option.unwrap();
@ -183,14 +185,17 @@ pub async fn build_acme_manager(config: &ConfigToml) -> Result<(), anyhow::Error
})
.collect::<Vec<_>>();
let acme_contexts = AcmeContexts::try_new(
if domains.is_empty() {
return Ok(None);
}
let acme_manager = AcmeManager::try_new(
acme_option.dir_url.as_deref(),
acme_option.registry_path.as_deref(),
&[acme_option.email],
domains.as_slice(),
runtime_handle,
)?;
// TODO: remove later
println!("ACME contexts: {:#?}", acme_contexts);
Ok(())
Ok(Some(acme_manager))
}

View file

@ -68,16 +68,33 @@ async fn rpxy_service_without_watcher(
let config_toml = ConfigToml::new(config_file_path).map_err(|e| anyhow!("Invalid toml file: {e}"))?;
let (proxy_conf, app_conf) = build_settings(&config_toml).map_err(|e| anyhow!("Invalid configuration: {e}"))?;
#[cfg(feature = "acme")] // TODO: CURRENTLY NOT IMPLEMENTED, UNDER DESIGNING
let acme_manager = build_acme_manager(&config_toml).await;
#[cfg(feature = "acme")]
let acme_manager = build_acme_manager(&config_toml, runtime_handle.clone()).await?;
let cert_service_and_rx = build_cert_manager(&config_toml)
.await
.map_err(|e| anyhow!("Invalid cert configuration: {e}"))?;
rpxy_entrypoint(&proxy_conf, &app_conf, cert_service_and_rx.as_ref(), &runtime_handle, None)
#[cfg(feature = "acme")]
{
rpxy_entrypoint(
&proxy_conf,
&app_conf,
cert_service_and_rx.as_ref(),
acme_manager.as_ref(),
&runtime_handle,
None,
)
.await
.map_err(|e| anyhow!(e))
}
#[cfg(not(feature = "acme"))]
{
rpxy_entrypoint(&proxy_conf, &app_conf, cert_service_and_rx.as_ref(), &runtime_handle, None)
.await
.map_err(|e| anyhow!(e))
}
}
async fn rpxy_service_with_watcher(
@ -93,8 +110,8 @@ async fn rpxy_service_with_watcher(
.ok_or(anyhow!("Something wrong in config reloader receiver"))?;
let (mut proxy_conf, mut app_conf) = build_settings(&config_toml).map_err(|e| anyhow!("Invalid configuration: {e}"))?;
#[cfg(feature = "acme")] // TODO: CURRENTLY NOT IMPLEMENTED, UNDER DESIGNING
let acme_manager = build_acme_manager(&config_toml).await;
#[cfg(feature = "acme")]
let acme_manager = build_acme_manager(&config_toml, runtime_handle.clone()).await?;
let mut cert_service_and_rx = build_cert_manager(&config_toml)
.await
@ -106,7 +123,16 @@ async fn rpxy_service_with_watcher(
// Continuous monitoring
loop {
tokio::select! {
rpxy_res = rpxy_entrypoint(&proxy_conf, &app_conf, cert_service_and_rx.as_ref(), &runtime_handle, Some(term_notify.clone())) => {
rpxy_res = {
#[cfg(feature = "acme")]
{
rpxy_entrypoint(&proxy_conf, &app_conf, cert_service_and_rx.as_ref(), acme_manager.as_ref(), &runtime_handle, Some(term_notify.clone()))
}
#[cfg(not(feature = "acme"))]
{
rpxy_entrypoint(&proxy_conf, &app_conf, cert_service_and_rx.as_ref(), &runtime_handle, Some(term_notify.clone()))
}
} => {
error!("rpxy entrypoint or cert service exited");
return rpxy_res.map_err(|e| anyhow!(e));
}
@ -145,6 +171,7 @@ async fn rpxy_service_with_watcher(
Ok(())
}
#[cfg(not(feature = "acme"))]
/// Wrapper of entry point for rpxy service with certificate management service
async fn rpxy_entrypoint(
proxy_config: &rpxy_lib::ProxyConfig,
@ -152,7 +179,7 @@ async fn rpxy_entrypoint(
cert_service_and_rx: Option<&(
ReloaderService<rpxy_certs::CryptoReloader, rpxy_certs::ServerCryptoBase>,
ReloaderReceiver<rpxy_certs::ServerCryptoBase>,
)>, // TODO:
)>,
runtime_handle: &tokio::runtime::Handle,
term_notify: Option<std::sync::Arc<tokio::sync::Notify>>,
) -> Result<(), anyhow::Error> {
@ -173,3 +200,41 @@ async fn rpxy_entrypoint(
.map_err(|e| anyhow!(e))
}
}
#[cfg(feature = "acme")]
/// Wrapper of entry point for rpxy service with certificate management service
async fn rpxy_entrypoint(
proxy_config: &rpxy_lib::ProxyConfig,
app_config_list: &rpxy_lib::AppConfigList,
cert_service_and_rx: Option<&(
ReloaderService<rpxy_certs::CryptoReloader, rpxy_certs::ServerCryptoBase>,
ReloaderReceiver<rpxy_certs::ServerCryptoBase>,
)>,
acme_manager: Option<&rpxy_acme::AcmeManager>,
runtime_handle: &tokio::runtime::Handle,
term_notify: Option<std::sync::Arc<tokio::sync::Notify>>,
) -> Result<(), anyhow::Error> {
// TODO: remove later, reconsider routine
println!("ACME manager:\n{:#?}", acme_manager);
let x = acme_manager.unwrap().clone();
let (handle, confs) = x.spawn_manager_tasks();
tokio::spawn(async move { futures_util::future::select_all(handle).await });
// TODO:
if let Some((cert_service, cert_rx)) = cert_service_and_rx {
tokio::select! {
rpxy_res = entrypoint(proxy_config, app_config_list, Some(cert_rx), runtime_handle, term_notify) => {
error!("rpxy entrypoint exited");
rpxy_res.map_err(|e| anyhow!(e))
}
cert_res = cert_service.start() => {
error!("cert reloader service exited");
cert_res.map_err(|e| anyhow!(e))
}
}
} else {
entrypoint(proxy_config, app_config_list, None, runtime_handle, term_notify)
.await
.map_err(|e| anyhow!(e))
}
}