idioamtic improvements
This commit is contained in:
		| @@ -13,13 +13,6 @@ try { | ||||
|         print(`Getting details for server: ${first_server.name}`); | ||||
|         let detailed_server = client.get_server(first_server.id); | ||||
|         print(detailed_server.show_details()); | ||||
|         print(`Pinging server ${detailed_server.name}...`); | ||||
|         let is_online = detailed_server.ping(); | ||||
|         if is_online { | ||||
|             print("Server is online."); | ||||
|         } else { | ||||
|             print("Server is offline."); | ||||
|         } | ||||
|          | ||||
|         // --- REBOOT --- | ||||
|         // To reboot the server, uncomment the following lines: | ||||
|   | ||||
| @@ -41,8 +41,6 @@ impl HetznerClient { | ||||
|  | ||||
|             all_servers.append(&mut servers); | ||||
|              | ||||
|             println!("next page? {:#?}", response.meta); | ||||
|  | ||||
|             if is_empty || response.meta.pagination.next_page.is_none() { | ||||
|                 break; | ||||
|             } | ||||
|   | ||||
							
								
								
									
										372
									
								
								src/rhai_api.rs
									
									
									
									
									
								
							
							
						
						
									
										372
									
								
								src/rhai_api.rs
									
									
									
									
									
								
							| @@ -2,14 +2,38 @@ use crate::async_handler::Response; | ||||
| use crate::async_handler::Request; | ||||
| use crate::hetzner_api::{HetznerClient, WrappedServer}; | ||||
| use rhai::{Engine, EvalAltResult}; | ||||
| use std::sync::{Arc, Mutex, mpsc::{Sender, Receiver}}; | ||||
| use std::sync::{mpsc::{Receiver, Sender}, Arc, Mutex}; | ||||
| use prettytable::{Table, Row, Cell}; | ||||
|  | ||||
| #[derive(Clone)] | ||||
| struct ApiBridge { | ||||
|     command_tx: Sender<Request>, | ||||
|     reply_rx: Arc<Mutex<Receiver<Response>>>, | ||||
| } | ||||
|  | ||||
| impl ApiBridge { | ||||
|     fn new(command_tx: Sender<Request>, reply_rx: Arc<Mutex<Receiver<Response>>>) -> Self { | ||||
|         Self { command_tx, reply_rx } | ||||
|     } | ||||
|  | ||||
|     fn call<T>( | ||||
|         &self, | ||||
|         request: Request, | ||||
|         response_handler: impl FnOnce(Response) -> Result<T, Box<EvalAltResult>>, | ||||
|     ) -> Result<T, Box<EvalAltResult>> { | ||||
|         self.command_tx.send(request).map_err(|e| e.to_string())?; | ||||
|         let response = self.reply_rx.lock().unwrap().recv().map_err(|e| e.to_string())?; | ||||
|         response_handler(response) | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn register_hetzner_api( | ||||
|     engine: &mut Engine, | ||||
|     command_tx: Sender<Request>, | ||||
|     reply_rx: Arc<Mutex<Receiver<Response>>>, | ||||
| ) { | ||||
|     let api_bridge = ApiBridge::new(command_tx, reply_rx); | ||||
|  | ||||
|     engine | ||||
|         .register_type_with_name::<HetznerClient>("HetznerClient") | ||||
|         .register_fn("new_hetzner_client", |api_token: &str| -> Result<HetznerClient, Box<EvalAltResult>> { | ||||
| @@ -19,261 +43,127 @@ pub fn register_hetzner_api( | ||||
|             Ok(HetznerClient::new(api_token)) | ||||
|         }); | ||||
|  | ||||
|     let list_servers_tx = command_tx.clone(); | ||||
|     let list_servers_rx = reply_rx.clone(); | ||||
|     let get_server_status_tx = command_tx.clone(); | ||||
|     let get_server_status_rx = reply_rx.clone(); | ||||
|     let get_server_tx = command_tx.clone(); | ||||
|     let get_server_rx = reply_rx.clone(); | ||||
|     let reboot_server_tx = command_tx.clone(); | ||||
|     let reboot_server_rx = reply_rx.clone(); | ||||
|     let reset_server_tx = command_tx.clone(); | ||||
|     let reset_server_rx = reply_rx.clone(); | ||||
|     let enable_rescue_mode_tx = command_tx.clone(); | ||||
|     let enable_rescue_mode_rx = reply_rx.clone(); | ||||
|     let disable_rescue_mode_tx = command_tx.clone(); | ||||
|     let disable_rescue_mode_rx = reply_rx.clone(); | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("list_servers", move |client: &mut HetznerClient| { | ||||
|         bridge.call(Request::ListServers(client.clone()), |response| { | ||||
|             match response { | ||||
|                 Response::ListServers(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("get_server_status", move |client: &mut HetznerClient, server_id: i64| { | ||||
|         bridge.call(Request::GetServerStatus(client.clone(), server_id), |response| { | ||||
|             match response { | ||||
|                 Response::GetServerStatus(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("get_server", move |client: &mut HetznerClient, server_id: i64| { | ||||
|         bridge.call(Request::GetServer(client.clone(), server_id), |response| { | ||||
|             match response { | ||||
|                 Response::GetServer(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|     engine | ||||
|         .register_fn( | ||||
|             "list_servers", | ||||
|             move |client: &mut HetznerClient| -> Result<Vec<WrappedServer>, Box<EvalAltResult>> { | ||||
|                 list_servers_tx.send(Request::ListServers(client.clone())) | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 let response = list_servers_rx.lock().unwrap().recv() | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 match response { | ||||
|                     Response::ListServers(result) => result.map_err(|e| e.into()), | ||||
|                     _ => Err("Unexpected response".into()), | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         .register_fn( | ||||
|             "get_server_status", | ||||
|             move |client: &mut HetznerClient, | ||||
|                   server_id: i64| | ||||
|                   -> Result<String, Box<EvalAltResult>> { | ||||
|                 get_server_status_tx.send(Request::GetServerStatus(client.clone(), server_id)) | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 let response = get_server_status_rx.lock().unwrap().recv() | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 match response { | ||||
|                     Response::GetServerStatus(result) => result.map_err(|e| e.into()), | ||||
|                     _ => Err("Unexpected response".into()), | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         .register_fn( | ||||
|             "get_server", | ||||
|             move |client: &mut HetznerClient, | ||||
|                   server_id: i64| | ||||
|                   -> Result<WrappedServer, Box<EvalAltResult>> { | ||||
|                 get_server_tx.send(Request::GetServer(client.clone(), server_id)) | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 let response = get_server_rx.lock().unwrap().recv() | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 match response { | ||||
|                     Response::GetServer(result) => result.map_err(|e| e.into()), | ||||
|                     _ => Err("Unexpected response".into()), | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         .register_type_with_name::<WrappedServer>("Server") | ||||
|         .register_get("id", |server: &mut WrappedServer| server.0.id) | ||||
|         .register_get("name", |server: &mut WrappedServer| { | ||||
|             server.0.name.clone() | ||||
|         .register_get("name", |server: &mut WrappedServer| server.0.name.clone()) | ||||
|         .register_get("status", |server: &mut WrappedServer| format!("{:?}", server.0.status)) | ||||
|         .register_get("created", |server: &mut WrappedServer| server.0.created.clone()) | ||||
|         .register_get("public_ipv4", |server: &mut WrappedServer| server.0.public_net.ipv4.clone().unwrap().ip) | ||||
|         .register_get("server_type", |server: &mut WrappedServer| server.0.server_type.clone().name) | ||||
|         .register_get("included_traffic", |server: &mut WrappedServer| server.0.included_traffic.unwrap_or(0)) | ||||
|         .register_get("ingoing_traffic", |server: &mut WrappedServer| server.0.ingoing_traffic.unwrap_or(0)) | ||||
|         .register_get("outgoing_traffic", |server: &mut WrappedServer| server.0.outgoing_traffic.unwrap_or(0)) | ||||
|         .register_get("primary_disk_size", |server: &mut WrappedServer| server.0.primary_disk_size) | ||||
|         .register_get("rescue_enabled", |server: &mut WrappedServer| server.0.rescue_enabled); | ||||
|      | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("reboot", move |server: &mut WrappedServer, client: HetznerClient| { | ||||
|         bridge.call(Request::RebootServer(client, server.0.id), |response| { | ||||
|             match response { | ||||
|                 Response::RebootServer(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|         .register_get("status", |server: &mut WrappedServer| { | ||||
|             format!("{:?}", server.0.status) | ||||
|         }) | ||||
|         .register_get("created", |server: &mut WrappedServer| { | ||||
|             server.0.created.clone() | ||||
|         }) | ||||
|         .register_get("public_ipv4", |server: &mut WrappedServer| { | ||||
|             server.0.public_net.ipv4.clone().unwrap().ip | ||||
|         }) | ||||
|         .register_get("server_type", |server: &mut WrappedServer| { | ||||
|             server.0.server_type.clone().name | ||||
|         }) | ||||
|         .register_get("included_traffic", |server: &mut WrappedServer| { | ||||
|             server.0.included_traffic.unwrap_or(0) | ||||
|         }) | ||||
|         .register_get("ingoing_traffic", |server: &mut WrappedServer| { | ||||
|             server.0.ingoing_traffic.unwrap_or(0) | ||||
|         }) | ||||
|         .register_get("outgoing_traffic", |server: &mut WrappedServer| { | ||||
|             server.0.outgoing_traffic.unwrap_or(0) | ||||
|         }) | ||||
|         .register_get("primary_disk_size", |server: &mut WrappedServer| { | ||||
|             server.0.primary_disk_size | ||||
|         }) | ||||
|         .register_get("rescue_enabled", |server: &mut WrappedServer| { | ||||
|             server.0.rescue_enabled | ||||
|         }) | ||||
|         .register_fn( | ||||
|             "reboot", | ||||
|             move |server: &mut WrappedServer, | ||||
|                   client: HetznerClient| | ||||
|                   -> Result<(), Box<EvalAltResult>> { | ||||
|                 reboot_server_tx | ||||
|                     .send(Request::RebootServer(client, server.0.id)) | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|     }); | ||||
|  | ||||
|                 let response = reboot_server_rx | ||||
|                     .lock() | ||||
|                     .unwrap() | ||||
|                     .recv() | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("reset", move |server: &mut WrappedServer, client: HetznerClient| { | ||||
|         bridge.call(Request::ResetServer(client, server.0.id), |response| { | ||||
|             match response { | ||||
|                 Response::ResetServer(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|                 match response { | ||||
|                     Response::RebootServer(result) => result.map_err(|e| e.into()), | ||||
|                     _ => Err("Unexpected response".into()), | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         .register_fn( | ||||
|            "reset", | ||||
|            move |server: &mut WrappedServer, | ||||
|                  client: HetznerClient| | ||||
|                  -> Result<(), Box<EvalAltResult>> { | ||||
|                reset_server_tx | ||||
|                    .send(Request::ResetServer(client, server.0.id)) | ||||
|                    .map_err(|e| e.to_string())?; | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("enable_rescue_mode", move |server: &mut WrappedServer, client: HetznerClient| { | ||||
|         bridge.call(Request::EnableRescueMode(client, server.0.id), |response| { | ||||
|             match response { | ||||
|                 Response::EnableRescueMode(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|                let response = reset_server_rx | ||||
|                    .lock() | ||||
|                    .unwrap() | ||||
|                    .recv() | ||||
|                    .map_err(|e| e.to_string())?; | ||||
|     let bridge = api_bridge.clone(); | ||||
|     engine.register_fn("disable_rescue_mode", move |server: &mut WrappedServer, client: HetznerClient| { | ||||
|         bridge.call(Request::DisableRescueMode(client, server.0.id), |response| { | ||||
|             match response { | ||||
|                 Response::DisableRescueMode(result) => result.map_err(|e| e.into()), | ||||
|                 _ => Err("Unexpected response".into()), | ||||
|             } | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|                match response { | ||||
|                    Response::ResetServer(result) => result.map_err(|e| e.into()), | ||||
|                    _ => Err("Unexpected response".into()), | ||||
|                } | ||||
|            }, | ||||
|        ) | ||||
|        .register_iterator::<Vec<WrappedServer>>() | ||||
|     engine | ||||
|         .register_iterator::<Vec<WrappedServer>>() | ||||
|         .register_fn("len", |list: &mut Vec<WrappedServer>| list.len() as i64) | ||||
|         .register_indexer_get(|list: &mut Vec<WrappedServer>, index: i64| list[index as usize].clone()) | ||||
|         .register_fn( | ||||
|             "show_table", | ||||
|             |servers: &mut Vec<WrappedServer>| -> Result<String, Box<EvalAltResult>> { | ||||
|                 let mut table = Table::new(); | ||||
|                 table.set_titles(Row::new(vec![Cell::new("Server List").style_spec("c")])); | ||||
|         .register_fn("show_table", |servers: &mut Vec<WrappedServer>| -> Result<String, Box<EvalAltResult>> { | ||||
|             let mut table = Table::new(); | ||||
|             table.set_titles(Row::new(vec![Cell::new("Server List").style_spec("c")])); | ||||
|             table.add_row(Row::new(vec![ | ||||
|                 Cell::new("ID"), | ||||
|                 Cell::new("Name"), | ||||
|                 Cell::new("Status"), | ||||
|                 Cell::new("Public IPv4"), | ||||
|             ])); | ||||
|             for server in servers { | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("ID"), | ||||
|                     Cell::new("Name"), | ||||
|                     Cell::new("Status"), | ||||
|                     Cell::new("Public IPv4"), | ||||
|                 ])); | ||||
|                 for server in servers { | ||||
|                     table.add_row(Row::new(vec![ | ||||
|                         Cell::new(&server.0.id.to_string()), | ||||
|                         Cell::new(&server.0.name), | ||||
|                         Cell::new(&format!("{:?}", server.0.status)), | ||||
|                         Cell::new(&server.0.public_net.ipv4.clone().unwrap().ip.to_string()), | ||||
|                     ])); | ||||
|                 } | ||||
|                 Ok(table.to_string()) | ||||
|             }, | ||||
|         ) | ||||
|         .register_fn( | ||||
|             "show_details", | ||||
|             |server: &mut WrappedServer| -> Result<String, Box<EvalAltResult>> { | ||||
|                 let mut table = Table::new(); | ||||
|                 table.set_titles(Row::new(vec![ | ||||
|                     Cell::new(&server.0.name).style_spec("c") | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("ID"), | ||||
|                     Cell::new(&server.0.id.to_string()), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Status"), | ||||
|                     Cell::new(&server.0.name), | ||||
|                     Cell::new(&format!("{:?}", server.0.status)), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Created"), | ||||
|                     Cell::new(&server.0.created), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("IPv4"), | ||||
|                     Cell::new(&server.0.public_net.ipv4.clone().unwrap().ip.to_string()), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Type"), | ||||
|                     Cell::new(&server.0.server_type.name), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Included Traffic"), | ||||
|                     Cell::new(&format!("{} GB", server.0.included_traffic.unwrap_or(0) / 1024 / 1024 / 1024)), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Ingoing Traffic"), | ||||
|                     Cell::new(&format!("{} MB", server.0.ingoing_traffic.unwrap_or(0) / 1024 / 1024)), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Outgoing Traffic"), | ||||
|                     Cell::new(&format!("{} MB", server.0.outgoing_traffic.unwrap_or(0) / 1024 / 1024)), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Primary Disk Size"), | ||||
|                     Cell::new(&server.0.primary_disk_size.to_string()), | ||||
|                 ])); | ||||
|                 table.add_row(Row::new(vec![ | ||||
|                     Cell::new("Rescue Enabled"), | ||||
|                     Cell::new(&server.0.rescue_enabled.to_string()), | ||||
|                 ])); | ||||
|             } | ||||
|             Ok(table.to_string()) | ||||
|         }) | ||||
|         .register_fn("show_details", |server: &mut WrappedServer| -> Result<String, Box<EvalAltResult>> { | ||||
|             let mut table = Table::new(); | ||||
|             table.set_titles(Row::new(vec![Cell::new(&server.0.name).style_spec("c")])); | ||||
|             table.add_row(Row::new(vec![Cell::new("ID"), Cell::new(&server.0.id.to_string())])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Status"), Cell::new(&format!("{:?}", server.0.status))])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Created"), Cell::new(&server.0.created)])); | ||||
|             table.add_row(Row::new(vec![Cell::new("IPv4"), Cell::new(&server.0.public_net.ipv4.clone().unwrap().ip.to_string())])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Type"), Cell::new(&server.0.server_type.name)])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Included Traffic"), Cell::new(&format!("{} GB", server.0.included_traffic.unwrap_or(0) / 1024 / 1024 / 1024))])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Ingoing Traffic"), Cell::new(&format!("{} MB", server.0.ingoing_traffic.unwrap_or(0) / 1024 / 1024))])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Outgoing Traffic"), Cell::new(&format!("{} MB", server.0.outgoing_traffic.unwrap_or(0) / 1024 / 1024))])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Primary Disk Size"), Cell::new(&server.0.primary_disk_size.to_string())])); | ||||
|             table.add_row(Row::new(vec![Cell::new("Rescue Enabled"), Cell::new(&server.0.rescue_enabled.to_string())])); | ||||
|  | ||||
|                 Ok(table.to_string()) | ||||
|             }, | ||||
|         ); | ||||
|      engine.register_fn( | ||||
|             "enable_rescue_mode", | ||||
|             move |server: &mut WrappedServer, | ||||
|                   client: HetznerClient| | ||||
|                   -> Result<String, Box<EvalAltResult>> { | ||||
|                 enable_rescue_mode_tx | ||||
|                     .send(Request::EnableRescueMode(client, server.0.id)) | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 let response = enable_rescue_mode_rx | ||||
|                     .lock() | ||||
|                     .unwrap() | ||||
|                     .recv() | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 match response { | ||||
|                     Response::EnableRescueMode(result) => result.map_err(|e| e.into()), | ||||
|                     _ => Err("Unexpected response".into()), | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         .register_fn( | ||||
|             "disable_rescue_mode", | ||||
|             move |server: &mut WrappedServer, | ||||
|                   client: HetznerClient| | ||||
|                   -> Result<(), Box<EvalAltResult>> { | ||||
|                 disable_rescue_mode_tx | ||||
|                     .send(Request::DisableRescueMode(client, server.0.id)) | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 let response = disable_rescue_mode_rx | ||||
|                     .lock() | ||||
|                     .unwrap() | ||||
|                     .recv() | ||||
|                     .map_err(|e| e.to_string())?; | ||||
|  | ||||
|                 match response { | ||||
|                     Response::DisableRescueMode(result) => result.map_err(|e| e.into()), | ||||
|                     _ => Err("Unexpected response".into()), | ||||
|                 } | ||||
|             }, | ||||
|         ); | ||||
|             Ok(table.to_string()) | ||||
|         }); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user