Extend fabric status reporting to cover the IS-IS fabric alongside the existing OpenFabric and OSPF support.
Signed-off-by: Gabriel Goller <[email protected]> --- pve-rs/src/bindings/sdn/fabrics.rs | 99 ++++++++++++++++++++++++++++++ pve-rs/src/sdn/status.rs | 15 +++++ 2 files changed, 114 insertions(+) diff --git a/pve-rs/src/bindings/sdn/fabrics.rs b/pve-rs/src/bindings/sdn/fabrics.rs index c4150c830a0a..6f4207b24813 100644 --- a/pve-rs/src/bindings/sdn/fabrics.rs +++ b/pve-rs/src/bindings/sdn/fabrics.rs @@ -687,6 +687,41 @@ pub mod pve_rs_sdn_fabrics { proxmox_sys::nodename(), ) } + FabricEntry::Isis(_) => { + let isis_ipv4_routes_string = String::from_utf8( + Command::new("sh") + .args(["-c", "vtysh -c 'show ip route isis json'"]) + .output()? + .stdout, + )?; + + let isis_ipv6_routes_string = String::from_utf8( + Command::new("sh") + .args(["-c", "vtysh -c 'show ipv6 route isis json'"]) + .output()? + .stdout, + )?; + + let mut isis_routes: proxmox_frr::de::Routes = + if isis_ipv4_routes_string.is_empty() { + proxmox_frr::de::Routes::default() + } else { + serde_json::from_str(&isis_ipv4_routes_string) + .with_context(|| "error parsing isis ipv4 routes")? + }; + if !isis_ipv6_routes_string.is_empty() { + let isis_ipv6_routes: proxmox_frr::de::Routes = + serde_json::from_str(&isis_ipv6_routes_string) + .with_context(|| "error parsing isis ipv6 routes")?; + isis_routes.0.extend(isis_ipv6_routes.0); + } + status::get_routes( + fabric_id, + config, + isis_routes, + proxmox_sys::nodename(), + ) + } FabricEntry::Ospf(_) => { let ospf_routes_string = String::from_utf8( Command::new("sh") @@ -738,6 +773,23 @@ pub mod pve_rs_sdn_fabrics { status::get_neighbors_openfabric(fabric_id, openfabric_neighbors).map(|v| v.into()) } + FabricEntry::Isis(_) => { + let isis_neighbors_string = String::from_utf8( + Command::new("sh") + .args(["-c", "vtysh -c 'show isis neighbor detail json'"]) + .output()? + .stdout, + )?; + let isis_neighbors: proxmox_frr::de::openfabric::Neighbors = + if isis_neighbors_string.is_empty() { + proxmox_frr::de::openfabric::Neighbors::default() + } else { + serde_json::from_str(&isis_neighbors_string) + .with_context(|| "error parsing isis neighbors")? + }; + + status::get_neighbors_openfabric(fabric_id, isis_neighbors).map(|v| v.into()) + } FabricEntry::Ospf(fabric) => { let ospf_neighbors_string = String::from_utf8( Command::new("sh") @@ -797,6 +849,24 @@ pub mod pve_rs_sdn_fabrics { status::get_interfaces_openfabric(fabric_id, openfabric_interfaces) .map(|v| v.into()) } + FabricEntry::Isis(_) => { + let isis_interface_string = String::from_utf8( + Command::new("sh") + .args(["-c", "vtysh -c 'show isis interface json'"]) + .output()? + .stdout, + )?; + let isis_interfaces: proxmox_frr::de::openfabric::Interfaces = + if isis_interface_string.is_empty() { + proxmox_frr::de::openfabric::Interfaces::default() + } else { + serde_json::from_str(&isis_interface_string) + .with_context(|| "error parsing isis interfaces")? + }; + + status::get_interfaces_openfabric(fabric_id, isis_interfaces) + .map(|v| v.into()) + } FabricEntry::Ospf(fabric) => { let ospf_interfaces_string = String::from_utf8( Command::new("sh") @@ -852,6 +922,20 @@ pub mod pve_rs_sdn_fabrics { .stdout, )?; + let isis_ipv4_routes_string = String::from_utf8( + Command::new("sh") + .args(["-c", "vtysh -c 'show ip route isis json'"]) + .output()? + .stdout, + )?; + + let isis_ipv6_routes_string = String::from_utf8( + Command::new("sh") + .args(["-c", "vtysh -c 'show ipv6 route isis json'"]) + .output()? + .stdout, + )?; + let ospf_routes_string = String::from_utf8( Command::new("sh") .args(["-c", "vtysh -c 'show ip route ospf json'"]) @@ -873,6 +957,20 @@ pub mod pve_rs_sdn_fabrics { openfabric_routes.0.extend(openfabric_ipv6_routes.0); } + let mut isis_routes: proxmox_frr::de::Routes = + if isis_ipv4_routes_string.is_empty() { + proxmox_frr::de::Routes::default() + } else { + serde_json::from_str(&isis_ipv4_routes_string) + .with_context(|| "error parsing isis ipv4 routes")? + }; + if !isis_ipv6_routes_string.is_empty() { + let isis_ipv6_routes: proxmox_frr::de::Routes = + serde_json::from_str(&isis_ipv6_routes_string) + .with_context(|| "error parsing isis ipv6 routes")?; + isis_routes.0.extend(isis_ipv6_routes.0); + } + let ospf_routes: proxmox_frr::de::Routes = if ospf_routes_string.is_empty() { proxmox_frr::de::Routes::default() } else { @@ -883,6 +981,7 @@ pub mod pve_rs_sdn_fabrics { let route_status = status::RoutesParsed { openfabric: openfabric_routes, ospf: ospf_routes, + isis: isis_routes, }; status::get_status(config, route_status, proxmox_sys::nodename()) diff --git a/pve-rs/src/sdn/status.rs b/pve-rs/src/sdn/status.rs index e1e336297ac9..a11603a8af22 100644 --- a/pve-rs/src/sdn/status.rs +++ b/pve-rs/src/sdn/status.rs @@ -135,6 +135,8 @@ pub enum Protocol { Openfabric, /// OSPF Ospf, + /// IS-IS + Isis, } /// The status of a fabric. @@ -173,6 +175,8 @@ pub struct RoutesParsed { pub openfabric: de::Routes, /// All ospf routes in FRR pub ospf: de::Routes, + /// All isis routes in FRR + pub isis: de::Routes, } /// Config used to parse the fabric part of the running-config @@ -217,6 +221,11 @@ pub fn get_routes( .interfaces() .map(|i| i.name().as_str()) .collect(), + ConfigNode::Isis(n) => n + .properties() + .interfaces() + .map(|i| i.name().as_str()) + .collect(), }; let dummy_interface = format!("dummy_{}", fabric_id.as_str()); @@ -429,6 +438,7 @@ pub fn get_status( let (current_protocol, all_routes) = match &node { ConfigNode::Openfabric(_) => (Protocol::Openfabric, &routes.openfabric.0), ConfigNode::Ospf(_) => (Protocol::Ospf, &routes.ospf.0), + ConfigNode::Isis(_) => (Protocol::Isis, &routes.isis.0), }; // get interfaces @@ -443,6 +453,11 @@ pub fn get_status( .interfaces() .map(|i| i.name().as_str()) .collect(), + ConfigNode::Isis(n) => n + .properties() + .interfaces() + .map(|i| i.name().as_str()) + .collect(), }; // determine status by checking if any routes exist for our interfaces -- 2.47.3
