Some checks failed
Run Check Script / check (pull_request) Failing after 11m29s
243 lines
7.5 KiB
Rust
243 lines
7.5 KiB
Rust
use std::io::{self, Write};
|
|
|
|
use brocade::{
|
|
BrocadeOptions, InterfaceConfig, InterfaceSpeed, InterfaceType, PortOperatingMode,
|
|
SwitchInterface, Vlan, VlanList, ssh,
|
|
};
|
|
use harmony_secret::{Secret, SecretManager};
|
|
use harmony_types::switch::PortLocation;
|
|
use schemars::JsonSchema;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Secret, Clone, Debug, JsonSchema, Serialize, Deserialize)]
|
|
struct BrocadeSwitchAuth {
|
|
username: String,
|
|
password: String,
|
|
}
|
|
|
|
fn wait_for_enter() {
|
|
println!("\n--- Press ENTER to continue ---");
|
|
io::stdout().flush().unwrap();
|
|
io::stdin().read_line(&mut String::new()).unwrap();
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
|
|
|
let ip0 = std::net::IpAddr::V4(std::net::Ipv4Addr::new(192, 168, 12, 147));
|
|
let ip1 = std::net::IpAddr::V4(std::net::Ipv4Addr::new(192, 168, 12, 109));
|
|
let switch_addresses = vec![ip0, ip1];
|
|
|
|
let config = SecretManager::get_or_prompt::<BrocadeSwitchAuth>()
|
|
.await
|
|
.unwrap();
|
|
|
|
let brocade = brocade::init(
|
|
&switch_addresses,
|
|
&config.username,
|
|
&config.password,
|
|
&BrocadeOptions {
|
|
dry_run: false,
|
|
ssh: ssh::SshOptions {
|
|
port: 22,
|
|
..Default::default()
|
|
},
|
|
..Default::default()
|
|
},
|
|
)
|
|
.await
|
|
.expect("Brocade client failed to connect");
|
|
|
|
println!("=== Connecting to Brocade switches ===");
|
|
let version = brocade.version().await.unwrap();
|
|
println!("Version: {version:?}");
|
|
let entries = brocade.get_stack_topology().await.unwrap();
|
|
println!("Stack topology: {entries:#?}");
|
|
|
|
println!("\n=== Creating VLANs 100, 200, 300 ===");
|
|
brocade
|
|
.create_vlan(&Vlan {
|
|
id: 100,
|
|
name: "vlan100".to_string(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
println!("Created VLAN 100 (vlan100)");
|
|
brocade
|
|
.create_vlan(&Vlan {
|
|
id: 200,
|
|
name: "vlan200".to_string(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
println!("Created VLAN 200 (vlan200)");
|
|
brocade
|
|
.create_vlan(&Vlan {
|
|
id: 300,
|
|
name: "vlan300".to_string(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
println!("Created VLAN 300 (vlan300)");
|
|
|
|
println!("\n=== Press ENTER to continue to port configuration tests ---");
|
|
wait_for_enter();
|
|
|
|
println!("\n=== TEST 1: Trunk port (all VLANs, speed 10Gbps) on TenGigabitEthernet 1/0/1 ===");
|
|
println!("Configuring port as trunk with all VLANs and speed 10Gbps...");
|
|
let configs = vec![InterfaceConfig {
|
|
interface: SwitchInterface::Ethernet(
|
|
InterfaceType::TenGigabitEthernet,
|
|
PortLocation(1, 0, 1),
|
|
),
|
|
mode: PortOperatingMode::Trunk,
|
|
access_vlan: None,
|
|
trunk_vlans: Some(VlanList::All),
|
|
speed: Some(InterfaceSpeed::Gbps10),
|
|
}];
|
|
brocade.configure_interfaces(&configs).await.unwrap();
|
|
println!("Querying interfaces...");
|
|
let interfaces = brocade.get_interfaces().await.unwrap();
|
|
for iface in &interfaces {
|
|
if iface.name.contains("1/0/1") {
|
|
println!(" {iface:?}");
|
|
}
|
|
}
|
|
wait_for_enter();
|
|
|
|
println!("\n=== TEST 2: Trunk port (specific VLANs) on TenGigabitEthernet 1/0/2 ===");
|
|
println!("Configuring port as trunk with VLANs 100, 200...");
|
|
let configs = vec![InterfaceConfig {
|
|
interface: SwitchInterface::Ethernet(
|
|
InterfaceType::TenGigabitEthernet,
|
|
PortLocation(1, 0, 2),
|
|
),
|
|
mode: PortOperatingMode::Trunk,
|
|
access_vlan: None,
|
|
trunk_vlans: Some(VlanList::Specific(vec![
|
|
Vlan {
|
|
id: 100,
|
|
name: "vlan100".to_string(),
|
|
},
|
|
Vlan {
|
|
id: 200,
|
|
name: "vlan200".to_string(),
|
|
},
|
|
])),
|
|
speed: None,
|
|
}];
|
|
brocade.configure_interfaces(&configs).await.unwrap();
|
|
println!("Querying interfaces...");
|
|
let interfaces = brocade.get_interfaces().await.unwrap();
|
|
for iface in &interfaces {
|
|
if iface.name.contains("1/0/2") {
|
|
println!(" {iface:?}");
|
|
}
|
|
}
|
|
wait_for_enter();
|
|
|
|
println!("\n=== TEST 3: Access port (default VLAN 1) on TenGigabitEthernet 1/0/3 ===");
|
|
println!("Configuring port as access (default VLAN 1)...");
|
|
let configs = vec![InterfaceConfig {
|
|
interface: SwitchInterface::Ethernet(
|
|
InterfaceType::TenGigabitEthernet,
|
|
PortLocation(1, 0, 3),
|
|
),
|
|
mode: PortOperatingMode::Access,
|
|
access_vlan: None,
|
|
trunk_vlans: None,
|
|
speed: None,
|
|
}];
|
|
brocade.configure_interfaces(&configs).await.unwrap();
|
|
println!("Querying interfaces...");
|
|
let interfaces = brocade.get_interfaces().await.unwrap();
|
|
for iface in &interfaces {
|
|
if iface.name.contains("1/0/3") {
|
|
println!(" {iface:?}");
|
|
}
|
|
}
|
|
wait_for_enter();
|
|
|
|
println!("\n=== TEST 4: Access port (custom VLAN 100) on TenGigabitEthernet 1/0/4 ===");
|
|
println!("Configuring port as access with VLAN 100...");
|
|
let configs = vec![InterfaceConfig {
|
|
interface: SwitchInterface::Ethernet(
|
|
InterfaceType::TenGigabitEthernet,
|
|
PortLocation(1, 0, 4),
|
|
),
|
|
mode: PortOperatingMode::Access,
|
|
access_vlan: Some(100),
|
|
trunk_vlans: None,
|
|
speed: None,
|
|
}];
|
|
brocade.configure_interfaces(&configs).await.unwrap();
|
|
println!("Querying interfaces...");
|
|
let interfaces = brocade.get_interfaces().await.unwrap();
|
|
for iface in &interfaces {
|
|
if iface.name.contains("1/0/4") {
|
|
println!(" {iface:?}");
|
|
}
|
|
}
|
|
wait_for_enter();
|
|
|
|
println!("\n=== TEST 5: Port-channel on TenGigabitEthernet 1/0/5 and 1/0/6 ===");
|
|
let channel_id = 1;
|
|
println!("Using channel ID: {channel_id}");
|
|
println!("Creating port-channel with ports 1/0/5 and 1/0/6...");
|
|
let ports = [PortLocation(1, 0, 5), PortLocation(1, 0, 6)];
|
|
brocade
|
|
.create_port_channel(channel_id, "HARMONY_LAG", &ports, None)
|
|
.await
|
|
.unwrap();
|
|
println!("Port-channel created.");
|
|
println!("Querying port-channel summary...");
|
|
let interfaces = brocade.get_interfaces().await.unwrap();
|
|
for iface in &interfaces {
|
|
if iface.name.contains("1/0/5") || iface.name.contains("1/0/6") {
|
|
println!(" {iface:?}");
|
|
}
|
|
}
|
|
wait_for_enter();
|
|
|
|
println!("\n=== TEARDOWN: Clearing port-channels and deleting VLANs ===");
|
|
println!("Clearing port-channel {channel_id}...");
|
|
brocade
|
|
.clear_port_channel(&channel_id.to_string())
|
|
.await
|
|
.unwrap();
|
|
println!("Resetting interfaces...");
|
|
for port in 1..=6 {
|
|
let interface = format!("TenGigabitEthernet 1/0/{port}");
|
|
println!(" Resetting {interface}...");
|
|
brocade.reset_interface(&interface).await.unwrap();
|
|
}
|
|
|
|
println!("Deleting VLAN 100...");
|
|
brocade
|
|
.delete_vlan(&Vlan {
|
|
id: 100,
|
|
name: "vlan100".to_string(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
println!("Deleting VLAN 200...");
|
|
brocade
|
|
.delete_vlan(&Vlan {
|
|
id: 200,
|
|
name: "vlan200".to_string(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
println!("Deleting VLAN 300...");
|
|
brocade
|
|
.delete_vlan(&Vlan {
|
|
id: 300,
|
|
name: "vlan300".to_string(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
|
|
println!("\n=== DONE ===");
|
|
}
|