Compare commits
	
		
			No commits in common. "c069207f124d9fcba9c24a5772b030dc508e1f25" and "05205f4ac1e24d240ad0c32242d3dd5f00628e96" have entirely different histories.
		
	
	
		
			c069207f12
			...
			05205f4ac1
		
	
		
							
								
								
									
										27
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1780,7 +1780,6 @@ dependencies = [ | ||||
| name = "example-nanodc" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "brocade", | ||||
|  "cidr", | ||||
|  "env_logger", | ||||
|  "harmony", | ||||
| @ -1789,7 +1788,6 @@ dependencies = [ | ||||
|  "harmony_tui", | ||||
|  "harmony_types", | ||||
|  "log", | ||||
|  "serde", | ||||
|  "tokio", | ||||
|  "url", | ||||
| ] | ||||
| @ -1808,7 +1806,6 @@ dependencies = [ | ||||
| name = "example-okd-install" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "brocade", | ||||
|  "cidr", | ||||
|  "env_logger", | ||||
|  "harmony", | ||||
| @ -1839,16 +1836,13 @@ dependencies = [ | ||||
| name = "example-opnsense" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "brocade", | ||||
|  "cidr", | ||||
|  "env_logger", | ||||
|  "harmony", | ||||
|  "harmony_macros", | ||||
|  "harmony_secret", | ||||
|  "harmony_tui", | ||||
|  "harmony_types", | ||||
|  "log", | ||||
|  "serde", | ||||
|  "tokio", | ||||
|  "url", | ||||
| ] | ||||
| @ -1857,7 +1851,6 @@ dependencies = [ | ||||
| name = "example-pxe" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "brocade", | ||||
|  "cidr", | ||||
|  "env_logger", | ||||
|  "harmony", | ||||
| @ -1872,15 +1865,6 @@ dependencies = [ | ||||
|  "url", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "example-remove-rook-osd" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "harmony", | ||||
|  "harmony_cli", | ||||
|  "tokio", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "example-rust" | ||||
| version = "0.1.0" | ||||
| @ -1934,6 +1918,8 @@ dependencies = [ | ||||
|  "env_logger", | ||||
|  "harmony", | ||||
|  "harmony_macros", | ||||
|  "harmony_secret", | ||||
|  "harmony_secret_derive", | ||||
|  "harmony_tui", | ||||
|  "harmony_types", | ||||
|  "log", | ||||
| @ -4627,6 +4613,15 @@ version = "0.8.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "remove_rook_osd" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "harmony", | ||||
|  "harmony_cli", | ||||
|  "tokio", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "reqwest" | ||||
| version = "0.11.27" | ||||
|  | ||||
| @ -10,7 +10,6 @@ use log::{debug, info}; | ||||
| use regex::Regex; | ||||
| use std::{collections::HashSet, str::FromStr}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct FastIronClient { | ||||
|     shell: BrocadeShell, | ||||
|     version: BrocadeInfo, | ||||
|  | ||||
| @ -162,7 +162,7 @@ pub async fn init( | ||||
| } | ||||
| 
 | ||||
| #[async_trait] | ||||
| pub trait BrocadeClient: std::fmt::Debug { | ||||
| pub trait BrocadeClient { | ||||
|     /// Retrieves the operating system and version details from the connected Brocade switch.
 | ||||
|     ///
 | ||||
|     /// This is typically the first call made after establishing a connection to determine
 | ||||
|  | ||||
| @ -10,7 +10,6 @@ use crate::{ | ||||
|     parse_brocade_mac_address, shell::BrocadeShell, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct NetworkOperatingSystemClient { | ||||
|     shell: BrocadeShell, | ||||
|     version: BrocadeInfo, | ||||
|  | ||||
| @ -13,7 +13,6 @@ use log::info; | ||||
| use russh::ChannelMsg; | ||||
| use tokio::time::timeout; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct BrocadeShell { | ||||
|     ip: IpAddr, | ||||
|     port: u16, | ||||
|  | ||||
| @ -17,5 +17,3 @@ harmony_secret = { path = "../../harmony_secret" } | ||||
| log = { workspace = true } | ||||
| env_logger = { workspace = true } | ||||
| url = { workspace = true } | ||||
| serde = { workspace = true } | ||||
| brocade = { path = "../../brocade" } | ||||
|  | ||||
| @ -3,13 +3,12 @@ use std::{ | ||||
|     sync::Arc, | ||||
| }; | ||||
| 
 | ||||
| use brocade::BrocadeOptions; | ||||
| use cidr::Ipv4Cidr; | ||||
| use harmony::{ | ||||
|     config::secret::SshKeyPair, | ||||
|     data::{FileContent, FilePath}, | ||||
|     hardware::{HostCategory, Location, PhysicalHost, SwitchGroup}, | ||||
|     infra::{brocade::BrocadeSwitchClient, opnsense::OPNSenseManagementInterface}, | ||||
|     infra::opnsense::OPNSenseManagementInterface, | ||||
|     inventory::Inventory, | ||||
|     modules::{ | ||||
|         http::StaticFilesHttpScore, | ||||
| @ -23,9 +22,8 @@ use harmony::{ | ||||
|     topology::{LogicalHost, UnmanagedRouter}, | ||||
| }; | ||||
| use harmony_macros::{ip, mac_address}; | ||||
| use harmony_secret::{Secret, SecretManager}; | ||||
| use harmony_secret::SecretManager; | ||||
| use harmony_types::net::Url; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
| @ -34,26 +32,6 @@ async fn main() { | ||||
|         name: String::from("fw0"), | ||||
|     }; | ||||
| 
 | ||||
|     let switch_auth = SecretManager::get_or_prompt::<BrocadeSwitchAuth>() | ||||
|         .await | ||||
|         .expect("Failed to get credentials"); | ||||
| 
 | ||||
|     let switches: Vec<IpAddr> = vec![ip!("192.168.33.101")]; | ||||
|     let brocade_options = Some(BrocadeOptions { | ||||
|         dry_run: *harmony::config::DRY_RUN, | ||||
|         ..Default::default() | ||||
|     }); | ||||
|     let switch_client = BrocadeSwitchClient::init( | ||||
|         &switches, | ||||
|         &switch_auth.username, | ||||
|         &switch_auth.password, | ||||
|         brocade_options, | ||||
|     ) | ||||
|     .await | ||||
|     .expect("Failed to connect to switch"); | ||||
| 
 | ||||
|     let switch_client = Arc::new(switch_client); | ||||
| 
 | ||||
|     let opnsense = Arc::new( | ||||
|         harmony::infra::opnsense::OPNSenseFirewall::new(firewall, None, "root", "opnsense").await, | ||||
|     ); | ||||
| @ -105,7 +83,7 @@ async fn main() { | ||||
|                 name: "wk2".to_string(), | ||||
|             }, | ||||
|         ], | ||||
|         switch_client: switch_client.clone(), | ||||
|         switch: vec![], | ||||
|     }; | ||||
| 
 | ||||
|     let inventory = Inventory { | ||||
| @ -188,9 +166,3 @@ async fn main() { | ||||
|     .await | ||||
|     .unwrap(); | ||||
| } | ||||
| 
 | ||||
| #[derive(Secret, Serialize, Deserialize, Debug)] | ||||
| pub struct BrocadeSwitchAuth { | ||||
|     pub username: String, | ||||
|     pub password: String, | ||||
| } | ||||
|  | ||||
| @ -19,4 +19,3 @@ log = { workspace = true } | ||||
| env_logger = { workspace = true } | ||||
| url = { workspace = true } | ||||
| serde.workspace = true | ||||
| brocade = { path = "../../brocade" } | ||||
|  | ||||
| @ -1,8 +1,7 @@ | ||||
| use brocade::BrocadeOptions; | ||||
| use cidr::Ipv4Cidr; | ||||
| use harmony::{ | ||||
|     hardware::{Location, SwitchGroup}, | ||||
|     infra::{brocade::BrocadeSwitchClient, opnsense::OPNSenseManagementInterface}, | ||||
|     infra::opnsense::OPNSenseManagementInterface, | ||||
|     inventory::Inventory, | ||||
|     topology::{HAClusterTopology, LogicalHost, UnmanagedRouter}, | ||||
| }; | ||||
| @ -23,26 +22,6 @@ pub async fn get_topology() -> HAClusterTopology { | ||||
|         name: String::from("opnsense-1"), | ||||
|     }; | ||||
| 
 | ||||
|     let switch_auth = SecretManager::get_or_prompt::<BrocadeSwitchAuth>() | ||||
|         .await | ||||
|         .expect("Failed to get credentials"); | ||||
| 
 | ||||
|     let switches: Vec<IpAddr> = vec![ip!("192.168.1.101")]; // TODO: Adjust me
 | ||||
|     let brocade_options = Some(BrocadeOptions { | ||||
|         dry_run: *harmony::config::DRY_RUN, | ||||
|         ..Default::default() | ||||
|     }); | ||||
|     let switch_client = BrocadeSwitchClient::init( | ||||
|         &switches, | ||||
|         &switch_auth.username, | ||||
|         &switch_auth.password, | ||||
|         brocade_options, | ||||
|     ) | ||||
|     .await | ||||
|     .expect("Failed to connect to switch"); | ||||
| 
 | ||||
|     let switch_client = Arc::new(switch_client); | ||||
| 
 | ||||
|     let config = SecretManager::get_or_prompt::<OPNSenseFirewallConfig>().await; | ||||
|     let config = config.unwrap(); | ||||
| 
 | ||||
| @ -79,7 +58,7 @@ pub async fn get_topology() -> HAClusterTopology { | ||||
|             name: "bootstrap".to_string(), | ||||
|         }, | ||||
|         workers: vec![], | ||||
|         switch_client: switch_client.clone(), | ||||
|         switch: vec![], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -96,9 +75,3 @@ pub fn get_inventory() -> Inventory { | ||||
|         control_plane_host: vec![], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Secret, Serialize, Deserialize, Debug)] | ||||
| pub struct BrocadeSwitchAuth { | ||||
|     pub username: String, | ||||
|     pub password: String, | ||||
| } | ||||
|  | ||||
| @ -19,4 +19,3 @@ log = { workspace = true } | ||||
| env_logger = { workspace = true } | ||||
| url = { workspace = true } | ||||
| serde.workspace = true | ||||
| brocade = { path = "../../brocade" } | ||||
|  | ||||
| @ -1,15 +1,13 @@ | ||||
| use brocade::BrocadeOptions; | ||||
| use cidr::Ipv4Cidr; | ||||
| use harmony::{ | ||||
|     config::secret::OPNSenseFirewallCredentials, | ||||
|     hardware::{Location, SwitchGroup}, | ||||
|     infra::{brocade::BrocadeSwitchClient, opnsense::OPNSenseManagementInterface}, | ||||
|     infra::opnsense::OPNSenseManagementInterface, | ||||
|     inventory::Inventory, | ||||
|     topology::{HAClusterTopology, LogicalHost, UnmanagedRouter}, | ||||
| }; | ||||
| use harmony_macros::{ip, ipv4}; | ||||
| use harmony_secret::{Secret, SecretManager}; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use harmony_secret::SecretManager; | ||||
| use std::{net::IpAddr, sync::Arc}; | ||||
| 
 | ||||
| pub async fn get_topology() -> HAClusterTopology { | ||||
| @ -18,26 +16,6 @@ pub async fn get_topology() -> HAClusterTopology { | ||||
|         name: String::from("opnsense-1"), | ||||
|     }; | ||||
| 
 | ||||
|     let switch_auth = SecretManager::get_or_prompt::<BrocadeSwitchAuth>() | ||||
|         .await | ||||
|         .expect("Failed to get credentials"); | ||||
| 
 | ||||
|     let switches: Vec<IpAddr> = vec![ip!("192.168.1.101")]; // TODO: Adjust me
 | ||||
|     let brocade_options = Some(BrocadeOptions { | ||||
|         dry_run: *harmony::config::DRY_RUN, | ||||
|         ..Default::default() | ||||
|     }); | ||||
|     let switch_client = BrocadeSwitchClient::init( | ||||
|         &switches, | ||||
|         &switch_auth.username, | ||||
|         &switch_auth.password, | ||||
|         brocade_options, | ||||
|     ) | ||||
|     .await | ||||
|     .expect("Failed to connect to switch"); | ||||
| 
 | ||||
|     let switch_client = Arc::new(switch_client); | ||||
| 
 | ||||
|     let config = SecretManager::get_or_prompt::<OPNSenseFirewallCredentials>().await; | ||||
|     let config = config.unwrap(); | ||||
| 
 | ||||
| @ -74,7 +52,7 @@ pub async fn get_topology() -> HAClusterTopology { | ||||
|             name: "cp0".to_string(), | ||||
|         }, | ||||
|         workers: vec![], | ||||
|         switch_client: switch_client.clone(), | ||||
|         switch: vec![], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -91,9 +69,3 @@ pub fn get_inventory() -> Inventory { | ||||
|         control_plane_host: vec![], | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Secret, Serialize, Deserialize, Debug)] | ||||
| pub struct BrocadeSwitchAuth { | ||||
|     pub username: String, | ||||
|     pub password: String, | ||||
| } | ||||
|  | ||||
| @ -16,6 +16,3 @@ harmony_macros = { path = "../../harmony_macros" } | ||||
| log = { workspace = true } | ||||
| env_logger = { workspace = true } | ||||
| url = { workspace = true } | ||||
| harmony_secret = { path = "../../harmony_secret" } | ||||
| brocade = { path = "../../brocade" } | ||||
| serde = { workspace = true } | ||||
|  | ||||
| @ -3,11 +3,10 @@ use std::{ | ||||
|     sync::Arc, | ||||
| }; | ||||
| 
 | ||||
| use brocade::BrocadeOptions; | ||||
| use cidr::Ipv4Cidr; | ||||
| use harmony::{ | ||||
|     hardware::{HostCategory, Location, PhysicalHost, SwitchGroup}, | ||||
|     infra::{brocade::BrocadeSwitchClient, opnsense::OPNSenseManagementInterface}, | ||||
|     infra::opnsense::OPNSenseManagementInterface, | ||||
|     inventory::Inventory, | ||||
|     modules::{ | ||||
|         dummy::{ErrorScore, PanicScore, SuccessScore}, | ||||
| @ -19,9 +18,7 @@ use harmony::{ | ||||
|     topology::{LogicalHost, UnmanagedRouter}, | ||||
| }; | ||||
| use harmony_macros::{ip, mac_address}; | ||||
| use harmony_secret::{Secret, SecretManager}; | ||||
| use harmony_types::net::Url; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
| @ -30,26 +27,6 @@ async fn main() { | ||||
|         name: String::from("opnsense-1"), | ||||
|     }; | ||||
| 
 | ||||
|     let switch_auth = SecretManager::get_or_prompt::<BrocadeSwitchAuth>() | ||||
|         .await | ||||
|         .expect("Failed to get credentials"); | ||||
| 
 | ||||
|     let switches: Vec<IpAddr> = vec![ip!("192.168.5.101")]; // TODO: Adjust me
 | ||||
|     let brocade_options = Some(BrocadeOptions { | ||||
|         dry_run: *harmony::config::DRY_RUN, | ||||
|         ..Default::default() | ||||
|     }); | ||||
|     let switch_client = BrocadeSwitchClient::init( | ||||
|         &switches, | ||||
|         &switch_auth.username, | ||||
|         &switch_auth.password, | ||||
|         brocade_options, | ||||
|     ) | ||||
|     .await | ||||
|     .expect("Failed to connect to switch"); | ||||
| 
 | ||||
|     let switch_client = Arc::new(switch_client); | ||||
| 
 | ||||
|     let opnsense = Arc::new( | ||||
|         harmony::infra::opnsense::OPNSenseFirewall::new(firewall, None, "root", "opnsense").await, | ||||
|     ); | ||||
| @ -77,7 +54,7 @@ async fn main() { | ||||
|             name: "cp0".to_string(), | ||||
|         }, | ||||
|         workers: vec![], | ||||
|         switch_client: switch_client.clone(), | ||||
|         switch: vec![], | ||||
|     }; | ||||
| 
 | ||||
|     let inventory = Inventory { | ||||
| @ -132,9 +109,3 @@ async fn main() { | ||||
|     .await | ||||
|     .unwrap(); | ||||
| } | ||||
| 
 | ||||
| #[derive(Secret, Serialize, Deserialize, Debug)] | ||||
| pub struct BrocadeSwitchAuth { | ||||
|     pub username: String, | ||||
|     pub password: String, | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| use async_trait::async_trait; | ||||
| use brocade::BrocadeOptions; | ||||
| use harmony_macros::ip; | ||||
| use harmony_secret::SecretManager; | ||||
| use harmony_types::{ | ||||
|     net::{MacAddress, Url}, | ||||
|     switch::PortLocation, | ||||
| @ -12,6 +14,8 @@ use log::info; | ||||
| use crate::data::FileContent; | ||||
| use crate::executors::ExecutorError; | ||||
| use crate::hardware::PhysicalHost; | ||||
| use crate::infra::brocade::BrocadeSwitchAuth; | ||||
| use crate::infra::brocade::BrocadeSwitchClient; | ||||
| use crate::modules::okd::crd::{ | ||||
|     InstallPlanApproval, OperatorGroup, OperatorGroupSpec, Subscription, SubscriptionSpec, | ||||
|     nmstate::{self, NMState, NodeNetworkConfigurationPolicy, NodeNetworkConfigurationPolicySpec}, | ||||
| @ -26,6 +30,7 @@ use super::{ | ||||
| }; | ||||
| 
 | ||||
| use std::collections::BTreeMap; | ||||
| use std::net::IpAddr; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| @ -38,10 +43,10 @@ pub struct HAClusterTopology { | ||||
|     pub tftp_server: Arc<dyn TftpServer>, | ||||
|     pub http_server: Arc<dyn HttpServer>, | ||||
|     pub dns_server: Arc<dyn DnsServer>, | ||||
|     pub switch_client: Arc<dyn SwitchClient>, | ||||
|     pub bootstrap_host: LogicalHost, | ||||
|     pub control_plane: Vec<LogicalHost>, | ||||
|     pub workers: Vec<LogicalHost>, | ||||
|     pub switch: Vec<LogicalHost>, | ||||
| } | ||||
| 
 | ||||
| #[async_trait] | ||||
| @ -275,15 +280,36 @@ impl HAClusterTopology { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async fn get_switch_client(&self) -> Result<Box<dyn SwitchClient>, SwitchError> { | ||||
|         let auth = SecretManager::get_or_prompt::<BrocadeSwitchAuth>() | ||||
|             .await | ||||
|             .map_err(|e| SwitchError::new(format!("Failed to get credentials: {e}")))?; | ||||
| 
 | ||||
|         // FIXME: We assume Brocade switches
 | ||||
|         let switches: Vec<IpAddr> = self.switch.iter().map(|s| s.ip).collect(); | ||||
|         let brocade_options = Some(BrocadeOptions { | ||||
|             dry_run: *crate::config::DRY_RUN, | ||||
|             ..Default::default() | ||||
|         }); | ||||
|         let client = | ||||
|             BrocadeSwitchClient::init(&switches, &auth.username, &auth.password, brocade_options) | ||||
|                 .await | ||||
|                 .map_err(|e| SwitchError::new(format!("Failed to connect to switch: {e}")))?; | ||||
| 
 | ||||
|         Ok(Box::new(client)) | ||||
|     } | ||||
| 
 | ||||
|     async fn configure_port_channel( | ||||
|         &self, | ||||
|         host: &PhysicalHost, | ||||
|         config: &HostNetworkConfig, | ||||
|     ) -> Result<(), SwitchError> { | ||||
|         debug!("Configuring port channel: {config:#?}"); | ||||
|         let client = self.get_switch_client().await?; | ||||
| 
 | ||||
|         let switch_ports = config.switch_ports.iter().map(|s| s.port.clone()).collect(); | ||||
| 
 | ||||
|         self.switch_client | ||||
|         client | ||||
|             .configure_port_channel(&format!("Harmony_{}", host.id), switch_ports) | ||||
|             .await | ||||
|             .map_err(|e| SwitchError::new(format!("Failed to configure switch: {e}")))?; | ||||
| @ -307,10 +333,10 @@ impl HAClusterTopology { | ||||
|             tftp_server: dummy_infra.clone(), | ||||
|             http_server: dummy_infra.clone(), | ||||
|             dns_server: dummy_infra.clone(), | ||||
|             switch_client: dummy_infra.clone(), | ||||
|             bootstrap_host: dummy_host, | ||||
|             control_plane: vec![], | ||||
|             workers: vec![], | ||||
|             switch: vec![], | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -468,7 +494,8 @@ impl HttpServer for HAClusterTopology { | ||||
| #[async_trait] | ||||
| impl Switch for HAClusterTopology { | ||||
|     async fn setup_switch(&self) -> Result<(), SwitchError> { | ||||
|         self.switch_client.setup().await?; | ||||
|         let client = self.get_switch_client().await?; | ||||
|         client.setup().await?; | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
| @ -476,7 +503,8 @@ impl Switch for HAClusterTopology { | ||||
|         &self, | ||||
|         mac_address: &MacAddress, | ||||
|     ) -> Result<Option<PortLocation>, SwitchError> { | ||||
|         let port = self.switch_client.find_port(mac_address).await?; | ||||
|         let client = self.get_switch_client().await?; | ||||
|         let port = client.find_port(mac_address).await?; | ||||
|         Ok(port) | ||||
|     } | ||||
| 
 | ||||
| @ -676,25 +704,3 @@ impl DnsServer for DummyInfra { | ||||
|         unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[async_trait] | ||||
| impl SwitchClient for DummyInfra { | ||||
|     async fn setup(&self) -> Result<(), SwitchError> { | ||||
|         unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA) | ||||
|     } | ||||
| 
 | ||||
|     async fn find_port( | ||||
|         &self, | ||||
|         _mac_address: &MacAddress, | ||||
|     ) -> Result<Option<PortLocation>, SwitchError> { | ||||
|         unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA) | ||||
|     } | ||||
| 
 | ||||
|     async fn configure_port_channel( | ||||
|         &self, | ||||
|         _channel_name: &str, | ||||
|         _switch_ports: Vec<PortLocation>, | ||||
|     ) -> Result<u8, SwitchError> { | ||||
|         unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,4 @@ | ||||
| use std::{ | ||||
|     error::Error, | ||||
|     fmt::{self, Debug}, | ||||
|     net::Ipv4Addr, | ||||
|     str::FromStr, | ||||
|     sync::Arc, | ||||
| }; | ||||
| use std::{error::Error, net::Ipv4Addr, str::FromStr, sync::Arc}; | ||||
| 
 | ||||
| use async_trait::async_trait; | ||||
| use derive_new::new; | ||||
| @ -25,8 +19,8 @@ pub struct DHCPStaticEntry { | ||||
|     pub ip: Ipv4Addr, | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for DHCPStaticEntry { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
| impl std::fmt::Display for DHCPStaticEntry { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         let mac = self | ||||
|             .mac | ||||
|             .iter() | ||||
| @ -48,8 +42,8 @@ pub trait Firewall: Send + Sync { | ||||
|     fn get_host(&self) -> LogicalHost; | ||||
| } | ||||
| 
 | ||||
| impl Debug for dyn Firewall { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
| impl std::fmt::Debug for dyn Firewall { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.write_fmt(format_args!("Firewall {}", self.get_ip())) | ||||
|     } | ||||
| } | ||||
| @ -71,7 +65,7 @@ pub struct PxeOptions { | ||||
| } | ||||
| 
 | ||||
| #[async_trait] | ||||
| pub trait DhcpServer: Send + Sync + Debug { | ||||
| pub trait DhcpServer: Send + Sync + std::fmt::Debug { | ||||
|     async fn add_static_mapping(&self, entry: &DHCPStaticEntry) -> Result<(), ExecutorError>; | ||||
|     async fn remove_static_mapping(&self, mac: &MacAddress) -> Result<(), ExecutorError>; | ||||
|     async fn list_static_mappings(&self) -> Vec<(MacAddress, IpAddress)>; | ||||
| @ -110,8 +104,8 @@ pub trait DnsServer: Send + Sync { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Debug for dyn DnsServer { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
| impl std::fmt::Debug for dyn DnsServer { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.write_fmt(format_args!("DnsServer {}", self.get_ip())) | ||||
|     } | ||||
| } | ||||
| @ -147,8 +141,8 @@ pub enum DnsRecordType { | ||||
|     TXT, | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for DnsRecordType { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
| impl std::fmt::Display for DnsRecordType { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             DnsRecordType::A => write!(f, "A"), | ||||
|             DnsRecordType::AAAA => write!(f, "AAAA"), | ||||
| @ -222,8 +216,8 @@ pub struct SwitchError { | ||||
|     msg: String, | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for SwitchError { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
| impl std::fmt::Display for SwitchError { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.write_str(&self.msg) | ||||
|     } | ||||
| } | ||||
| @ -231,7 +225,7 @@ impl fmt::Display for SwitchError { | ||||
| impl Error for SwitchError {} | ||||
| 
 | ||||
| #[async_trait] | ||||
| pub trait SwitchClient: Debug + Send + Sync { | ||||
| pub trait SwitchClient: Send + Sync { | ||||
|     /// Executes essential, idempotent, one-time initial configuration steps.
 | ||||
|     ///
 | ||||
|     /// This is an opiniated procedure that setups a switch to provide high availability
 | ||||
|  | ||||
| @ -1,14 +1,15 @@ | ||||
| use async_trait::async_trait; | ||||
| use brocade::{BrocadeClient, BrocadeOptions, InterSwitchLink, InterfaceStatus, PortOperatingMode}; | ||||
| use harmony_secret::Secret; | ||||
| use harmony_types::{ | ||||
|     net::{IpAddress, MacAddress}, | ||||
|     switch::{PortDeclaration, PortLocation}, | ||||
| }; | ||||
| use option_ext::OptionExt; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| use crate::topology::{SwitchClient, SwitchError}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct BrocadeSwitchClient { | ||||
|     brocade: Box<dyn BrocadeClient + Send + Sync>, | ||||
| } | ||||
| @ -113,6 +114,12 @@ impl SwitchClient for BrocadeSwitchClient { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Secret, Serialize, Deserialize, Debug)] | ||||
| pub struct BrocadeSwitchAuth { | ||||
|     pub username: String, | ||||
|     pub password: String, | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use std::sync::{Arc, Mutex}; | ||||
| @ -228,7 +235,7 @@ mod tests { | ||||
|         assert_that!(*configured_interfaces).is_empty(); | ||||
|     } | ||||
| 
 | ||||
|     #[derive(Debug, Clone)] | ||||
|     #[derive(Clone)] | ||||
|     struct FakeBrocadeClient { | ||||
|         stack_topology: Vec<InterSwitchLink>, | ||||
|         interfaces: Vec<InterfaceInfo>, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user