Compare commits
4 Commits
feature/ng
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c5485c449 | ||
|
|
076e87695d | ||
|
|
83037f3ee2 | ||
|
|
2c20d08127 |
@@ -80,34 +80,6 @@ mod tests {
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
fn create_exec_file(path: &Path) {
|
||||
write_file(path);
|
||||
let metadata = fs::metadata(path);
|
||||
assert!(metadata.is_ok());
|
||||
let metadata = metadata.ok();
|
||||
assert!(metadata.is_some());
|
||||
let metadata = metadata.unwrap_or_else(|| unreachable!());
|
||||
|
||||
let mut perms = metadata.permissions();
|
||||
perms.set_mode(0o755);
|
||||
let result = fs::set_permissions(path, perms);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
fn create_non_exec_file(path: &Path) {
|
||||
write_file(path);
|
||||
let metadata = fs::metadata(path);
|
||||
assert!(metadata.is_ok());
|
||||
let metadata = metadata.ok();
|
||||
assert!(metadata.is_some());
|
||||
let metadata = metadata.unwrap_or_else(|| unreachable!());
|
||||
|
||||
let mut perms = metadata.permissions();
|
||||
perms.set_mode(0o644);
|
||||
let result = fs::set_permissions(path, perms);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
fn valid_tls_raw_paths(temp_dir: &TempDir) -> (PathBuf, PathBuf, PathBuf) {
|
||||
let ca_path = temp_dir.path().join("ca.pem");
|
||||
let cert_path = temp_dir.path().join("cert.pem");
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
pub mod ssh;
|
||||
|
||||
pub type AgentClient =
|
||||
@@ -47,8 +43,6 @@ mod tests {
|
||||
atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::config::settings::{
|
||||
GrpcSettings, LogSettings, MAuthSettings, Settings, TLSSettings,
|
||||
};
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::sync::Weak;
|
||||
|
||||
use nxmesh_proto::{
|
||||
AgentMessage, ConfigUpdate, MasterMessage, command::Command, master_message::Payload,
|
||||
};
|
||||
use nxmesh_proto::{ConfigUpdate, MasterMessage, command::Command, master_message::Payload};
|
||||
|
||||
use crate::service::master_handler::{MasterHandlerError, MessageResult};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use thiserror::Error;
|
||||
use tokio::process::Command;
|
||||
use tracing::{debug, warn};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{config::settings::NginxSettings, service::master_handler::MasterHandlerError};
|
||||
|
||||
@@ -120,10 +120,7 @@ impl CommandHandler for CommandHandlerImpl {
|
||||
if !output.status.success() {
|
||||
let error_info = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(CommandHandlerError::CommandExecutionError(
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("Failed to reload nginx: {}", error_info.trim()),
|
||||
),
|
||||
std::io::Error::other(format!("Failed to reload nginx: {}", error_info.trim())),
|
||||
));
|
||||
}
|
||||
let success_info = String::from_utf8_lossy(&output.stdout);
|
||||
@@ -142,10 +139,7 @@ impl CommandHandler for CommandHandlerImpl {
|
||||
if !output.status.success() {
|
||||
let error_info = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(CommandHandlerError::CommandExecutionError(
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("Failed to stop nginx: {}", error_info.trim()),
|
||||
),
|
||||
std::io::Error::other(format!("Failed to stop nginx: {}", error_info.trim())),
|
||||
));
|
||||
}
|
||||
let success_info = String::from_utf8_lossy(&output.stdout);
|
||||
@@ -171,10 +165,10 @@ impl CommandHandler for CommandHandlerImpl {
|
||||
if !output.status.success() {
|
||||
let error_info = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(CommandHandlerError::CommandExecutionError(
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("Failed to validate nginx config: {}", error_info.trim()),
|
||||
),
|
||||
std::io::Error::other(format!(
|
||||
"Failed to validate nginx config: {}",
|
||||
error_info.trim()
|
||||
)),
|
||||
));
|
||||
}
|
||||
let success_info = String::from_utf8_lossy(&output.stdout);
|
||||
@@ -191,10 +185,10 @@ impl CommandHandler for CommandHandlerImpl {
|
||||
if !output.status.success() {
|
||||
let error_info = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(CommandHandlerError::CommandExecutionError(
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("Failed to get nginx version: {}", error_info.trim()),
|
||||
),
|
||||
std::io::Error::other(format!(
|
||||
"Failed to get nginx version: {}",
|
||||
error_info.trim()
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -211,10 +205,7 @@ impl CommandHandler for CommandHandlerImpl {
|
||||
if !output.status.success() {
|
||||
let error_info = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(CommandHandlerError::CommandExecutionError(
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("Failed to get nginx status: {}", error_info.trim()),
|
||||
),
|
||||
std::io::Error::other(format!("Failed to get nginx status: {}", error_info.trim())),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use fs4::tokio::AsyncFileExt;
|
||||
use thiserror::Error;
|
||||
use tokio::{io::AsyncWriteExt, process::Command};
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{config::settings::NginxSettings, service::master_handler::MasterHandlerError};
|
||||
@@ -222,19 +222,19 @@ impl FsHandler for FsHandlerImpl {
|
||||
let mut entries = tokio::fs::read_dir(&deployment_dir).await?;
|
||||
let mut candidates: Vec<(std::path::PathBuf, std::time::SystemTime)> = Vec::new();
|
||||
while let Some(entry) = entries.next_entry().await? {
|
||||
if entry.file_type().await.map_or(false, |t| t.is_dir()) {
|
||||
if let Ok(mtime) = entry.metadata().await.and_then(|m| m.modified()) {
|
||||
candidates.push((entry.path(), mtime));
|
||||
}
|
||||
if entry.file_type().await.is_ok_and(|t| t.is_dir())
|
||||
&& let Ok(mtime) = entry.metadata().await.and_then(|m| m.modified())
|
||||
{
|
||||
candidates.push((entry.path(), mtime));
|
||||
}
|
||||
}
|
||||
// sort descending by mtime (newest first)
|
||||
candidates.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
candidates.sort_by_key(|b| std::cmp::Reverse(b.1));
|
||||
|
||||
for (dir, _) in &candidates {
|
||||
let mut dir_entries = tokio::fs::read_dir(dir).await?;
|
||||
while let Some(file) = dir_entries.next_entry().await? {
|
||||
if file.file_type().await.map_or(false, |t| t.is_file()) {
|
||||
if file.file_type().await.is_ok_and(|t| t.is_file()) {
|
||||
let name = file.file_name().to_string_lossy().to_string();
|
||||
if name == "nginx.conf" || name.ends_with(".conf") {
|
||||
let path = file.path().to_string_lossy().to_string();
|
||||
|
||||
@@ -107,7 +107,9 @@ impl OnConfigUpdateHandler for NginxMasterMessageHandlerImpl {
|
||||
// apply reload on the root config
|
||||
self.command_handler.reload(Some(&root_config_path)).await?;
|
||||
// persist deployment path so Reload/Test commands survive agent restarts
|
||||
self.fs_handler.save_last_deployment(&root_config_path).await?;
|
||||
self.fs_handler
|
||||
.save_last_deployment(&root_config_path)
|
||||
.await?;
|
||||
info!("Persisted last deployment path: {}", root_config_path);
|
||||
// Reply the master to confirm the config update is successful
|
||||
self.master_handler
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use sea_orm::DatabaseConnection;
|
||||
use tonic::transport::Server;
|
||||
|
||||
pub mod ssh;
|
||||
|
||||
|
||||
@@ -54,7 +54,9 @@ mod tests {
|
||||
proxy_setting_service: Arc::new(proxy_setting::MockProxySettingService::new()),
|
||||
rewrite_rule_service: Arc::new(rewrite_rule::MockRewriteRuleService::new()),
|
||||
ssl_certificate_service: Arc::new(ssl_certificate::MockSslCertificateService::new()),
|
||||
config_inheritance_service: Arc::new(config_inheritance::MockConfigInheritanceService::new()),
|
||||
config_inheritance_service: Arc::new(
|
||||
config_inheritance::MockConfigInheritanceService::new(),
|
||||
),
|
||||
});
|
||||
get_router().await.with_state(state)
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ pub async fn update_agent_handler(
|
||||
Path(id): Path<uuid::Uuid>,
|
||||
Json(body): Json<UpdateAgentRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
if let Some(ref name) = body.name {
|
||||
if name.trim().is_empty() {
|
||||
return Err(AppError::BadRequest("name must not be empty".to_string()));
|
||||
}
|
||||
if let Some(ref name) = body.name
|
||||
&& name.trim().is_empty()
|
||||
{
|
||||
return Err(AppError::BadRequest("name must not be empty".to_string()));
|
||||
}
|
||||
|
||||
let rec = UpdateAgentRecord {
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::access_rule::{
|
||||
AccessRuleService, CreateAccessRuleParams, UpdateAccessRuleParams,
|
||||
};
|
||||
@@ -151,10 +151,7 @@ pub(super) fn routes() -> ApiRouter {
|
||||
"/locations/{location_id}/access-rules",
|
||||
axum::routing::get(list_access_rules_by_location),
|
||||
)
|
||||
.route(
|
||||
"/access-rules",
|
||||
axum::routing::post(create_access_rule),
|
||||
)
|
||||
.route("/access-rules", axum::routing::post(create_access_rule))
|
||||
.route(
|
||||
"/access-rules/{id}",
|
||||
axum::routing::get(get_access_rule)
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::{ProxyServiceTrait, types::AgentConfigBinding};
|
||||
|
||||
use super::configs::ProxyConfigResponse;
|
||||
@@ -56,7 +56,10 @@ async fn bind_agent(
|
||||
Json(body): Json<BindAgentRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
let binding = svc.bind_agent(agent_id, body.config_id).await?;
|
||||
Ok((StatusCode::CREATED, Json(AgentConfigResponse::from(binding))))
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(AgentConfigResponse::from(binding)),
|
||||
))
|
||||
}
|
||||
|
||||
async fn unbind_agent(
|
||||
@@ -72,11 +75,10 @@ async fn unbind_agent(
|
||||
}
|
||||
|
||||
pub(super) fn routes() -> ApiRouter {
|
||||
ApiRouter::new()
|
||||
.route(
|
||||
"/agents/{agent_id}/config",
|
||||
axum::routing::get(get_active_agent_config)
|
||||
.post(bind_agent)
|
||||
.delete(unbind_agent),
|
||||
)
|
||||
ApiRouter::new().route(
|
||||
"/agents/{agent_id}/config",
|
||||
axum::routing::get(get_active_agent_config)
|
||||
.post(bind_agent)
|
||||
.delete(unbind_agent),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::cache_zone::{
|
||||
CacheZoneService, CreateCacheZoneParams, UpdateCacheZoneParams,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::config_inheritance::{
|
||||
AddInheritanceParams, ConfigInheritanceRecord, ConfigInheritanceService,
|
||||
};
|
||||
@@ -100,8 +100,5 @@ pub(super) fn routes() -> ApiRouter {
|
||||
"/configs/{id}/parents/{parent_id}",
|
||||
axum::routing::delete(remove_parent),
|
||||
)
|
||||
.route(
|
||||
"/configs/{id}/children",
|
||||
axum::routing::get(list_children),
|
||||
)
|
||||
.route("/configs/{id}/children", axum::routing::get(list_children))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::{
|
||||
ProxyServiceTrait,
|
||||
types::{CreateProxyConfigParams, ProxyConfigSummary, UpdateProxyConfigParams},
|
||||
@@ -93,7 +93,7 @@ async fn get_config(
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<Json<serde_json::Value>, AppError> {
|
||||
let config = svc.get_proxy_config(id).await?;
|
||||
Ok(Json(serde_json::to_value(&config.id).unwrap_or_default()))
|
||||
Ok(Json(serde_json::to_value(config.id).unwrap_or_default()))
|
||||
}
|
||||
|
||||
async fn update_config(
|
||||
@@ -136,7 +136,10 @@ async fn render_config(
|
||||
|
||||
pub(super) fn routes() -> ApiRouter {
|
||||
ApiRouter::new()
|
||||
.route("/configs", axum::routing::get(list_configs).post(create_config))
|
||||
.route(
|
||||
"/configs",
|
||||
axum::routing::get(list_configs).post(create_config),
|
||||
)
|
||||
.route(
|
||||
"/configs/{id}",
|
||||
axum::routing::get(get_config)
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::limit_rule::{
|
||||
CreateLimitRuleParams, LimitRuleService, UpdateLimitRuleParams,
|
||||
};
|
||||
@@ -131,10 +131,7 @@ pub(super) fn routes() -> ApiRouter {
|
||||
"/locations/{location_id}/limit-rules",
|
||||
axum::routing::get(list_limit_rules_by_location),
|
||||
)
|
||||
.route(
|
||||
"/limit-rules",
|
||||
axum::routing::post(create_limit_rule),
|
||||
)
|
||||
.route("/limit-rules", axum::routing::post(create_limit_rule))
|
||||
.route(
|
||||
"/limit-rules/{id}",
|
||||
axum::routing::get(get_limit_rule)
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::limit_zone::{
|
||||
CreateLimitZoneParams, LimitZoneService, UpdateLimitZoneParams,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::location_block::{
|
||||
CreateLocationBlockParams, LocationBlockService, UpdateLocationBlockParams,
|
||||
};
|
||||
@@ -95,7 +95,10 @@ async fn create_location(
|
||||
let mut params = CreateLocationBlockParams::from(body);
|
||||
params.server_id = server_id;
|
||||
let location = svc.create(params).await?;
|
||||
Ok((StatusCode::CREATED, Json(LocationBlockResponse::from(location))))
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(LocationBlockResponse::from(location)),
|
||||
))
|
||||
}
|
||||
|
||||
async fn get_location(
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::log_setting::{
|
||||
CreateLogSettingParams, LogSettingService, UpdateLogSettingParams,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::proxy_setting::{
|
||||
CreateProxySettingParams, ProxySettingService, UpdateProxySettingParams,
|
||||
};
|
||||
@@ -107,7 +107,10 @@ async fn create_proxy_setting(
|
||||
let mut params = CreateProxySettingParams::from(body);
|
||||
params.location_id = location_id;
|
||||
let setting = svc.create(params).await?;
|
||||
Ok((StatusCode::CREATED, Json(ProxySettingResponse::from(setting))))
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(ProxySettingResponse::from(setting)),
|
||||
))
|
||||
}
|
||||
|
||||
async fn get_proxy_setting(
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::rewrite_rule::{
|
||||
CreateRewriteRuleParams, RewriteRuleService, UpdateRewriteRuleParams,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::server_block::{
|
||||
CreateServerBlockParams, ServerBlockService, UpdateServerBlockParams,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::ssl_certificate::{
|
||||
CreateSslCertificateParams, SslCertificateService, UpdateSslCertificateParams,
|
||||
};
|
||||
@@ -86,7 +86,10 @@ async fn create_ssl_certificate(
|
||||
Json(body): Json<CreateSslCertificateRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
let cert = svc.create(body.into()).await?;
|
||||
Ok((StatusCode::CREATED, Json(SslCertificateResponse::from(cert))))
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(SslCertificateResponse::from(cert)),
|
||||
))
|
||||
}
|
||||
|
||||
async fn get_ssl_certificate(
|
||||
|
||||
@@ -5,18 +5,12 @@ use axum_test::TestServer;
|
||||
use crate::routes::api::{ApiState, LocalApiState};
|
||||
use crate::service::proxy::*;
|
||||
use crate::service::proxy::{
|
||||
access_rule::MockAccessRuleService,
|
||||
cache_zone::MockCacheZoneService,
|
||||
config_inheritance::MockConfigInheritanceService,
|
||||
limit_rule::MockLimitRuleService,
|
||||
limit_zone::MockLimitZoneService,
|
||||
location_block::MockLocationBlockService,
|
||||
log_setting::MockLogSettingService,
|
||||
proxy_setting::MockProxySettingService,
|
||||
rewrite_rule::MockRewriteRuleService,
|
||||
server_block::MockServerBlockService,
|
||||
ssl_certificate::MockSslCertificateService,
|
||||
upstream::MockUpstreamService,
|
||||
access_rule::MockAccessRuleService, cache_zone::MockCacheZoneService,
|
||||
config_inheritance::MockConfigInheritanceService, limit_rule::MockLimitRuleService,
|
||||
limit_zone::MockLimitZoneService, location_block::MockLocationBlockService,
|
||||
log_setting::MockLogSettingService, proxy_setting::MockProxySettingService,
|
||||
rewrite_rule::MockRewriteRuleService, server_block::MockServerBlockService,
|
||||
ssl_certificate::MockSslCertificateService, upstream::MockUpstreamService,
|
||||
};
|
||||
|
||||
pub(crate) struct TestProxyApiBuilder {
|
||||
@@ -121,31 +115,41 @@ impl TestProxyApiBuilder {
|
||||
|
||||
pub async fn build(self) -> TestServer {
|
||||
let state = ApiState {
|
||||
proxy_service: Arc::new(self.proxy_service.unwrap_or_else(MockProxyServiceTrait::new)),
|
||||
proxy_service: Arc::new(
|
||||
self.proxy_service
|
||||
.unwrap_or_else(MockProxyServiceTrait::new),
|
||||
),
|
||||
server_block_service: Arc::new(
|
||||
self.server_block_service.unwrap_or_else(MockServerBlockService::new),
|
||||
self.server_block_service
|
||||
.unwrap_or_else(MockServerBlockService::new),
|
||||
),
|
||||
upstream_service: Arc::new(
|
||||
self.upstream_service.unwrap_or_else(MockUpstreamService::new),
|
||||
self.upstream_service
|
||||
.unwrap_or_else(MockUpstreamService::new),
|
||||
),
|
||||
location_block_service: Arc::new(
|
||||
self.location_block_service
|
||||
.unwrap_or_else(MockLocationBlockService::new),
|
||||
),
|
||||
access_rule_service: Arc::new(
|
||||
self.access_rule_service.unwrap_or_else(MockAccessRuleService::new),
|
||||
self.access_rule_service
|
||||
.unwrap_or_else(MockAccessRuleService::new),
|
||||
),
|
||||
cache_zone_service: Arc::new(
|
||||
self.cache_zone_service.unwrap_or_else(MockCacheZoneService::new),
|
||||
self.cache_zone_service
|
||||
.unwrap_or_else(MockCacheZoneService::new),
|
||||
),
|
||||
limit_rule_service: Arc::new(
|
||||
self.limit_rule_service.unwrap_or_else(MockLimitRuleService::new),
|
||||
self.limit_rule_service
|
||||
.unwrap_or_else(MockLimitRuleService::new),
|
||||
),
|
||||
limit_zone_service: Arc::new(
|
||||
self.limit_zone_service.unwrap_or_else(MockLimitZoneService::new),
|
||||
self.limit_zone_service
|
||||
.unwrap_or_else(MockLimitZoneService::new),
|
||||
),
|
||||
log_setting_service: Arc::new(
|
||||
self.log_setting_service.unwrap_or_else(MockLogSettingService::new),
|
||||
self.log_setting_service
|
||||
.unwrap_or_else(MockLogSettingService::new),
|
||||
),
|
||||
proxy_setting_service: Arc::new(
|
||||
self.proxy_setting_service
|
||||
|
||||
@@ -9,10 +9,10 @@ use axum::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::routes::api::{AppError, ApiRouter};
|
||||
use crate::routes::api::{ApiRouter, AppError};
|
||||
use crate::service::proxy::types::UpstreamConfig;
|
||||
use crate::service::proxy::upstream::{
|
||||
CreateUpstreamParams, UpstreamService, UpdateUpstreamParams,
|
||||
CreateUpstreamParams, UpdateUpstreamParams, UpstreamService,
|
||||
};
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
||||
@@ -36,7 +36,9 @@ mod tests {
|
||||
proxy_setting_service: Arc::new(proxy_setting::MockProxySettingService::new()),
|
||||
rewrite_rule_service: Arc::new(rewrite_rule::MockRewriteRuleService::new()),
|
||||
ssl_certificate_service: Arc::new(ssl_certificate::MockSslCertificateService::new()),
|
||||
config_inheritance_service: Arc::new(config_inheritance::MockConfigInheritanceService::new()),
|
||||
config_inheritance_service: Arc::new(
|
||||
config_inheritance::MockConfigInheritanceService::new(),
|
||||
),
|
||||
});
|
||||
let router = get_root_router(state).await;
|
||||
let server = TestServer::new(router);
|
||||
@@ -61,7 +63,9 @@ mod tests {
|
||||
proxy_setting_service: Arc::new(proxy_setting::MockProxySettingService::new()),
|
||||
rewrite_rule_service: Arc::new(rewrite_rule::MockRewriteRuleService::new()),
|
||||
ssl_certificate_service: Arc::new(ssl_certificate::MockSslCertificateService::new()),
|
||||
config_inheritance_service: Arc::new(config_inheritance::MockConfigInheritanceService::new()),
|
||||
config_inheritance_service: Arc::new(
|
||||
config_inheritance::MockConfigInheritanceService::new(),
|
||||
),
|
||||
});
|
||||
let router = get_root_router(state).await;
|
||||
let server = TestServer::new(router);
|
||||
|
||||
@@ -131,7 +131,7 @@ impl CertificateService for CertificateServiceImpl {
|
||||
.collect::<Vec<SanType>>(),
|
||||
san_dns
|
||||
.into_iter()
|
||||
.map(|dns| SanType::DnsName(dns))
|
||||
.map(SanType::DnsName)
|
||||
.collect::<Vec<SanType>>(),
|
||||
]
|
||||
.concat();
|
||||
|
||||
@@ -60,22 +60,18 @@ pub async fn start_master_server(
|
||||
db_connection.clone(),
|
||||
)),
|
||||
server_block_service: Arc::new(
|
||||
crate::service::proxy::server_block::ServerBlockServiceImpl::new(
|
||||
db_connection.clone(),
|
||||
),
|
||||
),
|
||||
upstream_service: Arc::new(
|
||||
crate::service::proxy::upstream::UpstreamServiceImpl::new(db_connection.clone()),
|
||||
crate::service::proxy::server_block::ServerBlockServiceImpl::new(db_connection.clone()),
|
||||
),
|
||||
upstream_service: Arc::new(crate::service::proxy::upstream::UpstreamServiceImpl::new(
|
||||
db_connection.clone(),
|
||||
)),
|
||||
location_block_service: Arc::new(
|
||||
crate::service::proxy::location_block::LocationBlockServiceImpl::new(
|
||||
db_connection.clone(),
|
||||
),
|
||||
),
|
||||
access_rule_service: Arc::new(
|
||||
crate::service::proxy::access_rule::AccessRuleServiceImpl::new(
|
||||
db_connection.clone(),
|
||||
),
|
||||
crate::service::proxy::access_rule::AccessRuleServiceImpl::new(db_connection.clone()),
|
||||
),
|
||||
cache_zone_service: Arc::new(
|
||||
crate::service::proxy::cache_zone::CacheZoneServiceImpl::new(db_connection.clone()),
|
||||
@@ -87,9 +83,7 @@ pub async fn start_master_server(
|
||||
crate::service::proxy::limit_zone::LimitZoneServiceImpl::new(db_connection.clone()),
|
||||
),
|
||||
log_setting_service: Arc::new(
|
||||
crate::service::proxy::log_setting::LogSettingServiceImpl::new(
|
||||
db_connection.clone(),
|
||||
),
|
||||
crate::service::proxy::log_setting::LogSettingServiceImpl::new(db_connection.clone()),
|
||||
),
|
||||
proxy_setting_service: Arc::new(
|
||||
crate::service::proxy::proxy_setting::ProxySettingServiceImpl::new(
|
||||
@@ -97,9 +91,7 @@ pub async fn start_master_server(
|
||||
),
|
||||
),
|
||||
rewrite_rule_service: Arc::new(
|
||||
crate::service::proxy::rewrite_rule::RewriteRuleServiceImpl::new(
|
||||
db_connection.clone(),
|
||||
),
|
||||
crate::service::proxy::rewrite_rule::RewriteRuleServiceImpl::new(db_connection.clone()),
|
||||
),
|
||||
ssl_certificate_service: Arc::new(
|
||||
crate::service::proxy::ssl_certificate::SslCertificateServiceImpl::new(
|
||||
|
||||
@@ -16,10 +16,10 @@ impl std::fmt::Display for ProxySettingRender<'_> {
|
||||
if let Some(buffer) = self.setting.buffer_size {
|
||||
writeln!(f, " proxy_buffer_size {};", buffer)?;
|
||||
}
|
||||
if self.setting.cache_enabled.unwrap_or(false) {
|
||||
if let Some(zone_name) = self.cache_zone_name {
|
||||
writeln!(f, " proxy_cache {};", zone_name)?;
|
||||
}
|
||||
if self.setting.cache_enabled.unwrap_or(false)
|
||||
&& let Some(zone_name) = self.cache_zone_name
|
||||
{
|
||||
writeln!(f, " proxy_cache {};", zone_name)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ impl std::fmt::Display for ServerBlockRender<'_> {
|
||||
writeln!(f, " listen {};", self.block.listen_port)?;
|
||||
}
|
||||
|
||||
if let Some(ref names) = self.block.server_name {
|
||||
if !names.is_empty() {
|
||||
writeln!(f, " server_name {};", names.join(" "))?;
|
||||
}
|
||||
if let Some(ref names) = self.block.server_name
|
||||
&& !names.is_empty()
|
||||
{
|
||||
writeln!(f, " server_name {};", names.join(" "))?;
|
||||
}
|
||||
|
||||
if let Some(cert) = self.ssl_cert {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::service::proxy::types::{
|
||||
ProxyServiceError, ProxyServiceResult, UpstreamConfig,
|
||||
};
|
||||
use crate::service::proxy::types::{ProxyServiceError, ProxyServiceResult, UpstreamConfig};
|
||||
|
||||
pub struct CreateUpstreamParams {
|
||||
pub config_id: Uuid,
|
||||
|
||||
@@ -12,114 +12,3 @@ pub use agent::*;
|
||||
pub mod auth;
|
||||
#[allow(ambiguous_glob_reexports)]
|
||||
pub use tonic_async_interceptor::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prost::Message;
|
||||
|
||||
use crate::agent::{
|
||||
AgentMessage, ConfigApplyStatus, ConfigStatus, DeploymentMode, Error, MasterMessage,
|
||||
MetricType, RegistrationRequest, agent_message, master_message,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn agent_message_round_trip_with_registration_payload() {
|
||||
let msg = AgentMessage {
|
||||
agent_id: "agent-1".to_string(),
|
||||
timestamp: 123,
|
||||
payload: Some(agent_message::Payload::Registration(RegistrationRequest {
|
||||
hostname: "node-1".to_string(),
|
||||
ip_address: "127.0.0.1".to_string(),
|
||||
version: "1.0.0".to_string(),
|
||||
capabilities: vec!["reload".to_string(), "metrics".to_string()],
|
||||
labels: std::collections::HashMap::from([
|
||||
("region".to_string(), "dev".to_string()),
|
||||
("tier".to_string(), "edge".to_string()),
|
||||
]),
|
||||
deployment_mode: DeploymentMode::Standalone as i32,
|
||||
})),
|
||||
};
|
||||
|
||||
let encoded = msg.encode_to_vec();
|
||||
let decoded = AgentMessage::decode(encoded.as_slice());
|
||||
assert!(decoded.is_ok());
|
||||
let decoded = decoded.unwrap_or_else(|_| unreachable!());
|
||||
|
||||
assert_eq!(decoded.agent_id, "agent-1");
|
||||
assert_eq!(decoded.timestamp, 123);
|
||||
|
||||
match decoded.payload {
|
||||
Some(agent_message::Payload::Registration(payload)) => {
|
||||
assert_eq!(payload.hostname, "node-1");
|
||||
assert_eq!(payload.ip_address, "127.0.0.1");
|
||||
assert_eq!(payload.version, "1.0.0");
|
||||
assert_eq!(payload.capabilities.len(), 2);
|
||||
assert_eq!(payload.labels.get("region"), Some(&"dev".to_string()));
|
||||
assert_eq!(payload.deployment_mode, DeploymentMode::Standalone as i32);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn master_message_round_trip_with_error_payload() {
|
||||
let msg = MasterMessage {
|
||||
timestamp: 999,
|
||||
payload: Some(master_message::Payload::Error(Error {
|
||||
code: "E_CONFIG_INVALID".to_string(),
|
||||
message: "invalid config".to_string(),
|
||||
details: std::collections::HashMap::from([
|
||||
("file".to_string(), "site.conf".to_string()),
|
||||
("line".to_string(), "42".to_string()),
|
||||
]),
|
||||
})),
|
||||
};
|
||||
|
||||
let encoded = msg.encode_to_vec();
|
||||
let decoded = MasterMessage::decode(encoded.as_slice());
|
||||
assert!(decoded.is_ok());
|
||||
let decoded = decoded.unwrap_or_else(|_| unreachable!());
|
||||
|
||||
assert_eq!(decoded.timestamp, 999);
|
||||
match decoded.payload {
|
||||
Some(master_message::Payload::Error(err)) => {
|
||||
assert_eq!(err.code, "E_CONFIG_INVALID");
|
||||
assert_eq!(err.message, "invalid config");
|
||||
assert_eq!(err.details.get("line"), Some(&"42".to_string()));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enum_integer_mappings_are_stable() {
|
||||
assert_eq!(DeploymentMode::Unspecified as i32, 0);
|
||||
assert_eq!(DeploymentMode::DockerSidecar as i32, 1);
|
||||
assert_eq!(DeploymentMode::KubernetesSidecar as i32, 2);
|
||||
assert_eq!(DeploymentMode::Standalone as i32, 3);
|
||||
|
||||
assert_eq!(ConfigApplyStatus::Unspecified as i32, 0);
|
||||
assert_eq!(ConfigApplyStatus::Pending as i32, 1);
|
||||
assert_eq!(ConfigApplyStatus::Validating as i32, 2);
|
||||
assert_eq!(ConfigApplyStatus::Applying as i32, 3);
|
||||
assert_eq!(ConfigApplyStatus::Success as i32, 4);
|
||||
assert_eq!(ConfigApplyStatus::Failed as i32, 5);
|
||||
assert_eq!(ConfigApplyStatus::RolledBack as i32, 6);
|
||||
|
||||
assert_eq!(MetricType::Unspecified as i32, 0);
|
||||
assert_eq!(MetricType::Gauge as i32, 1);
|
||||
assert_eq!(MetricType::Counter as i32, 2);
|
||||
assert_eq!(MetricType::Histogram as i32, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_status_defaults_are_proto3_zero_values() {
|
||||
let status = ConfigStatus::default();
|
||||
|
||||
assert_eq!(status.config_id, "");
|
||||
assert_eq!(status.version, 0);
|
||||
assert_eq!(status.status, ConfigApplyStatus::Unspecified as i32);
|
||||
assert_eq!(status.error_message, "");
|
||||
assert_eq!(status.applied_at, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user