diff --git a/src/rust/uisp_integration/src/strategies/full/mod.rs b/src/rust/uisp_integration/src/strategies/full/mod.rs index 6828086d..1dc9b661 100644 --- a/src/rust/uisp_integration/src/strategies/full/mod.rs +++ b/src/rust/uisp_integration/src/strategies/full/mod.rs @@ -138,7 +138,7 @@ pub async fn build_full_network( squash_squashed_sites(&mut sites, config.clone(), &root_site)?; // Build Path Weights - walk_tree_for_routing(&mut sites, &root_site, &routing_overrides)?; + walk_tree_for_routing(config.clone(), &mut sites, &root_site, &routing_overrides)?; // Print Sites if let Some(root_idx) = sites.iter().position(|s| s.name == root_site) { diff --git a/src/rust/uisp_integration/src/strategies/full/routes_override.rs b/src/rust/uisp_integration/src/strategies/full/routes_override.rs index 2cc7bb05..8f6a85d4 100644 --- a/src/rust/uisp_integration/src/strategies/full/routes_override.rs +++ b/src/rust/uisp_integration/src/strategies/full/routes_override.rs @@ -3,6 +3,7 @@ use csv::ReaderBuilder; use lqos_config::Config; use serde::{Deserialize, Serialize}; use std::path::Path; +use std::sync::Arc; use tracing::{error, info}; /// Represents a route override in the integrationUISProutes.csv file. @@ -82,3 +83,14 @@ pub fn get_route_overrides(config: &Config) -> Result, UispIn Ok(Vec::new()) } } + +pub fn write_routing_overrides_template(config: Arc, natural_routes: &[RouteOverride]) -> anyhow::Result<()> { + let file_path = Path::new(&config.lqos_directory).join("integrationUISProutes.template.csv"); + let mut writer = csv::Writer::from_path(file_path)?; + writer.write_record(&["From Site", "To Site", "Cost"])?; + for route in natural_routes { + writer.write_record(&[&route.from_site, &route.to_site, &route.cost.to_string()])?; + } + writer.flush()?; + Ok(()) +} diff --git a/src/rust/uisp_integration/src/strategies/full/tree_walk.rs b/src/rust/uisp_integration/src/strategies/full/tree_walk.rs index 931b5bac..c11309bd 100644 --- a/src/rust/uisp_integration/src/strategies/full/tree_walk.rs +++ b/src/rust/uisp_integration/src/strategies/full/tree_walk.rs @@ -1,6 +1,8 @@ use std::io::Write; +use std::sync::Arc; +use lqos_config::Config; use crate::errors::UispIntegrationError; -use crate::strategies::full::routes_override::RouteOverride; +use crate::strategies::full::routes_override::{write_routing_overrides_template, RouteOverride}; use crate::uisp_types::{UispSite, UispSiteType}; /// Walks the tree to determine the best route for each site @@ -12,6 +14,7 @@ use crate::uisp_types::{UispSite, UispSiteType}; /// * `root_site` - The name of the root site /// * `overrides` - The list of route overrides pub fn walk_tree_for_routing( + config: Arc, sites: &mut Vec, root_site: &str, overrides: &Vec, @@ -19,8 +22,9 @@ pub fn walk_tree_for_routing( if let Some(root_idx) = sites.iter().position(|s| s.name == root_site) { let mut visited = std::collections::HashSet::new(); let current_node = root_idx; + let mut natural_weights: Vec = Vec::new(); let mut dot_graph = "digraph G {\n graph [ ranksep=2.0 overlap=false ]".to_string(); - walk_node(current_node, 10, sites, &mut visited, overrides, &mut dot_graph); + walk_node(current_node, 10, sites, &mut visited, overrides, &mut dot_graph, &mut natural_weights); dot_graph.push_str("}\n"); { let graph_file = std::fs::File::create("graph.dot"); @@ -28,6 +32,11 @@ pub fn walk_tree_for_routing( let _ = file.write_all(dot_graph.as_bytes()); } } + if let Err(e) = write_routing_overrides_template(config, &natural_weights) { + tracing::error!("Unable to write routing overrides template: {:?}", e); + } else { + tracing::info!("Wrote routing overrides template"); + } } else { tracing::error!("Unable to build a path-weights graph because I can't find the root node"); return Err(UispIntegrationError::NoRootSite); @@ -52,6 +61,7 @@ fn walk_node( visited: &mut std::collections::HashSet, overrides: &Vec, dot_graph: &mut String, + natural_weights: &mut Vec, ) { if visited.contains(&idx) { return; @@ -61,9 +71,14 @@ fn walk_node( if sites[i].parent_indices.contains(&idx) { let from = sites[i].name.clone(); let to = sites[idx].name.clone(); - if sites[idx].site_type != UispSiteType::Client + if sites[idx].site_type != UispSiteType::Client && sites[i].site_type != UispSiteType::Client { dot_graph.push_str(&format!("\"{}\" [label=\"{}\"];\n", to, to)); + natural_weights.push(RouteOverride { + from_site: from.clone(), + to_site: to.clone(), + cost: weight, + }); } if let Some(route_override) = overrides .iter() @@ -74,7 +89,7 @@ fn walk_node( } else { sites[i].route_weights.push((idx, weight)); } - walk_node(i, weight + 10, sites, visited, overrides, dot_graph); + walk_node(i, weight + 10, sites, visited, overrides, dot_graph, natural_weights); } } }