136 lines
3.9 KiB
136 lines
3.9 KiB
use serde_json::{from_str, to_value, Value}; |
|
use structopt::StructOpt; |
|
use u_lib::{ |
|
api::HttpClient, |
|
jobs::join_payload, |
|
messaging::AsMsg, |
|
models::{Agent, AssignedJob, RawJob}, |
|
types::Id, |
|
types::PanelResult, |
|
UError, UResult, |
|
}; |
|
|
|
#[derive(StructOpt, Debug)] |
|
pub struct Args { |
|
#[structopt(subcommand)] |
|
cmd: Cmd, |
|
} |
|
|
|
#[derive(StructOpt, Debug)] |
|
enum Cmd { |
|
Agents(RUD), |
|
Jobs(JobCRUD), |
|
Map(JobMapCRUD), |
|
Ping, |
|
Serve, |
|
} |
|
|
|
#[derive(StructOpt, Debug)] |
|
enum JobCRUD { |
|
Create { |
|
job: String, |
|
}, |
|
#[structopt(flatten)] |
|
RUD(RUD), |
|
} |
|
|
|
#[derive(StructOpt, Debug)] |
|
enum JobCmd { |
|
#[structopt(external_subcommand)] |
|
Cmd(Vec<String>), |
|
} |
|
|
|
#[derive(StructOpt, Debug)] |
|
enum JobMapCRUD { |
|
Create { |
|
#[structopt(parse(try_from_str = parse_uuid))] |
|
agent_id: Id, |
|
|
|
job_idents: Vec<String>, |
|
}, |
|
#[structopt(flatten)] |
|
RUD(RUD), |
|
} |
|
|
|
#[derive(StructOpt, Debug)] |
|
enum RUD { |
|
Read { |
|
#[structopt(parse(try_from_str = parse_uuid))] |
|
id: Option<Id>, |
|
}, |
|
Update { |
|
item: String, |
|
}, |
|
Delete { |
|
#[structopt(parse(try_from_str = parse_uuid))] |
|
id: Id, |
|
}, |
|
} |
|
|
|
fn parse_uuid(src: &str) -> Result<Id, String> { |
|
Id::parse_str(src).map_err(|e| e.to_string()) |
|
} |
|
|
|
pub fn into_value<M: AsMsg>(data: M) -> Value { |
|
to_value(data).unwrap() |
|
} |
|
|
|
pub async fn process_cmd(client: HttpClient, args: Args) -> PanelResult<Value> { |
|
let catcher: UResult<Value> = (|| async { |
|
Ok(match args.cmd { |
|
Cmd::Agents(action) => match action { |
|
RUD::Read { id } => into_value(client.get_agents(id).await?), |
|
RUD::Update { item } => { |
|
let agent = from_str::<Agent>(&item)?; |
|
into_value(client.update_agent(&agent).await?) |
|
} |
|
RUD::Delete { id } => into_value(client.del(id).await?), |
|
}, |
|
Cmd::Jobs(action) => match action { |
|
JobCRUD::Create { job } => { |
|
let raw_job = from_str::<RawJob>(&job)?; |
|
let job = raw_job.validated()?; |
|
let fat_job = join_payload(job)?; |
|
|
|
into_value(client.upload_jobs(&fat_job).await?) |
|
} |
|
JobCRUD::RUD(RUD::Read { id }) => match id { |
|
//todo: use vec not to break frontend api, possibly refactor later |
|
Some(id) => into_value(vec![client.get_job(id, false).await?]), |
|
None => into_value(client.get_jobs().await?), |
|
}, |
|
JobCRUD::RUD(RUD::Update { item }) => { |
|
let raw_job = from_str::<RawJob>(&item)?; |
|
let job = raw_job.validated()?; |
|
into_value(client.update_job(&join_payload(job)?).await?) |
|
} |
|
JobCRUD::RUD(RUD::Delete { id }) => into_value(client.del(id).await?), |
|
}, |
|
Cmd::Map(action) => match action { |
|
JobMapCRUD::Create { |
|
agent_id, |
|
job_idents, |
|
} => into_value(client.set_jobs(agent_id, &job_idents).await?), |
|
JobMapCRUD::RUD(RUD::Read { id }) => into_value(client.get_agent_jobs(id).await?), |
|
JobMapCRUD::RUD(RUD::Update { item }) => { |
|
let assigned = from_str::<AssignedJob>(&item)?; |
|
into_value(client.update_result(&assigned).await?) |
|
} |
|
JobMapCRUD::RUD(RUD::Delete { id }) => into_value(client.del(id).await?), |
|
}, |
|
Cmd::Ping => into_value(client.ping().await?), |
|
Cmd::Serve => { |
|
crate::gui::serve(client) |
|
.await |
|
.map_err(|e| UError::PanelError(format!("{e:?}")))?; |
|
Value::Null |
|
} |
|
}) |
|
})() |
|
.await; |
|
|
|
match catcher { |
|
Ok(r) => PanelResult::Ok(r), |
|
Err(e) => PanelResult::Err(e), |
|
} |
|
}
|
|
|