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