1895 lines
67 KiB
Rust
1895 lines
67 KiB
Rust
use prettytable::{Table, row};
|
|
use rhai::{Array, CustomType, TypeBuilder};
|
|
use serde::{Deserialize, Deserializer};
|
|
use serde_json::Value;
|
|
use std::fmt;
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct ServerWrapper {
|
|
pub server: Server,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Server {
|
|
pub server_ip: Option<String>,
|
|
pub server_ipv6_net: Option<String>,
|
|
pub server_number: i32,
|
|
pub server_name: String,
|
|
pub product: String,
|
|
pub dc: String,
|
|
pub traffic: String,
|
|
pub status: String,
|
|
pub cancelled: bool,
|
|
pub paid_until: String,
|
|
pub ip: Option<Vec<String>>,
|
|
pub subnet: Option<Vec<Subnet>>,
|
|
pub reset: Option<bool>,
|
|
pub rescue: Option<bool>,
|
|
pub vnc: Option<bool>,
|
|
pub windows: Option<bool>,
|
|
pub plesk: Option<bool>,
|
|
pub cpanel: Option<bool>,
|
|
pub wol: Option<bool>,
|
|
pub hot_swap: Option<bool>,
|
|
pub linked_storagebox: Option<i32>,
|
|
}
|
|
|
|
impl Server {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Server")
|
|
.with_get("server_ip", |s: &mut Server| {
|
|
s.server_ip.clone().unwrap_or_default()
|
|
})
|
|
.with_get("server_ipv6_net", |s: &mut Server| {
|
|
s.server_ipv6_net.clone().unwrap_or_default()
|
|
})
|
|
.with_get("server_number", |s: &mut Server| s.server_number)
|
|
.with_get("server_name", |s: &mut Server| s.server_name.clone())
|
|
.with_get("product", |s: &mut Server| s.product.clone())
|
|
.with_get("dc", |s: &mut Server| s.dc.clone())
|
|
.with_get("traffic", |s: &mut Server| s.traffic.clone())
|
|
.with_get("status", |s: &mut Server| s.status.clone())
|
|
.with_get("cancelled", |s: &mut Server| s.cancelled)
|
|
.with_get("paid_until", |s: &mut Server| s.paid_until.clone())
|
|
.with_get("ip", |s: &mut Server| s.ip.clone().unwrap_or_default())
|
|
.with_get("subnet", |s: &mut Server| s.subnet.clone())
|
|
.with_get("reset", |s: &mut Server| s.reset.clone())
|
|
.with_get("rescue", |s: &mut Server| s.rescue.clone())
|
|
.with_get("vnc", |s: &mut Server| s.vnc.clone())
|
|
.with_get("windows", |s: &mut Server| s.windows.clone())
|
|
.with_get("plesk", |s: &mut Server| s.plesk.clone())
|
|
.with_get("cpanel", |s: &mut Server| s.cpanel.clone())
|
|
.with_get("wol", |s: &mut Server| s.wol.clone())
|
|
.with_get("hot_swap", |s: &mut Server| s.hot_swap.clone())
|
|
.with_get("linked_storagebox", |s: &mut Server| {
|
|
s.linked_storagebox.clone()
|
|
})
|
|
// when doing `print(server) in Rhai script, this will execute`
|
|
.on_print(|s: &mut Server| s.to_string())
|
|
// also add the pretty_print function for convience
|
|
.with_fn("pretty_print", |s: &mut Server| s.to_string());
|
|
}
|
|
}
|
|
|
|
// Server should always be printed as a table, hence implement the Display trait to render the table
|
|
impl fmt::Display for Server {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["Server Number", self.server_number.to_string()]);
|
|
table.add_row(row!["Server Name", self.server_name.clone()]);
|
|
table.add_row(row![
|
|
"Server IP",
|
|
self.server_ip.as_deref().unwrap_or("N/A")
|
|
]);
|
|
table.add_row(row![
|
|
"IPv6 Network",
|
|
self.server_ipv6_net.as_deref().unwrap_or("N/A")
|
|
]);
|
|
table.add_row(row!["Product", self.product.clone()]);
|
|
table.add_row(row!["Datacenter", self.dc.clone()]);
|
|
table.add_row(row!["Traffic", self.traffic.clone()]);
|
|
table.add_row(row!["Status", self.status.clone()]);
|
|
table.add_row(row!["Cancelled", self.cancelled.to_string()]);
|
|
table.add_row(row!["Paid Until", self.paid_until.clone()]);
|
|
table.add_row(row!["IP Addresses", self.ip.as_deref().unwrap_or_default().join(", ")]);
|
|
table.add_row(row!["Reset", self.reset.unwrap_or(false).to_string()]);
|
|
table.add_row(row!["VNC", self.vnc.unwrap_or(false).to_string()]);
|
|
table.add_row(row!["Windows", self.windows.is_some().to_string()]);
|
|
table.add_row(row!["Plesk", self.plesk.is_some().to_string()]);
|
|
table.add_row(row!["cPanel", self.cpanel.is_some().to_string()]);
|
|
table.add_row(row!["WOL", self.wol.unwrap_or(false).to_string()]);
|
|
table.add_row(row!["Hot Swap", self.hot_swap.unwrap_or(false).to_string()]);
|
|
table.add_row(row![
|
|
"Linked Storagebox",
|
|
self.linked_storagebox
|
|
.map_or("N/A".to_string(), |id| id.to_string())
|
|
]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Subnet {
|
|
pub ip: String,
|
|
pub mask: String,
|
|
}
|
|
|
|
impl Subnet {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Subnet")
|
|
.with_get("ip", |s: &mut Subnet| s.ip.clone())
|
|
.with_get("mask", |s: &mut Subnet| s.mask.clone())
|
|
.on_print(|s: &mut Subnet| s.to_string())
|
|
.with_fn("pretty_print", |s: &mut Subnet| s.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Subnet {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "IP: {}, Mask: {}", self.ip, self.mask)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct SshKeyWrapper {
|
|
pub key: SshKey,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct SshKey {
|
|
pub name: String,
|
|
pub fingerprint: String,
|
|
#[serde(rename = "type")]
|
|
pub key_type: String,
|
|
pub size: i32,
|
|
pub data: String,
|
|
pub created_at: String,
|
|
}
|
|
|
|
impl SshKey {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("SshKey")
|
|
.with_get("name", |s: &mut SshKey| s.name.clone())
|
|
.with_get("fingerprint", |s: &mut SshKey| s.fingerprint.clone())
|
|
.with_get("key_type", |s: &mut SshKey| s.key_type.clone())
|
|
.with_get("size", |s: &mut SshKey| s.size)
|
|
.with_get("data", |s: &mut SshKey| s.data.clone())
|
|
.with_get("created_at", |s: &mut SshKey| s.created_at.clone())
|
|
.on_print(|s: &mut SshKey| s.to_string())
|
|
.with_fn("pretty_print", |s: &mut SshKey| s.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for SshKey {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Name", "Fingerprint", "Type", "Size", "Created At"]);
|
|
table.add_row(row![
|
|
self.name.clone(),
|
|
self.fingerprint.clone(),
|
|
self.key_type.clone(),
|
|
self.size.to_string(),
|
|
self.created_at.clone()
|
|
]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct BootWrapper {
|
|
pub boot: Boot,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Boot {
|
|
pub rescue: Rescue,
|
|
pub linux: Linux,
|
|
pub vnc: Vnc,
|
|
pub windows: Option<Windows>,
|
|
pub plesk: Option<Plesk>,
|
|
pub cpanel: Option<Cpanel>,
|
|
}
|
|
|
|
impl Boot {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Boot")
|
|
.with_get("rescue", |b: &mut Boot| b.rescue.clone())
|
|
.with_get("linux", |b: &mut Boot| b.linux.clone())
|
|
.with_get("vnc", |b: &mut Boot| b.vnc.clone())
|
|
.with_get("windows", |b: &mut Boot| b.windows.clone())
|
|
.with_get("plesk", |b: &mut Boot| b.plesk.clone())
|
|
.with_get("cpanel", |b: &mut Boot| b.cpanel.clone())
|
|
.on_print(|b: &mut Boot| b.to_string())
|
|
.with_fn("pretty_print", |b: &mut Boot| b.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Boot {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Configuration", "Details"]);
|
|
table.add_row(row!["Rescue", self.rescue.to_string()]);
|
|
table.add_row(row!["Linux", self.linux.to_string()]);
|
|
table.add_row(row!["VNC", self.vnc.to_string()]);
|
|
if let Some(windows) = &self.windows {
|
|
table.add_row(row!["Windows", windows.to_string()]);
|
|
}
|
|
if let Some(plesk) = &self.plesk {
|
|
table.add_row(row!["Plesk", plesk.to_string()]);
|
|
}
|
|
if let Some(cpanel) = &self.cpanel {
|
|
table.add_row(row!["cPanel", cpanel.to_string()]);
|
|
}
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
#[serde(untagged)]
|
|
pub enum Os {
|
|
Single(String),
|
|
Multiple(Vec<String>),
|
|
}
|
|
|
|
impl Os {
|
|
pub fn to_vec(&self) -> Vec<String> {
|
|
match self {
|
|
Os::Single(s) => vec![s.clone()],
|
|
Os::Multiple(v) => v.clone(),
|
|
}
|
|
}
|
|
}
|
|
#[derive(Deserialize)]
|
|
pub struct RescueWrapped {
|
|
pub rescue: Rescue,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Rescue {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: String,
|
|
pub server_number: i32,
|
|
pub os: Os,
|
|
pub active: bool,
|
|
pub password: Option<String>,
|
|
#[serde(rename = "authorized_key")]
|
|
pub authorized_keys: Vec<RescueKey>,
|
|
pub host_key: Vec<HostKey>,
|
|
}
|
|
|
|
impl Rescue {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Rescue")
|
|
.with_get("server_ip", |r: &mut Rescue| r.server_ip.clone())
|
|
.with_get("server_ipv6_net", |r: &mut Rescue| {
|
|
r.server_ipv6_net.clone()
|
|
})
|
|
.with_get("server_number", |r: &mut Rescue| r.server_number)
|
|
.with_get("os", |r: &mut Rescue| r.os.to_vec())
|
|
.with_get("active", |r: &mut Rescue| r.active)
|
|
.with_get("password", |r: &mut Rescue| r.password.clone())
|
|
.with_get("authorized_keys", |r: &mut Rescue| {
|
|
r.authorized_keys
|
|
.iter()
|
|
.map(|k| rhai::Dynamic::from(k.key.clone()))
|
|
.collect::<rhai::Array>()
|
|
})
|
|
.with_get("host_key", |r: &mut Rescue| r.host_key.clone())
|
|
.on_print(|r: &mut Rescue| r.to_string())
|
|
.with_fn("pretty_print", |r: &mut Rescue| r.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Rescue {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["Server IP", self.server_ip]);
|
|
table.add_row(row!["Server IPv6 Net", self.server_ipv6_net]);
|
|
table.add_row(row!["Server Number", self.server_number.to_string()]);
|
|
table.add_row(row!["OS", self.os.to_vec().join(", ")]);
|
|
table.add_row(row!["Active", self.active.to_string()]);
|
|
table.add_row(row!["Password", self.password.as_deref().unwrap_or("N/A")]);
|
|
|
|
let authorized_keys: Vec<String> = self
|
|
.authorized_keys
|
|
.iter()
|
|
.filter_map(|key| key.key.fingerprint.clone())
|
|
.collect();
|
|
table.add_row(row!["Authorized Keys", authorized_keys.join("\n")]);
|
|
|
|
let host_keys: Vec<String> = self
|
|
.host_key
|
|
.iter()
|
|
.filter_map(|key| key.fingerprint.clone())
|
|
.collect();
|
|
table.add_row(row!["Host Keys", host_keys.join("\n")]);
|
|
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Linux {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: String,
|
|
pub server_number: i32,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub dist: Vec<String>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub lang: Vec<String>,
|
|
pub active: bool,
|
|
pub password: Option<String>,
|
|
#[serde(rename = "authorized_key")]
|
|
pub authorized_keys: Vec<RescueKey>,
|
|
pub host_key: Vec<HostKey>,
|
|
}
|
|
|
|
impl Linux {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Linux")
|
|
.with_get("server_ip", |l: &mut Linux| l.server_ip.clone())
|
|
.with_get("server_ipv6_net", |l: &mut Linux| l.server_ipv6_net.clone())
|
|
.with_get("server_number", |l: &mut Linux| l.server_number)
|
|
.with_get("dist", |l: &mut Linux| l.dist.clone())
|
|
.with_get("lang", |l: &mut Linux| l.lang.clone())
|
|
.with_get("active", |l: &mut Linux| l.active)
|
|
.with_get("password", |l: &mut Linux| l.password.clone())
|
|
.with_get("authorized_keys", |l: &mut Linux| {
|
|
l.authorized_keys
|
|
.iter()
|
|
.map(|k| rhai::Dynamic::from(k.key.clone()))
|
|
.collect::<rhai::Array>()
|
|
})
|
|
.with_get("host_key", |l: &mut Linux| l.host_key.clone())
|
|
.on_print(|l: &mut Linux| l.to_string())
|
|
.with_fn("pretty_print", |l: &mut Linux| l.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Linux {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["Server IP", self.server_ip]);
|
|
table.add_row(row!["Server IPv6 Net", self.server_ipv6_net]);
|
|
table.add_row(row!["Server Number", self.server_number.to_string()]);
|
|
table.add_row(row!["Distribution", self.dist.join(", ")]);
|
|
table.add_row(row!["Language", self.lang.join(", ")]);
|
|
table.add_row(row!["Active", self.active.to_string()]);
|
|
table.add_row(row!["Password", self.password.as_deref().unwrap_or("N/A")]);
|
|
|
|
let authorized_keys: Vec<String> = self
|
|
.authorized_keys
|
|
.iter()
|
|
.filter_map(|key| key.key.fingerprint.clone())
|
|
.collect();
|
|
table.add_row(row!["Authorized Keys", authorized_keys.join("\n")]);
|
|
|
|
let host_keys: Vec<String> = self
|
|
.host_key
|
|
.iter()
|
|
.filter_map(|key| key.fingerprint.clone())
|
|
.collect();
|
|
table.add_row(row!["Host Keys", host_keys.join("\n")]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Vnc {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: String,
|
|
pub server_number: i32,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub dist: Vec<String>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub lang: Vec<String>,
|
|
pub active: bool,
|
|
pub password: Option<String>,
|
|
}
|
|
|
|
impl Vnc {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Vnc")
|
|
.with_get("server_ip", |v: &mut Vnc| v.server_ip.clone())
|
|
.with_get("server_ipv6_net", |v: &mut Vnc| v.server_ipv6_net.clone())
|
|
.with_get("server_number", |v: &mut Vnc| v.server_number)
|
|
.with_get("dist", |v: &mut Vnc| v.dist.clone())
|
|
.with_get("lang", |v: &mut Vnc| v.lang.clone())
|
|
.with_get("active", |v: &mut Vnc| v.active)
|
|
.with_get("password", |v: &mut Vnc| v.password.clone())
|
|
.on_print(|v: &mut Vnc| v.to_string())
|
|
.with_fn("pretty_print", |v: &mut Vnc| v.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Vnc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"Dist: {}, Lang: {}, Active: {}",
|
|
self.dist.join(", "),
|
|
self.lang.join(", "),
|
|
self.active
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Windows {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: String,
|
|
pub server_number: i32,
|
|
#[serde(deserialize_with = "option_string_or_seq_string")]
|
|
pub dist: Option<Vec<String>>,
|
|
#[serde(deserialize_with = "option_string_or_seq_string")]
|
|
pub lang: Option<Vec<String>>,
|
|
pub active: bool,
|
|
pub password: Option<String>,
|
|
}
|
|
|
|
impl Windows {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Windows")
|
|
.with_get("server_ip", |w: &mut Windows| w.server_ip.clone())
|
|
.with_get("server_ipv6_net", |w: &mut Windows| {
|
|
w.server_ipv6_net.clone()
|
|
})
|
|
.with_get("server_number", |w: &mut Windows| w.server_number)
|
|
.with_get("dist", |w: &mut Windows| w.dist.clone())
|
|
.with_get("lang", |w: &mut Windows| w.lang.clone())
|
|
.with_get("active", |w: &mut Windows| w.active)
|
|
.with_get("password", |w: &mut Windows| w.password.clone())
|
|
.on_print(|w: &mut Windows| w.to_string())
|
|
.with_fn("pretty_print", |w: &mut Windows| w.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Windows {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"Dist: {}, Lang: {}, Active: {}",
|
|
self.dist.as_deref().unwrap_or_default().join(", "),
|
|
self.lang.as_deref().unwrap_or_default().join(", "),
|
|
self.active
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Plesk {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: String,
|
|
pub server_number: i32,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub dist: Vec<String>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub lang: Vec<String>,
|
|
pub active: bool,
|
|
pub password: Option<String>,
|
|
pub hostname: Option<String>,
|
|
}
|
|
|
|
impl Plesk {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Plesk")
|
|
.with_get("server_ip", |p: &mut Plesk| p.server_ip.clone())
|
|
.with_get("server_ipv6_net", |p: &mut Plesk| p.server_ipv6_net.clone())
|
|
.with_get("server_number", |p: &mut Plesk| p.server_number)
|
|
.with_get("dist", |p: &mut Plesk| p.dist.clone())
|
|
.with_get("lang", |p: &mut Plesk| p.lang.clone())
|
|
.with_get("active", |p: &mut Plesk| p.active)
|
|
.with_get("password", |p: &mut Plesk| p.password.clone())
|
|
.with_get("hostname", |p: &mut Plesk| p.hostname.clone())
|
|
.on_print(|p: &mut Plesk| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut Plesk| p.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Plesk {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"Dist: {}, Lang: {}, Active: {}, Hostname: {}",
|
|
self.dist.join(", "),
|
|
self.lang.join(", "),
|
|
self.active,
|
|
self.hostname.as_deref().unwrap_or("N/A")
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Cpanel {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: String,
|
|
pub server_number: i32,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub dist: Vec<String>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub lang: Vec<String>,
|
|
pub active: bool,
|
|
pub password: Option<String>,
|
|
pub hostname: Option<String>,
|
|
}
|
|
|
|
impl Cpanel {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Cpanel")
|
|
.with_get("server_ip", |c: &mut Cpanel| c.server_ip.clone())
|
|
.with_get("server_ipv6_net", |c: &mut Cpanel| {
|
|
c.server_ipv6_net.clone()
|
|
})
|
|
.with_get("server_number", |c: &mut Cpanel| c.server_number)
|
|
.with_get("dist", |c: &mut Cpanel| c.dist.clone())
|
|
.with_get("lang", |c: &mut Cpanel| c.lang.clone())
|
|
.with_get("active", |c: &mut Cpanel| c.active)
|
|
.with_get("password", |c: &mut Cpanel| c.password.clone())
|
|
.with_get("hostname", |c: &mut Cpanel| c.hostname.clone())
|
|
.on_print(|c: &mut Cpanel| c.to_string())
|
|
.with_fn("pretty_print", |c: &mut Cpanel| c.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Cpanel {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"Dist: {}, Lang: {}, Active: {}, Hostname: {}",
|
|
self.dist.join(", "),
|
|
self.lang.join(", "),
|
|
self.active,
|
|
self.hostname.as_deref().unwrap_or("N/A")
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct CancellationWrapper {
|
|
pub cancellation: Cancellation,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Cancellation {
|
|
pub server_ip: String,
|
|
pub server_ipv6_net: Option<String>,
|
|
pub server_number: i32,
|
|
pub server_name: String,
|
|
pub earliest_cancellation_date: String,
|
|
pub cancelled: bool,
|
|
pub reservation_possible: bool,
|
|
pub reserved: bool,
|
|
pub cancellation_date: Option<String>,
|
|
pub cancellation_reason: Vec<String>,
|
|
}
|
|
|
|
impl Cancellation {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Cancellation")
|
|
.with_get("server_ip", |c: &mut Cancellation| c.server_ip.clone())
|
|
.with_get("server_ipv6_net", |c: &mut Cancellation| {
|
|
c.server_ipv6_net.clone()
|
|
})
|
|
.with_get("server_number", |c: &mut Cancellation| c.server_number)
|
|
.with_get("server_name", |c: &mut Cancellation| c.server_name.clone())
|
|
.with_get("earliest_cancellation_date", |c: &mut Cancellation| {
|
|
c.earliest_cancellation_date.clone()
|
|
})
|
|
.with_get("cancelled", |c: &mut Cancellation| c.cancelled)
|
|
.with_get("reservation_possible", |c: &mut Cancellation| {
|
|
c.reservation_possible
|
|
})
|
|
.with_get("reserved", |c: &mut Cancellation| c.reserved)
|
|
.with_get("cancellation_date", |c: &mut Cancellation| {
|
|
c.cancellation_date.clone()
|
|
})
|
|
.with_get("cancellation_reason", |c: &mut Cancellation| {
|
|
c.cancellation_reason.clone()
|
|
})
|
|
.on_print(|c: &mut Cancellation| c.to_string())
|
|
.with_fn("pretty_print", |c: &mut Cancellation| c.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Cancellation {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["Server IP", self.server_ip.clone()]);
|
|
table.add_row(row![
|
|
"Server IPv6 Net",
|
|
self.server_ipv6_net.as_deref().unwrap_or("N/A").to_string()
|
|
]);
|
|
table.add_row(row!["Server Number", self.server_number.to_string()]);
|
|
table.add_row(row!["Server Name", self.server_name.clone()]);
|
|
table.add_row(row![
|
|
"Earliest Cancellation Date",
|
|
self.earliest_cancellation_date.clone()
|
|
]);
|
|
table.add_row(row!["Cancelled", self.cancelled.to_string()]);
|
|
table.add_row(row![
|
|
"Reservation Possible",
|
|
self.reservation_possible.to_string()
|
|
]);
|
|
table.add_row(row!["Reserved", self.reserved.to_string()]);
|
|
table.add_row(row![
|
|
"Cancellation Date",
|
|
self.cancellation_date
|
|
.as_deref()
|
|
.unwrap_or("N/A")
|
|
.to_string()
|
|
]);
|
|
table.add_row(row![
|
|
"Cancellation Reason",
|
|
self.cancellation_reason.join(", ")
|
|
]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct ApiError {
|
|
#[allow(dead_code)]
|
|
pub status: u16,
|
|
#[allow(dead_code)]
|
|
pub message: String,
|
|
}
|
|
|
|
impl From<reqwest::blocking::Response> for ApiError {
|
|
fn from(value: reqwest::blocking::Response) -> Self {
|
|
ApiError {
|
|
status: value.status().into(),
|
|
message: value
|
|
.text()
|
|
.unwrap_or("The API call returned an error.".to_string()),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Price {
|
|
pub net: String,
|
|
pub gross: String,
|
|
pub hourly_net: String,
|
|
pub hourly_gross: String,
|
|
}
|
|
|
|
impl Price {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Price")
|
|
.with_get("net", |p: &mut Price| p.net.clone())
|
|
.with_get("gross", |p: &mut Price| p.gross.clone())
|
|
.with_get("hourly_net", |p: &mut Price| p.hourly_net.clone())
|
|
.with_get("hourly_gross", |p: &mut Price| p.hourly_gross.clone())
|
|
.on_print(|p: &mut Price| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut Price| p.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Price {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"Net: {}, Gross: {}, Hourly Net: {}, Hourly Gross: {}",
|
|
self.net, self.gross, self.hourly_net, self.hourly_gross
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct PriceSetup {
|
|
pub net: String,
|
|
pub gross: String,
|
|
}
|
|
|
|
impl PriceSetup {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("PriceSetup")
|
|
.with_get("net", |p: &mut PriceSetup| p.net.clone())
|
|
.with_get("gross", |p: &mut PriceSetup| p.gross.clone())
|
|
.on_print(|p: &mut PriceSetup| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut PriceSetup| p.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for PriceSetup {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "Net: {}, Gross: {}", self.net, self.gross)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct ProductPrice {
|
|
pub location: String,
|
|
pub price: Price,
|
|
pub price_setup: PriceSetup,
|
|
}
|
|
|
|
impl ProductPrice {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("ProductPrice")
|
|
.with_get("location", |p: &mut ProductPrice| p.location.clone())
|
|
.with_get("price", |p: &mut ProductPrice| p.price.clone())
|
|
.with_get("price_setup", |p: &mut ProductPrice| p.price_setup.clone())
|
|
.on_print(|p: &mut ProductPrice| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut ProductPrice| p.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ProductPrice {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"Location: {}, Price: ({}), Price Setup: ({})",
|
|
self.location, self.price, self.price_setup
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct OrderableAddon {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub min: i32,
|
|
pub max: i32,
|
|
pub prices: Vec<ProductPrice>,
|
|
}
|
|
|
|
impl OrderableAddon {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("OrderableAddon")
|
|
.with_get("id", |o: &mut OrderableAddon| o.id.clone())
|
|
.with_get("name", |o: &mut OrderableAddon| o.name.clone())
|
|
.with_get("min", |o: &mut OrderableAddon| o.min)
|
|
.with_get("max", |o: &mut OrderableAddon| o.max)
|
|
.with_get("prices", |o: &mut OrderableAddon| o.prices.clone())
|
|
.on_print(|o: &mut OrderableAddon| o.to_string())
|
|
.with_fn("pretty_print", |o: &mut OrderableAddon| o.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for OrderableAddon {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["ID", self.id.clone()]);
|
|
table.add_row(row!["Name", self.name.clone()]);
|
|
table.add_row(row!["Min", self.min.to_string()]);
|
|
table.add_row(row!["Max", self.max.to_string()]);
|
|
table.add_row(row!["Prices", format!("{:?}", self.prices)]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct ServerAddonProductWrapper {
|
|
pub product: ServerAddonProduct,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct ServerAddonProduct {
|
|
pub id: String,
|
|
pub name: String,
|
|
#[serde(rename = "type")]
|
|
pub product_type: String,
|
|
pub price: ProductPrice,
|
|
}
|
|
|
|
impl ServerAddonProduct {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("ServerAddonProduct")
|
|
.with_get("id", |p: &mut ServerAddonProduct| p.id.clone())
|
|
.with_get("name", |p: &mut ServerAddonProduct| p.name.clone())
|
|
.with_get("product_type", |p: &mut ServerAddonProduct| {
|
|
p.product_type.clone()
|
|
})
|
|
.with_get("price", |p: &mut ServerAddonProduct| p.price.clone())
|
|
.on_print(|p: &mut ServerAddonProduct| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut ServerAddonProduct| p.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ServerAddonProduct {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["ID", self.id.clone()]);
|
|
table.add_row(row!["Name", self.name.clone()]);
|
|
table.add_row(row!["Type", self.product_type.clone()]);
|
|
table.add_row(row!["Price", self.price.to_string()]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct ServerAddonTransactionWrapper {
|
|
pub transaction: ServerAddonTransaction,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct ServerAddonTransaction {
|
|
pub id: String,
|
|
pub date: String,
|
|
pub status: String,
|
|
pub server_number: i32,
|
|
pub product: ServerAddonTransactionProduct,
|
|
pub resources: Vec<ServerAddonResource>,
|
|
}
|
|
|
|
impl ServerAddonTransaction {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("ServerAddonTransaction")
|
|
.with_get("id", |t: &mut ServerAddonTransaction| t.id.clone())
|
|
.with_get("date", |t: &mut ServerAddonTransaction| t.date.clone())
|
|
.with_get("status", |t: &mut ServerAddonTransaction| t.status.clone())
|
|
.with_get("server_number", |t: &mut ServerAddonTransaction| {
|
|
t.server_number
|
|
})
|
|
.with_get("product", |t: &mut ServerAddonTransaction| {
|
|
t.product.clone()
|
|
})
|
|
.with_get("resources", |t: &mut ServerAddonTransaction| {
|
|
t.resources.clone()
|
|
})
|
|
.on_print(|t: &mut ServerAddonTransaction| t.to_string())
|
|
.with_fn("pretty_print", |t: &mut ServerAddonTransaction| {
|
|
t.to_string()
|
|
});
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ServerAddonTransaction {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["ID", self.id.clone()]);
|
|
table.add_row(row!["Date", self.date.clone()]);
|
|
table.add_row(row!["Status", self.status.clone()]);
|
|
table.add_row(row!["Server Number", self.server_number.to_string()]);
|
|
table.add_row(row!["Product ID", self.product.id.clone()]);
|
|
table.add_row(row!["Product Name", self.product.name.clone()]);
|
|
table.add_row(row!["Product Price", self.product.price.to_string()]);
|
|
|
|
let mut resources_table = Table::new();
|
|
resources_table.add_row(row![b => "Type", "ID"]);
|
|
for resource in &self.resources {
|
|
resources_table.add_row(row![resource.resource_type, resource.id]);
|
|
}
|
|
table.add_row(row!["Resources", resources_table]);
|
|
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct ServerAddonTransactionProduct {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub price: ProductPrice,
|
|
}
|
|
|
|
impl ServerAddonTransactionProduct {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("ServerAddonTransactionProduct")
|
|
.with_get("id", |p: &mut ServerAddonTransactionProduct| p.id.clone())
|
|
.with_get("name", |p: &mut ServerAddonTransactionProduct| {
|
|
p.name.clone()
|
|
})
|
|
.with_get("price", |p: &mut ServerAddonTransactionProduct| {
|
|
p.price.clone()
|
|
})
|
|
.on_print(|p: &mut ServerAddonTransactionProduct| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut ServerAddonTransactionProduct| {
|
|
p.to_string()
|
|
});
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ServerAddonTransactionProduct {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"ID: {}, Name: {}, Price: ({})",
|
|
self.id, self.name, self.price
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct ServerAddonResource {
|
|
#[serde(rename = "type")]
|
|
pub resource_type: String,
|
|
pub id: String,
|
|
}
|
|
|
|
impl ServerAddonResource {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("ServerAddonResource")
|
|
.with_get("resource_type", |r: &mut ServerAddonResource| {
|
|
r.resource_type.clone()
|
|
})
|
|
.with_get("id", |r: &mut ServerAddonResource| r.id.clone())
|
|
.on_print(|r: &mut ServerAddonResource| r.to_string())
|
|
.with_fn("pretty_print", |r: &mut ServerAddonResource| {
|
|
r.to_string()
|
|
});
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ServerAddonResource {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "Type: {}, ID: {}", self.resource_type, self.id)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct OrderServerProductWrapper {
|
|
pub product: OrderServerProduct,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct OrderServerProduct {
|
|
pub id: String,
|
|
pub name: String,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub description: Vec<String>,
|
|
pub traffic: String,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub dist: Vec<String>,
|
|
#[serde(
|
|
rename = "@deprecated arch",
|
|
default,
|
|
deserialize_with = "option_string_or_seq_string"
|
|
)]
|
|
#[deprecated(note = "use `dist` instead")]
|
|
pub arch: Option<Vec<String>>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub lang: Vec<String>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub location: Vec<String>,
|
|
pub prices: Vec<ProductPrice>,
|
|
pub orderable_addons: Vec<OrderableAddon>,
|
|
}
|
|
|
|
impl OrderServerProduct {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("OrderServerProduct")
|
|
.with_get("id", |o: &mut OrderServerProduct| o.id.clone())
|
|
.with_get("name", |o: &mut OrderServerProduct| o.name.clone())
|
|
.with_get("description", |o: &mut OrderServerProduct| {
|
|
o.description.clone()
|
|
})
|
|
.with_get("traffic", |o: &mut OrderServerProduct| o.traffic.clone())
|
|
.with_get("dist", |o: &mut OrderServerProduct| o.dist.clone())
|
|
.with_get("arch", |o: &mut OrderServerProduct| o.dist.clone())
|
|
.with_get("lang", |o: &mut OrderServerProduct| o.lang.clone())
|
|
.with_get("location", |o: &mut OrderServerProduct| o.location.clone())
|
|
.with_get("prices", |o: &mut OrderServerProduct| o.prices.clone())
|
|
.with_get("orderable_addons", |o: &mut OrderServerProduct| {
|
|
o.orderable_addons.clone()
|
|
})
|
|
.on_print(|o: &mut OrderServerProduct| o.to_string())
|
|
.with_fn("pretty_print", |o: &mut OrderServerProduct| o.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for OrderServerProduct {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["ID", self.id.clone()]);
|
|
table.add_row(row!["Name", self.name.clone()]);
|
|
table.add_row(row!["Description", self.description.join(", ")]);
|
|
table.add_row(row!["Traffic", self.traffic.clone()]);
|
|
table.add_row(row!["Distributions", self.dist.join(", ")]);
|
|
table.add_row(row![
|
|
"Architectures",
|
|
self.dist.join(", ")
|
|
]);
|
|
table.add_row(row!["Languages", self.lang.join(", ")]);
|
|
table.add_row(row!["Locations", self.location.join(", ")]);
|
|
let mut prices_table = Table::new();
|
|
prices_table.add_row(row![b => "Location", "Net", "Gross", "Hourly Net", "Hourly Gross", "Setup Net", "Setup Gross"]);
|
|
for price in &self.prices {
|
|
prices_table.add_row(row![
|
|
price.location,
|
|
price.price.net,
|
|
price.price.gross,
|
|
price.price.hourly_net,
|
|
price.price.hourly_gross,
|
|
price.price_setup.net,
|
|
price.price_setup.gross
|
|
]);
|
|
}
|
|
table.add_row(row!["Prices", prices_table]);
|
|
|
|
let mut addons_table = Table::new();
|
|
addons_table.add_row(row![b => "ID", "Name", "Min", "Max", "Prices"]);
|
|
for addon in &self.orderable_addons {
|
|
let mut addon_prices_table = Table::new();
|
|
addon_prices_table.add_row(row![b => "Location", "Net", "Gross", "Hourly Net", "Hourly Gross", "Setup Net", "Setup Gross"]);
|
|
for price in &addon.prices {
|
|
addon_prices_table.add_row(row![
|
|
price.location,
|
|
price.price.net,
|
|
price.price.gross,
|
|
price.price.hourly_net,
|
|
price.price.hourly_gross,
|
|
price.price_setup.net,
|
|
price.price_setup.gross
|
|
]);
|
|
}
|
|
addons_table.add_row(row![
|
|
addon.id,
|
|
addon.name,
|
|
addon.min,
|
|
addon.max,
|
|
addon_prices_table
|
|
]);
|
|
}
|
|
table.add_row(row!["Orderable Addons", addons_table]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct TransactionWrapper {
|
|
pub transaction: Transaction,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct Transaction {
|
|
pub id: String,
|
|
pub date: String,
|
|
pub status: String,
|
|
pub server_number: Option<i32>,
|
|
pub server_ip: Option<String>,
|
|
pub authorized_key: Vec<AuthorizedKeyWrapper>,
|
|
pub host_key: Vec<HostKeyWrapper>,
|
|
pub comment: Option<String>,
|
|
pub product: TransactionProduct,
|
|
pub addons: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct AuthorizedKeyWrapper {
|
|
pub key: AuthorizedKey,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct AuthorizedKey {
|
|
pub name: Option<String>,
|
|
pub fingerprint: Option<String>,
|
|
#[serde(rename = "type")]
|
|
pub key_type: Option<String>,
|
|
pub size: Option<i32>,
|
|
}
|
|
|
|
impl From<SshKey> for AuthorizedKey {
|
|
fn from(key: SshKey) -> Self {
|
|
Self {
|
|
name: Some(key.name),
|
|
fingerprint: Some(key.fingerprint),
|
|
key_type: Some(key.key_type),
|
|
size: Some(key.size),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct TransactionProduct {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub description: Vec<String>,
|
|
pub traffic: String,
|
|
pub dist: String,
|
|
#[serde(rename = "@deprecated arch")]
|
|
pub arch: String,
|
|
pub lang: String,
|
|
pub location: String,
|
|
}
|
|
|
|
impl Transaction {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("Transaction")
|
|
.with_get("id", |t: &mut Transaction| t.id.clone())
|
|
.with_get("date", |t: &mut Transaction| t.date.clone())
|
|
.with_get("status", |t: &mut Transaction| t.status.clone())
|
|
.with_get("server_number", |t: &mut Transaction| t.server_number)
|
|
.with_get("server_ip", |t: &mut Transaction| t.server_ip.clone())
|
|
.with_get("authorized_key", |t: &mut Transaction| {
|
|
t.authorized_key.clone()
|
|
})
|
|
.with_get("host_key", |t: &mut Transaction| t.host_key.clone())
|
|
.with_get("comment", |t: &mut Transaction| t.comment.clone())
|
|
.with_get("product", |t: &mut Transaction| t.product.clone())
|
|
.with_get("addons", |t: &mut Transaction| t.addons.clone());
|
|
}
|
|
}
|
|
|
|
impl AuthorizedKey {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("AuthorizedKey")
|
|
.with_get("name", |k: &mut AuthorizedKey| k.name.clone())
|
|
.with_get("fingerprint", |k: &mut AuthorizedKey| k.fingerprint.clone())
|
|
.with_get("key_type", |k: &mut AuthorizedKey| k.key_type.clone())
|
|
.with_get("size", |k: &mut AuthorizedKey| k.size);
|
|
}
|
|
}
|
|
|
|
impl TransactionProduct {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("TransactionProduct")
|
|
.with_get("id", |p: &mut TransactionProduct| p.id.clone())
|
|
.with_get("name", |p: &mut TransactionProduct| p.name.clone())
|
|
.with_get("description", |p: &mut TransactionProduct| {
|
|
p.description.clone()
|
|
})
|
|
.with_get("traffic", |p: &mut TransactionProduct| p.traffic.clone())
|
|
.with_get("dist", |p: &mut TransactionProduct| p.dist.clone())
|
|
.with_get("arch", |p: &mut TransactionProduct| p.arch.clone())
|
|
.with_get("lang", |p: &mut TransactionProduct| p.lang.clone())
|
|
.with_get("location", |p: &mut TransactionProduct| p.location.clone());
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct HostKeyWrapper {
|
|
pub key: HostKey,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct HostKey {
|
|
pub fingerprint: Option<String>,
|
|
#[serde(rename = "type")]
|
|
pub key_type: Option<String>,
|
|
pub size: Option<i32>,
|
|
}
|
|
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct RescueKey {
|
|
pub key: HostKey,
|
|
}
|
|
|
|
impl HostKey {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("HostKey")
|
|
.with_get("fingerprint", |k: &mut HostKey| k.fingerprint.clone())
|
|
.with_get("key_type", |k: &mut HostKey| k.key_type.clone())
|
|
.with_get("size", |k: &mut HostKey| k.size);
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct AuctionServerProductWrapper {
|
|
pub product: AuctionServerProduct,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct AuctionServerProduct {
|
|
pub id: i32,
|
|
pub name: String,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub description: Vec<String>,
|
|
pub traffic: String,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub dist: Vec<String>,
|
|
#[serde(
|
|
rename = "@deprecated arch",
|
|
default,
|
|
deserialize_with = "option_string_or_seq_string"
|
|
)]
|
|
#[deprecated(note = "use `dist` instead")]
|
|
pub arch: Option<Vec<String>>,
|
|
#[serde(deserialize_with = "string_or_seq_string")]
|
|
pub lang: Vec<String>,
|
|
pub cpu: String,
|
|
pub cpu_benchmark: i32,
|
|
pub memory_size: i32,
|
|
pub hdd_size: i32,
|
|
pub hdd_text: String,
|
|
pub hdd_count: i32,
|
|
pub datacenter: String,
|
|
pub network_speed: String,
|
|
pub price: String,
|
|
pub price_hourly: Option<String>,
|
|
pub price_setup: String,
|
|
#[serde(rename = "price_vat")]
|
|
pub price_with_vat: String,
|
|
#[serde(rename = "price_hourly_vat")]
|
|
pub price_hourly_with_vat: Option<String>,
|
|
#[serde(rename = "price_setup_vat")]
|
|
pub price_setup_with_vat: String,
|
|
pub fixed_price: bool,
|
|
pub next_reduce: i32,
|
|
pub next_reduce_date: String,
|
|
pub orderable_addons: Vec<OrderableAddon>,
|
|
}
|
|
|
|
impl AuctionServerProduct {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("AuctionServerProduct")
|
|
.with_get("id", |p: &mut AuctionServerProduct| p.id)
|
|
.with_get("name", |p: &mut AuctionServerProduct| p.name.clone())
|
|
.with_get("description", |p: &mut AuctionServerProduct| {
|
|
p.description.clone()
|
|
})
|
|
.with_get("traffic", |p: &mut AuctionServerProduct| p.traffic.clone())
|
|
.with_get("dist", |p: &mut AuctionServerProduct| p.dist.clone())
|
|
.with_get("arch", |p: &mut AuctionServerProduct| p.dist.clone())
|
|
.with_get("lang", |p: &mut AuctionServerProduct| p.lang.clone())
|
|
.with_get("cpu", |p: &mut AuctionServerProduct| p.cpu.clone())
|
|
.with_get("cpu_benchmark", |p: &mut AuctionServerProduct| {
|
|
p.cpu_benchmark
|
|
})
|
|
.with_get("memory_size", |p: &mut AuctionServerProduct| p.memory_size)
|
|
.with_get("hdd_size", |p: &mut AuctionServerProduct| p.hdd_size)
|
|
.with_get("hdd_text", |p: &mut AuctionServerProduct| {
|
|
p.hdd_text.clone()
|
|
})
|
|
.with_get("hdd_count", |p: &mut AuctionServerProduct| p.hdd_count)
|
|
.with_get("datacenter", |p: &mut AuctionServerProduct| {
|
|
p.datacenter.clone()
|
|
})
|
|
.with_get("network_speed", |p: &mut AuctionServerProduct| {
|
|
p.network_speed.clone()
|
|
})
|
|
.with_get("price", |p: &mut AuctionServerProduct| p.price.clone())
|
|
.with_get("price_hourly", |p: &mut AuctionServerProduct| {
|
|
p.price_hourly.clone()
|
|
})
|
|
.with_get("price_setup", |p: &mut AuctionServerProduct| {
|
|
p.price_setup.clone()
|
|
})
|
|
.with_get("price_with_vat", |p: &mut AuctionServerProduct| {
|
|
p.price_with_vat.clone()
|
|
})
|
|
.with_get("price_hourly_with_vat", |p: &mut AuctionServerProduct| {
|
|
p.price_hourly_with_vat.clone()
|
|
})
|
|
.with_get("price_setup_with_vat", |p: &mut AuctionServerProduct| {
|
|
p.price_setup_with_vat.clone()
|
|
})
|
|
.with_get("fixed_price", |p: &mut AuctionServerProduct| p.fixed_price)
|
|
.with_get("next_reduce", |p: &mut AuctionServerProduct| p.next_reduce)
|
|
.with_get("next_reduce_date", |p: &mut AuctionServerProduct| {
|
|
p.next_reduce_date.clone()
|
|
})
|
|
.with_get("orderable_addons", |p: &mut AuctionServerProduct| {
|
|
p.orderable_addons.clone()
|
|
})
|
|
.on_print(|p: &mut AuctionServerProduct| p.to_string())
|
|
.with_fn("pretty_print", |p: &mut AuctionServerProduct| p.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for AuctionServerProduct {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["ID", self.id.to_string()]);
|
|
table.add_row(row!["Name", self.name.clone()]);
|
|
table.add_row(row!["Description", self.description.join(", ")]);
|
|
table.add_row(row!["Traffic", self.traffic.clone()]);
|
|
table.add_row(row!["Distributions", self.dist.join(", ")]);
|
|
table.add_row(row![
|
|
"Architectures",
|
|
self.dist.join(", ")
|
|
]);
|
|
table.add_row(row!["Languages", self.lang.join(", ")]);
|
|
table.add_row(row!["CPU", self.cpu.clone()]);
|
|
table.add_row(row!["CPU Benchmark", self.cpu_benchmark.to_string()]);
|
|
table.add_row(row!["Memory Size (GB)", self.memory_size.to_string()]);
|
|
table.add_row(row!["HDD Size (GB)", self.hdd_size.to_string()]);
|
|
table.add_row(row!["HDD Text", self.hdd_text.clone()]);
|
|
table.add_row(row!["HDD Count", self.hdd_count.to_string()]);
|
|
table.add_row(row!["Datacenter", self.datacenter.clone()]);
|
|
table.add_row(row!["Network Speed", self.network_speed.clone()]);
|
|
table.add_row(row!["Price (Net)", self.price.clone()]);
|
|
table.add_row(row![
|
|
"Price (Hourly Net)",
|
|
self.price_hourly.as_deref().unwrap_or("N/A").to_string()
|
|
]);
|
|
table.add_row(row!["Price (Setup Net)", self.price_setup.clone()]);
|
|
table.add_row(row!["Price (VAT)", self.price_with_vat.clone()]);
|
|
table.add_row(row![
|
|
"Price (Hourly VAT)",
|
|
self.price_hourly_with_vat
|
|
.as_deref()
|
|
.unwrap_or("N/A")
|
|
.to_string()
|
|
]);
|
|
table.add_row(row!["Price (Setup VAT)", self.price_setup_with_vat.clone()]);
|
|
table.add_row(row!["Fixed Price", self.fixed_price.to_string()]);
|
|
table.add_row(row!["Next Reduce (seconds)", self.next_reduce.to_string()]);
|
|
table.add_row(row!["Next Reduce Date", self.next_reduce_date.clone()]);
|
|
|
|
let mut addons_table = Table::new();
|
|
addons_table.add_row(row![b => "ID", "Name", "Min", "Max", "Prices"]);
|
|
for addon in &self.orderable_addons {
|
|
let mut addon_prices_table = Table::new();
|
|
addon_prices_table.add_row(row![b => "Location", "Net", "Gross", "Hourly Net", "Hourly Gross", "Setup Net", "Setup Gross"]);
|
|
for price in &addon.prices {
|
|
addon_prices_table.add_row(row![
|
|
price.location,
|
|
price.price.net,
|
|
price.price.gross,
|
|
price.price.hourly_net,
|
|
price.price.hourly_gross,
|
|
price.price_setup.net,
|
|
price.price_setup.gross
|
|
]);
|
|
}
|
|
addons_table.add_row(row![
|
|
addon.id,
|
|
addon.name,
|
|
addon.min,
|
|
addon.max,
|
|
addon_prices_table
|
|
]);
|
|
}
|
|
table.add_row(row!["Orderable Addons", addons_table]);
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct AuctionTransactionWrapper {
|
|
pub transaction: AuctionTransaction,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct AuctionTransaction {
|
|
pub id: String,
|
|
pub date: String,
|
|
pub status: String,
|
|
pub server_number: Option<i32>,
|
|
pub server_ip: Option<String>,
|
|
pub authorized_key: Vec<AuthorizedKeyWrapper>,
|
|
pub host_key: Vec<HostKeyWrapper>,
|
|
pub comment: Option<String>,
|
|
pub product: AuctionTransactionProduct,
|
|
pub addons: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct AuctionTransactionProduct {
|
|
pub id: i32,
|
|
pub name: String,
|
|
pub description: Vec<String>,
|
|
pub traffic: String,
|
|
pub dist: String,
|
|
#[serde(rename = "@deprecated arch")]
|
|
pub arch: Option<String>,
|
|
pub lang: String,
|
|
pub cpu: String,
|
|
pub cpu_benchmark: i32,
|
|
pub memory_size: i32,
|
|
pub hdd_size: i32,
|
|
pub hdd_text: String,
|
|
pub hdd_count: i32,
|
|
pub datacenter: String,
|
|
pub network_speed: String,
|
|
pub fixed_price: Option<bool>,
|
|
pub next_reduce: Option<i32>,
|
|
pub next_reduce_date: Option<String>,
|
|
}
|
|
|
|
impl AuctionTransaction {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("AuctionTransaction")
|
|
.with_get("id", |t: &mut AuctionTransaction| t.id.clone())
|
|
.with_get("date", |t: &mut AuctionTransaction| t.date.clone())
|
|
.with_get("status", |t: &mut AuctionTransaction| t.status.clone())
|
|
.with_get("server_number", |t: &mut AuctionTransaction| {
|
|
t.server_number
|
|
})
|
|
.with_get("server_ip", |t: &mut AuctionTransaction| {
|
|
t.server_ip.clone()
|
|
})
|
|
.with_get("authorized_key", |t: &mut AuctionTransaction| {
|
|
t.authorized_key.clone()
|
|
})
|
|
.with_get("host_key", |t: &mut AuctionTransaction| t.host_key.clone())
|
|
.with_get("comment", |t: &mut AuctionTransaction| t.comment.clone())
|
|
.with_get("product", |t: &mut AuctionTransaction| t.product.clone())
|
|
.with_get("addons", |t: &mut AuctionTransaction| t.addons.clone())
|
|
.on_print(|t: &mut AuctionTransaction| t.to_string())
|
|
.with_fn("pretty_print", |t: &mut AuctionTransaction| t.to_string());
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for AuctionTransaction {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut table = Table::new();
|
|
table.add_row(row!["Property", "Value"]);
|
|
table.add_row(row!["ID", self.id.clone()]);
|
|
table.add_row(row!["Date", self.date.clone()]);
|
|
table.add_row(row!["Status", self.status.clone()]);
|
|
table.add_row(row![
|
|
"Server Number",
|
|
self.server_number
|
|
.map_or("N/A".to_string(), |id| id.to_string())
|
|
]);
|
|
table.add_row(row![
|
|
"Server IP",
|
|
self.server_ip.as_deref().unwrap_or("N/A").to_string()
|
|
]);
|
|
table.add_row(row![
|
|
"Comment",
|
|
self.comment.as_deref().unwrap_or("N/A").to_string()
|
|
]);
|
|
table.add_row(row!["Product ID", self.product.id.to_string()]);
|
|
table.add_row(row!["Product Name", self.product.name.clone()]);
|
|
table.add_row(row![
|
|
"Product Description",
|
|
self.product.description.join(", ")
|
|
]);
|
|
table.add_row(row!["Product Traffic", self.product.traffic.clone()]);
|
|
table.add_row(row!["Product Distributions", self.product.dist.clone()]);
|
|
table.add_row(row![
|
|
"Product Architectures",
|
|
&self.product.dist
|
|
]);
|
|
table.add_row(row!["Product Languages", self.product.lang.clone()]);
|
|
table.add_row(row!["Product CPU", self.product.cpu.clone()]);
|
|
table.add_row(row![
|
|
"Product CPU Benchmark",
|
|
self.product.cpu_benchmark.to_string()
|
|
]);
|
|
table.add_row(row![
|
|
"Product Memory Size (GB)",
|
|
self.product.memory_size.to_string()
|
|
]);
|
|
table.add_row(row![
|
|
"Product HDD Size (GB)",
|
|
self.product.hdd_size.to_string()
|
|
]);
|
|
table.add_row(row!["Product HDD Text", self.product.hdd_text.clone()]);
|
|
table.add_row(row![
|
|
"Product HDD Count",
|
|
self.product.hdd_count.to_string()
|
|
]);
|
|
table.add_row(row!["Product Datacenter", self.product.datacenter.clone()]);
|
|
table.add_row(row![
|
|
"Product Network Speed",
|
|
self.product.network_speed.clone()
|
|
]);
|
|
table.add_row(row![
|
|
"Product Fixed Price",
|
|
self.product.fixed_price.unwrap_or_default().to_string()
|
|
]);
|
|
table.add_row(row![
|
|
"Product Next Reduce (seconds)",
|
|
self.product
|
|
.next_reduce
|
|
.map_or("N/A".to_string(), |r| r.to_string())
|
|
]);
|
|
table.add_row(row![
|
|
"Product Next Reduce Date",
|
|
self.product.next_reduce_date.as_deref().unwrap_or("N/A")
|
|
]);
|
|
table.add_row(row!["Addons", self.addons.join(", ")]);
|
|
|
|
let mut authorized_keys_table = Table::new();
|
|
authorized_keys_table.add_row(row![b => "Name", "Fingerprint", "Type", "Size"]);
|
|
for key in &self.authorized_key {
|
|
authorized_keys_table.add_row(row![
|
|
key.key.name.as_deref().unwrap_or("N/A"),
|
|
key.key.fingerprint.as_deref().unwrap_or("N/A"),
|
|
key.key.key_type.as_deref().unwrap_or("N/A"),
|
|
key.key.size.map_or("N/A".to_string(), |s| s.to_string())
|
|
]);
|
|
}
|
|
table.add_row(row!["Authorized Keys", authorized_keys_table]);
|
|
|
|
let mut host_keys_table = Table::new();
|
|
host_keys_table.add_row(row![b => "Fingerprint", "Type", "Size"]);
|
|
for key in &self.host_key {
|
|
host_keys_table.add_row(row![
|
|
key.key.fingerprint.as_deref().unwrap_or("N/A"),
|
|
key.key.key_type.as_deref().unwrap_or("N/A"),
|
|
key.key.size.map_or("N/A".to_string(), |s| s.to_string())
|
|
]);
|
|
}
|
|
table.add_row(row!["Host Keys", host_keys_table]);
|
|
|
|
write!(f, "{}", table)
|
|
}
|
|
}
|
|
|
|
impl AuctionTransactionProduct {
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("AuctionTransactionProduct")
|
|
.with_get("id", |p: &mut AuctionTransactionProduct| p.id)
|
|
.with_get("name", |p: &mut AuctionTransactionProduct| p.name.clone())
|
|
.with_get("description", |p: &mut AuctionTransactionProduct| {
|
|
p.description.clone()
|
|
})
|
|
.with_get("traffic", |p: &mut AuctionTransactionProduct| {
|
|
p.traffic.clone()
|
|
})
|
|
.with_get("dist", |p: &mut AuctionTransactionProduct| p.dist.clone())
|
|
.with_get("arch", |p: &mut AuctionTransactionProduct| {
|
|
p.dist.clone()
|
|
})
|
|
.with_get("lang", |p: &mut AuctionTransactionProduct| p.lang.clone())
|
|
.with_get("cpu", |p: &mut AuctionTransactionProduct| p.cpu.clone())
|
|
.with_get("cpu_benchmark", |p: &mut AuctionTransactionProduct| {
|
|
p.cpu_benchmark
|
|
})
|
|
.with_get("memory_size", |p: &mut AuctionTransactionProduct| {
|
|
p.memory_size
|
|
})
|
|
.with_get("hdd_size", |p: &mut AuctionTransactionProduct| p.hdd_size)
|
|
.with_get("hdd_text", |p: &mut AuctionTransactionProduct| {
|
|
p.hdd_text.clone()
|
|
})
|
|
.with_get("hdd_count", |p: &mut AuctionTransactionProduct| p.hdd_count)
|
|
.with_get("datacenter", |p: &mut AuctionTransactionProduct| {
|
|
p.datacenter.clone()
|
|
})
|
|
.with_get("network_speed", |p: &mut AuctionTransactionProduct| {
|
|
p.network_speed.clone()
|
|
})
|
|
.with_get("fixed_price", |p: &mut AuctionTransactionProduct| {
|
|
p.fixed_price.unwrap_or_default()
|
|
})
|
|
.with_get("next_reduce", |p: &mut AuctionTransactionProduct| {
|
|
p.next_reduce.unwrap_or_default()
|
|
})
|
|
.with_get("next_reduce_date", |p: &mut AuctionTransactionProduct| {
|
|
p.next_reduce_date.clone().unwrap_or_default()
|
|
});
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct OrderServerBuilder {
|
|
pub product_id: String,
|
|
pub authorized_keys: Option<Vec<String>>,
|
|
pub dist: Option<String>,
|
|
pub location: Option<String>,
|
|
pub lang: Option<String>,
|
|
pub comment: Option<String>,
|
|
pub addons: Option<Vec<String>>,
|
|
pub test: Option<bool>,
|
|
}
|
|
|
|
impl OrderServerBuilder {
|
|
pub fn new(product_id: &str) -> Self {
|
|
Self {
|
|
product_id: product_id.to_string(),
|
|
authorized_keys: None,
|
|
dist: None,
|
|
location: None,
|
|
lang: None,
|
|
comment: None,
|
|
addons: None,
|
|
test: Some(true),
|
|
}
|
|
}
|
|
|
|
pub fn with_authorized_keys(mut self, keys: Array) -> Self {
|
|
let authorized_keys: Vec<String> = if keys.is_empty() {
|
|
vec![]
|
|
} else if keys[0].is::<SshKey>() {
|
|
keys.into_iter()
|
|
.map(|k| k.cast::<SshKey>().fingerprint)
|
|
.collect()
|
|
} else {
|
|
keys.into_iter().map(|k| k.into_string().unwrap()).collect()
|
|
};
|
|
self.authorized_keys = Some(authorized_keys);
|
|
self
|
|
}
|
|
|
|
pub fn with_dist(mut self, dist: &str) -> Self {
|
|
self.dist = Some(dist.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_location(mut self, location: &str) -> Self {
|
|
self.location = Some(location.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_lang(mut self, lang: &str) -> Self {
|
|
self.lang = Some(lang.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_comment(mut self, comment: &str) -> Self {
|
|
self.comment = Some(comment.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_addons(mut self, addons: Array) -> Self {
|
|
let addon_list: Vec<String> = addons
|
|
.into_iter()
|
|
.map(|a| a.into_string().unwrap())
|
|
.collect();
|
|
self.addons = Some(addon_list);
|
|
self
|
|
}
|
|
|
|
pub fn with_test(mut self, test: bool) -> Self {
|
|
self.test = Some(test);
|
|
self
|
|
}
|
|
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("OrderServerBuilder")
|
|
.with_fn("new_server_builder", Self::new)
|
|
.with_fn("with_authorized_keys", Self::with_authorized_keys)
|
|
.with_fn("with_dist", Self::with_dist)
|
|
.with_fn("with_location", Self::with_location)
|
|
.with_fn("with_lang", Self::with_lang)
|
|
.with_fn("with_comment", Self::with_comment)
|
|
.with_fn("with_addons", Self::with_addons)
|
|
.with_fn("with_test", Self::with_test)
|
|
.with_get("product_id", |b: &mut OrderServerBuilder| b.product_id.clone())
|
|
.with_get("dist", |b: &mut OrderServerBuilder| b.dist.clone())
|
|
.with_get("location", |b: &mut OrderServerBuilder| b.location.clone())
|
|
.with_get("authorized_keys", |b: &mut OrderServerBuilder| {
|
|
b.authorized_keys.clone()
|
|
})
|
|
.with_get("addons", |b: &mut OrderServerBuilder| b.addons.clone())
|
|
.with_get("test", |b: &mut OrderServerBuilder| b.test.clone());
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct OrderAuctionServerBuilder {
|
|
pub product_id: i64,
|
|
pub authorized_keys: Option<Vec<String>>,
|
|
pub dist: Option<String>,
|
|
pub lang: Option<String>,
|
|
pub comment: Option<String>,
|
|
pub addon: Option<Vec<String>>,
|
|
pub test: Option<bool>,
|
|
}
|
|
|
|
impl OrderAuctionServerBuilder {
|
|
pub fn new(product_id: i64) -> Self {
|
|
Self {
|
|
product_id,
|
|
authorized_keys: None,
|
|
dist: None,
|
|
lang: None,
|
|
comment: None,
|
|
addon: None,
|
|
// by default test is enabled
|
|
test: Some(true),
|
|
}
|
|
}
|
|
|
|
pub fn with_authorized_keys(mut self, keys: Array) -> Self {
|
|
let authorized_keys: Vec<String> = if keys.is_empty() {
|
|
vec![]
|
|
} else if keys[0].is::<SshKey>() {
|
|
keys.into_iter()
|
|
.map(|k| k.cast::<SshKey>().fingerprint)
|
|
.collect()
|
|
} else {
|
|
keys.into_iter().map(|k| k.into_string().unwrap()).collect()
|
|
};
|
|
self.authorized_keys = Some(authorized_keys);
|
|
self
|
|
}
|
|
|
|
pub fn with_dist(mut self, dist: &str) -> Self {
|
|
self.dist = Some(dist.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_lang(mut self, lang: &str) -> Self {
|
|
self.lang = Some(lang.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_comment(mut self, comment: &str) -> Self {
|
|
self.comment = Some(comment.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_addon(mut self, addon: Array) -> Self {
|
|
let addons = addon
|
|
.into_iter()
|
|
.map(|a| a.into_string().unwrap())
|
|
.collect();
|
|
self.addon = Some(addons);
|
|
self
|
|
}
|
|
|
|
pub fn with_test(mut self, test: bool) -> Self {
|
|
self.test = Some(test);
|
|
self
|
|
}
|
|
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("OrderAuctionServerBuilder")
|
|
.with_fn("new_auction_server_builder", Self::new)
|
|
.with_fn("with_authorized_keys", Self::with_authorized_keys)
|
|
.with_fn("with_dist", Self::with_dist)
|
|
.with_fn("with_lang", Self::with_lang)
|
|
.with_fn("with_comment", Self::with_comment)
|
|
.with_fn("with_addon", Self::with_addon)
|
|
.with_fn("with_test", Self::with_test)
|
|
.with_get("authorized_keys", |b: &mut OrderAuctionServerBuilder| {
|
|
b.authorized_keys.clone()
|
|
})
|
|
.with_get("dist", |b: &mut OrderAuctionServerBuilder| b.dist.clone())
|
|
.with_get("lang", |b: &mut OrderAuctionServerBuilder| b.lang.clone())
|
|
.with_get("comment", |b: &mut OrderAuctionServerBuilder| {
|
|
b.comment.clone().unwrap_or("".to_string())
|
|
})
|
|
.with_get("addon", |b: &mut OrderAuctionServerBuilder| b.addon.clone())
|
|
.with_get("test", |b: &mut OrderAuctionServerBuilder| b.test.clone());
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone, CustomType)]
|
|
#[rhai_type(extra = Self::build_rhai_type)]
|
|
pub struct OrderServerAddonBuilder {
|
|
pub server_number: i64,
|
|
pub product_id: String,
|
|
pub reason: Option<String>,
|
|
pub gateway: Option<String>,
|
|
pub test: Option<bool>,
|
|
}
|
|
|
|
impl OrderServerAddonBuilder {
|
|
pub fn new(server_number: i64, product_id: &str) -> Self {
|
|
Self {
|
|
server_number,
|
|
product_id: product_id.to_string(),
|
|
reason: None,
|
|
gateway: None,
|
|
test: Some(true), // by default test is enabled
|
|
}
|
|
}
|
|
|
|
pub fn with_reason(mut self, reason: &str) -> Self {
|
|
self.reason = Some(reason.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_gateway(mut self, gateway: &str) -> Self {
|
|
self.gateway = Some(gateway.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn with_test(mut self, test: bool) -> Self {
|
|
self.test = Some(test);
|
|
self
|
|
}
|
|
|
|
fn build_rhai_type(builder: &mut TypeBuilder<Self>) {
|
|
builder
|
|
.with_name("OrderServerAddonBuilder")
|
|
.with_fn("new_server_addon_builder", Self::new)
|
|
.with_fn("with_reason", Self::with_reason)
|
|
.with_fn("with_gateway", Self::with_gateway)
|
|
.with_fn("with_test", Self::with_test)
|
|
.with_get("server_number", |b: &mut OrderServerAddonBuilder| {
|
|
b.server_number
|
|
})
|
|
.with_get("product_id", |b: &mut OrderServerAddonBuilder| {
|
|
b.product_id.clone()
|
|
})
|
|
.with_get("reason", |b: &mut OrderServerAddonBuilder| b.reason.clone())
|
|
.with_get("gateway", |b: &mut OrderServerAddonBuilder| {
|
|
b.gateway.clone()
|
|
})
|
|
.with_get("test", |b: &mut OrderServerAddonBuilder| b.test.clone());
|
|
}
|
|
}
|
|
|
|
|
|
fn string_or_seq_string<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let value = Value::deserialize(deserializer)?;
|
|
match value {
|
|
Value::String(s) => Ok(vec![s]),
|
|
Value::Array(a) => a
|
|
.into_iter()
|
|
.map(|v| {
|
|
v.as_str()
|
|
.map(ToString::to_string)
|
|
.ok_or(serde::de::Error::custom("expected string"))
|
|
})
|
|
.collect(),
|
|
_ => Err(serde::de::Error::custom(
|
|
"expected string or array of strings",
|
|
)),
|
|
}
|
|
}
|
|
|
|
fn option_string_or_seq_string<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let value = Value::deserialize(deserializer)?;
|
|
match value {
|
|
Value::Null => Ok(None),
|
|
Value::String(s) => Ok(Some(vec![s])),
|
|
Value::Array(a) => Ok(Some(
|
|
a.into_iter()
|
|
.map(|v| {
|
|
v.as_str()
|
|
.map(ToString::to_string)
|
|
.ok_or(serde::de::Error::custom("expected string"))
|
|
})
|
|
.collect::<Result<Vec<String>, _>>()?,
|
|
)),
|
|
_ => Err(serde::de::Error::custom(
|
|
"expected string or array of strings",
|
|
)),
|
|
}
|
|
}
|