feat: update monitoring and config reload
* monitoring: added read of current config * config: get config by single url
This commit is contained in:
parent
3fb83f7f77
commit
05ef0cd339
116
src/config.rs
116
src/config.rs
@ -28,6 +28,7 @@ pub struct Context {
|
|||||||
pub flags: Flags,
|
pub flags: Flags,
|
||||||
pub sas: HashMap<String, SetMap>,
|
pub sas: HashMap<String, SetMap>,
|
||||||
pub hashwd: HashMap<String, WatchDescriptor>,
|
pub hashwd: HashMap<String, WatchDescriptor>,
|
||||||
|
pub reloadinterval: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -35,7 +36,7 @@ pub struct SetMap {
|
|||||||
pub filename: String,
|
pub filename: String,
|
||||||
pub fullpath: String,
|
pub fullpath: String,
|
||||||
pub regex: Regex,
|
pub regex: Regex,
|
||||||
pub set: Set,
|
pub set: SetCfg,
|
||||||
pub watchedfiles: HashMap<String, u64>,
|
pub watchedfiles: HashMap<String, u64>,
|
||||||
pub wd: WatchDescriptor,
|
pub wd: WatchDescriptor,
|
||||||
}
|
}
|
||||||
@ -64,6 +65,7 @@ impl Context {
|
|||||||
sas: HashMap::new(),
|
sas: HashMap::new(),
|
||||||
blocklist: HashMap::new(),
|
blocklist: HashMap::new(),
|
||||||
hashwd: HashMap::new(),
|
hashwd: HashMap::new(),
|
||||||
|
reloadinterval: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
print!("Loading config ... ");
|
print!("Loading config ... ");
|
||||||
@ -282,7 +284,7 @@ impl Context {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub sets: HashMap<String, Set>,
|
pub sets: HashMap<String, SetCfg>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub trustnets: Vec<String>,
|
pub trustnets: Vec<String>,
|
||||||
pub ws: HashMap<String, WebSocketCfg>,
|
pub ws: HashMap<String, WebSocketCfg>,
|
||||||
@ -294,7 +296,7 @@ impl Config {
|
|||||||
Self {
|
Self {
|
||||||
sets: HashMap::from([
|
sets: HashMap::from([
|
||||||
("smtp".to_string(),
|
("smtp".to_string(),
|
||||||
Set {
|
SetCfg {
|
||||||
src: "smtp".to_string(),
|
src: "smtp".to_string(),
|
||||||
filename: "mail.log".to_string(),
|
filename: "mail.log".to_string(),
|
||||||
regex: "(SASL LOGIN authentication failed)".to_string(),
|
regex: "(SASL LOGIN authentication failed)".to_string(),
|
||||||
@ -303,7 +305,7 @@ impl Config {
|
|||||||
tryfail: 5,
|
tryfail: 5,
|
||||||
}),
|
}),
|
||||||
("ssh".to_string(),
|
("ssh".to_string(),
|
||||||
Set {
|
SetCfg {
|
||||||
src: "ssh".to_string(),
|
src: "ssh".to_string(),
|
||||||
filename: "auth.log".to_string(),
|
filename: "auth.log".to_string(),
|
||||||
regex: "(Invalid user|BREAK|not allowed because|no matching key exchange method found)".to_string(),
|
regex: "(Invalid user|BREAK|not allowed because|no matching key exchange method found)".to_string(),
|
||||||
@ -312,7 +314,7 @@ impl Config {
|
|||||||
tryfail: 5,
|
tryfail: 5,
|
||||||
},),
|
},),
|
||||||
("http".to_string(),
|
("http".to_string(),
|
||||||
Set {
|
SetCfg {
|
||||||
src: "http".to_string(),
|
src: "http".to_string(),
|
||||||
filename: "".to_string(),
|
filename: "".to_string(),
|
||||||
regex: "(anonymousfox.co)".to_string(),
|
regex: "(anonymousfox.co)".to_string(),
|
||||||
@ -321,7 +323,7 @@ impl Config {
|
|||||||
tryfail: 5,
|
tryfail: 5,
|
||||||
},),
|
},),
|
||||||
("openvpn".to_string(),
|
("openvpn".to_string(),
|
||||||
Set {
|
SetCfg {
|
||||||
src: "openvpn".to_string(),
|
src: "openvpn".to_string(),
|
||||||
filename: "status".to_string(),
|
filename: "status".to_string(),
|
||||||
regex: "(UNDEF)".to_string(),
|
regex: "(UNDEF)".to_string(),
|
||||||
@ -350,96 +352,40 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn load(&mut self, server: &String) -> Result<(), ReqError> {
|
pub async fn load(&mut self, server: &String) -> Result<(), ReqError> {
|
||||||
self.get_global_config(server).await?;
|
self.get_config(server).await?;
|
||||||
self.get_trustnets(server).await?;
|
|
||||||
self.get_sets(server).await?;
|
|
||||||
self.get_ws_config(server).await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_global_config(&mut self, server: &String) -> Result<(), ReqError> {
|
async fn get_config(&mut self, server: &String) -> Result<(), ReqError> {
|
||||||
let resp: Result<Response, ReqError> =
|
|
||||||
httpclient().get(format!("{server}/config")).send().await;
|
|
||||||
let req = match resp {
|
|
||||||
Ok(re) => re,
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
};
|
|
||||||
let data: HashMap<String, GlobalConfig> = match req.json::<Vec<GlobalConfig>>().await {
|
|
||||||
Ok(res) => {
|
|
||||||
let mut out: HashMap<String, GlobalConfig> = HashMap::new();
|
|
||||||
res.into_iter().map(|x| x).for_each(|x| {
|
|
||||||
out.insert(x.key.to_string(), x);
|
|
||||||
});
|
|
||||||
out
|
|
||||||
}
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
};
|
|
||||||
let key = "".to_string();
|
|
||||||
self.api = data
|
|
||||||
.get(&key.to_string())
|
|
||||||
.unwrap_or(&GlobalConfig {
|
|
||||||
key: "api".to_string(),
|
|
||||||
value: "127.0.0.1:8060".to_string(),
|
|
||||||
})
|
|
||||||
.value
|
|
||||||
.clone();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_trustnets(&mut self, server: &String) -> Result<(), ReqError> {
|
|
||||||
let resp: Result<Response, ReqError> = httpclient()
|
let resp: Result<Response, ReqError> = httpclient()
|
||||||
.get(format!("{server}/config/trustlist"))
|
.get(format!("{server}/config?v=2"))
|
||||||
.send()
|
.send()
|
||||||
.await;
|
.await;
|
||||||
let req = match resp {
|
let req = match resp {
|
||||||
Ok(re) => re,
|
Ok(re) => re,
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
let data: Vec<String> = match req.json::<Vec<String>>().await {
|
let data: GlobalConfigV2 = match req.json::<GlobalConfigV2>().await {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
self.trustnets = data;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_sets(&mut self, server: &String) -> Result<(), ReqError> {
|
for d in data.sets {
|
||||||
let resp: Result<Response, ReqError> = httpclient()
|
|
||||||
.get(format!("{server}/config/sets"))
|
|
||||||
.send()
|
|
||||||
.await;
|
|
||||||
let req = match resp {
|
|
||||||
Ok(re) => re,
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
};
|
|
||||||
let data: Vec<Set> = match req.json::<Vec<Set>>().await {
|
|
||||||
Ok(res) => res,
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
};
|
|
||||||
for d in data {
|
|
||||||
self.sets.insert(d.src.clone(), d);
|
self.sets.insert(d.src.clone(), d);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_ws_config(&mut self, server: &String) -> Result<(), ReqError> {
|
self.trustnets = data.trustlists;
|
||||||
let resp: Result<Response, ReqError> =
|
|
||||||
httpclient().get(format!("{server}/config/ws")).send().await;
|
data.ws.into_iter().map(|x| x).for_each(|x| {
|
||||||
let req = match resp {
|
self.ws.insert(x.t.to_string(), x);
|
||||||
Ok(re) => re,
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
};
|
|
||||||
let data: HashMap<String, WebSocketCfg> = match req.json::<Vec<WebSocketCfg>>().await {
|
|
||||||
Ok(res) => {
|
|
||||||
let mut out: HashMap<String, WebSocketCfg> = HashMap::new();
|
|
||||||
res.into_iter().map(|x| x).for_each(|x| {
|
|
||||||
out.insert(x.t.to_string(), x);
|
|
||||||
});
|
});
|
||||||
out
|
|
||||||
}
|
self.api = data
|
||||||
Err(err) => return Err(err),
|
.cfg
|
||||||
};
|
.get(&"api".to_string())
|
||||||
self.ws = data;
|
.unwrap_or(&self.api)
|
||||||
|
.clone();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,13 +454,15 @@ pub fn httpclient() -> Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct GlobalConfig {
|
pub struct GlobalConfigV2 {
|
||||||
pub key: String,
|
pub cfg: HashMap<String, String>,
|
||||||
pub value: String,
|
pub sets: Vec<SetCfg>,
|
||||||
|
pub trustlists: Vec<String>,
|
||||||
|
pub ws: Vec<WebSocketCfg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct Set {
|
pub struct SetCfg {
|
||||||
pub src: String,
|
pub src: String,
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
pub regex: String,
|
pub regex: String,
|
||||||
@ -543,13 +491,13 @@ pub struct URL {
|
|||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Set {
|
impl PartialEq for SetCfg {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.src == other.src
|
self.src == other.src
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for Set {
|
impl Hash for SetCfg {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.src.hash(state);
|
self.src.hash(state);
|
||||||
}
|
}
|
||||||
|
@ -24,20 +24,27 @@ pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
|
|||||||
loop {
|
loop {
|
||||||
match listener.accept().await {
|
match listener.accept().await {
|
||||||
Ok((stream, _addr)) => {
|
Ok((stream, _addr)) => {
|
||||||
//let mut buf = [0; 1024];
|
stream.readable().await.unwrap();
|
||||||
let data;
|
let (reader, mut writer) = stream.into_split();
|
||||||
{
|
let mut buf: [u8; 16] = [0; 16];
|
||||||
let ctx = ctxarc.read().await;
|
|
||||||
data = serde_json::to_string(&ctx.blocklist);
|
|
||||||
}
|
|
||||||
|
|
||||||
match data {
|
match reader.try_read(&mut buf) {
|
||||||
Ok(dt) => {
|
Ok(_) => {}
|
||||||
let (_reader, mut writer) = stream.into_split();
|
Err(e) => {
|
||||||
match writer.write_all(format!("{dt}").as_bytes()).await {
|
println!("error: {}", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let msg = match String::from_utf8(buf.to_vec()) {
|
||||||
|
Ok(o) => o.trim_matches(char::from(0)).trim().to_string(),
|
||||||
|
Err(_) => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = format_result(&ctxarc, msg.as_str()).await;
|
||||||
|
|
||||||
|
match writer.write_all(format!("{res}").as_bytes()).await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("{err}");
|
println!("ee {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,11 +53,17 @@ pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
println!("couldn't get client: {}", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn format_result(ctxarc: &Arc<RwLock<Context>>, mode: &str) -> String {
|
||||||
|
let data;
|
||||||
|
let ctx = ctxarc.read().await;
|
||||||
|
match mode {
|
||||||
|
"cfg" => data = serde_json::to_string(&ctx.cfg).unwrap(),
|
||||||
|
"blocklist" => data = serde_json::to_string(&ctx.blocklist).unwrap(),
|
||||||
|
_ => data = serde_json::to_string(&ctx.blocklist).unwrap(),
|
||||||
|
};
|
||||||
|
data
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user