mirror of
https://github.com/sadoyan/aralez.git
synced 2026-04-30 23:08:40 +08:00
Async apply of config via API
This commit is contained in:
@@ -40,7 +40,6 @@ pub async fn load_configuration(d: &str, kind: &str) -> (Option<Configuration>,
|
|||||||
return (None, e.to_string());
|
return (None, e.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut toreturn = Configuration::default();
|
let mut toreturn = Configuration::default();
|
||||||
|
|
||||||
populate_headers_and_auth(&mut toreturn, &parsed).await;
|
populate_headers_and_auth(&mut toreturn, &parsed).await;
|
||||||
@@ -69,7 +68,6 @@ pub async fn load_configuration(d: &str, kind: &str) -> (Option<Configuration>,
|
|||||||
async fn populate_headers_and_auth(config: &mut Configuration, parsed: &Config) {
|
async fn populate_headers_and_auth(config: &mut Configuration, parsed: &Config) {
|
||||||
let mut ch: Vec<(Arc<str>, Arc<str>)> = Vec::new();
|
let mut ch: Vec<(Arc<str>, Arc<str>)> = Vec::new();
|
||||||
ch.push((Arc::from("Server"), Arc::from("Aralez")));
|
ch.push((Arc::from("Server"), Arc::from("Aralez")));
|
||||||
// println!("{:?}", &parsed.client_headers);
|
|
||||||
if let Some(headers) = &parsed.client_headers {
|
if let Some(headers) = &parsed.client_headers {
|
||||||
for header in headers {
|
for header in headers {
|
||||||
if let Some((key, val)) = header.split_once(':') {
|
if let Some((key, val)) = header.split_once(':') {
|
||||||
|
|||||||
@@ -12,14 +12,16 @@ pub struct GetHostsReturHeaders {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait GetHost {
|
pub trait GetHost {
|
||||||
// fn get_host<'a>(&self, peer: &str, path: &str, backend_id: Option<&str>) -> Option<&'a InnerMap>;
|
|
||||||
|
|
||||||
fn get_host(&self, peer: &str, path: &str, backend_id: Option<&str>) -> Option<Arc<InnerMap>>;
|
fn get_host(&self, peer: &str, path: &str, backend_id: Option<&str>) -> Option<Arc<InnerMap>>;
|
||||||
|
|
||||||
fn get_header(&self, peer: &str, path: &str) -> Option<GetHostsReturHeaders>;
|
fn get_header(&self, peer: &str, path: &str) -> Option<GetHostsReturHeaders>;
|
||||||
|
// fn get_upstreams(&self) -> Arc<UpstreamsDashMap>;
|
||||||
}
|
}
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl GetHost for LB {
|
impl GetHost for LB {
|
||||||
|
// fn get_upstreams(&self) -> Arc<UpstreamsDashMap> {
|
||||||
|
// self.ump_full.clone()
|
||||||
|
// }
|
||||||
fn get_host(&self, peer: &str, path: &str, backend_id: Option<&str>) -> Option<Arc<InnerMap>> {
|
fn get_host(&self, peer: &str, path: &str, backend_id: Option<&str>) -> Option<Arc<InnerMap>> {
|
||||||
if let Some(b) = backend_id {
|
if let Some(b) = backend_id {
|
||||||
if let Some(bb) = self.ump_byid.get(b) {
|
if let Some(bb) = self.ump_byid.get(b) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::utils::discovery::APIUpstreamProvider;
|
use crate::utils::discovery::APIUpstreamProvider;
|
||||||
use crate::utils::structs::Configuration;
|
use crate::utils::structs::{Config, Configuration};
|
||||||
use axum::body::Body;
|
use axum::body::Body;
|
||||||
use axum::extract::{Query, State};
|
use axum::extract::{Query, State};
|
||||||
use axum::http::{Response, StatusCode};
|
use axum::http::{Response, StatusCode};
|
||||||
@@ -82,37 +82,41 @@ pub async fn run_server(config: &APIUpstreamProvider, mut to_return: Sender<Conf
|
|||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn conf(State(mut st): State<AppState>, Query(params): Query<HashMap<String, String>>, content: String) -> impl IntoResponse {
|
async fn conf(State(st): State<AppState>, Query(params): Query<HashMap<String, String>>, content: String) -> impl IntoResponse {
|
||||||
if !st.config_api_enabled {
|
if !st.config_api_enabled {
|
||||||
return Response::builder()
|
return Response::builder().status(StatusCode::FORBIDDEN).body(Body::from("Config API is disabled !\n")).unwrap();
|
||||||
.status(StatusCode::FORBIDDEN)
|
|
||||||
.body(Body::from("Config remote API is disabled !\n"))
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(s) = params.get("key") {
|
if let Some(s) = params.get("key") {
|
||||||
if s.to_owned() == st.master_key {
|
if s.to_owned() == st.master_key {
|
||||||
let sl = crate::utils::parceyaml::load_configuration(content.as_str(), "content").await;
|
let strcontent = content.as_str();
|
||||||
if let Some(serverlist) = sl.0 {
|
let parsed = serde_yaml::from_str::<Config>(strcontent);
|
||||||
let r = st.config_sender.send(serverlist).await;
|
match parsed {
|
||||||
match r {
|
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
return Response::builder().status(StatusCode::OK).body(Body::from("Config, conf file, updated!\n")).unwrap();
|
if let Some(s) = params.get("key") {
|
||||||
}
|
if s.to_owned() == st.master_key {
|
||||||
Err(e) => {
|
let _ = tokio::spawn(async move { apply_config(content.as_str(), st).await });
|
||||||
let error_msg = format!("Failed to send configuration: {}\n", e);
|
return Response::builder().status(StatusCode::OK).body(Body::from("Accepted! Applying in background\n")).unwrap();
|
||||||
return Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR).body(Body::from(error_msg)).unwrap();
|
}
|
||||||
|
}
|
||||||
|
return Response::builder().status(StatusCode::FORBIDDEN).body(Body::from("Access Denied !\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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
let err: String = "Error parsing config file: ".to_owned() + sl.1.as_str() + "\n";
|
|
||||||
return Response::builder().status(StatusCode::BAD_GATEWAY).body(Body::from(err)).unwrap();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Response::builder().status(StatusCode::FORBIDDEN).body(Body::from("Access Denied !\n")).unwrap()
|
Response::builder().status(StatusCode::FORBIDDEN).body(Body::from("Access Denied !\n")).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn apply_config(content: &str, mut st: AppState) {
|
||||||
|
let sl = crate::utils::parceyaml::load_configuration(content, "content").await;
|
||||||
|
if let Some(serverlist) = sl.0 {
|
||||||
|
let _ = st.config_sender.send(serverlist).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn jwt_gen(State(state): State<AppState>, Json(payload): Json<InputKey>) -> (StatusCode, Json<OutToken>) {
|
async fn jwt_gen(State(state): State<AppState>, Json(payload): Json<InputKey>) -> (StatusCode, Json<OutToken>) {
|
||||||
if payload.master_key == state.master_key {
|
if payload.master_key == state.master_key {
|
||||||
let now = SystemTime::now() + Duration::from_secs(payload.valid * 60);
|
let now = SystemTime::now() + Duration::from_secs(payload.valid * 60);
|
||||||
@@ -142,7 +146,6 @@ async fn jwt_gen(State(state): State<AppState>, Json(payload): Json<InputKey>) -
|
|||||||
async fn metrics() -> impl IntoResponse {
|
async fn metrics() -> impl IntoResponse {
|
||||||
let metric_families = gather();
|
let metric_families = gather();
|
||||||
let encoder = TextEncoder::new();
|
let encoder = TextEncoder::new();
|
||||||
|
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
if let Err(e) = encoder.encode(&metric_families, &mut buffer) {
|
if let Err(e) = encoder.encode(&metric_families, &mut buffer) {
|
||||||
// encoding error fallback
|
// encoding error fallback
|
||||||
|
|||||||
Reference in New Issue
Block a user