pub const TAKE_ALL: i16 = -1; #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct Config { pub anti_phishing_code: String, pub keymap: Option, pub modules: Option, pub auths: Vec, pub networks: Vec, #[serde(default)] pub ssh: SSHServer, #[serde(default)] pub pre_lvm_crypt: Vec, #[serde(default)] pub lvm: Vec, #[serde(default)] pub crypt: Vec, pub bootstrap: Bootstrap, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct Auth { pub name: String, #[serde(rename = "sshKey")] pub ssh_key: String, pub password: String, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct Network { pub name: String, pub interfaces: Vec, pub script: String, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct NetworkInterface { pub var: String, pub n: i16, pub regexps: Vec, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct SSHServer { pub listen: String, pub keys: SSHKeys, } impl Default for SSHServer { fn default() -> Self { Self { listen: "[::]:22".to_string(), keys: SSHKeys::default(), } } } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct SSHKeys { dsa: Option, rsa: Option, ecdsa: Option, ed25519: Option, } impl SSHKeys { pub fn iter(&self) -> impl Iterator { [ self.dsa.iter(), self.rsa.iter(), self.ecdsa.iter(), self.ed25519.iter(), ] .into_iter() .flatten() .map(String::as_str) } } impl Default for SSHKeys { fn default() -> Self { Self { dsa: Some("id_dsa".to_string()), rsa: Some("id_rsa".to_string()), ecdsa: Some("id_ecdsa".to_string()), ed25519: Some("id_ed25519".to_string()), } } } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct LvmVG { #[serde(alias = "vg")] pub name: String, pub pvs: LvmPV, #[serde(default)] pub defaults: LvmLVDefaults, pub lvs: Vec, } #[derive(Debug, Default, serde::Deserialize, serde::Serialize)] pub struct LvmLVDefaults { #[serde(default)] pub fs: Filesystem, #[serde(default)] pub raid: Raid, } #[derive(Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "snake_case")] pub enum Filesystem { Ext4, Xfs, Btrfs, Other(String), } impl Filesystem { pub fn fstype(&self) -> &str { use Filesystem as F; match self { F::Ext4 => "ext4", F::Xfs => "xfs", F::Btrfs => "btrfs", F::Other(t) => t, } } } impl Default for Filesystem { fn default() -> Self { Filesystem::Ext4 } } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct LvmLV { pub name: String, #[serde(skip_serializing_if = "Option::is_none")] pub fs: Option, #[serde(skip_serializing_if = "Option::is_none")] pub raid: Option, #[serde(flatten)] pub size: LvSize, } #[derive(Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "snake_case")] pub enum LvSize { Size(String), Extents(String), } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct LvmPV { pub n: i16, pub regexps: Vec, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct CryptDev { pub name: String, #[serde(flatten)] pub filter: DevFilter, pub optional: Option, } impl CryptDev { pub fn optional(&self) -> bool { self.optional.unwrap_or_else(|| self.filter.is_prefix()) } } #[derive(Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "snake_case")] pub enum DevFilter { Dev(String), Prefix(String), } impl DevFilter { pub fn is_dev(&self) -> bool { match self { Self::Dev(_) => true, _ => false, } } pub fn is_prefix(&self) -> bool { match self { Self::Prefix(_) => true, _ => false, } } } #[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)] pub struct Raid { pub mirrors: Option, pub stripes: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct Bootstrap { pub dev: String, pub seed: Option, }