added functionality to create servers + example rhai script to demonstrate it
This commit is contained in:
parent
34e810b611
commit
6f12a1bf09
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -466,6 +466,7 @@ dependencies = [
|
||||
"prettytable-rs",
|
||||
"reqwest",
|
||||
"rhai",
|
||||
"serde",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@ -1261,6 +1262,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"rhai_codegen",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"smartstring",
|
||||
"thin-vec",
|
||||
@ -1519,6 +1521,9 @@ name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smartstring"
|
||||
@ -1527,6 +1532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"version_check",
|
||||
]
|
||||
@ -1662,6 +1668,9 @@ name = "thin-vec"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
|
@ -6,8 +6,9 @@ edition = "2024"
|
||||
[dependencies]
|
||||
hcloud = "0.21.0"
|
||||
reqwest = "0.12.22"
|
||||
rhai = { version = "1.22.2", features = ["sync"] }
|
||||
rhai = { version = "1.22.2", features = ["sync", "serde"] }
|
||||
tokio = { version = "1.46.1", features = ["full"] }
|
||||
|
||||
ping = "0.6.1"
|
||||
prettytable-rs = "0.10.0"
|
||||
serde = "1.0.219"
|
||||
|
44
README.md
44
README.md
@ -39,7 +39,42 @@ All API interactions start by creating a client instance.
|
||||
let client = new_hetzner_client(HETZNER_API_TOKEN);
|
||||
```
|
||||
|
||||
### 2. List Servers & Display Details
|
||||
### 2. Create a Server
|
||||
|
||||
You can create a new server using the `ServerBuilder` pattern. This provides a flexible way to configure the server before creation.
|
||||
|
||||
```rust
|
||||
// Create a server builder with required parameters
|
||||
let server_builder = new_server_builder("my-new-server", "cpx11", "ubuntu-20.04");
|
||||
|
||||
// Chain optional parameters
|
||||
let server_builder = server_builder
|
||||
.with_location("fsn1")
|
||||
.with_datacenter("fsn1-dc14")
|
||||
.with_start_after_create(true)
|
||||
.with_user_data("#cloud-config\nruncmd:\n - [ ls, -l, / ]");
|
||||
|
||||
// Specify SSH key IDs. If this is omitted, all SSH keys in your project will be used.
|
||||
let server_builder = server_builder.with_ssh_keys([12345, 67890]);
|
||||
|
||||
// Create the server
|
||||
let response = client.create_server(server_builder);
|
||||
|
||||
print(`Server creation initiated for: ${response.name}`);
|
||||
```
|
||||
|
||||
The following options are available on the `ServerBuilder`:
|
||||
|
||||
| Method | Description |
|
||||
| :--- | :--- |
|
||||
| `with_location(string)` | Sets the server location (e.g., "fsn1"). |
|
||||
| `with_datacenter(string)`| Sets the datacenter (e.g., "fsn1-dc14"). |
|
||||
| `with_user_data(string)` | Provides user data for cloud-init. |
|
||||
| `with_start_after_create(bool)` | Specifies whether the server should start after creation. |
|
||||
| `with_ssh_keys(array)` | An array of SSH Key IDs to attach to the server. |
|
||||
|
||||
|
||||
### 3. List Servers & Display Details
|
||||
|
||||
You can fetch all your servers and display their details in a formatted table.
|
||||
|
||||
@ -54,7 +89,7 @@ let test_server = client.get_server(104301883);
|
||||
print(test_server.show_details());
|
||||
```
|
||||
|
||||
### 3. List SSH Keys
|
||||
### 4. List SSH Keys
|
||||
|
||||
You can also list all the SSH keys in your project.
|
||||
|
||||
@ -65,7 +100,7 @@ let ssh_keys = client.list_ssh_keys();
|
||||
print(ssh_keys.show_table());
|
||||
```
|
||||
|
||||
### 4. Manage Server State
|
||||
### 5. Manage Server State
|
||||
|
||||
Perform actions like enabling rescue mode, disabling it, or rebooting the server.
|
||||
|
||||
@ -106,7 +141,7 @@ if ssh_key_from_env != "" {
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Example Output (from `test.rhai` script)
|
||||
### 6. Example Output (from `test.rhai` script)
|
||||
|
||||
```text
|
||||
Listing all servers...
|
||||
@ -155,4 +190,3 @@ Listing details from server with ID 104301883...
|
||||
+-------------------+----------------------+
|
||||
| Rescue Enabled | false |
|
||||
+-------------------+----------------------+
|
||||
```
|
||||
|
25
create_server.rhai
Normal file
25
create_server.rhai
Normal file
@ -0,0 +1,25 @@
|
||||
let client = new_hetzner_client(get_env("HETZNER_API_TOKEN"));
|
||||
|
||||
let server_builder = new_server_builder("my-new-test-server", "cx22", "ubuntu-24.04");
|
||||
|
||||
// Example of using the new optional parameters
|
||||
let server_builder = server_builder
|
||||
.with_location("fsn1");
|
||||
// .with_datacenter("fsn1-dc14")
|
||||
// .with_start_after_create(true)
|
||||
// .with_user_data("#cloud-config\nruncmd:\n - [ ls, -l, / ]");
|
||||
|
||||
// Example of specifying SSH key IDs.
|
||||
// If you don't call with_ssh_keys, all keys will be added by default.
|
||||
// let server_builder = server_builder.with_ssh_keys([12345, 67890]);
|
||||
|
||||
let response = client.create_server(server_builder);
|
||||
|
||||
print(`Server creation initiated for: ${response.name}`);
|
||||
print(` ID: ${response.id}`);
|
||||
print(` Status: ${response.status}`);
|
||||
if response.root_password != "" {
|
||||
print(` Root Password: ${response.root_password}`);
|
||||
} else {
|
||||
print(" Root Password: Not set (SSH key id was provided)");
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
use crate::hetzner_api::{HetznerClient, WrappedServer, WrappedSshKey};
|
||||
use crate::hetzner_api::{
|
||||
HetznerClient, ServerBuilder, WrappedCreateServerResponse, 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),
|
||||
@ -16,6 +19,7 @@ pub enum Request {
|
||||
}
|
||||
|
||||
pub enum Response {
|
||||
CreateServer(Result<WrappedCreateServerResponse, String>),
|
||||
ListSshKeys(Result<Vec<WrappedSshKey>, String>),
|
||||
ListServers(Result<Vec<WrappedServer>, String>),
|
||||
GetServerStatus(Result<String, String>),
|
||||
@ -38,12 +42,20 @@ pub fn run_worker(
|
||||
|
||||
while let Ok(request) = command_rx.recv() {
|
||||
let response = match request {
|
||||
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());
|
||||
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) => {
|
||||
|
@ -2,11 +2,14 @@ use hcloud::apis::{
|
||||
configuration::Configuration,
|
||||
servers_api::{
|
||||
self, DisableRescueModeForServerParams, EnableRescueModeForServerParams, ListServersParams,
|
||||
ResetServerParams,
|
||||
ResetServerParams, CreateServerParams,
|
||||
},
|
||||
ssh_keys_api::{self, ListSshKeysParams},
|
||||
};
|
||||
use hcloud::models::{EnableRescueModeForServerRequest, Server, SshKey};
|
||||
use hcloud::models::{
|
||||
CreateServerRequest, CreateServerResponse, EnableRescueModeForServerRequest, Server, SshKey,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HetznerClient {
|
||||
@ -19,6 +22,77 @@ pub struct WrappedServer(pub Server);
|
||||
#[derive(Clone)]
|
||||
pub struct WrappedSshKey(pub SshKey);
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ServerBuilder {
|
||||
pub name: String,
|
||||
pub server_type: String,
|
||||
pub image: String,
|
||||
pub location: Option<String>,
|
||||
pub datacenter: Option<String>,
|
||||
pub user_data: Option<String>,
|
||||
pub start_after_create: Option<bool>,
|
||||
pub ssh_keys: Option<Vec<i64>>,
|
||||
}
|
||||
|
||||
impl ServerBuilder {
|
||||
pub fn new(name: String, server_type: String, image: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
server_type,
|
||||
image,
|
||||
location: None,
|
||||
datacenter: None,
|
||||
user_data: None,
|
||||
start_after_create: None,
|
||||
ssh_keys: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_location(mut self, location: String) -> Self {
|
||||
self.location = Some(location);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_datacenter(mut self, datacenter: String) -> Self {
|
||||
self.datacenter = Some(datacenter);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_user_data(mut self, user_data: String) -> Self {
|
||||
self.user_data = Some(user_data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_start_after_create(mut self, start_after_create: bool) -> Self {
|
||||
self.start_after_create = Some(start_after_create);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_ssh_keys(mut self, ssh_keys: Vec<i64>) -> Self {
|
||||
self.ssh_keys = Some(ssh_keys);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> CreateServerRequest {
|
||||
CreateServerRequest {
|
||||
name: self.name,
|
||||
server_type: self.server_type,
|
||||
image: self.image,
|
||||
location: self.location,
|
||||
datacenter: self.datacenter,
|
||||
user_data: self.user_data,
|
||||
start_after_create: self.start_after_create,
|
||||
ssh_keys: self
|
||||
.ssh_keys
|
||||
.map(|keys| keys.into_iter().map(|id| id.to_string()).collect()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WrappedCreateServerResponse(pub CreateServerResponse);
|
||||
|
||||
impl HetznerClient {
|
||||
pub fn new(api_token: &str) -> Self {
|
||||
let mut configuration = Configuration::new();
|
||||
@ -32,6 +106,23 @@ impl HetznerClient {
|
||||
Self { configuration }
|
||||
}
|
||||
|
||||
pub async fn create_server(
|
||||
&self,
|
||||
mut builder: ServerBuilder,
|
||||
) -> Result<WrappedCreateServerResponse, Box<dyn std::error::Error>> {
|
||||
if builder.ssh_keys.is_none() {
|
||||
let all_keys = self.list_ssh_keys().await?;
|
||||
let key_ids: Vec<i64> = all_keys.into_iter().map(|k| k.0.id).collect();
|
||||
builder.ssh_keys = Some(key_ids);
|
||||
}
|
||||
|
||||
let params = CreateServerParams {
|
||||
create_server_request: Some(builder.build()),
|
||||
};
|
||||
let response = servers_api::create_server(&self.configuration, params).await?;
|
||||
Ok(WrappedCreateServerResponse(response))
|
||||
}
|
||||
|
||||
pub async fn list_servers(&self) -> Result<Vec<WrappedServer>, Box<dyn std::error::Error>> {
|
||||
let mut all_servers = Vec::new();
|
||||
let mut page = 1;
|
||||
|
380
src/rhai_api.rs
380
src/rhai_api.rs
@ -1,10 +1,15 @@
|
||||
use crate::async_handler::Response;
|
||||
use crate::async_handler::Request;
|
||||
use crate::hetzner_api::{HetznerClient, WrappedServer, WrappedSshKey};
|
||||
use crate::async_handler::Response;
|
||||
use crate::hetzner_api::{
|
||||
HetznerClient, ServerBuilder, WrappedCreateServerResponse, WrappedServer, WrappedSshKey,
|
||||
};
|
||||
use prettytable::{Cell, Row, Table};
|
||||
use rhai::{Engine, EvalAltResult};
|
||||
use std::env;
|
||||
use std::sync::{mpsc::{Receiver, Sender}, Arc, Mutex};
|
||||
use prettytable::{Table, Row, Cell};
|
||||
use std::sync::{
|
||||
Arc, Mutex,
|
||||
mpsc::{Receiver, Sender},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ApiBridge {
|
||||
@ -14,7 +19,10 @@ struct ApiBridge {
|
||||
|
||||
impl ApiBridge {
|
||||
fn new(command_tx: Sender<Request>, reply_rx: Arc<Mutex<Receiver<Response>>>) -> Self {
|
||||
Self { command_tx, reply_rx }
|
||||
Self {
|
||||
command_tx,
|
||||
reply_rx,
|
||||
}
|
||||
}
|
||||
|
||||
fn call<T>(
|
||||
@ -23,7 +31,12 @@ impl ApiBridge {
|
||||
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())?;
|
||||
let response = self
|
||||
.reply_rx
|
||||
.lock()
|
||||
.unwrap()
|
||||
.recv()
|
||||
.map_err(|e| e.to_string())?;
|
||||
response_handler(response)
|
||||
}
|
||||
}
|
||||
@ -37,171 +50,313 @@ pub fn register_hetzner_api(
|
||||
|
||||
engine
|
||||
.register_type_with_name::<HetznerClient>("HetznerClient")
|
||||
.register_fn("new_hetzner_client", |api_token: &str| -> Result<HetznerClient, Box<EvalAltResult>> {
|
||||
if api_token.is_empty() {
|
||||
return Err("HETZNER_API_TOKEN cannot be empty.".into());
|
||||
}
|
||||
Ok(HetznerClient::new(api_token))
|
||||
})
|
||||
.register_fn(
|
||||
"new_hetzner_client",
|
||||
|api_token: &str| -> Result<HetznerClient, Box<EvalAltResult>> {
|
||||
if api_token.is_empty() {
|
||||
return Err("HETZNER_API_TOKEN cannot be empty.".into());
|
||||
}
|
||||
Ok(HetznerClient::new(api_token))
|
||||
},
|
||||
)
|
||||
.register_fn("list_servers", {
|
||||
let bridge = api_bridge.clone();
|
||||
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()),
|
||||
})
|
||||
bridge.call(
|
||||
Request::ListServers(client.clone()),
|
||||
|response| match response {
|
||||
Response::ListServers(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.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()),
|
||||
})
|
||||
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", {
|
||||
let bridge = api_bridge.clone();
|
||||
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()),
|
||||
})
|
||||
bridge.call(
|
||||
Request::GetServerStatus(client.clone(), server_id),
|
||||
|response| match response {
|
||||
Response::GetServerStatus(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("get_server", {
|
||||
let bridge = api_bridge.clone();
|
||||
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()),
|
||||
bridge.call(
|
||||
Request::GetServer(client.clone(), server_id),
|
||||
|response| match response {
|
||||
Response::GetServer(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("create_server", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, builder: ServerBuilder| {
|
||||
bridge.call(Request::CreateServer(client.clone(), builder), |response| {
|
||||
match response {
|
||||
Response::CreateServer(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
engine
|
||||
.register_type_with_name::<ServerBuilder>("ServerBuilder")
|
||||
.register_fn(
|
||||
"new_server_builder",
|
||||
|name: String, server_type: String, image: String| {
|
||||
ServerBuilder::new(name, server_type, image)
|
||||
},
|
||||
)
|
||||
.register_fn("with_location", ServerBuilder::with_location)
|
||||
.register_fn("with_datacenter", ServerBuilder::with_datacenter)
|
||||
.register_fn("with_user_data", ServerBuilder::with_user_data)
|
||||
.register_fn(
|
||||
"with_start_after_create",
|
||||
ServerBuilder::with_start_after_create,
|
||||
)
|
||||
.register_fn(
|
||||
"with_ssh_keys",
|
||||
|builder: ServerBuilder, ssh_keys: rhai::Array| {
|
||||
builder.with_ssh_keys(
|
||||
ssh_keys
|
||||
.into_iter()
|
||||
.map(|k| k.as_int().unwrap())
|
||||
.collect(),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
engine
|
||||
.register_type_with_name::<WrappedCreateServerResponse>("CreateServerResponse")
|
||||
.register_get("id", |resp: &mut WrappedCreateServerResponse| {
|
||||
resp.0.server.id
|
||||
})
|
||||
.register_get("name", |resp: &mut WrappedCreateServerResponse| {
|
||||
resp.0.server.name.clone()
|
||||
})
|
||||
.register_get("status", |resp: &mut WrappedCreateServerResponse| {
|
||||
format!("{:?}", resp.0.server.status)
|
||||
})
|
||||
.register_get("root_password", |resp: &mut WrappedCreateServerResponse| {
|
||||
resp.0.root_password.clone().unwrap_or_default()
|
||||
});
|
||||
|
||||
engine
|
||||
.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_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
|
||||
});
|
||||
|
||||
engine
|
||||
.register_fn("reboot", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, server_id: i64| {
|
||||
bridge.call(Request::RebootServer(client.clone(), server_id), |response| {
|
||||
match response {
|
||||
bridge.call(
|
||||
Request::RebootServer(client.clone(), server_id),
|
||||
|response| match response {
|
||||
Response::RebootServer(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("reset", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, server_id: i64| {
|
||||
bridge.call(Request::ResetServer(client.clone(), server_id), |response| {
|
||||
match response {
|
||||
bridge.call(
|
||||
Request::ResetServer(client.clone(), server_id),
|
||||
|response| match response {
|
||||
Response::ResetServer(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("enable_rescue_mode", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, server_id: i64| {
|
||||
bridge.call(Request::EnableRescueModeWithAllKeys(client.clone(), server_id), |response| {
|
||||
match response {
|
||||
bridge.call(
|
||||
Request::EnableRescueModeWithAllKeys(client.clone(), server_id),
|
||||
|response| match response {
|
||||
Response::EnableRescueMode(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("enable_rescue_mode", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, server_id: i64, ssh_key: i64| {
|
||||
bridge.call(Request::EnableRescueMode(client.clone(), server_id, vec![ssh_key]), |response| {
|
||||
match response {
|
||||
bridge.call(
|
||||
Request::EnableRescueMode(client.clone(), server_id, vec![ssh_key]),
|
||||
|response| match response {
|
||||
Response::EnableRescueMode(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("enable_rescue_mode", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, server_id: i64, ssh_keys: rhai::Array| {
|
||||
let keys: Vec<i64> = ssh_keys.into_iter().map(|k| k.as_int().unwrap_or(0)).collect();
|
||||
bridge.call(Request::EnableRescueMode(client.clone(), server_id, keys), |response| {
|
||||
match response {
|
||||
let keys: Vec<i64> = ssh_keys
|
||||
.into_iter()
|
||||
.map(|k| k.as_int().unwrap_or(0))
|
||||
.collect();
|
||||
bridge.call(
|
||||
Request::EnableRescueMode(client.clone(), server_id, keys),
|
||||
|response| match response {
|
||||
Response::EnableRescueMode(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.register_fn("disable_rescue_mode", {
|
||||
let bridge = api_bridge.clone();
|
||||
move |client: &mut HetznerClient, server_id: i64| {
|
||||
bridge.call(Request::DisableRescueMode(client.clone(), server_id), |response| {
|
||||
match response {
|
||||
bridge.call(
|
||||
Request::DisableRescueMode(client.clone(), server_id),
|
||||
|response| match response {
|
||||
Response::DisableRescueMode(result) => result.map_err(|e| e.into()),
|
||||
_ => Err("Unexpected response".into()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
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")]));
|
||||
table.add_row(Row::new(vec![
|
||||
Cell::new("ID"),
|
||||
Cell::new("Name"),
|
||||
Cell::new("Status"),
|
||||
Cell::new("Public IPv4"),
|
||||
]));
|
||||
for server in servers {
|
||||
.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")]));
|
||||
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()),
|
||||
Cell::new(&server.0.name),
|
||||
]));
|
||||
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()),
|
||||
]));
|
||||
}
|
||||
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())]));
|
||||
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())
|
||||
});
|
||||
Ok(table.to_string())
|
||||
},
|
||||
);
|
||||
|
||||
engine.register_fn("get_env", |key: &str| -> String {
|
||||
env::var(key).unwrap_or("".to_string())
|
||||
@ -211,27 +366,34 @@ pub fn register_hetzner_api(
|
||||
.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());
|
||||
.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 {
|
||||
.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(&key.0.id.to_string()),
|
||||
Cell::new(&key.0.name),
|
||||
Cell::new(&key.0.fingerprint),
|
||||
Cell::new("ID"),
|
||||
Cell::new("Name"),
|
||||
Cell::new("Fingerprint"),
|
||||
]));
|
||||
}
|
||||
Ok(table.to_string())
|
||||
});
|
||||
}
|
||||
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())
|
||||
},
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user