use crate::hetzner_api::{ HetznerClient, ListImagesParamsBuilder, ServerBuilder, WrappedCreateServerResponse, WrappedImage, WrappedServer, WrappedSshKey, }; use std::sync::mpsc::{Receiver, Sender}; use tokio::runtime::Builder; #[derive(Clone)] pub enum Request { CreateServer(HetznerClient, ServerBuilder), ListServers(HetznerClient), GetServerStatus(HetznerClient, i64), GetServer(HetznerClient, i64), RebootServer(HetznerClient, i64), ResetServer(HetznerClient, i64), EnableRescueMode(HetznerClient, i64, Vec), EnableRescueModeWithAllKeys(HetznerClient, i64), DisableRescueMode(HetznerClient, i64), ListSshKeys(HetznerClient), ListImages(HetznerClient, ListImagesParamsBuilder), InstallImage(HetznerClient, i64, String), } pub enum Response { CreateServer(Result), ListSshKeys(Result, String>), ListServers(Result, String>), GetServerStatus(Result), GetServer(Result), RebootServer(Result<(), String>), ResetServer(Result<(), String>), EnableRescueMode(Result), DisableRescueMode(Result<(), String>), ListImages(Result, String>), InstallImage(Result<(), String>), } pub fn run_worker(command_rx: Receiver, reply_tx: Sender) { std::thread::spawn(move || { let rt = Builder::new_current_thread() .enable_all() .build() .expect("Failed to create async runtime"); while let Ok(request) = command_rx.recv() { let response = match request { Request::ListImages(client, builder) => { let result = rt .block_on(client.list_images(builder)) .map_err(|e| e.to_string()); Response::ListImages(result) } Request::CreateServer(client, builder) => { let result = rt .block_on(client.create_server(builder)) .map_err(|e| e.to_string()); Response::CreateServer(result) } 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::ResetServer(client, server_id) => { let result = rt .block_on(client.reset_server(server_id)) .map_err(|e| e.to_string()); Response::ResetServer(result) } Request::EnableRescueMode(client, server_id, ssh_keys) => { let result = rt .block_on(client.enable_rescue_mode_for_server(server_id, ssh_keys)) .map_err(|e| e.to_string()); Response::EnableRescueMode(result) } Request::EnableRescueModeWithAllKeys(client, server_id) => { let result = rt .block_on(async { let ssh_keys = client.list_ssh_keys().await?; let ssh_key_ids: Vec = ssh_keys.into_iter().map(|k| k.0.id).collect(); println!("Passing in the following ssh key ids: {:#?}", ssh_key_ids); client .enable_rescue_mode_for_server(server_id, ssh_key_ids) .await }) .map_err(|e: Box| e.to_string()); Response::EnableRescueMode(result) } Request::DisableRescueMode(client, server_id) => { let result = rt .block_on(client.disable_rescue_mode_for_server(server_id)) .map_err(|e| e.to_string()); Response::DisableRescueMode(result) } Request::ListSshKeys(client) => { let result = rt .block_on(client.list_ssh_keys()) .map_err(|e| e.to_string()); Response::ListSshKeys(result) } Request::InstallImage(client, server_id, image) => { let result = rt .block_on(client.install_image(server_id, image)) .map_err(|e| e.to_string()); Response::InstallImage(result) } }; reply_tx.send(response).expect("Failed to send response"); } }); }