use std::num::NonZeroU16;
use indexmap::IndexMap;
use isoloom_spec::syntax::{OsRef, PortProtocol};
use isoloom_spec::{Appliance, Tc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Topology {
pub name: String,
pub nodes: IndexMap<String, Node>,
#[serde(default)]
pub networks: IndexMap<String, Lan>,
#[serde(default)]
pub links: Vec<Link>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Lan {
pub cidr: String,
#[serde(default = "yes")]
pub internet: bool,
#[serde(default)]
pub switch: Option<String>,
#[serde(default)]
pub vlan: Option<u16>,
#[serde(default)]
pub device: Option<String>,
#[serde(default)]
pub tc: Option<Tc>,
}
fn yes() -> bool {
true
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Node {
pub kind: Kind,
#[serde(default)]
pub access: bool,
#[serde(default)]
pub services: Vec<Service>,
#[serde(default)]
pub networks: IndexMap<String, Option<u8>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Service {
pub port: NonZeroU16,
#[serde(default)]
pub protocol: PortProtocol,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase", deny_unknown_fields)]
#[non_exhaustive]
pub enum Kind {
Container {
image: String,
#[serde(default)]
idle: bool,
#[serde(default)]
appliance: Option<Appliance>,
#[serde(default)]
config: Option<String>,
},
Vm {
os: OsRef,
#[serde(default)]
provision: Vec<String>,
},
Router {},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Link {
pub a: Endpoint,
pub b: Endpoint,
#[serde(default)]
pub tc: Option<Tc>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Endpoint {
pub node: String,
pub port: String,
}