feat: added proxy_host builder, and improve transaction borrowing
This commit is contained in:
@@ -81,12 +81,13 @@ impl NginxService {
|
||||
|
||||
pub async fn generate_config(
|
||||
&self,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<String, ServiceError> {
|
||||
let mut builder = NginxConfigBuilder::default();
|
||||
self.upstream_service
|
||||
.generate_config(&mut builder, tx)
|
||||
.await?;
|
||||
self.proxy_service.generate_config(&mut builder, tx).await?;
|
||||
|
||||
builder.to_nginx_config(None)
|
||||
}
|
||||
@@ -94,7 +95,7 @@ impl NginxService {
|
||||
pub async fn regenerate_and_apply_config(
|
||||
&self,
|
||||
agent: Arc<dyn AgentService>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
let config = self.generate_config(tx).await?;
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use crate::{errors::service_error::ServiceError, services::nginx::info::upstream::UpstreamInfo};
|
||||
use crate::{
|
||||
errors::service_error::ServiceError,
|
||||
services::nginx::info::{proxy_host::ProxyHostInfo, upstream::UpstreamInfo},
|
||||
};
|
||||
|
||||
pub const INDENT_SIZE: usize = 2;
|
||||
|
||||
@@ -9,6 +12,7 @@ pub trait NginxConfigProvider {
|
||||
#[derive(Default)]
|
||||
pub struct NginxConfigBuilder {
|
||||
upstreams: Vec<UpstreamInfo>,
|
||||
proxy_hosts: Vec<ProxyHostInfo>,
|
||||
}
|
||||
|
||||
impl NginxConfigBuilder {
|
||||
@@ -21,6 +25,16 @@ impl NginxConfigBuilder {
|
||||
self.add_upstream(upstream);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_proxy_host(&mut self, proxy_host: ProxyHostInfo) {
|
||||
self.proxy_hosts.push(proxy_host);
|
||||
}
|
||||
|
||||
pub fn add_proxy_hosts(&mut self, proxy_hosts: Vec<ProxyHostInfo>) {
|
||||
for proxy_host in proxy_hosts {
|
||||
self.add_proxy_host(proxy_host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NginxConfigProvider for NginxConfigBuilder {
|
||||
@@ -35,6 +49,10 @@ impl NginxConfigProvider for NginxConfigBuilder {
|
||||
config.push_str(&upstream.to_nginx_config(indent)?);
|
||||
}
|
||||
|
||||
for proxy_host in &self.proxy_hosts {
|
||||
config.push('\n');
|
||||
config.push_str(&proxy_host.to_nginx_config(indent)?);
|
||||
}
|
||||
// TODO: Add other sections like servers, locations, etc.
|
||||
// trailing newline for file ending
|
||||
config.push('\n');
|
||||
|
||||
@@ -11,7 +11,10 @@ use database::generated::entities::{location, proxy_host};
|
||||
use crate::{
|
||||
errors::service_error::ServiceError,
|
||||
helpers::database::PaginationFilter,
|
||||
services::nginx::info::proxy_host::{ProxyHostCreateInfo, ProxyHostInfo, UpdateProxyHostInfo},
|
||||
services::nginx::{
|
||||
builder::NginxConfigBuilder,
|
||||
info::proxy_host::{ProxyHostCreateInfo, ProxyHostInfo, UpdateProxyHostInfo},
|
||||
},
|
||||
with_conn,
|
||||
};
|
||||
|
||||
@@ -20,35 +23,40 @@ pub trait ProxyService: Send + Sync {
|
||||
async fn create_proxy(
|
||||
&self,
|
||||
create_info: ProxyHostCreateInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<ProxyHostInfo, ServiceError>;
|
||||
async fn get_total_proxies(
|
||||
&self,
|
||||
options: Option<ProxyTotalCountOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<u64, ServiceError>;
|
||||
async fn get_proxies(
|
||||
&self,
|
||||
pagination: Option<PaginationFilter>,
|
||||
options: Option<ProxyHostListOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<Vec<ProxyHostInfo>, ServiceError>;
|
||||
async fn get_proxy(
|
||||
&self,
|
||||
proxy_id: uuid::Uuid,
|
||||
options: Option<ProxyHostGetOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<ProxyHostInfo, ServiceError>;
|
||||
async fn update_proxy(
|
||||
&self,
|
||||
proxy_id: uuid::Uuid,
|
||||
update: UpdateProxyHostInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<ProxyHostInfo, ServiceError>;
|
||||
async fn delete_proxy(
|
||||
&self,
|
||||
proxy_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError>;
|
||||
async fn generate_config(
|
||||
&self,
|
||||
builder: &mut NginxConfigBuilder,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError>;
|
||||
}
|
||||
|
||||
@@ -78,18 +86,18 @@ impl ProxyService for ProxyServiceImpl {
|
||||
async fn create_proxy(
|
||||
&self,
|
||||
create_info: ProxyHostCreateInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<ProxyHostInfo, ServiceError> {
|
||||
let (proxy_host, location_models): (proxy_host::ActiveModel, Vec<location::ActiveModel>) =
|
||||
create_info.into();
|
||||
|
||||
let mut maybe_owned_tx: Option<DatabaseTransaction> = None;
|
||||
let tx_ref: Option<&mut DatabaseTransaction> = if let Some(tx) = tx {
|
||||
Some(tx)
|
||||
} else {
|
||||
maybe_owned_tx = Some(self.connection.begin().await?);
|
||||
maybe_owned_tx.as_mut()
|
||||
let owned_tx = match tx {
|
||||
Some(_) => None,
|
||||
None => Some(self.connection.begin().await.map_err(ServiceError::from)?),
|
||||
};
|
||||
|
||||
let tx_ref = owned_tx.as_ref().or(tx.as_deref());
|
||||
|
||||
let r = with_conn!(&*self.connection, tx_ref, conn, {
|
||||
let inserted_proxy = proxy_host.insert(*conn).await?;
|
||||
let mut inserted_location_models: Vec<location::Model> =
|
||||
@@ -103,16 +111,13 @@ impl ProxyService for ProxyServiceImpl {
|
||||
(inserted_proxy, inserted_location_models)
|
||||
});
|
||||
|
||||
if let Some(t) = maybe_owned_tx.take() {
|
||||
t.commit().await?;
|
||||
}
|
||||
Ok(r.into())
|
||||
}
|
||||
|
||||
async fn get_total_proxies(
|
||||
&self,
|
||||
_options: Option<ProxyTotalCountOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<u64, ServiceError> {
|
||||
#[derive(Debug, FromQueryResult)]
|
||||
struct CountResult {
|
||||
@@ -133,7 +138,7 @@ impl ProxyService for ProxyServiceImpl {
|
||||
&self,
|
||||
pagination: Option<PaginationFilter>,
|
||||
options: Option<ProxyHostListOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<Vec<ProxyHostInfo>, ServiceError> {
|
||||
let r = with_conn!(&*self.connection, tx, conn, {
|
||||
let mut find_query = proxy_host::Entity::find();
|
||||
@@ -177,7 +182,7 @@ impl ProxyService for ProxyServiceImpl {
|
||||
&self,
|
||||
proxy_id: uuid::Uuid,
|
||||
options: Option<ProxyHostGetOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<ProxyHostInfo, ServiceError> {
|
||||
let r: ProxyHostInfo = with_conn!(&*self.connection, tx, conn, {
|
||||
let find_query = proxy_host::Entity::find_by_id(proxy_id)
|
||||
@@ -217,7 +222,7 @@ impl ProxyService for ProxyServiceImpl {
|
||||
&self,
|
||||
proxy_id: uuid::Uuid,
|
||||
update: UpdateProxyHostInfo,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<ProxyHostInfo, ServiceError> {
|
||||
let current_model = with_conn!(&*self.connection, tx, conn, {
|
||||
proxy_host::Entity::find_by_id(proxy_id)
|
||||
@@ -239,7 +244,7 @@ impl ProxyService for ProxyServiceImpl {
|
||||
async fn delete_proxy(
|
||||
&self,
|
||||
proxy_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
let model = with_conn!(&*self.connection, tx, conn, {
|
||||
proxy_host::Entity::find_by_id(proxy_id)
|
||||
@@ -255,6 +260,25 @@ impl ProxyService for ProxyServiceImpl {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
async fn generate_config(
|
||||
&self,
|
||||
builder: &mut NginxConfigBuilder,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
let proxies = self
|
||||
.get_proxies(
|
||||
None,
|
||||
Some(ProxyHostListOptions {
|
||||
include_upstream: true,
|
||||
..Default::default()
|
||||
}),
|
||||
tx,
|
||||
)
|
||||
.await?;
|
||||
builder.add_proxy_hosts(proxies);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -331,7 +355,7 @@ mod tests {
|
||||
locations: Vec::new(),
|
||||
};
|
||||
|
||||
let res = svc.create_proxy(create_info, None).await;
|
||||
let res = svc.create_proxy(create_info, &None).await;
|
||||
assert!(res.is_ok());
|
||||
let info = res.expect("Failed to create proxy");
|
||||
assert_eq!(info.domain, "example.com");
|
||||
@@ -345,7 +369,7 @@ mod tests {
|
||||
|
||||
let svc = ProxyServiceImpl::new(Arc::new(db));
|
||||
let res = svc
|
||||
.get_total_proxies(None, None)
|
||||
.get_total_proxies(None, &None)
|
||||
.await
|
||||
.expect("Failed to get total proxies");
|
||||
assert_eq!(res, 0u64);
|
||||
@@ -398,7 +422,7 @@ mod tests {
|
||||
.into_connection();
|
||||
|
||||
let svc = ProxyServiceImpl::new(Arc::new(db));
|
||||
let res = svc.get_proxies(None, None, None).await;
|
||||
let res = svc.get_proxies(None, None, &None).await;
|
||||
assert!(res.is_ok());
|
||||
let list = res.expect("Failed to get proxies");
|
||||
assert_eq!(list.len(), 2);
|
||||
@@ -431,7 +455,7 @@ mod tests {
|
||||
.into_connection();
|
||||
|
||||
let svc = ProxyServiceImpl::new(Arc::new(db));
|
||||
let res = svc.get_proxy(id, None, None).await;
|
||||
let res = svc.get_proxy(id, None, &None).await;
|
||||
assert!(res.is_ok());
|
||||
let got = res.expect("Failed to get proxy");
|
||||
assert_eq!(got.id, id);
|
||||
@@ -444,7 +468,7 @@ mod tests {
|
||||
.into_connection();
|
||||
|
||||
let svc = ProxyServiceImpl::new(Arc::new(db));
|
||||
let res = svc.get_proxy(uuid::Uuid::new_v4(), None, None).await;
|
||||
let res = svc.get_proxy(uuid::Uuid::new_v4(), None, &None).await;
|
||||
assert!(matches!(res, Err(ServiceError::NotFound(_))));
|
||||
}
|
||||
|
||||
@@ -510,7 +534,7 @@ mod tests {
|
||||
default_upstream_id: None,
|
||||
};
|
||||
|
||||
let res = svc.update_proxy(id, update_info, None).await;
|
||||
let res = svc.update_proxy(id, update_info, &None).await;
|
||||
assert!(res.is_ok());
|
||||
let got = res.expect("Failed to update proxy");
|
||||
assert_eq!(got.name.expect("Name should be present"), "new");
|
||||
@@ -541,7 +565,7 @@ mod tests {
|
||||
meta: None,
|
||||
default_upstream_id: None,
|
||||
},
|
||||
None,
|
||||
&None,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -580,7 +604,7 @@ mod tests {
|
||||
|
||||
let svc = ProxyServiceImpl::new(Arc::new(db));
|
||||
|
||||
let res = svc.delete_proxy(id, None).await;
|
||||
let res = svc.delete_proxy(id, &None).await;
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
@@ -592,7 +616,7 @@ mod tests {
|
||||
|
||||
let svc = ProxyServiceImpl::new(Arc::new(db));
|
||||
|
||||
let res = svc.delete_proxy(uuid::Uuid::new_v4(), None).await;
|
||||
let res = svc.delete_proxy(uuid::Uuid::new_v4(), &None).await;
|
||||
assert!(matches!(res, Err(ServiceError::NotFound(_))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ pub trait UpstreamService: Send + Sync {
|
||||
async fn generate_config(
|
||||
&self,
|
||||
builder: &mut NginxConfigBuilder,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError>;
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ impl UpstreamService for UpstreamServiceImpl {
|
||||
async fn generate_config(
|
||||
&self,
|
||||
builder: &mut NginxConfigBuilder,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
tx: &Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
// get all upstreams and their targets
|
||||
let upstreams = with_conn!(&*self.connection, tx, conn, {
|
||||
|
||||
Reference in New Issue
Block a user