added functionality to list SSH key IDs
This commit is contained in:
parent
be4f35af98
commit
841901368f
@ -1,4 +1,4 @@
|
|||||||
use crate::hetzner_api::{HetznerClient, WrappedServer};
|
use crate::hetzner_api::{HetznerClient, WrappedServer, WrappedSshKey};
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
use tokio::runtime::Builder;
|
use tokio::runtime::Builder;
|
||||||
|
|
||||||
@ -11,9 +11,11 @@ pub enum Request {
|
|||||||
ResetServer(HetznerClient, i64),
|
ResetServer(HetznerClient, i64),
|
||||||
EnableRescueMode(HetznerClient, i64, Vec<i64>),
|
EnableRescueMode(HetznerClient, i64, Vec<i64>),
|
||||||
DisableRescueMode(HetznerClient, i64),
|
DisableRescueMode(HetznerClient, i64),
|
||||||
|
ListSshKeys(HetznerClient),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Response {
|
pub enum Response {
|
||||||
|
ListSshKeys(Result<Vec<WrappedSshKey>, String>),
|
||||||
ListServers(Result<Vec<WrappedServer>, String>),
|
ListServers(Result<Vec<WrappedServer>, String>),
|
||||||
GetServerStatus(Result<String, String>),
|
GetServerStatus(Result<String, String>),
|
||||||
GetServer(Result<WrappedServer, String>),
|
GetServer(Result<WrappedServer, String>),
|
||||||
@ -63,6 +65,10 @@ pub fn run_worker(
|
|||||||
let result = rt.block_on(client.disable_rescue_mode_for_server(server_id)).map_err(|e| e.to_string());
|
let result = rt.block_on(client.disable_rescue_mode_for_server(server_id)).map_err(|e| e.to_string());
|
||||||
Response::DisableRescueMode(result)
|
Response::DisableRescueMode(result)
|
||||||
}
|
}
|
||||||
|
Request::ListSshKeys(client) => {
|
||||||
|
let result = rt.block_on(client.list_ssh_keys()).map_err(|e| e.to_string());
|
||||||
|
Response::ListSshKeys(result)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
reply_tx.send(response).expect("Failed to send response");
|
reply_tx.send(response).expect("Failed to send response");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
use hcloud::apis::{configuration::Configuration, servers_api::{self, ListServersParams, ResetServerParams, EnableRescueModeForServerParams, DisableRescueModeForServerParams}};
|
use hcloud::apis::{
|
||||||
use hcloud::models::{Server, EnableRescueModeForServerRequest};
|
configuration::Configuration,
|
||||||
|
servers_api::{
|
||||||
|
self, DisableRescueModeForServerParams, EnableRescueModeForServerParams, ListServersParams,
|
||||||
|
ResetServerParams,
|
||||||
|
},
|
||||||
|
ssh_keys_api::{self, ListSshKeysParams},
|
||||||
|
};
|
||||||
|
use hcloud::models::{EnableRescueModeForServerRequest, Server, SshKey};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct HetznerClient {
|
pub struct HetznerClient {
|
||||||
@ -9,6 +16,9 @@ pub struct HetznerClient {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WrappedServer(pub Server);
|
pub struct WrappedServer(pub Server);
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct WrappedSshKey(pub SshKey);
|
||||||
|
|
||||||
impl HetznerClient {
|
impl HetznerClient {
|
||||||
pub fn new(api_token: &str) -> Self {
|
pub fn new(api_token: &str) -> Self {
|
||||||
let mut configuration = Configuration::new();
|
let mut configuration = Configuration::new();
|
||||||
@ -19,7 +29,6 @@ impl HetznerClient {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
configuration.client = client;
|
configuration.client = client;
|
||||||
|
|
||||||
|
|
||||||
Self { configuration }
|
Self { configuration }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,11 +45,12 @@ impl HetznerClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let response = servers_api::list_servers(&self.configuration, params).await?;
|
let response = servers_api::list_servers(&self.configuration, params).await?;
|
||||||
let mut servers: Vec<WrappedServer> = response.servers.into_iter().map(WrappedServer).collect();
|
let mut servers: Vec<WrappedServer> =
|
||||||
|
response.servers.into_iter().map(WrappedServer).collect();
|
||||||
let is_empty = servers.is_empty();
|
let is_empty = servers.is_empty();
|
||||||
|
|
||||||
all_servers.append(&mut servers);
|
all_servers.append(&mut servers);
|
||||||
|
|
||||||
if is_empty || response.meta.pagination.next_page.is_none() {
|
if is_empty || response.meta.pagination.next_page.is_none() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -51,12 +61,12 @@ impl HetznerClient {
|
|||||||
Ok(all_servers)
|
Ok(all_servers)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_server_status(&self, server_id: i64) -> Result<String, Box<dyn std::error::Error>> {
|
pub async fn get_server_status(
|
||||||
let params = servers_api::GetServerParams {
|
&self,
|
||||||
id: server_id,
|
server_id: i64,
|
||||||
};
|
) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
let server_response = servers_api::get_server(&self.configuration, params)
|
let params = servers_api::GetServerParams { id: server_id };
|
||||||
.await?;
|
let server_response = servers_api::get_server(&self.configuration, params).await?;
|
||||||
|
|
||||||
if let Some(server) = server_response.server {
|
if let Some(server) = server_response.server {
|
||||||
Ok(format!("{:?}", server.status))
|
Ok(format!("{:?}", server.status))
|
||||||
@ -65,12 +75,12 @@ impl HetznerClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_server(&self, server_id: i64) -> Result<WrappedServer, Box<dyn std::error::Error>> {
|
pub async fn get_server(
|
||||||
let params = servers_api::GetServerParams {
|
&self,
|
||||||
id: server_id,
|
server_id: i64,
|
||||||
};
|
) -> Result<WrappedServer, Box<dyn std::error::Error>> {
|
||||||
let server_response = servers_api::get_server(&self.configuration, params)
|
let params = servers_api::GetServerParams { id: server_id };
|
||||||
.await?;
|
let server_response = servers_api::get_server(&self.configuration, params).await?;
|
||||||
|
|
||||||
if let Some(server) = server_response.server {
|
if let Some(server) = server_response.server {
|
||||||
Ok(WrappedServer(*server))
|
Ok(WrappedServer(*server))
|
||||||
@ -80,37 +90,73 @@ impl HetznerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reboot_server(&self, server_id: i64) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn reboot_server(&self, server_id: i64) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let params = servers_api::SoftRebootServerParams {
|
let params = servers_api::SoftRebootServerParams { id: server_id };
|
||||||
id: server_id,
|
|
||||||
};
|
|
||||||
servers_api::soft_reboot_server(&self.configuration, params).await?;
|
servers_api::soft_reboot_server(&self.configuration, params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reset_server(&self, server_id: i64) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn reset_server(&self, server_id: i64) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let params = ResetServerParams {
|
let params = ResetServerParams { id: server_id };
|
||||||
id: server_id,
|
|
||||||
};
|
|
||||||
servers_api::reset_server(&self.configuration, params).await?;
|
servers_api::reset_server(&self.configuration, params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub async fn enable_rescue_mode_for_server(&self, server_id: i64, ssh_keys: Vec<i64>) -> Result<String, Box<dyn std::error::Error>> {
|
pub async fn enable_rescue_mode_for_server(
|
||||||
|
&self,
|
||||||
|
server_id: i64,
|
||||||
|
ssh_keys: Vec<i64>,
|
||||||
|
) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
let params = EnableRescueModeForServerParams {
|
let params = EnableRescueModeForServerParams {
|
||||||
id: server_id,
|
id: server_id,
|
||||||
enable_rescue_mode_for_server_request: Some(EnableRescueModeForServerRequest {
|
enable_rescue_mode_for_server_request: Some(EnableRescueModeForServerRequest {
|
||||||
ssh_keys: if ssh_keys.is_empty() { None } else { Some(ssh_keys) },
|
ssh_keys: if ssh_keys.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ssh_keys)
|
||||||
|
},
|
||||||
r#type: Some(hcloud::models::enable_rescue_mode_for_server_request::Type::Linux64),
|
r#type: Some(hcloud::models::enable_rescue_mode_for_server_request::Type::Linux64),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
let response = servers_api::enable_rescue_mode_for_server(&self.configuration, params).await?;
|
let response =
|
||||||
Ok(response.root_password.expect("Unable to fetch root_password from enabling rescue mode for server response"))
|
servers_api::enable_rescue_mode_for_server(&self.configuration, params).await?;
|
||||||
|
Ok(response
|
||||||
|
.root_password
|
||||||
|
.expect("Unable to fetch root_password from enabling rescue mode for server response"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn disable_rescue_mode_for_server(&self, server_id: i64) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn disable_rescue_mode_for_server(
|
||||||
let params = DisableRescueModeForServerParams {
|
&self,
|
||||||
id: server_id,
|
server_id: i64,
|
||||||
};
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let params = DisableRescueModeForServerParams { id: server_id };
|
||||||
servers_api::disable_rescue_mode_for_server(&self.configuration, params).await?;
|
servers_api::disable_rescue_mode_for_server(&self.configuration, params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub async fn list_ssh_keys(&self) -> Result<Vec<WrappedSshKey>, Box<dyn std::error::Error>> {
|
||||||
|
let mut all_keys = Vec::new();
|
||||||
|
let mut page = 1;
|
||||||
|
let per_page = 50;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let params = ListSshKeysParams {
|
||||||
|
page: Some(page),
|
||||||
|
per_page: Some(per_page),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = ssh_keys_api::list_ssh_keys(&self.configuration, params).await?;
|
||||||
|
let mut keys: Vec<WrappedSshKey> =
|
||||||
|
response.ssh_keys.into_iter().map(WrappedSshKey).collect();
|
||||||
|
let is_empty = keys.is_empty();
|
||||||
|
|
||||||
|
all_keys.append(&mut keys);
|
||||||
|
|
||||||
|
if is_empty || response.meta.pagination.next_page.is_none() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
page += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(all_keys)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::async_handler::Response;
|
use crate::async_handler::Response;
|
||||||
use crate::async_handler::Request;
|
use crate::async_handler::Request;
|
||||||
use crate::hetzner_api::{HetznerClient, WrappedServer};
|
use crate::hetzner_api::{HetznerClient, WrappedServer, WrappedSshKey};
|
||||||
use rhai::{Engine, EvalAltResult};
|
use rhai::{Engine, EvalAltResult};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::{mpsc::{Receiver, Sender}, Arc, Mutex};
|
use std::sync::{mpsc::{Receiver, Sender}, Arc, Mutex};
|
||||||
@ -52,6 +52,15 @@ pub fn register_hetzner_api(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.register_fn("list_ssh_keys", {
|
||||||
|
let bridge = api_bridge.clone();
|
||||||
|
move |client: &mut HetznerClient| {
|
||||||
|
bridge.call(Request::ListSshKeys(client.clone()), |response| match response {
|
||||||
|
Response::ListSshKeys(result) => result.map_err(|e| e.into()),
|
||||||
|
_ => Err("Unexpected response".into()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
.register_fn("get_server_status", {
|
.register_fn("get_server_status", {
|
||||||
let bridge = api_bridge.clone();
|
let bridge = api_bridge.clone();
|
||||||
move |client: &mut HetznerClient, server_id: i64| {
|
move |client: &mut HetznerClient, server_id: i64| {
|
||||||
@ -197,4 +206,32 @@ pub fn register_hetzner_api(
|
|||||||
engine.register_fn("get_env", |key: &str| -> String {
|
engine.register_fn("get_env", |key: &str| -> String {
|
||||||
env::var(key).unwrap_or("".to_string())
|
env::var(key).unwrap_or("".to_string())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
engine
|
||||||
|
.register_type_with_name::<WrappedSshKey>("SshKey")
|
||||||
|
.register_get("id", |key: &mut WrappedSshKey| key.0.id)
|
||||||
|
.register_get("name", |key: &mut WrappedSshKey| key.0.name.clone())
|
||||||
|
.register_get("fingerprint", |key: &mut WrappedSshKey| key.0.fingerprint.clone());
|
||||||
|
|
||||||
|
engine
|
||||||
|
.register_iterator::<Vec<WrappedSshKey>>()
|
||||||
|
.register_fn("len", |list: &mut Vec<WrappedSshKey>| list.len() as i64)
|
||||||
|
.register_indexer_get(|list: &mut Vec<WrappedSshKey>, index: i64| list[index as usize].clone())
|
||||||
|
.register_fn("show_table", |keys: &mut Vec<WrappedSshKey>| -> Result<String, Box<EvalAltResult>> {
|
||||||
|
let mut table = Table::new();
|
||||||
|
table.set_titles(Row::new(vec![Cell::new("SSH Keys").style_spec("c")]));
|
||||||
|
table.add_row(Row::new(vec![
|
||||||
|
Cell::new("ID"),
|
||||||
|
Cell::new("Name"),
|
||||||
|
Cell::new("Fingerprint"),
|
||||||
|
]));
|
||||||
|
for key in keys {
|
||||||
|
table.add_row(Row::new(vec![
|
||||||
|
Cell::new(&key.0.id.to_string()),
|
||||||
|
Cell::new(&key.0.name),
|
||||||
|
Cell::new(&key.0.fingerprint),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
Ok(table.to_string())
|
||||||
|
});
|
||||||
}
|
}
|
22
test.rhai
22
test.rhai
@ -5,6 +5,10 @@ let client = new_hetzner_client(HETZNER_API_TOKEN);
|
|||||||
print("Listing all servers...");
|
print("Listing all servers...");
|
||||||
let servers = client.list_servers();
|
let servers = client.list_servers();
|
||||||
print(servers.show_table());
|
print(servers.show_table());
|
||||||
|
// List all SSH keys and print in table
|
||||||
|
print("Listing all SSH keys...");
|
||||||
|
let ssh_keys = client.list_ssh_keys();
|
||||||
|
print(ssh_keys.show_table());
|
||||||
|
|
||||||
// Get server through ID and print details in table
|
// Get server through ID and print details in table
|
||||||
print("Listing details from server with ID 104301883...");
|
print("Listing details from server with ID 104301883...");
|
||||||
@ -12,19 +16,19 @@ let test_server = client.get_server(104301883);
|
|||||||
print(test_server.show_details());
|
print(test_server.show_details());
|
||||||
|
|
||||||
// Enable rescue mode flag on server
|
// Enable rescue mode flag on server
|
||||||
print(`Enabling rescue mode on server with ID: ${test_server.id}`);
|
// print(`Enabling rescue mode on server with ID: ${test_server.id}`);
|
||||||
let root_password = client.enable_rescue_mode(test_server.id, 1337);
|
// let root_password = client.enable_rescue_mode(test_server.id, 1337);
|
||||||
print(`Root password is: ${root_password}`);
|
// print(`Root password is: ${root_password}`);
|
||||||
|
|
||||||
// Enable rescue mode with multiple keys from array
|
// Enable rescue mode with multiple keys from array
|
||||||
let ssh_keys = [123, 456, 789];
|
let ssh_keys = [100324992, 100325001];
|
||||||
let root_password = client.enable_rescue_mode(test_server.id, ssh_keys);
|
let root_password = client.enable_rescue_mode(test_server.id, ssh_keys);
|
||||||
|
|
||||||
// read SSH key from env var
|
// // read SSH key from env var and use it for rescue mode
|
||||||
let ssh_key_from_env = get_env("SSH_KEY_ID");
|
// let ssh_key_from_env = get_env("SSH_KEY_ID");
|
||||||
if ssh_key_from_env != "" {
|
// if ssh_key_from_env != "" {
|
||||||
client.enable_rescue_mode(test_server.id, ssh_key_from_env.parse_int());
|
// client.enable_rescue_mode(test_server.id, ssh_key_from_env.parse_int());
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Disable rescue mode flag on server
|
// Disable rescue mode flag on server
|
||||||
print(`Disabling rescue mode on server with ID: ${test_server.id}`);
|
print(`Disabling rescue mode on server with ID: ${test_server.id}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user