use serde::{Serialize, Deserialize, Deserializer}; use std::fmt; use crate::clouds::on_clouds::load_config_data; use crate::clouds::defs::Cloud; #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize, Default)] pub struct LoginUser { pub sshKeys: Vec, } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize, Default)] pub struct Cluster { pub role: String, } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NetworkInterface { pub access: String, pub family: String, pub network: Option, pub ipaddress: Option, } impl Default for NetworkInterface { fn default() -> Self { Self { access: String::from("public"), family: String::from("IPv4"), network: None, ipaddress: None, } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SSHAccess { pub keyPath: String, pub password: String, pub port: u16, pub host: String, pub utype: String, pub user: String, } impl Default for SSHAccess { fn default() -> Self { Self { keyPath: String::from(""), password: String::from(""), port: 22, host: String::from(""), utype: String::from("key"), user: String::from("root"), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct StorageDevice { pub action: String, pub size: u16, pub finalSize: u16, pub storage: String, pub partSizes: Option, pub makefs: Option, pub tier: String, pub title: String, pub source: String, } impl Default for StorageDevice { fn default() -> Self { Self { action: String::from("clone"), size: 5, finalSize: 5, partSizes: None, makefs: None, storage: String::from(""), tier: String::from("maxiops"), title: String::from(""), source: String::from(""), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum TskSrvcName { os, systemfix, sysconfig, tools, proxy, coredns, etcd, vpn, keepalived, containerd, crio, podman, kubernetes, k3s, webhook, cloudmandala, zterton, repo, postgres, nfs, redis, local, devel, scale, klouds, pause, } impl Default for TskSrvcName { fn default() -> Self { TskSrvcName::os } } impl fmt::Display for TskSrvcName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { TskSrvcName::os => write!(f,"os"), TskSrvcName::systemfix => write!(f,"systemfix"), TskSrvcName::sysconfig => write!(f,"sysconfig"), TskSrvcName::tools => write!(f,"tools"), TskSrvcName::proxy => write!(f,"proxy"), TskSrvcName::etcd => write!(f,"etcd"), TskSrvcName::vpn => write!(f,"vpn"), TskSrvcName::coredns => write!(f,"coredns"), TskSrvcName::keepalived => write!(f,"keepalived"), TskSrvcName::crio => write!(f,"crio"), TskSrvcName::containerd => write!(f,"containerd"), TskSrvcName::kubernetes => write!(f,"kubernetes"), TskSrvcName::k3s => write!(f,"k3s"), TskSrvcName::webhook => write!(f,"webhook"), TskSrvcName::podman => write!(f,"podman"), TskSrvcName::repo => write!(f,"repo"), TskSrvcName::postgres => write!(f,"postgres"), TskSrvcName::redis => write!(f,"redis"), TskSrvcName::local => write!(f,"local"), TskSrvcName::scale => write!(f,"scale"), TskSrvcName::devel => write!(f,"devel"), TskSrvcName::klouds => write!(f,"klouds"), TskSrvcName::cloudmandala => write!(f,"cloudmandala"), TskSrvcName::zterton => write!(f,"zterton"), TskSrvcName::nfs => write!(f,"nfs"), TskSrvcName::pause => write!(f,"pause"), } } } impl TskSrvcName { pub fn set_systsksrvc(pack: String) -> TskSrvcName { match pack.as_str() { "os" => TskSrvcName::os, "systemfix" => TskSrvcName::systemfix, "sysconfig" => TskSrvcName::sysconfig, "tools" => TskSrvcName::tools, "proxy" => TskSrvcName::proxy, "coredns" => TskSrvcName::coredns, "etcd" => TskSrvcName::etcd, "vpn" => TskSrvcName::vpn, "keepalived" => TskSrvcName::keepalived, "containerd" => TskSrvcName::containerd, "crio" => TskSrvcName::crio, "podman" => TskSrvcName::podman, "kubernetes" => TskSrvcName::kubernetes, "k3s" => TskSrvcName::k3s, "webhook" => TskSrvcName::webhook, "cloudmandala" => TskSrvcName::cloudmandala, "zterton" => TskSrvcName::zterton, "nfs" => TskSrvcName::nfs, "repo" => TskSrvcName::repo, "postgres" => TskSrvcName::postgres, "redis" => TskSrvcName::redis, "local" => TskSrvcName::local, "devel" => TskSrvcName::devel, "scale" => TskSrvcName::scale, "klouds" => TskSrvcName::klouds, "pause" => TskSrvcName::pause, &_ => TskSrvcName::default(), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum AppName { none, registry, repo, wp_site, mariadb, postgres, redis, mail, gitea, local, zterton, } impl Default for AppName { fn default() -> Self { AppName::none } } impl fmt::Display for AppName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { AppName::none => write!(f,"none"), AppName::registry => write!(f,"registry"), AppName::repo => write!(f,"repo"), AppName::wp_site => write!(f,"wp_site"), AppName::mariadb => write!(f,"mariadb"), AppName::postgres => write!(f,"postgres"), AppName::redis => write!(f,"redis"), AppName::mail => write!(f,"mail"), AppName::gitea => write!(f,"gitea"), AppName::local => write!(f,"local"), AppName::zterton => write!(f,"zterton"), } } } impl AppName { pub fn set_appname(pack: String) -> AppName { match pack.as_str() { "none" => AppName::none, "registry" => AppName::registry, "repo" => AppName::repo, "wp_site" => AppName::wp_site, "mariadb" => AppName::mariadb, "postgres" => AppName::postgres, "redis" => AppName::redis, "mail" => AppName::mail, "gitea" => AppName::gitea, "local" => AppName::local, "zterton" => AppName::zterton, &_ => AppName::default(), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum ProviderName { none, manual, upcloud, } impl Default for ProviderName { fn default() -> Self { ProviderName::none } } impl fmt::Display for ProviderName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ProviderName::none => write!(f,"none"), ProviderName::manual => write!(f,"manual"), ProviderName::upcloud => write!(f,"upcloud"), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum InfaceMode { none, float, alias, } impl InfaceMode { pub fn set_infacemode(pack: String) -> InfaceMode { match pack.as_str() { "none" => InfaceMode::none, "float" => InfaceMode::float, "alias" => InfaceMode::alias, &_ => InfaceMode::default(), } } } impl Default for InfaceMode { fn default() -> Self { InfaceMode::none } } impl fmt::Display for InfaceMode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { InfaceMode::none => write!(f,"none"), InfaceMode::float => write!(f,"float"), InfaceMode::alias => write!(f,"alias"), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum InfaceNet { none, public, sdn, prv, vpn, } impl InfaceNet { pub fn set_infacenet(pack: String) -> InfaceNet { match pack.as_str() { "none" => InfaceNet::none, "public" => InfaceNet::public, "pub" => InfaceNet::public, "sdn" => InfaceNet::sdn, "prv" => InfaceNet::prv, "vpn" => InfaceNet::vpn, &_ => InfaceNet::default(), } } } impl Default for InfaceNet { fn default() -> Self { InfaceNet::none } } impl fmt::Display for InfaceNet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { InfaceNet::none => write!(f,"none"), InfaceNet::public => write!(f,"pub"), InfaceNet::sdn => write!(f,"sdn"), InfaceNet::prv => write!(f,"prv"), InfaceNet::vpn => write!(f,"vpn"), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum NetworkMethodName { none, firstavailable, } impl NetworkMethodName { pub fn set_providername(pack: String) -> NetworkMethodName { match pack.as_str() { "none" => NetworkMethodName::none, "firstavailable" => NetworkMethodName::firstavailable, &_ => NetworkMethodName::default(), } } } impl Default for NetworkMethodName { fn default() -> Self { NetworkMethodName::none } } impl fmt::Display for NetworkMethodName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { NetworkMethodName::none => write!(f,"none"), NetworkMethodName::firstavailable => write!(f,"firstavailable"), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum IsCritical { no, yes, cloud, group, ifresized, } impl IsCritical { pub fn set_infacenet(pack: String) -> IsCritical { match pack.as_str() { "no" => IsCritical::no, "yes" => IsCritical::yes, "cloud" => IsCritical::cloud, "group" => IsCritical::group, "ifresized" => IsCritical::ifresized, &_ => IsCritical::default(), } } } impl Default for IsCritical { fn default() -> Self { IsCritical::no } } impl fmt::Display for IsCritical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { IsCritical::no => write!(f,"no"), IsCritical::yes => write!(f,"yes"), IsCritical::cloud => write!(f,"cloud"), IsCritical::group => write!(f,"group"), IsCritical::ifresized => write!(f,"ifresized"), } } } #[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub enum EdgeDirection { directional, unidirectional, bidirectional, } impl EdgeDirection { pub fn set_infacenet(pack: String) -> EdgeDirection { match pack.as_str() { "directional" => EdgeDirection::directional, "unidirectional" => EdgeDirection::unidirectional, "bidirectional" => EdgeDirection::bidirectional, &_ => EdgeDirection::default(), } } } impl Default for EdgeDirection { fn default() -> Self { EdgeDirection::directional } } impl fmt::Display for EdgeDirection { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { EdgeDirection::directional => write!(f,"directional"), EdgeDirection::unidirectional => write!(f,"unidirectional"), EdgeDirection::bidirectional => write!(f,"bidirectional"), } } } fn deserialize_infacenet<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { let buf = String::deserialize(deserializer)?; // let res = String::from_str(&buf).map_err(serde::de::Error::custom) { // .unwrap_or_else(|| serde::de::Error::custom); Ok(InfaceNet::set_infacenet(buf)) } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct IpDef { pub ip: String, pub hostname: String, pub inface: String, pub mode: InfaceMode, pub methods: Vec, #[serde(deserialize_with = "deserialize_infacenet")] pub inet: InfaceNet, pub ports: Vec, pub aliveport: String, pub targets: Vec, pub monitor: String, pub critical: IsCritical, pub graph: GraphNode, } impl Default for IpDef { fn default() -> Self { Self { ip: String::from(""), hostname: String::from(""), inface: String::from(""), mode: InfaceMode::default(), methods: vec!(NetworkMethodName::default()), inet: InfaceNet::default(), ports: Vec::new(), aliveport: String::from(""), targets: Vec::new(), monitor: String::from(""), critical: IsCritical::no, graph: GraphNode::default(), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Cntrllr { pub host: String, pub sshaccess: SSHAccess, pub cldPath: String, pub masterPath: String, } impl Default for Cntrllr { fn default() -> Self { Self { host: String::from(""), sshaccess: SSHAccess::default(), cldPath: String::from(""), masterPath: String::from(""), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Price { pub item: String, pub amount: i64, pub month: f64, pub hour: f64, } impl Default for Price { fn default() -> Self { Self { item: String::from(""), amount: 1, month: 0.0, hour: 0.0, } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CloudItem { pub name: String, pub path: String, pub info: String, pub resources: Option, pub liveness: Option, pub provision: Option, pub critical: IsCritical, pub graph: GraphNode, } impl Default for CloudItem { fn default() -> Self { Self { name: String::from(""), path: String::from(""), info: String::from(""), resources: Some(String::from("")), liveness: Some(String::from("")), provision: Some(String::from("")), critical: IsCritical::no, graph: GraphNode::default(), } } } impl CloudItem { #[allow(clippy::missing_errors_doc)] pub async fn load_resources(&self,cloud: &Cloud) -> anyhow::Result { // dbg!("{}/{}",&home_path,&self.path); Ok(load_config_data(&cloud, &self.path).await .unwrap_or_else(|e|{ eprintln!("CloudGroup error loading resources {} -> {}",&self.path,e); String::from("") }) ) } #[allow(clippy::missing_errors_doc)] pub async fn with_resources(&self,cloud: &Cloud) -> Self { Self { name: self.name.to_owned(), path: self.path.to_owned(), info: self.info.to_owned(), resources: Some(self.load_resources(cloud).await.unwrap_or_else(|_|String::from(""))), liveness: self.liveness.to_owned(), provision: self.provision.to_owned(), graph: self.graph.to_owned(), critical: self.critical.to_owned(), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CloudGroup { pub name: String, pub path: String, pub info: String, pub resources: Option, pub liveness: Option, pub provision: Option, pub items: Vec, pub graph: GraphNode, pub prices: Vec, } impl Default for CloudGroup { fn default() -> Self { Self { name: String::from(""), path: String::from(""), info: String::from(""), resources: Some(String::from("")), liveness: Some(String::from("")), provision: Some(String::from("")), items: Vec::new(), graph: GraphNode::default(), prices: Vec::new(), } } } impl CloudGroup { #[allow(clippy::missing_errors_doc)] pub async fn load_resources(&self,cloud: &Cloud) -> anyhow::Result { // dbg!("{}/{}",&home_path,&self.path); Ok(load_config_data(&cloud, &self.path).await .unwrap_or_else(|e|{ eprintln!("CloudGroup error loading resources {} -> {}",&self.path,e); String::from("") }) ) } #[allow(clippy::missing_errors_doc)] pub async fn with_resources(&self,cloud: &Cloud) -> Self { Self { name: self.name.to_owned(), path: self.path.to_owned(), info: self.info.to_owned(), resources: Some(self.load_resources(cloud).await.unwrap_or_else(|_|String::from(""))), liveness: self.liveness.to_owned(), provision: self.liveness.to_owned(), items: self.items.to_owned(), graph: self.graph.to_owned(), prices: self.prices.to_owned(), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct KloudHome { pub name: String, pub title: String, pub dflts: String, pub provider: Vec, pub netips: Vec, pub cntrllrs: Vec, pub groups: Vec, pub monitor_info: Option, pub graph: GraphNode, pub prices: Vec, } impl Default for KloudHome { fn default() -> Self { Self { name: String::from(""), title: String::from(""), dflts: String::from(""), provider: vec!(ProviderName::default()), netips: vec!(IpDef::default()), cntrllrs: vec!(Cntrllr::default()), groups: vec!(CloudGroup::default()), monitor_info: Some(String::from("")), graph: GraphNode::default(), prices: vec!(Price::default()), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CloudCheckItem { pub name: String, pub path: String, pub info: String, pub liveness: Option, pub critical: IsCritical, } impl Default for CloudCheckItem { fn default() -> Self { Self { name: String::from(""), path: String::from(""), info: String::from(""), liveness: Some(String::from("")), critical: IsCritical::no, } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CloudCheckGroup { pub name: String, pub path: String, pub info: String, pub liveness: Option, pub items: Vec, } impl Default for CloudCheckGroup { fn default() -> Self { Self { name: String::from(""), path: String::from(""), info: String::from(""), liveness: Some(String::from("")), items: Vec::new(), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct KloudCheckHome { pub name: String, pub title: String, pub dflts: String, pub provider: Vec, pub netips: Vec, pub cntrllrs: Vec, pub groups: Vec, pub monitor_info: Option, } impl Default for KloudCheckHome { fn default() -> Self { Self { name: String::from(""), title: String::from(""), dflts: String::from(""), provider: vec!(ProviderName::default()), netips: vec!(IpDef::default()), cntrllrs: vec!(Cntrllr::default()), groups: vec!(CloudCheckGroup::default()), monitor_info: Some(String::from("")), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct GraphEdge { pub name: String, pub direction: EdgeDirection, pub origin: String, pub target: String, pub text: String, pub color: String, pub text_color: String, } impl Default for GraphEdge { fn default() -> Self { Self { name: String::from(""), direction: EdgeDirection::default(), origin: String::from(""), target: String::from(""), text: String::from(""), color: String::from(""), text_color: String::from(""), } } } #[allow(non_snake_case)] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct GraphNode { pub name: String, pub parent: String, pub text: String, pub x: i32, pub y: i32, pub n: i32, pub color: String, pub bg_color: String, pub text_color: String, pub edges: Vec, } impl Default for GraphNode { fn default() -> Self { Self { name: String::from(""), parent: String::from(""), text: String::from(""), x: 0, y: 0, n: 1, color: String::from(""), bg_color: String::from(""), text_color: String::from(""), edges: Vec::new(), // vec!(GraphEdge::default()), } } }