use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum HetznerError {
NoCredentials {
looked_for: Vec<String>,
},
Unauthorized,
RateLimited {
retry_after_secs: Option<u64>,
},
Api {
status: u16,
code: String,
message: String,
},
Transport(String),
Decode(String),
Timeout {
waiting_for: String,
after_secs: u64,
},
}
impl std::fmt::Display for HetznerError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NoCredentials { looked_for } => write!(
f,
"no Hetzner token: set one of {}",
looked_for.join(" or ")
),
Self::Unauthorized => write!(
f,
"Hetzner rejected the token (401) — check the token's value and that it has \
read+write on the project"
),
Self::RateLimited { retry_after_secs } => match retry_after_secs {
Some(secs) => write!(f, "Hetzner rate limit hit; resets in {secs}s"),
None => write!(f, "Hetzner rate limit hit"),
},
Self::Api {
status,
code,
message,
} => write!(f, "Hetzner API error {status} ({code}): {message}"),
Self::Transport(e) => write!(f, "transport error talking to Hetzner: {e}"),
Self::Decode(e) => write!(f, "could not decode Hetzner's response: {e}"),
Self::Timeout {
waiting_for,
after_secs,
} => write!(f, "timed out after {after_secs}s waiting for {waiting_for}"),
}
}
}
impl std::error::Error for HetznerError {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ServerStatus {
Initializing,
Starting,
Running,
Stopping,
Off,
Deleting,
Migrating,
Rebuilding,
Unknown,
#[serde(other)]
Other,
}
impl ServerStatus {
#[must_use]
pub fn is_settled(self) -> bool {
matches!(self, Self::Running | Self::Off | Self::Unknown | Self::Other)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Server {
pub id: i64,
pub name: String,
pub status: ServerStatus,
pub public_ipv4: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SshKey {
pub id: i64,
pub name: String,
pub fingerprint: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct CreateServerRequest {
pub name: String,
pub server_type: String,
pub image: String,
pub location: Option<String>,
pub ssh_keys: Vec<i64>,
pub user_data: Option<String>,
pub labels: std::collections::BTreeMap<String, String>,
}