Master, multi slave cluster

This commit is contained in:
Ara Sadoyan
2026-10-16 17:57:33 +02:00
parent cdeb120a39
commit 0ee39559ca
11 changed files with 479 additions and 112 deletions
+5
View File
@@ -34,6 +34,7 @@ pub struct LB {
pub config: Arc<AppConfig>,
pub extraparams: Arc<ArcSwap<Extraparams>>,
pub cache_enabled: bool,
pub master_server: bool,
}
pub struct Context {
@@ -105,6 +106,10 @@ impl ProxyHttp for LB {
}
async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result<bool> {
if self.master_server {
let _ = session.respond_error(400).await;
return Ok(true);
};
ACTIVE_SESSIONS.inc();
let hostname = return_header_host_from_upstream(session, &self.ump_upst);
_ctx.hostname = hostname;
+2
View File
@@ -34,6 +34,7 @@ pub fn run() {
let file = parameters.conf.clone().unwrap();
let maincfg = crate::utils::parceyaml::parce_main_config(file.as_str());
let master_server = maincfg.cluster_member.as_deref() == Some("master");
let cache_enabled = maincfg.cache_size_mb.is_some();
CACHE_TTL.set(maincfg.cache_ttl.unwrap_or(60)).unwrap();
if let Some(size) = maincfg.cache_size_mb {
@@ -70,6 +71,7 @@ pub fn run() {
server_headers: sh_config,
extraparams: ec_config,
cache_enabled,
master_server,
};
let grade = cfg.proxy_tls_grade.clone().unwrap_or("medium".to_string());
+52 -1
View File
@@ -1,6 +1,7 @@
use crate::auth::jwt::Claims;
use crate::ingress::APIUpstreamProvider;
use crate::tls::acme::http01::{acme_create, acme_order, http01_challenge};
use crate::utils::lazylock::NODE_STATUS;
use crate::utils::metrics::{MEMORY_USAGE, OPEN_FILES, get_memory_usage, get_open_files};
use crate::utils::tools::{upstreams_liveness_json, upstreams_to_json};
use crate::utils::types::{Config, Configuration, UpstreamsDashMap};
@@ -63,6 +64,7 @@ pub async fn run_server(config: &APIUpstreamProvider, mut to_return: mpsc::Sende
.route("/acme_order/{*domain}", any(acme_order))
.route("/.well-known/acme-challenge/{*token}", any(http01_challenge))
.route("/conf", post(conf))
.route("/workerconf", post(workerconf))
.route("/metrics", get(metrics))
.route("/status", get(status))
.with_state(app_state);
@@ -84,7 +86,8 @@ pub async fn run_server(config: &APIUpstreamProvider, mut to_return: mpsc::Sende
let listener = port_is_available("Config API", &config.address).await;
info!("Starting the API server on: {}", config.address);
let api_server = tokio::spawn(async move { axum::serve(listener, app).await.unwrap() });
// let api_server = tokio::spawn(async move { axum::serve(listener, app).await.unwrap() });
let api_server = tokio::spawn(async move { axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await.unwrap() });
let (tx, mut rx) = mpsc::channel(1);
std::thread::spawn(move || {
@@ -124,6 +127,54 @@ async fn conf(State(st): State<AppState>, Query(params): Query<HashMap<String, S
}
}
use axum::extract::ConnectInfo;
use axum::http::HeaderMap;
async fn workerconf(State(st): State<AppState>, ConnectInfo(addr): ConnectInfo<SocketAddr>, headers: HeaderMap, content: String) -> impl IntoResponse {
let api_key = headers.get("API-KEY").and_then(|v| v.to_str().ok());
if api_key != st.master_key.as_deref() {
warn!("Unauthorised access to workerconf endpoint from {}", addr.ip());
return Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body(Body::from("Unauthorized: Invalid API-KEY\n"))
.unwrap();
}
if let Some(member) = NODE_STATUS.get() {
if let Some(mbr) = member.as_ref() {
match mbr.as_ref() {
"worker" => {
info!("Accepted new config from master server {}", addr.ip());
let strcontent = content.as_str();
let parsed = noyalib::from_str::<Config>(strcontent);
match parsed {
Ok(_) => {
tokio::spawn(async move { apply_config(content.as_str(), st, true).await });
return Response::builder().status(StatusCode::OK).body(Body::from("Accepted! Applying in background\n")).unwrap();
}
Err(err) => {
error!("Failed to parse upstreams file: {}", err);
return Response::builder().status(StatusCode::BAD_GATEWAY).body(Body::from(format!("Failed: {}\n", err))).unwrap();
}
}
}
_ => {
return Response::builder()
.status(StatusCode::BAD_GATEWAY)
.body(Body::from("Node is not running on worker mode !\n"))
.unwrap();
}
}
}
return Response::builder()
.status(StatusCode::BAD_GATEWAY)
.body(Body::from("Node is not running on worker mode !\n"))
.unwrap();
}
Response::builder()
.status(StatusCode::BAD_GATEWAY)
.body(Body::from("Node is not running on worker mode !\n"))
.unwrap()
}
async fn apply_config(content: &str, st: AppState, save: bool) {
let sl = crate::utils::parceyaml::load_configuration(content, "content").await;
if let Some(serverlist) = sl.0 {