diff --git a/harmony/src/domain/topology/ha_cluster.rs b/harmony/src/domain/topology/ha_cluster.rs index b9a3b4e..26ac28d 100644 --- a/harmony/src/domain/topology/ha_cluster.rs +++ b/harmony/src/domain/topology/ha_cluster.rs @@ -28,7 +28,6 @@ use super::PreparationOutcome; use super::Router; use super::Switch; use super::SwitchError; -use super::SwitchNetworkConfig; use super::TftpServer; use super::Topology; @@ -270,7 +269,7 @@ impl HttpServer for HAClusterTopology { #[async_trait] impl Switch for HAClusterTopology { - async fn get_port_for_mac_address(&self, mac_address: &MacAddress) -> Option { + async fn get_port_for_mac_address(&self, _mac_address: &MacAddress) -> Option { todo!() } @@ -281,14 +280,6 @@ impl Switch for HAClusterTopology { ) -> Result<(), SwitchError> { todo!() } - - async fn configure_switch_network( - &self, - _host: &PhysicalHost, - _config: SwitchNetworkConfig, - ) -> Result<(), SwitchError> { - todo!() - } } #[derive(Debug)] diff --git a/harmony/src/domain/topology/network.rs b/harmony/src/domain/topology/network.rs index 4492667..9b42a22 100644 --- a/harmony/src/domain/topology/network.rs +++ b/harmony/src/domain/topology/network.rs @@ -182,40 +182,20 @@ pub trait Switch: Send + Sync { host: &PhysicalHost, config: HostNetworkConfig, ) -> Result<(), SwitchError>; - - async fn configure_switch_network( - &self, - host: &PhysicalHost, - config: SwitchNetworkConfig, - ) -> Result<(), SwitchError>; } #[derive(Clone, Debug, PartialEq)] pub struct HostNetworkConfig { - pub bond: Bond, + pub switch_ports: Vec, } #[derive(Clone, Debug, PartialEq)] -pub struct Bond { - pub interfaces: Vec, -} - -#[derive(Clone, Debug, PartialEq)] -pub struct SlaveInterface { +pub struct SwitchPort { pub mac_address: MacAddress, + pub port_name: String, // FIXME: Should we add speed as well? And other params } -#[derive(Clone, Debug, PartialEq)] -pub struct SwitchNetworkConfig { - pub port_channel: PortChannel, -} - -#[derive(Clone, Debug, PartialEq)] -pub struct PortChannel { - pub ports: Vec, -} - #[derive(Debug, Clone, new)] pub struct SwitchError { msg: String, diff --git a/harmony/src/modules/okd/host_network.rs b/harmony/src/modules/okd/host_network.rs index 514a9fd..7a68115 100644 --- a/harmony/src/modules/okd/host_network.rs +++ b/harmony/src/modules/okd/host_network.rs @@ -8,10 +8,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::{ - self, Bond, HostNetworkConfig, PortChannel, SlaveInterface, Switch, SwitchNetworkConfig, - Topology, - }, + topology::{HostNetworkConfig, Switch, SwitchPort, Topology}, }; #[derive(Debug, Clone, Serialize)] @@ -60,31 +57,19 @@ impl Interpret for HostNetworkConfigurationInterpret { topology: &T, ) -> Result { for host in &self.score.hosts { - let mut interfaces = vec![]; - let mut ports = vec![]; + let mut switch_ports = vec![]; for mac_address in host.get_mac_address() { - if let Some(port) = topology.get_port_for_mac_address(&mac_address).await { - interfaces.push(SlaveInterface { mac_address }); - ports.push(port); + if let Some(port_name) = topology.get_port_for_mac_address(&mac_address).await { + switch_ports.push(SwitchPort { + mac_address, + port_name, + }); } } let _ = topology - .configure_host_network( - host, - HostNetworkConfig { - bond: Bond { interfaces }, - }, - ) - .await; - let _ = topology - .configure_switch_network( - host, - SwitchNetworkConfig { - port_channel: PortChannel { ports }, - }, - ) + .configure_host_network(host, HostNetworkConfig { switch_ports }) .await; } @@ -93,9 +78,8 @@ impl Interpret for HostNetworkConfigurationInterpret { // let port = topology.get_port_for_mac_address(); // si pas de port -> mac address pas connectee // create port channel for all ports found // create bond for all valid addresses (port found) - // apply network to host first, then switch (to avoid losing hosts that are already connected) - // topology.configure_host_network(host, config) <--- will create bonds - // topology.configure_switch_network(host, config) <--- will create port channels + // apply network config + // topology.configure_host_network(host, config) <--- will create both bonds & port channels Ok(Outcome::success("".into())) } @@ -110,8 +94,7 @@ mod tests { use crate::{ hardware::HostCategory, topology::{ - Bond, HostNetworkConfig, PortChannel, PreparationError, PreparationOutcome, - SlaveInterface, SwitchError, SwitchNetworkConfig, + HostNetworkConfig, PreparationError, PreparationOutcome, SwitchError, SwitchPort, }, }; use std::{ @@ -125,11 +108,11 @@ mod tests { pub static ref HOST_ID: Id = Id::from_str("host-1").unwrap(); pub static ref ANOTHER_HOST_ID: Id = Id::from_str("host-2").unwrap(); pub static ref EXISTING_INTERFACE: MacAddress = - MacAddress::try_from("00:00:00:00:00:00".to_string()).unwrap(); + MacAddress::try_from("AA:BB:CC:DD:EE:F1".to_string()).unwrap(); pub static ref ANOTHER_EXISTING_INTERFACE: MacAddress = - MacAddress::try_from("42:42:42:42:42:42".to_string()).unwrap(); + MacAddress::try_from("AA:BB:CC:DD:EE:F2".to_string()).unwrap(); pub static ref UNKNOWN_INTERFACE: MacAddress = - MacAddress::try_from("99:99:99:99:99:99".to_string()).unwrap(); + MacAddress::try_from("11:22:33:44:55:61".to_string()).unwrap(); pub static ref PORT: String = "1/0/42".into(); pub static ref ANOTHER_PORT: String = "2/0/42".into(); } @@ -146,30 +129,10 @@ mod tests { assert_that!(*configured_host_networks).contains_exactly(vec![( HOST_ID.clone(), HostNetworkConfig { - bond: Bond { - interfaces: vec![SlaveInterface { - mac_address: *EXISTING_INTERFACE, - }], - }, - }, - )]); - } - - #[tokio::test] - async fn host_with_one_mac_address_should_create_port_channel_with_one_port() { - let host = given_host(&HOST_ID, vec![*EXISTING_INTERFACE]); - let score = given_score(vec![host]); - let topology = TopologyWithSwitch::new(); - - let _ = score.interpret(&Inventory::empty(), &topology).await; - - let configured_switch_networks = topology.configured_switch_networks.lock().unwrap(); - assert_that!(*configured_switch_networks).contains_exactly(vec![( - HOST_ID.clone(), - SwitchNetworkConfig { - port_channel: PortChannel { - ports: vec![PORT.clone()], - }, + switch_ports: vec![SwitchPort { + mac_address: *EXISTING_INTERFACE, + port_name: PORT.clone(), + }], }, )]); } @@ -188,16 +151,16 @@ mod tests { assert_that!(*configured_host_networks).contains_exactly(vec![( HOST_ID.clone(), HostNetworkConfig { - bond: Bond { - interfaces: vec![ - SlaveInterface { - mac_address: *EXISTING_INTERFACE, - }, - SlaveInterface { - mac_address: *ANOTHER_EXISTING_INTERFACE, - }, - ], - }, + switch_ports: vec![ + SwitchPort { + mac_address: *EXISTING_INTERFACE, + port_name: PORT.clone(), + }, + SwitchPort { + mac_address: *ANOTHER_EXISTING_INTERFACE, + port_name: ANOTHER_PORT.clone(), + }, + ], }, )]); } @@ -217,52 +180,19 @@ mod tests { ( HOST_ID.clone(), HostNetworkConfig { - bond: Bond { - interfaces: vec![SlaveInterface { - mac_address: *EXISTING_INTERFACE, - }], - }, + switch_ports: vec![SwitchPort { + mac_address: *EXISTING_INTERFACE, + port_name: PORT.clone(), + }], }, ), ( ANOTHER_HOST_ID.clone(), HostNetworkConfig { - bond: Bond { - interfaces: vec![SlaveInterface { - mac_address: *ANOTHER_EXISTING_INTERFACE, - }], - }, - }, - ), - ]); - } - - #[tokio::test] - async fn multiple_hosts_should_create_one_port_channel_per_host() { - let score = given_score(vec![ - given_host(&HOST_ID, vec![*EXISTING_INTERFACE]), - given_host(&ANOTHER_HOST_ID, vec![*ANOTHER_EXISTING_INTERFACE]), - ]); - let topology = TopologyWithSwitch::new(); - - let _ = score.interpret(&Inventory::empty(), &topology).await; - - let configured_switch_networks = topology.configured_switch_networks.lock().unwrap(); - assert_that!(*configured_switch_networks).contains_exactly(vec![ - ( - HOST_ID.clone(), - SwitchNetworkConfig { - port_channel: PortChannel { - ports: vec![PORT.clone()], - }, - }, - ), - ( - ANOTHER_HOST_ID.clone(), - SwitchNetworkConfig { - port_channel: PortChannel { - ports: vec![ANOTHER_PORT.clone()], - }, + switch_ports: vec![SwitchPort { + mac_address: *ANOTHER_EXISTING_INTERFACE, + port_name: ANOTHER_PORT.clone(), + }], }, ), ]); @@ -280,14 +210,7 @@ mod tests { assert_that!(*configured_host_networks).contains_exactly(vec![( HOST_ID.clone(), HostNetworkConfig { - bond: Bond { interfaces: vec![] }, - }, - )]); - let configured_switch_networks = topology.configured_switch_networks.lock().unwrap(); - assert_that!(*configured_switch_networks).contains_exactly(vec![( - HOST_ID.clone(), - SwitchNetworkConfig { - port_channel: PortChannel { ports: vec![] }, + switch_ports: vec![], }, )]); } @@ -325,25 +248,22 @@ mod tests { } struct TopologyWithSwitch { - available_ports: Vec, + available_ports: Arc>>, configured_host_networks: Arc>>, - configured_switch_networks: Arc>>, } impl TopologyWithSwitch { fn new() -> Self { Self { - available_ports: vec![PORT.clone(), ANOTHER_PORT.clone()], + available_ports: Arc::new(Mutex::new(vec![PORT.clone(), ANOTHER_PORT.clone()])), configured_host_networks: Arc::new(Mutex::new(vec![])), - configured_switch_networks: Arc::new(Mutex::new(vec![])), } } fn new_port_not_found() -> Self { Self { - available_ports: vec![], + available_ports: Arc::new(Mutex::new(vec![])), configured_host_networks: Arc::new(Mutex::new(vec![])), - configured_switch_networks: Arc::new(Mutex::new(vec![])), } } } @@ -362,16 +282,11 @@ mod tests { #[async_trait] impl Switch for TopologyWithSwitch { async fn get_port_for_mac_address(&self, _mac_address: &MacAddress) -> Option { - if self.available_ports.is_empty() { + let mut ports = self.available_ports.lock().unwrap(); + if ports.is_empty() { return None; } - - Some( - self.available_ports - .get(self.configured_host_networks.lock().unwrap().len() % 2) - .unwrap() - .clone(), - ) + Some(ports.remove(0)) } async fn configure_host_network( @@ -384,16 +299,5 @@ mod tests { Ok(()) } - - async fn configure_switch_network( - &self, - host: &PhysicalHost, - config: SwitchNetworkConfig, - ) -> Result<(), SwitchError> { - let mut configured_switch_networks = self.configured_switch_networks.lock().unwrap(); - configured_switch_networks.push((host.id.clone(), config.clone())); - - Ok(()) - } } }