WIP: configure-switch #159
@ -27,7 +27,8 @@ impl BrocadeClient {
|
|||||||
username: &str,
|
username: &str,
|
||||||
password: &str,
|
password: &str,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let ip = ip_addresses[0];
|
let ip = ip_addresses[0]; // FIXME: Find a better way to get master switch IP address
|
||||||
|
|
||||||
let config = russh::client::Config::default();
|
let config = russh::client::Config::default();
|
||||||
let mut client = russh::client::connect(Arc::new(config), (ip, 22), Client {}).await?;
|
let mut client = russh::client::connect(Arc::new(config), (ip, 22), Client {}).await?;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use cidr::Ipv4Cidr;
|
use cidr::Ipv4Cidr;
|
||||||
use harmony::{
|
use harmony::{
|
||||||
hardware::{FirewallGroup, HostCategory, Location, PhysicalHost, SwitchGroup},
|
hardware::{Location, SwitchGroup},
|
||||||
infra::opnsense::OPNSenseManagementInterface,
|
infra::opnsense::OPNSenseManagementInterface,
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
topology::{HAClusterTopology, LogicalHost, UnmanagedRouter},
|
topology::{HAClusterTopology, LogicalHost, UnmanagedRouter},
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use brocade::BrocadeClient;
|
|
||||||
use harmony_macros::ip;
|
use harmony_macros::ip;
|
||||||
use harmony_secret::Secret;
|
|
||||||
use harmony_secret::SecretManager;
|
use harmony_secret::SecretManager;
|
||||||
use harmony_types::net::MacAddress;
|
use harmony_types::net::MacAddress;
|
||||||
use harmony_types::net::Url;
|
use harmony_types::net::Url;
|
||||||
@ -9,12 +7,12 @@ use k8s_openapi::api::core::v1::Namespace;
|
|||||||
use kube::api::ObjectMeta;
|
use kube::api::ObjectMeta;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use crate::data::FileContent;
|
use crate::data::FileContent;
|
||||||
use crate::executors::ExecutorError;
|
use crate::executors::ExecutorError;
|
||||||
use crate::hardware::PhysicalHost;
|
use crate::hardware::PhysicalHost;
|
||||||
|
use crate::infra::brocade::BrocadeSwitchAuth;
|
||||||
|
use crate::infra::brocade::BrocadeSwitchClient;
|
||||||
use crate::modules::okd::crd::InstallPlanApproval;
|
use crate::modules::okd::crd::InstallPlanApproval;
|
||||||
use crate::modules::okd::crd::OperatorGroup;
|
use crate::modules::okd::crd::OperatorGroup;
|
||||||
use crate::modules::okd::crd::OperatorGroupSpec;
|
use crate::modules::okd::crd::OperatorGroupSpec;
|
||||||
@ -43,6 +41,7 @@ use super::PreparationError;
|
|||||||
use super::PreparationOutcome;
|
use super::PreparationOutcome;
|
||||||
use super::Router;
|
use super::Router;
|
||||||
use super::Switch;
|
use super::Switch;
|
||||||
|
use super::SwitchClient;
|
||||||
use super::SwitchError;
|
use super::SwitchError;
|
||||||
use super::TftpServer;
|
use super::TftpServer;
|
||||||
|
|
||||||
@ -527,54 +526,6 @@ impl Switch for HAClusterTopology {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
trait SwitchClient: Send + Sync {
|
|
||||||
async fn find_port(&self, mac_address: &MacAddress) -> Option<String>;
|
|
||||||
async fn configure_port_channel(&self, switch_ports: Vec<String>) -> Result<u8, SwitchError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BrocadeSwitchClient {
|
|
||||||
brocade: BrocadeClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BrocadeSwitchClient {
|
|
||||||
async fn init(
|
|
||||||
ip_addresses: &[IpAddress],
|
|
||||||
username: &str,
|
|
||||||
password: &str,
|
|
||||||
) -> Result<Self, brocade::Error> {
|
|
||||||
let brocade = BrocadeClient::init(ip_addresses, username, password).await?;
|
|
||||||
Ok(Self { brocade })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl SwitchClient for BrocadeSwitchClient {
|
|
||||||
async fn find_port(&self, mac_address: &MacAddress) -> Option<String> {
|
|
||||||
let Ok(table) = self.brocade.show_mac_address_table().await else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
table
|
|
||||||
.iter()
|
|
||||||
.find(|entry| entry.mac_address == *mac_address)
|
|
||||||
.map(|entry| entry.port_name.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn configure_port_channel(&self, switch_ports: Vec<String>) -> Result<u8, SwitchError> {
|
|
||||||
self.brocade
|
|
||||||
.configure_port_channel(&switch_ports)
|
|
||||||
.await
|
|
||||||
.map_err(|e| SwitchError::new(format!("Failed to configure port channel: {e}")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Secret, Serialize, Deserialize, Debug)]
|
|
||||||
struct BrocadeSwitchAuth {
|
|
||||||
username: String,
|
|
||||||
password: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DummyInfra;
|
pub struct DummyInfra;
|
||||||
|
|
||||||
|
|||||||
@ -216,6 +216,12 @@ impl std::fmt::Display for SwitchError {
|
|||||||
|
|
||||||
impl Error for SwitchError {}
|
impl Error for SwitchError {}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait SwitchClient: Send + Sync {
|
||||||
|
async fn find_port(&self, mac_address: &MacAddress) -> Option<String>;
|
||||||
|
async fn configure_port_channel(&self, switch_ports: Vec<String>) -> Result<u8, SwitchError>;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|||||||
49
harmony/src/infra/brocade.rs
Normal file
49
harmony/src/infra/brocade.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
use brocade::BrocadeClient;
|
||||||
|
use harmony_secret::Secret;
|
||||||
|
use harmony_types::net::{IpAddress, MacAddress};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::topology::{SwitchClient, SwitchError};
|
||||||
|
|
||||||
|
pub struct BrocadeSwitchClient {
|
||||||
|
brocade: BrocadeClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BrocadeSwitchClient {
|
||||||
|
pub async fn init(
|
||||||
|
ip_addresses: &[IpAddress],
|
||||||
|
username: &str,
|
||||||
|
password: &str,
|
||||||
|
) -> Result<Self, brocade::Error> {
|
||||||
|
let brocade = BrocadeClient::init(ip_addresses, username, password).await?;
|
||||||
|
Ok(Self { brocade })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl SwitchClient for BrocadeSwitchClient {
|
||||||
|
async fn find_port(&self, mac_address: &MacAddress) -> Option<String> {
|
||||||
|
let Ok(table) = self.brocade.show_mac_address_table().await else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
table
|
||||||
|
.iter()
|
||||||
|
.find(|entry| entry.mac_address == *mac_address)
|
||||||
|
.map(|entry| entry.port_name.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn configure_port_channel(&self, switch_ports: Vec<String>) -> Result<u8, SwitchError> {
|
||||||
|
self.brocade
|
||||||
|
.configure_port_channel(&switch_ports)
|
||||||
|
.await
|
||||||
|
.map_err(|e| SwitchError::new(format!("Failed to configure port channel: {e}")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Secret, Serialize, Deserialize, Debug)]
|
||||||
|
pub struct BrocadeSwitchAuth {
|
||||||
|
pub username: String,
|
||||||
|
pub password: String,
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
pub mod brocade;
|
||||||
pub mod executors;
|
pub mod executors;
|
||||||
pub mod hp_ilo;
|
pub mod hp_ilo;
|
||||||
pub mod intel_amt;
|
pub mod intel_amt;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user