use std::borrow::Cow;
use std::fmt::Display;
use crate::api::server::ServerId;
use crate::{error::Error, AsyncRobot};
use crate::api::{wrapper::Single, UnauthenticatedRequest};
fn get_rescue_config(server_number: ServerId) -> UnauthenticatedRequest<Single<Rescue>> {
UnauthenticatedRequest::from(&format!(
"https://robot-ws.your-server.de/boot/{server_number}/rescue"
))
}
fn enable_rescue_config(
server_number: ServerId,
rescue: RescueConfig,
) -> Result<UnauthenticatedRequest<Single<ActiveRescueConfig>>, serde_html_form::ser::Error> {
UnauthenticatedRequest::from(&format!(
"https://robot-ws.your-server.de/boot/{server_number}/rescue"
))
.with_method("POST")
.with_body(rescue)
}
fn disable_rescue_config(
server_number: ServerId,
) -> UnauthenticatedRequest<Single<AvailableRescueConfig>> {
UnauthenticatedRequest::from(&format!(
"https://robot-ws.your-server.de/boot/{server_number}/rescue"
))
.with_method("DELETE")
}
fn get_last_rescue_config(
server_number: ServerId,
) -> UnauthenticatedRequest<Single<ActiveRescueConfig>> {
UnauthenticatedRequest::from(&format!(
"https://robot-ws.your-server.de/boot/{server_number}/rescue/last"
))
}
impl AsyncRobot {
pub async fn get_rescue_config(&self, server_number: ServerId) -> Result<Rescue, Error> {
Ok(self.go(get_rescue_config(server_number)).await?.0)
}
pub async fn get_last_rescue_config(
&self,
server_number: ServerId,
) -> Result<ActiveRescueConfig, Error> {
Ok(self.go(get_last_rescue_config(server_number)).await?.0)
}
pub async fn enable_rescue_config(
&self,
server_number: ServerId,
config: RescueConfig,
) -> Result<ActiveRescueConfig, Error> {
Ok(self
.go(enable_rescue_config(server_number, config)?)
.await?
.0)
}
pub async fn disable_rescue_config(
&self,
server_number: ServerId,
) -> Result<AvailableRescueConfig, Error> {
Ok(self.go(disable_rescue_config(server_number)).await?.0)
}
}
use serde::{Deserialize, Serialize};
use crate::api::keys::SshKeyReference;
#[derive(Debug, Clone, Default, Serialize, PartialEq, Eq, PartialOrd, Ord)]
pub enum Keyboard {
#[default]
#[serde(rename = "us")]
US,
#[serde(rename = "uk")]
UK,
#[serde(rename = "ch")]
Swiss,
#[serde(rename = "de")]
German,
#[serde(rename = "fi")]
Finnish,
#[serde(rename = "fr")]
French,
#[serde(rename = "jp")]
Japanese,
#[serde(untagged)]
Other(String),
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct RescueConfig {
#[serde(rename = "os")]
pub operating_system: RescueOperatingSystem,
#[serde(rename = "authorized_key", skip_serializing_if = "Vec::is_empty")]
pub authorized_keys: Vec<String>,
pub keyboard: Keyboard,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ActiveRescueConfig {
#[serde(rename = "os")]
pub operating_system: RescueOperatingSystem,
pub password: Option<String>,
#[serde(rename = "host_key")]
pub host_keys: Vec<String>,
#[serde(
rename = "authorized_key",
deserialize_with = "crate::api::wrapper::deserialize_inner_vec"
)]
pub authorized_keys: Vec<SshKeyReference>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AvailableRescueConfig {
#[serde(rename = "os")]
pub operating_systems: Vec<RescueOperatingSystem>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum Rescue {
Active(ActiveRescueConfig),
Available(AvailableRescueConfig),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RescueOperatingSystem(pub Cow<'static, str>);
impl From<String> for RescueOperatingSystem {
fn from(value: String) -> Self {
RescueOperatingSystem(Cow::from(value))
}
}
impl From<&'static str> for RescueOperatingSystem {
fn from(value: &'static str) -> Self {
RescueOperatingSystem(Cow::from(value))
}
}
impl Display for RescueOperatingSystem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl PartialEq<str> for RescueOperatingSystem {
fn eq(&self, other: &str) -> bool {
self.0.eq(other)
}
}
#[cfg(test)]
mod isolated_tests {
use crate::api::boot::Keyboard;
#[test]
fn serialize_keyboard() {
let german = Keyboard::German;
let danish = Keyboard::Other("da".to_string());
assert_eq!(serde_json::to_string(&german).unwrap(), r#""de""#);
assert_eq!(serde_json::to_string(&danish).unwrap(), r#""da""#);
}
}