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 sas: HashMap<String, SetMap>,
|
||||
pub hashwd: HashMap<String, WatchDescriptor>,
|
||||
pub reloadinterval: isize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -35,7 +36,7 @@ pub struct SetMap {
|
||||
pub filename: String,
|
||||
pub fullpath: String,
|
||||
pub regex: Regex,
|
||||
pub set: Set,
|
||||
pub set: SetCfg,
|
||||
pub watchedfiles: HashMap<String, u64>,
|
||||
pub wd: WatchDescriptor,
|
||||
}
|
||||
@ -64,6 +65,7 @@ impl Context {
|
||||
sas: HashMap::new(),
|
||||
blocklist: HashMap::new(),
|
||||
hashwd: HashMap::new(),
|
||||
reloadinterval: 5,
|
||||
};
|
||||
|
||||
print!("Loading config ... ");
|
||||
@ -282,7 +284,7 @@ impl Context {
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Config {
|
||||
pub sets: HashMap<String, Set>,
|
||||
pub sets: HashMap<String, SetCfg>,
|
||||
#[serde(skip_serializing)]
|
||||
pub trustnets: Vec<String>,
|
||||
pub ws: HashMap<String, WebSocketCfg>,
|
||||
@ -294,7 +296,7 @@ impl Config {
|
||||
Self {
|
||||
sets: HashMap::from([
|
||||
("smtp".to_string(),
|
||||
Set {
|
||||
SetCfg {
|
||||
src: "smtp".to_string(),
|
||||
filename: "mail.log".to_string(),
|
||||
regex: "(SASL LOGIN authentication failed)".to_string(),
|
||||
@ -303,7 +305,7 @@ impl Config {
|
||||
tryfail: 5,
|
||||
}),
|
||||
("ssh".to_string(),
|
||||
Set {
|
||||
SetCfg {
|
||||
src: "ssh".to_string(),
|
||||
filename: "auth.log".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,
|
||||
},),
|
||||
("http".to_string(),
|
||||
Set {
|
||||
SetCfg {
|
||||
src: "http".to_string(),
|
||||
filename: "".to_string(),
|
||||
regex: "(anonymousfox.co)".to_string(),
|
||||
@ -321,7 +323,7 @@ impl Config {
|
||||
tryfail: 5,
|
||||
},),
|
||||
("openvpn".to_string(),
|
||||
Set {
|
||||
SetCfg {
|
||||
src: "openvpn".to_string(),
|
||||
filename: "status".to_string(),
|
||||
regex: "(UNDEF)".to_string(),
|
||||
@ -350,96 +352,40 @@ impl Config {
|
||||
}
|
||||
|
||||
pub async fn load(&mut self, server: &String) -> Result<(), ReqError> {
|
||||
self.get_global_config(server).await?;
|
||||
self.get_trustnets(server).await?;
|
||||
self.get_sets(server).await?;
|
||||
self.get_ws_config(server).await?;
|
||||
self.get_config(server).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_global_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> {
|
||||
async fn get_config(&mut self, server: &String) -> Result<(), ReqError> {
|
||||
let resp: Result<Response, ReqError> = httpclient()
|
||||
.get(format!("{server}/config/trustlist"))
|
||||
.get(format!("{server}/config?v=2"))
|
||||
.send()
|
||||
.await;
|
||||
let req = match resp {
|
||||
Ok(re) => re,
|
||||
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,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
self.trustnets = data;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_sets(&mut self, server: &String) -> Result<(), ReqError> {
|
||||
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 {
|
||||
for d in data.sets {
|
||||
self.sets.insert(d.src.clone(), d);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_ws_config(&mut self, server: &String) -> Result<(), ReqError> {
|
||||
let resp: Result<Response, ReqError> =
|
||||
httpclient().get(format!("{server}/config/ws")).send().await;
|
||||
let req = match resp {
|
||||
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);
|
||||
self.trustnets = data.trustlists;
|
||||
|
||||
data.ws.into_iter().map(|x| x).for_each(|x| {
|
||||
self.ws.insert(x.t.to_string(), x);
|
||||
});
|
||||
out
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
self.ws = data;
|
||||
|
||||
self.api = data
|
||||
.cfg
|
||||
.get(&"api".to_string())
|
||||
.unwrap_or(&self.api)
|
||||
.clone();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -508,13 +454,15 @@ pub fn httpclient() -> Client {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct GlobalConfig {
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
pub struct GlobalConfigV2 {
|
||||
pub cfg: HashMap<String, String>,
|
||||
pub sets: Vec<SetCfg>,
|
||||
pub trustlists: Vec<String>,
|
||||
pub ws: Vec<WebSocketCfg>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Set {
|
||||
pub struct SetCfg {
|
||||
pub src: String,
|
||||
pub filename: String,
|
||||
pub regex: String,
|
||||
@ -543,13 +491,13 @@ pub struct URL {
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl PartialEq for Set {
|
||||
impl PartialEq for SetCfg {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.src == other.src
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Set {
|
||||
impl Hash for SetCfg {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.src.hash(state);
|
||||
}
|
||||
|
@ -24,20 +24,27 @@ pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
|
||||
loop {
|
||||
match listener.accept().await {
|
||||
Ok((stream, _addr)) => {
|
||||
//let mut buf = [0; 1024];
|
||||
let data;
|
||||
{
|
||||
let ctx = ctxarc.read().await;
|
||||
data = serde_json::to_string(&ctx.blocklist);
|
||||
}
|
||||
stream.readable().await.unwrap();
|
||||
let (reader, mut writer) = stream.into_split();
|
||||
let mut buf: [u8; 16] = [0; 16];
|
||||
|
||||
match data {
|
||||
Ok(dt) => {
|
||||
let (_reader, mut writer) = stream.into_split();
|
||||
match writer.write_all(format!("{dt}").as_bytes()).await {
|
||||
match reader.try_read(&mut buf) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
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(_) => {}
|
||||
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(())
|
||||
}
|
||||
|
||||
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