diff --git a/brocade/src/fast_iron.rs b/brocade/src/fast_iron.rs index c3eb374..6e256a8 100644 --- a/brocade/src/fast_iron.rs +++ b/brocade/src/fast_iron.rs @@ -216,7 +216,9 @@ impl BrocadeClient for FastIronClient { "configure terminal".into(), "snmp-server view ALL 1 included".into(), "snmp-server group public v3 priv read ALL".into(), - format!("snmp-server user {user_name} groupname public auth md5 {auth} priv des {des}"), + format!( + "snmp-server user {user_name} groupname public auth md5 auth-password {auth} priv des priv-password {des}" + ), "exit".into(), ]; self.shell diff --git a/brocade/src/network_operating_system.rs b/brocade/src/network_operating_system.rs index bfb45ed..1985aba 100644 --- a/brocade/src/network_operating_system.rs +++ b/brocade/src/network_operating_system.rs @@ -336,7 +336,9 @@ impl BrocadeClient for NetworkOperatingSystemClient { "configure terminal".into(), "snmp-server view ALL 1 included".into(), "snmp-server group public v3 priv read ALL".into(), - format!("snmp-server user {user_name} groupname public auth md5 {auth} priv des {des}"), + format!( + "snmp-server user {user_name} groupname public auth md5 auth-password {auth} priv des priv-password {des}" + ), "exit".into(), ]; self.shell diff --git a/examples/brocade_snmp_server/Cargo.toml b/examples/brocade_snmp_server/Cargo.toml new file mode 100644 index 0000000..0f476a8 --- /dev/null +++ b/examples/brocade_snmp_server/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "brocade-snmp-server" +edition = "2024" +version.workspace = true +readme.workspace = true +license.workspace = true + +[dependencies] +harmony = { path = "../../harmony" } +brocade = { path = "../../brocade" } +harmony_secret = { path = "../../harmony_secret" } +harmony_cli = { path = "../../harmony_cli" } +harmony_types = { path = "../../harmony_types" } +harmony_macros = { path = "../../harmony_macros" } +tokio = { workspace = true } +log = { workspace = true } +env_logger = { workspace = true } +url = { workspace = true } +base64.workspace = true +serde.workspace = true diff --git a/examples/brocade_snmp_server/src/main.rs b/examples/brocade_snmp_server/src/main.rs new file mode 100644 index 0000000..ff9b671 --- /dev/null +++ b/examples/brocade_snmp_server/src/main.rs @@ -0,0 +1,22 @@ +use std::net::{IpAddr, Ipv4Addr}; + +use harmony::{ + inventory::Inventory, modules::brocade::BrocadeEnableSnmpScore, topology::K8sAnywhereTopology, +}; + +#[tokio::main] +async fn main() { + let brocade_snmp_server = BrocadeEnableSnmpScore { + server_ips: vec![IpAddr::V4(Ipv4Addr::new(192, 168, 1, 111))], + dry_run: true, + }; + + harmony_cli::run( + Inventory::autoload(), + K8sAnywhereTopology::from_env(), + vec![Box::new(brocade_snmp_server)], + None, + ) + .await + .unwrap(); +} diff --git a/harmony/src/modules/brocade.rs b/harmony/src/modules/brocade.rs new file mode 100644 index 0000000..7264609 --- /dev/null +++ b/harmony/src/modules/brocade.rs @@ -0,0 +1,117 @@ +use std::net::{IpAddr, Ipv4Addr}; + +use async_trait::async_trait; +use brocade::BrocadeOptions; +use harmony_secret::{Secret, SecretManager}; +use harmony_types::id::Id; +use serde::{Deserialize, Serialize}; + +use crate::{ + data::Version, + interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, + inventory::Inventory, + score::Score, + topology::Topology, +}; + +#[derive(Debug, Clone, Serialize)] +pub struct BrocadeEnableSnmpScore { + pub server_ips: Vec, + pub dry_run: bool, +} + +impl Score for BrocadeEnableSnmpScore { + fn name(&self) -> String { + "BrocadeEnableSnmpScore".to_string() + } + + fn create_interpret(&self) -> Box> { + Box::new(BrocadeEnableSnmpInterpret { + score: self.clone(), + }) + } +} + +#[derive(Debug, Clone, Serialize)] +pub struct BrocadeEnableSnmpInterpret { + score: BrocadeEnableSnmpScore, +} + +#[derive(Secret, Clone, Debug, Serialize, Deserialize)] +struct BrocadeSwitchAuth { + username: String, + password: String, +} + +#[derive(Secret, Clone, Debug, Serialize, Deserialize)] +struct BrocadeSnmpAuth { + username: String, + auth_password: String, + des_password: String, +} + +#[async_trait] +impl Interpret for BrocadeEnableSnmpInterpret { + async fn execute( + &self, + _inventory: &Inventory, + _topology: &T, + ) -> Result { + let switch_addresses = &self.score.server_ips; + + let snmp_auth = SecretManager::get_or_prompt::() + .await + .unwrap(); + + let config = SecretManager::get_or_prompt::() + .await + .unwrap(); + + let brocade = brocade::init( + &switch_addresses, + 22, + &config.username, + &config.password, + Some(BrocadeOptions { + dry_run: self.score.dry_run, + ..Default::default() + }), + ) + .await + .expect("Brocade client failed to connect"); + + brocade + .enable_snmp( + &snmp_auth.username, + &snmp_auth.auth_password, + &snmp_auth.des_password, + ) + .await + .map_err(|e| InterpretError::new(e.to_string()))?; + + Ok(Outcome::success(format!( + "Activated snmp server for Brocade at {}", + switch_addresses + .iter() + .map(|s| s.to_string()) + .collect::>() + .join(", ") + ))) + } + + fn get_name(&self) -> InterpretName { + InterpretName::Custom("BrocadeEnableSnmpInterpret") + } + + fn get_version(&self) -> Version { + todo!() + } + + fn get_status(&self) -> InterpretStatus { + todo!() + } + + fn get_children(&self) -> Vec { + todo!() + } +} diff --git a/harmony/src/modules/mod.rs b/harmony/src/modules/mod.rs index 682e16b..a5a2ad1 100644 --- a/harmony/src/modules/mod.rs +++ b/harmony/src/modules/mod.rs @@ -1,4 +1,5 @@ pub mod application; +pub mod brocade; pub mod cert_manager; pub mod dhcp; pub mod dns;