implemented list servers + ping + reboot + example shown in example.rhai
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/target
 | 
				
			||||||
							
								
								
									
										2280
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2280
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "hetzner_rhai"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2024"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					hcloud = "0.21.0"
 | 
				
			||||||
 | 
					reqwest = "0.12.22"
 | 
				
			||||||
 | 
					rhai = { version = "1.22.2", features = ["sync"] }
 | 
				
			||||||
 | 
					tokio = { version = "1.46.1", features = ["full"] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ping = "0.6.1"
 | 
				
			||||||
							
								
								
									
										37
									
								
								example.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								example.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					let client = new_hetzner_client(HETZNER_API_TOKEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try {
 | 
				
			||||||
 | 
					    print("Listing servers...");
 | 
				
			||||||
 | 
					    let servers = client.list_servers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if servers.len() == 0 {
 | 
				
			||||||
 | 
					        print("No servers found.");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        for server in servers {
 | 
				
			||||||
 | 
					            print(`Server: ${server.name} (${server.id}), Status: ${server.status}`);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let first_server = servers[0];
 | 
				
			||||||
 | 
					        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.");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // To reboot the server, uncomment the following lines:
 | 
				
			||||||
 | 
					        // print("\nAttempting to reboot the server...");
 | 
				
			||||||
 | 
					        // try {
 | 
				
			||||||
 | 
					        //     first_server.reboot(client);
 | 
				
			||||||
 | 
					        //     print("Reboot command sent successfully.");
 | 
				
			||||||
 | 
					        // } catch(e) {
 | 
				
			||||||
 | 
					        //     print(`Error during reboot: ${e}`);
 | 
				
			||||||
 | 
					        // }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} catch (e) {
 | 
				
			||||||
 | 
					    print(`An error occurred: ${e}`);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										60
									
								
								src/async_handler.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/async_handler.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					use crate::hetzner_api::{HetznerClient, WrappedServer};
 | 
				
			||||||
 | 
					use crate::ping::ping_server;
 | 
				
			||||||
 | 
					use std::net::IpAddr;
 | 
				
			||||||
 | 
					use std::sync::mpsc::{Receiver, Sender};
 | 
				
			||||||
 | 
					use tokio::runtime::Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub enum Request {
 | 
				
			||||||
 | 
					    ListServers(HetznerClient),
 | 
				
			||||||
 | 
					    GetServerStatus(HetznerClient, i64),
 | 
				
			||||||
 | 
					    GetServer(HetznerClient, i64),
 | 
				
			||||||
 | 
					    RebootServer(HetznerClient, i64),
 | 
				
			||||||
 | 
					    PingServer(IpAddr),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub enum Response {
 | 
				
			||||||
 | 
					    ListServers(Result<Vec<WrappedServer>, String>),
 | 
				
			||||||
 | 
					    GetServerStatus(Result<String, String>),
 | 
				
			||||||
 | 
					    GetServer(Result<WrappedServer, String>),
 | 
				
			||||||
 | 
					    RebootServer(Result<(), String>),
 | 
				
			||||||
 | 
					    PingServer(Result<bool, String>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn run_worker(
 | 
				
			||||||
 | 
					    command_rx: Receiver<Request>,
 | 
				
			||||||
 | 
					    reply_tx: Sender<Response>,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    std::thread::spawn(move || {
 | 
				
			||||||
 | 
					        let rt = Builder::new_current_thread()
 | 
				
			||||||
 | 
					            .enable_all()
 | 
				
			||||||
 | 
					            .build()
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while let Ok(request) = command_rx.recv() {
 | 
				
			||||||
 | 
					            let response = match request {
 | 
				
			||||||
 | 
					                Request::ListServers(client) => {
 | 
				
			||||||
 | 
					                    let result = rt.block_on(client.list_servers()).map_err(|e| e.to_string());
 | 
				
			||||||
 | 
					                    Response::ListServers(result)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Request::GetServerStatus(client, server_id) => {
 | 
				
			||||||
 | 
					                    let result = rt.block_on(client.get_server_status(server_id)).map_err(|e| e.to_string());
 | 
				
			||||||
 | 
					                    Response::GetServerStatus(result)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Request::GetServer(client, server_id) => {
 | 
				
			||||||
 | 
					                    let result = rt.block_on(client.get_server(server_id)).map_err(|e| e.to_string());
 | 
				
			||||||
 | 
					                    Response::GetServer(result)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Request::RebootServer(client, server_id) => {
 | 
				
			||||||
 | 
					                    let result = rt.block_on(client.reboot_server(server_id)).map_err(|e| e.to_string());
 | 
				
			||||||
 | 
					                    Response::RebootServer(result)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Request::PingServer(ip) => {
 | 
				
			||||||
 | 
					                    let result = ping_server(ip).map_err(|e| e.to_string());
 | 
				
			||||||
 | 
					                    Response::PingServer(result)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            reply_tx.send(response).expect("Failed to send response");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										0
									
								
								src/error.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/error.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										72
									
								
								src/hetzner_api.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/hetzner_api.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					use hcloud::apis::{configuration::Configuration, servers_api};
 | 
				
			||||||
 | 
					use hcloud::models::Server;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					pub struct HetznerClient {
 | 
				
			||||||
 | 
					    pub configuration: Configuration,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub struct WrappedServer(pub Server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl HetznerClient {
 | 
				
			||||||
 | 
					    pub fn new(api_token: &str) -> Self {
 | 
				
			||||||
 | 
					        let mut configuration = Configuration::new();
 | 
				
			||||||
 | 
					        configuration.bearer_access_token = Some(api_token.to_string());
 | 
				
			||||||
 | 
					        let client = reqwest::Client::builder()
 | 
				
			||||||
 | 
					            .timeout(std::time::Duration::from_secs(5))
 | 
				
			||||||
 | 
					            .build()
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					        configuration.client = client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Self { configuration }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn list_servers(&self) -> Result<Vec<WrappedServer>, Box<dyn std::error::Error>> {
 | 
				
			||||||
 | 
					        let servers = servers_api::list_servers(&self.configuration, Default::default())
 | 
				
			||||||
 | 
					            .await?
 | 
				
			||||||
 | 
					            .servers
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(WrappedServer)
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(servers)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn get_server_status(&self, server_id: i64) -> Result<String, Box<dyn std::error::Error>> {
 | 
				
			||||||
 | 
					        let params = servers_api::GetServerParams {
 | 
				
			||||||
 | 
					            id: server_id,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let server_response = servers_api::get_server(&self.configuration, params)
 | 
				
			||||||
 | 
					            .await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(server) = server_response.server {
 | 
				
			||||||
 | 
					            Ok(format!("{:?}", server.status))
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Err(Box::from(format!("Server with id {} not found", server_id)))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn get_server(&self, server_id: i64) -> Result<WrappedServer, Box<dyn std::error::Error>> {
 | 
				
			||||||
 | 
					        let params = servers_api::GetServerParams {
 | 
				
			||||||
 | 
					            id: server_id,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let server_response = servers_api::get_server(&self.configuration, params)
 | 
				
			||||||
 | 
					            .await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(server) = server_response.server {
 | 
				
			||||||
 | 
					            Ok(WrappedServer(*server))
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Err(Box::from(format!("Server with id {} not found", server_id)))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn reboot_server(&self, server_id: i64) -> Result<(), Box<dyn std::error::Error>> {
 | 
				
			||||||
 | 
					        let params = servers_api::SoftRebootServerParams {
 | 
				
			||||||
 | 
					            id: server_id,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        servers_api::soft_reboot_server(&self.configuration, params).await?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										50
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					mod error;
 | 
				
			||||||
 | 
					mod hetzner_api;
 | 
				
			||||||
 | 
					mod rhai_api;
 | 
				
			||||||
 | 
					mod async_handler;
 | 
				
			||||||
 | 
					mod ping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::rhai_api::register_hetzner_api;
 | 
				
			||||||
 | 
					use rhai::{Engine, Scope};
 | 
				
			||||||
 | 
					use std::env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::thread;
 | 
				
			||||||
 | 
					use std::sync::{Arc, Mutex, mpsc};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use rhai::EvalAltResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
 | 
				
			||||||
 | 
					    let (command_tx, command_rx) = mpsc::channel::<async_handler::Request>();
 | 
				
			||||||
 | 
					    let (reply_tx, reply_rx) = mpsc::channel::<async_handler::Response>();
 | 
				
			||||||
 | 
					    async_handler::run_worker(command_rx, reply_tx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let rhai_thread = thread::spawn(move || -> Result<(), Box<EvalAltResult>> {
 | 
				
			||||||
 | 
					        let reply_rx = Arc::new(Mutex::new(reply_rx));
 | 
				
			||||||
 | 
					        let mut engine = Engine::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        register_hetzner_api(&mut engine, command_tx, reply_rx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut scope = Scope::new();
 | 
				
			||||||
 | 
					        scope.push(
 | 
				
			||||||
 | 
					            "HETZNER_API_TOKEN",
 | 
				
			||||||
 | 
					            env::var("HETZNER_API_TOKEN").unwrap_or_else(|_| {
 | 
				
			||||||
 | 
					                let args: Vec<String> = env::args().collect();
 | 
				
			||||||
 | 
					                args.get(1).cloned().unwrap_or_default()
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let script = std::env::args().nth(2);
 | 
				
			||||||
 | 
					        if let Some(s) = script {
 | 
				
			||||||
 | 
					            engine.run_with_scope(&mut scope, &s)?;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            engine.run_file_with_scope(&mut scope, "example.rhai".into())?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Err(err) = rhai_thread.join().unwrap() {
 | 
				
			||||||
 | 
					        eprintln!("Error in Rhai script: {}", *err);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/ping.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/ping.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					use std::net::IpAddr;
 | 
				
			||||||
 | 
					use std::time::Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn ping_server(ip: IpAddr) -> Result<bool, Box<dyn std::error::Error>> {
 | 
				
			||||||
 | 
					    match ping::new(ip)
 | 
				
			||||||
 | 
					        .socket_type(ping::SocketType::DGRAM)
 | 
				
			||||||
 | 
					        .timeout(Duration::from_secs(2))
 | 
				
			||||||
 | 
					        .send()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ok(_) => Ok(true),
 | 
				
			||||||
 | 
					        Err(e) => {
 | 
				
			||||||
 | 
					            eprintln!("Ping error: {}", e);
 | 
				
			||||||
 | 
					            Ok(false)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										178
									
								
								src/rhai_api.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								src/rhai_api.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
				
			|||||||
 | 
					use crate::async_handler::Response;
 | 
				
			||||||
 | 
					use crate::async_handler::Request;
 | 
				
			||||||
 | 
					use crate::hetzner_api::{HetznerClient, WrappedServer};
 | 
				
			||||||
 | 
					use rhai::{Engine, EvalAltResult};
 | 
				
			||||||
 | 
					use rhai::EvalContext;
 | 
				
			||||||
 | 
					use std::sync::{Arc, Mutex, mpsc::{Sender, Receiver}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn register_hetzner_api(
 | 
				
			||||||
 | 
					    engine: &mut Engine,
 | 
				
			||||||
 | 
					    command_tx: Sender<Request>,
 | 
				
			||||||
 | 
					    reply_rx: Arc<Mutex<Receiver<Response>>>,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    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 ping_server_tx = command_tx.clone();
 | 
				
			||||||
 | 
					    let ping_server_rx = reply_rx.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    engine
 | 
				
			||||||
 | 
					        .register_type_with_name::<HetznerClient>("HetznerClient")
 | 
				
			||||||
 | 
					        .register_fn("new_hetzner_client", HetznerClient::new)
 | 
				
			||||||
 | 
					        .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("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())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                match response {
 | 
				
			||||||
 | 
					                    Response::RebootServer(result) => result.map_err(|e| e.into()),
 | 
				
			||||||
 | 
					                    _ => Err("Unexpected response".into()),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .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(
 | 
				
			||||||
 | 
					            "ping",
 | 
				
			||||||
 | 
					            move |server: &mut WrappedServer| -> Result<bool, Box<EvalAltResult>> {
 | 
				
			||||||
 | 
					                ping_server_tx
 | 
				
			||||||
 | 
					                    .send(Request::PingServer(
 | 
				
			||||||
 | 
					                        server
 | 
				
			||||||
 | 
					                            .0
 | 
				
			||||||
 | 
					                            .public_net
 | 
				
			||||||
 | 
					                            .ipv4
 | 
				
			||||||
 | 
					                            .clone()
 | 
				
			||||||
 | 
					                            .unwrap()
 | 
				
			||||||
 | 
					                            .ip
 | 
				
			||||||
 | 
					                            .parse()
 | 
				
			||||||
 | 
					                            .unwrap(),
 | 
				
			||||||
 | 
					                    ))
 | 
				
			||||||
 | 
					                    .map_err(|e| e.to_string())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let response = ping_server_rx
 | 
				
			||||||
 | 
					                    .lock()
 | 
				
			||||||
 | 
					                    .unwrap()
 | 
				
			||||||
 | 
					                    .recv()
 | 
				
			||||||
 | 
					                    .map_err(|e| e.to_string())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                match response {
 | 
				
			||||||
 | 
					                    Response::PingServer(result) => result.map_err(|e| e.into()),
 | 
				
			||||||
 | 
					                    _ => Err("Unexpected response".into()),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .register_fn(
 | 
				
			||||||
 | 
					            "show_details",
 | 
				
			||||||
 | 
					            |server: &mut WrappedServer| -> Result<String, Box<EvalAltResult>> {
 | 
				
			||||||
 | 
					                let mut details = String::new();
 | 
				
			||||||
 | 
					                details.push_str(&format!("  ID: {}\n", server.0.id));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Status: {:?}\n", server.0.status));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Created: {}\n", server.0.created));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  IPv4: {}\n", server.0.public_net.ipv4.clone().unwrap().ip));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Type: {}\n", server.0.server_type.clone().name));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Included Traffic: {} GB\n", server.0.included_traffic.unwrap_or(0) / 1024 / 1024 / 1024));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Ingoing Traffic: {} MB\n", server.0.ingoing_traffic.unwrap_or(0) / 1024 / 1024));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Outgoing Traffic: {} MB\n", server.0.outgoing_traffic.unwrap_or(0) / 1024 / 1024));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Primary Disk Size: {} GB\n", server.0.primary_disk_size));
 | 
				
			||||||
 | 
					                details.push_str(&format!("  Rescue Enabled: {}\n", server.0.rescue_enabled));
 | 
				
			||||||
 | 
					                Ok(details)
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user