You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

172 lines
5.5 KiB

use serde_json::{from_str, to_value, Value};
use structopt::StructOpt;
use u_lib::{
api::HttpClient, messaging::AsMsg, models::*, types::Id, types::PanelResult, UError, UResult,
};
#[derive(StructOpt, Debug)]
pub struct Args {
#[structopt(subcommand)]
cmd: Cmd,
#[structopt(short, long, default_value)]
brief: BriefMode,
}
#[derive(StructOpt, Debug)]
enum Cmd {
Agents(RUD),
Jobs(CRUD),
Map(MapCRUD),
Payloads(PayloadCRUD),
Ping,
Serve,
}
#[derive(StructOpt, Debug)]
enum CRUD {
Create {
item: String,
},
#[structopt(flatten)]
RUD(RUD),
}
#[derive(StructOpt, Debug)]
enum MapCRUD {
Create {
#[structopt(parse(try_from_str = parse_uuid))]
agent_id: Id,
job_idents: Vec<String>,
},
#[structopt(flatten)]
RUD(RUD),
}
#[derive(StructOpt, Debug)]
enum PayloadCRUD {
Create {
item: String,
},
Read {
id: Option<String>,
},
Update {
item: String,
},
Delete {
#[structopt(parse(try_from_str = parse_uuid))]
id: Id,
},
}
#[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)
.map_err(|e| UError::DeserializeError(e.to_string(), item))?;
into_value(client.update_agent(&agent).await?)
}
RUD::Delete { id } => into_value(client.del(id).await?),
},
Cmd::Jobs(action) => match action {
CRUD::Create { item: job } => {
let raw_job = from_str::<RawJob>(&job)
.map_err(|e| UError::DeserializeError(e.to_string(), job))?;
let mut job = raw_job.validated()?;
if let Some(payload) = &mut job.payload {
payload.join_payload()?;
}
into_value(client.upload_jobs([&job]).await?)
}
CRUD::RUD(RUD::Read { id }) => match id {
Some(id) => into_value(vec![client.get_job(id, args.brief).await?]),
None => into_value(client.get_jobs().await?),
},
CRUD::RUD(RUD::Update { item }) => {
let raw_job = from_str::<RawJob>(&item)
.map_err(|e| UError::DeserializeError(e.to_string(), item))?;
let mut job = raw_job.validated()?;
if let Some(payload) = &mut job.payload {
payload.join_payload()?;
}
into_value(client.update_job(&job).await?)
}
CRUD::RUD(RUD::Delete { id }) => into_value(client.del(id).await?),
},
Cmd::Map(action) => match action {
MapCRUD::Create {
agent_id,
job_idents,
} => into_value(client.set_jobs(agent_id, &job_idents).await?),
MapCRUD::RUD(RUD::Read { id }) => into_value(client.get_assigned_jobs(id).await?),
MapCRUD::RUD(RUD::Update { item }) => {
let assigned = from_str::<AssignedJob>(&item)
.map_err(|e| UError::DeserializeError(e.to_string(), item))?;
into_value(client.update_result(&assigned).await?)
}
MapCRUD::RUD(RUD::Delete { id }) => into_value(client.del(id).await?),
},
Cmd::Payloads(action) => match action {
PayloadCRUD::Create { item } => {
let payload = from_str::<RawPayload>(&item)
.map_err(|e| UError::DeserializeError(e.to_string(), item))?;
into_value(client.upload_payloads([&payload]).await?)
}
PayloadCRUD::Read { id } => match id {
None => into_value(client.get_payloads().await?),
Some(id) => into_value(client.get_payload(id, args.brief).await?),
},
PayloadCRUD::Update { item } => {
let payload = from_str::<Payload>(&item)
.map_err(|e| UError::DeserializeError(e.to_string(), item))?;
into_value(client.update_payload(&payload).await?)
}
PayloadCRUD::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),
}
}