diff --git a/src/api/models.rs b/src/api/models.rs index d7f79d5..ad4f16e 100644 --- a/src/api/models.rs +++ b/src/api/models.rs @@ -232,6 +232,21 @@ impl fmt::Display for Boot { } } +#[derive(Debug, Deserialize, Clone)] +#[serde(untagged)] +pub enum Os { + Single(String), + Multiple(Vec), +} + +impl Os { + pub fn to_vec(&self) -> Vec { + match self { + Os::Single(s) => vec![s.clone()], + Os::Multiple(v) => v.clone(), + } + } +} #[derive(Deserialize)] pub struct RescueWrapped { pub rescue: Rescue, @@ -243,12 +258,12 @@ pub struct Rescue { pub server_ip: String, pub server_ipv6_net: String, pub server_number: i32, - #[serde(deserialize_with = "string_or_seq_string")] - pub os: Vec, + pub os: Os, pub active: bool, pub password: Option, - pub authorized_key: Vec, - pub host_key: Vec, + #[serde(rename = "authorized_key")] + pub authorized_keys: Vec, + pub host_key: Vec, } impl Rescue { @@ -260,10 +275,15 @@ impl Rescue { r.server_ipv6_net.clone() }) .with_get("server_number", |r: &mut Rescue| r.server_number) - .with_get("os", |r: &mut Rescue| r.os.clone()) + .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_key", |r: &mut Rescue| r.authorized_key.clone()) + .with_get("authorized_keys", |r: &mut Rescue| { + r.authorized_keys + .iter() + .map(|k| rhai::Dynamic::from(k.key.clone())) + .collect::() + }) .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()); @@ -272,13 +292,30 @@ impl Rescue { impl fmt::Display for Rescue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "OS: {}, Active: {}, Keys: {}", - self.os.join(", "), - self.active, - self.authorized_key.join(", ") - ) + 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 = 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 = self + .host_key + .iter() + .filter_map(|key| key.fingerprint.clone()) + .collect(); + table.add_row(row!["Host Keys", host_keys.join("\n")]); + + write!(f, "{}", table) } } @@ -294,8 +331,9 @@ pub struct Linux { pub lang: Vec, pub active: bool, pub password: Option, - pub authorized_key: Vec, - pub host_key: Vec, + #[serde(rename = "authorized_key")] + pub authorized_keys: Vec, + pub host_key: Vec, } impl Linux { @@ -309,7 +347,12 @@ impl Linux { .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_key", |l: &mut Linux| l.authorized_key.clone()) + .with_get("authorized_keys", |l: &mut Linux| { + l.authorized_keys + .iter() + .map(|k| rhai::Dynamic::from(k.key.clone())) + .collect::() + }) .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()); @@ -318,13 +361,30 @@ impl Linux { impl fmt::Display for Linux { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "Dist: {}, Lang: {}, Active: {}", - self.dist.join(", "), - self.lang.join(", "), - self.active - ) + 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 = 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 = self + .host_key + .iter() + .filter_map(|key| key.fingerprint.clone()) + .collect(); + table.add_row(row!["Host Keys", host_keys.join("\n")]); + write!(f, "{}", table) } } @@ -1043,20 +1103,20 @@ pub struct AuthorizedKeyWrapper { #[derive(Debug, Deserialize, Clone, CustomType)] #[rhai_type(extra = Self::build_rhai_type)] pub struct AuthorizedKey { - pub name: String, - pub fingerprint: String, + pub name: Option, + pub fingerprint: Option, #[serde(rename = "type")] - pub key_type: String, - pub size: i32, + pub key_type: Option, + pub size: Option, } impl From for AuthorizedKey { fn from(key: SshKey) -> Self { Self { - name: key.name, - fingerprint: key.fingerprint, - key_type: key.key_type, - size: key.size, + name: Some(key.name), + fingerprint: Some(key.fingerprint), + key_type: Some(key.key_type), + size: Some(key.size), } } } @@ -1130,10 +1190,16 @@ pub struct HostKeyWrapper { #[derive(Debug, Deserialize, Clone, CustomType)] #[rhai_type(extra = Self::build_rhai_type)] pub struct HostKey { - pub fingerprint: String, + pub fingerprint: Option, #[serde(rename = "type")] - pub key_type: String, - pub size: i32, + pub key_type: Option, + pub size: Option, +} + + +#[derive(Debug, Deserialize, Clone)] +pub struct RescueKey { + pub key: HostKey, } impl HostKey { @@ -1466,10 +1532,10 @@ impl fmt::Display for AuctionTransaction { 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, - key.key.fingerprint, - key.key.key_type, - key.key.size + 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]); @@ -1477,7 +1543,11 @@ impl fmt::Display for AuctionTransaction { 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, key.key.key_type, key.key.size]); + 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]); diff --git a/src/scripting/printing/server_ordering_table.rs b/src/scripting/printing/server_ordering_table.rs index 95d4cf7..e4cf48c 100644 --- a/src/scripting/printing/server_ordering_table.rs +++ b/src/scripting/printing/server_ordering_table.rs @@ -196,10 +196,10 @@ pub fn pretty_print_auction_transactions(transactions: rhai::Array) { table.add_row(row![b => "Name", "Fingerprint", "Type", "Size"]); for key in &transaction.authorized_key { table.add_row(row![ - key.key.name, - key.key.fingerprint, - key.key.key_type, - key.key.size + 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 @@ -210,9 +210,9 @@ pub fn pretty_print_auction_transactions(transactions: rhai::Array) { table.add_row(row![b => "Fingerprint", "Type", "Size"]); for key in &transaction.host_key { table.add_row(row![ - key.key.fingerprint, - key.key.key_type, - key.key.size + 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