now parses host_vars/*.yml

This commit is contained in:
yannik 2017-11-17 02:14:12 +01:00
parent 5e7abdb2d8
commit f55e135b53

View file

@ -27,12 +27,8 @@ fn main() {
let nodes = hosts.iter().map(Host::to_dot_node); let nodes = hosts.iter().map(Host::to_dot_node);
let edges = hosts.iter().flat_map(Host::to_dot_edge); let edges = hosts.iter().flat_map(Host::to_dot_edge);
// let edges = ..
//render it //render it
println!("graph antennen {{");
println!("digraph antennen {{");
for node in nodes { for node in nodes {
println!("{}", node); println!("{}", node);
} }
@ -55,15 +51,15 @@ pub enum ParseError {
#[error_chain(custom)] #[error_chain(custom)]
#[error_chain(description = r#"|_| "Host file structure broken""#)] #[error_chain(description = r#"|_| "Host file structure broken""#)]
#[error_chain(display = r#"|t| write!(f, "the antenna config is wrong: {}", t)"#)] #[error_chain(display = r#"|&(ref name, ref err)| write!(f, "the antenna config of {} is wrong: {}", name, err)"#)]
Structure(String), Structure((String, String)),
} }
#[derive(Debug)] #[derive(Debug)]
struct Host { struct Host {
name: String, name: String,
ip: String, ip: String,
mac: String, mac: Option<String>,
kind: HostKind, kind: HostKind,
} }
impl Host { impl Host {
@ -71,20 +67,24 @@ impl Host {
RawHost::from_file(path)?.parse() RawHost::from_file(path)?.parse()
} }
fn to_dot_node(&self) -> String { fn to_dot_node(&self) -> String {
let mac = self.mac.clone().unwrap_or("no mac".into());
let mut attributes = vec! let mut attributes = vec!
[ "shape=record".to_string() [ "shape=record".to_string()
, format!("label=\"{{\'{name}\'|{typ}|{{{ip}|{mac}}}|{{{ipv6}}}}}\"" , format!("label=\"{{\'{name}\'|{typ}|{{{ip}|{mac}}}|{{{ipv6}}}}}\""
, name = self.name, typ=self.kind.name(), ip=self.ip, mac=self.mac, ipv6="no ipv6") , name = self.name, typ=self.kind.name(), ip=self.ip
, mac=mac, ipv6="no ipv6")
, "style=filled".into() , "style=filled".into()
]; ];
// type-specific handling // type-specific handling
match self.kind { match self.kind {
HostKind::Client {coordinates, ref subnet, .. } => attributes.extend_from_slice( HostKind::Client {coordinates, ref subnet, .. } =>
&[ format!("pos=\"{breitengrad},{längengrad}\"" { attributes.push("fillcolor=lightgray".into())
, längengrad=coordinates[0], breitengrad=coordinates[1]) ; if let Some(coordinates) = coordinates
, "fillcolor=lightgray".into() { attributes.push(format!("pos=\"{breitengrad},{längengrad}\""
]), , längengrad=coordinates[0], breitengrad=coordinates[1]))
}
},
_ => (), _ => (),
}; };
@ -95,7 +95,7 @@ impl Host {
fn to_dot_edge(&self) -> Option<String> { fn to_dot_edge(&self) -> Option<String> {
match self.kind { match self.kind {
HostKind::Client { ref parent, .. } => HostKind::Client { ref parent, .. } =>
format!("\"{name}\" -> \"{parent}\"", name=self.name, parent=parent).into(), format!("\"{name}\" -- \"{parent}\"", name=self.name, parent=parent).into(),
_ => None, _ => None,
} }
} }
@ -103,7 +103,7 @@ impl Host {
#[derive(Debug)] #[derive(Debug)]
enum HostKind { enum HostKind {
Client { subnet: String, coordinates: [f64;2], parent: String }, Client { subnet: String, coordinates: Option<[f64;2]>, parent: String },
AccessPoint, AccessPoint,
Other, Other,
} }
@ -127,7 +127,7 @@ struct RawHost {
ansible_host: String, ansible_host: String,
#[serde(rename = "type")] #[serde(rename = "type")]
kind: String, kind: String,
mac: String, mac: Option<String>,
client_of: Option<String>, client_of: Option<String>,
coordinate: Option<[f64;2]>, coordinate: Option<[f64;2]>,
subnet: Option<String>, subnet: Option<String>,
@ -135,21 +135,22 @@ struct RawHost {
impl RawHost { impl RawHost {
fn parse(self) -> Result<Host> { fn parse(self) -> Result<Host> {
let name = self.name let name : String = self.name
.ok_or(ParseError::Structure("got no file name? weird.".into()))? .ok_or(ParseError::Structure(("???".into(),"got no file name? weird.".into())))?
.into_string().unwrap() .into_string().unwrap()
.split('.') .split('.')
.next().unwrap().into(); .next().unwrap().into();
Ok(Host Ok(Host
{ name: name { name: name.clone()
, ip: self.ansible_host , ip: self.ansible_host
, mac: self.mac , mac: self.mac
, kind: match self.kind.as_ref() , kind: match self.kind.as_ref()
{ "wlan-ap" => HostKind::AccessPoint { "wlan-ap" => HostKind::AccessPoint
, "client" => HostKind::Client , "client" => HostKind::Client
{ subnet: self.subnet.ok_or(ParseError::Structure("is client, has no subnet".into()))? { subnet: self.subnet.ok_or(ParseError::Structure((name.clone(), "is client, has no subnet".into())))?
, coordinates: self.coordinate.ok_or(ParseError::Structure("is client, has no coordinates".into()))? //, coordinates: self.coordinate.ok_or(ParseError::Structure("is client, has no coordinates".into()))?
, parent: self.client_of.ok_or(ParseError::Structure("is client, has no client_of".into()))? , coordinates: self.coordinate
, parent: self.client_of.ok_or(ParseError::Structure((name.clone(), "is client, has no client_of".into())))?
} }
, _ => HostKind::Other , _ => HostKind::Other
} }