From f4d3d921460b606a9ff6686c9bb9a79bf546f264 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Thu, 2 Nov 2023 21:01:16 +0100 Subject: baseline ping --- src/requests/device.rs | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'src/requests/device.rs') diff --git a/src/requests/device.rs b/src/requests/device.rs index 525745a..f7754a4 100644 --- a/src/requests/device.rs +++ b/src/requests/device.rs @@ -1,55 +1,63 @@ -use crate::{error::CliError, default_headers, format_url}; +use crate::{error::CliError, default_headers, format_url, Protocols}; -pub fn put(id: String, mac: String, broadcast_addr: String) -> Result<(), CliError> { - let res = reqwest::blocking::Client::new() - .put(format_url("device")?) +pub async fn put(id: String, mac: String, broadcast_addr: String, ip: String) -> Result<(), CliError> { + let res = reqwest::Client::new() + .put(format_url("device", Protocols::Http)?) .headers(default_headers()?) .body( format!( - r#"{{"id": "{}", "mac": "{}", "broadcast_addr": "{}"}}"#, + r#"{{"id": "{}", "mac": "{}", "broadcast_addr": "{}", "ip": "{}"}}"#, id, mac, - broadcast_addr + broadcast_addr, + ip ) ) .send() + .await .map_err(CliError::Reqwest)? - .text(); + .text() + .await; println!("{:?}", res); Ok(()) } -pub fn get(id: String) -> Result<(), CliError> { - let res = reqwest::blocking::Client::new() - .get(format_url("device")?) +pub async fn get(id: String) -> Result<(), CliError> { + let res = reqwest::Client::new() + .get(format_url("device", Protocols::Http)?) .headers(default_headers()?) .body( format!(r#"{{"id": "{}"}}"#, id) ) .send() + .await .map_err(CliError::Reqwest)? - .text(); + .text() + .await; println!("{:?}", res); Ok(()) } -pub fn post(id: String, mac: String, broadcast_addr: String) -> Result<(), CliError> { - let res = reqwest::blocking::Client::new() - .post(format_url("device")?) +pub async fn post(id: String, mac: String, broadcast_addr: String, ip: String) -> Result<(), CliError> { + let res = reqwest::Client::new() + .post(format_url("device", Protocols::Http)?) .headers(default_headers()?) .body( format!( - r#"{{"id": "{}", "mac": "{}", "broadcast_addr": "{}"}}"#, + r#"{{"id": "{}", "mac": "{}", "broadcast_addr": "{}", "ip": "{}"}}"#, id, mac, - broadcast_addr + broadcast_addr, + ip ) ) .send() + .await .map_err(CliError::Reqwest)? - .text(); + .text() + .await; println!("{:?}", res); Ok(()) -- cgit v1.2.3 From 344af3ff7c9493b4e2c6eee134b9b341eaabf736 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Tue, 7 Nov 2023 12:58:12 +0100 Subject: add ping support and readable output --- .gitignore | 1 + src/error.rs | 2 + src/main.rs | 28 +++++++++++- src/requests/device.rs | 4 +- src/requests/start.rs | 113 ++++++++++++++++++++++++++++++++++--------------- webol-cli.toml | 2 +- 6 files changed, 112 insertions(+), 38 deletions(-) (limited to 'src/requests/device.rs') diff --git a/.gitignore b/.gitignore index 13a2081..f337b94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /postgres-data +webol-cli.toml diff --git a/src/error.rs b/src/error.rs index d35991b..27fc7a6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,6 +4,7 @@ pub enum CliError { Reqwest(reqwest::Error), Config(config::ConfigError), Serde(serde_json::Error), + WsResponse, } impl Debug for CliError { @@ -12,6 +13,7 @@ impl Debug for CliError { Self::Reqwest(err) => { err.fmt(f) }, Self::Config(err) => { err.fmt(f) }, Self::Serde(err) => { err.fmt(f) }, + Self::WsResponse => { f.write_str("Error in Response") }, } } } diff --git a/src/main.rs b/src/main.rs index 3e1388b..d7c985f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ -use std::fmt::Display; +use std::{fmt::Display, time::Duration}; use clap::{Parser, Subcommand}; use config::SETTINGS; use error::CliError; +use indicatif::{ProgressBar, ProgressStyle, MultiProgress}; use requests::{start::start, device}; use reqwest::header::{HeaderMap, HeaderValue}; use serde::Deserialize; @@ -11,7 +12,15 @@ mod config; mod error; mod requests; -/// webol http client +static OVERVIEW_STYLE: &str = "{spinner:.green} {wide_msg}({elapsed})"; +static OVERVIEW_ERROR: &str = "✗ {wide_msg}({elapsed})"; +static OVERVIEW_DONE: &str = "✓ {wide_msg}({elapsed})"; +static DEFAULT_STYLE: &str = " {spinner:.green} {wide_msg}"; +static DONE_STYLE: &str = " ✓ {wide_msg}"; +static ERROR_STYLE: &str = " ✗ {wide_msg}"; +static TICK_SPEED: u64 = 1000 / 16; + +/// webol client #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Args { @@ -103,6 +112,21 @@ fn format_url(path: &str, protocol: Protocols) -> Result { )) } +fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar { + let pb = mp.add(ProgressBar::new(1)); + pb.set_style(ProgressStyle::with_template(template).unwrap()); + pb.enable_steady_tick(Duration::from_millis(TICK_SPEED)); + pb.set_message(message); + + pb +} + +fn finish_pb(pb: ProgressBar, message: String, template: &str) { + pb.set_style(ProgressStyle::with_template(template).unwrap()); + pb.finish_with_message(message); + +} + enum Protocols { Http, Websocket, diff --git a/src/requests/device.rs b/src/requests/device.rs index f7754a4..cbc838e 100644 --- a/src/requests/device.rs +++ b/src/requests/device.rs @@ -1,8 +1,10 @@ use crate::{error::CliError, default_headers, format_url, Protocols}; pub async fn put(id: String, mac: String, broadcast_addr: String, ip: String) -> Result<(), CliError> { + let url = format_url("device", Protocols::Http)?; + println!("{}", url); let res = reqwest::Client::new() - .put(format_url("device", Protocols::Http)?) + .put(url) .headers(default_headers()?) .body( format!( diff --git a/src/requests/start.rs b/src/requests/start.rs index d0c4411..882b154 100644 --- a/src/requests/start.rs +++ b/src/requests/start.rs @@ -1,29 +1,19 @@ -use std::time::Duration; - use futures_util::{StreamExt, SinkExt}; -use indicatif::{ProgressBar, ProgressStyle}; +use indicatif::MultiProgress; use reqwest::StatusCode; use serde::Deserialize; use tokio_tungstenite::{connect_async, tungstenite::Message}; -use crate::{error::CliError, default_headers, ErrorResponse, format_url, Protocols}; +use crate::{error::CliError, default_headers, ErrorResponse, format_url, Protocols, OVERVIEW_STYLE, DEFAULT_STYLE, DONE_STYLE, finish_pb, ERROR_STYLE, OVERVIEW_ERROR, OVERVIEW_DONE, add_pb}; pub async fn start(id: String, ping: bool) -> Result<(), CliError> { - let send_start = ProgressBar::new(1); + let send_start = MultiProgress::new(); + let overview = add_pb(&send_start, OVERVIEW_STYLE, format!("start {}", id)); // TODO: calculate average start-time on server - send_start.set_style( - ProgressStyle::with_template("{spinner:.green} ({elapsed}) {wide_msg}") - .unwrap() - .tick_chars("|/-\\\\") - ); - let url = format_url("start", Protocols::Http)?; - - send_start.set_message(format!("connect to {}", url)); - send_start.enable_steady_tick(Duration::from_millis(125)); - + let connect = add_pb(&send_start, DEFAULT_STYLE, format!("connect to {}", url)); let res = reqwest::Client::new() .post(url) .headers(default_headers()?) @@ -33,7 +23,9 @@ pub async fn start(id: String, ping: bool) -> Result<(), CliError> { .send() .await .map_err(CliError::Reqwest)?; + finish_pb(connect, "connected, got response".to_string(), DONE_STYLE); + let res_pb = add_pb(&send_start, DEFAULT_STYLE, "analyzing response".to_string()); match res.status() { StatusCode::OK => { let body = serde_json::from_str::( @@ -42,11 +34,16 @@ pub async fn start(id: String, ping: bool) -> Result<(), CliError> { .map_err(CliError::Serde)?; if body.boot { - send_start.println("connected, sent start packet"); + finish_pb(res_pb, "sent start packet".to_string(), DONE_STYLE); } if ping { - send_start.println(status_socket(body.uuid, &send_start).await?.to_string()); + let status = status_socket(body.uuid, &send_start).await?; + if status { + finish_pb(overview, format!("successfully started {}", body.id), OVERVIEW_DONE); + } else { + finish_pb(overview, format!("error while starting {}", body.id), OVERVIEW_ERROR); + } } }, _ => { @@ -55,37 +52,63 @@ pub async fn start(id: String, ping: bool) -> Result<(), CliError> { ) .map_err(CliError::Serde)?; - println!("got error: {}", body.error); + res_pb.finish_with_message(format!("✗ got error: {}", body.error)); } } Ok(()) } -async fn status_socket(uuid: String, pb: &ProgressBar) -> Result { - pb.set_message("setup websocket"); - +async fn status_socket(uuid: String, pb: &MultiProgress) -> Result { + // TODO: Remove unwraps + let ws_pb = add_pb(pb, DEFAULT_STYLE, "connect to websocket".to_string()); let (mut ws_stream, _response) = connect_async(format_url("status", Protocols::Websocket)?) .await .expect("Failed to connect"); - pb.println("connected to websocket"); - - pb.set_message("send uuid message"); - ws_stream.send(Message::Text(uuid)).await.unwrap(); - pb.println("sent uuid message"); + finish_pb(ws_pb, "connected to websocket".to_string(), DONE_STYLE); + + ws_stream.send(Message::Text(uuid.clone())).await.unwrap(); - pb.set_message("wait for message"); + let msg_pb = add_pb(pb, DEFAULT_STYLE, "await message".to_string()); let msg = ws_stream.next().await.unwrap(); + finish_pb(msg_pb, "received message".to_string(), DONE_STYLE); - pb.println(format!("msg: {:?}", msg)); - ws_stream.close(None).await.unwrap(); - pb.println("connection closed"); - // TODO: Check for correct UUID and timeout - pb.set_message("verifying message"); - if msg.is_ok() { return Ok(true) } - Ok(false) + let v_pb = add_pb(pb, DEFAULT_STYLE, "verify response".to_string()); + let res = verify_response(msg.unwrap().to_string(), uuid)?; + match res { + Verified::WrongUuid => { + finish_pb(v_pb, "returned wrong uuid".to_string(), ERROR_STYLE); + Ok(false) + }, + Verified::ResponseType(res_type) => { + match res_type { + ResponseType::Start => { + finish_pb(v_pb, "device started".to_string(), DONE_STYLE); + Ok(true) + }, + ResponseType::Timeout => { + finish_pb(v_pb, "ping timed out".to_string(), ERROR_STYLE); + Ok(false) + }, + ResponseType::NotFound => { + finish_pb(v_pb, "unknown uuid".to_string(), ERROR_STYLE); + Ok(false) + }, + } + } + } +} + +fn verify_response(res: String, org_uuid: String) -> Result { + let spl: Vec<&str> = res.split('_').collect(); + let res_type = spl[0]; + let uuid = spl[1]; + + if uuid != org_uuid { return Ok(Verified::WrongUuid) }; + + Ok(Verified::ResponseType(ResponseType::from(res_type)?)) } #[derive(Debug, Deserialize)] @@ -94,3 +117,25 @@ struct StartResponse { id: String, uuid: String, } + +enum Verified { + ResponseType(ResponseType), + WrongUuid +} + +enum ResponseType { + Start, + Timeout, + NotFound, +} + +impl ResponseType { + fn from(value: &str) -> Result { + match value { + "start" => Ok(ResponseType::Start), + "timeout" => Ok(ResponseType::Timeout), + "notfound" => Ok(ResponseType::NotFound), + _ => Err(CliError::WsResponse), + } + } +} diff --git a/webol-cli.toml b/webol-cli.toml index 7ffb99d..822af46 100644 --- a/webol-cli.toml +++ b/webol-cli.toml @@ -1,2 +1,2 @@ -server = "192.168.178.28:7229" +server = "localhost:7229" key = "aaa" -- cgit v1.2.3