From fda007f014b575b20fb4772004f156337128709a Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Wed, 26 Mar 2025 23:10:51 -0400 Subject: [PATCH] feat(topology): generalize Score and Interpret implementations with topology traits Refactor various `Score` and `Interpret` implementations to utilize generic `Topology` traits, removing hardcoded dependencies on `HAClusterTopology`. This enhancement allows for more flexible and extensible code, accommodating different types of network topologies. --- harmony/src/domain/interpret/mod.rs | 11 +++--- harmony/src/domain/maestro/mod.rs | 23 +++++++------ harmony/src/domain/score.rs | 7 ++-- harmony/src/domain/topology/ha_cluster.rs | 16 +++++++-- harmony/src/domain/topology/mod.rs | 6 ++++ harmony/src/domain/topology/network.rs | 17 +++++----- harmony/src/modules/dhcp.rs | 29 ++++++---------- harmony/src/modules/dns.rs | 34 +++++++------------ harmony/src/modules/dummy.rs | 34 ++++++------------- harmony/src/modules/http.rs | 15 +++----- harmony/src/modules/k8s/deployment.rs | 10 ++---- harmony/src/modules/k8s/resource.rs | 16 ++++----- harmony/src/modules/lamp.rs | 16 ++++----- harmony/src/modules/load_balancer.rs | 31 ++++++----------- harmony/src/modules/okd/bootstrap_dhcp.rs | 10 ++---- .../modules/okd/bootstrap_load_balancer.rs | 11 ++---- harmony/src/modules/okd/dhcp.rs | 10 ++---- harmony/src/modules/okd/dns.rs | 10 ++---- harmony/src/modules/okd/load_balancer.rs | 11 ++---- harmony/src/modules/opnsense/shell.rs | 14 +++----- harmony/src/modules/opnsense/upgrade.rs | 9 ++--- harmony/src/modules/tftp.rs | 25 ++++++-------- 22 files changed, 148 insertions(+), 217 deletions(-) diff --git a/harmony/src/domain/interpret/mod.rs b/harmony/src/domain/interpret/mod.rs index 731d663..0268ffd 100644 --- a/harmony/src/domain/interpret/mod.rs +++ b/harmony/src/domain/interpret/mod.rs @@ -7,7 +7,7 @@ use super::{ data::{Id, Version}, executors::ExecutorError, inventory::Inventory, - topology::HAClusterTopology, + topology::Topology, }; pub enum InterpretName { @@ -37,12 +37,9 @@ impl std::fmt::Display for InterpretName { } #[async_trait] -pub trait Interpret: std::fmt::Debug + Send { - async fn execute( - &self, - inventory: &Inventory, - topology: &HAClusterTopology, - ) -> Result; +pub trait Interpret: std::fmt::Debug + Send { + async fn execute(&self, inventory: &Inventory, topology: &T) + -> Result; fn get_name(&self) -> InterpretName; fn get_version(&self) -> Version; fn get_status(&self) -> InterpretStatus; diff --git a/harmony/src/domain/maestro/mod.rs b/harmony/src/domain/maestro/mod.rs index 9f92ec5..ea4ff26 100644 --- a/harmony/src/domain/maestro/mod.rs +++ b/harmony/src/domain/maestro/mod.rs @@ -6,19 +6,19 @@ use super::{ interpret::{InterpretError, Outcome}, inventory::Inventory, score::Score, - topology::HAClusterTopology, + topology::Topology, }; -type ScoreVec = Vec>; +type ScoreVec = Vec>>; -pub struct Maestro { +pub struct Maestro { inventory: Inventory, - topology: HAClusterTopology, - scores: Arc>, + topology: T, + scores: Arc>>, } -impl Maestro { - pub fn new(inventory: Inventory, topology: HAClusterTopology) -> Self { +impl Maestro { + pub fn new(inventory: Inventory, topology: T) -> Self { Self { inventory, topology, @@ -51,12 +51,15 @@ impl Maestro { info!("Starting Maestro"); } - pub fn register_all(&mut self, mut scores: ScoreVec) { + pub fn register_all(&mut self, mut scores: ScoreVec) { let mut score_mut = self.scores.write().expect("Should acquire lock"); score_mut.append(&mut scores); } - pub async fn interpret(&self, score: Box) -> Result { + pub async fn interpret(&self, score: S) -> Result + where + S: Score, + { info!("Running score {score:?}"); let interpret = score.create_interpret(); info!("Launching interpret {interpret:?}"); @@ -65,7 +68,7 @@ impl Maestro { result } - pub fn scores(&self) -> Arc> { + pub fn scores(&self) -> Arc>> { self.scores.clone() } } diff --git a/harmony/src/domain/score.rs b/harmony/src/domain/score.rs index 7b2c790..672c1e5 100644 --- a/harmony/src/domain/score.rs +++ b/harmony/src/domain/score.rs @@ -1,7 +1,6 @@ -use super::interpret::Interpret; +use super::{interpret::Interpret, topology::Topology}; -pub trait Score: std::fmt::Debug + Send + Sync { - fn create_interpret(&self) -> Box; +pub trait Score: std::fmt::Debug + Send + Sync { + fn create_interpret(&self) -> Box>; fn name(&self) -> String; - fn clone_box(&self) -> Box; } diff --git a/harmony/src/domain/topology/ha_cluster.rs b/harmony/src/domain/topology/ha_cluster.rs index ba7c063..0750b71 100644 --- a/harmony/src/domain/topology/ha_cluster.rs +++ b/harmony/src/domain/topology/ha_cluster.rs @@ -15,9 +15,11 @@ use super::IpAddress; use super::LoadBalancer; use super::LoadBalancerService; use super::LogicalHost; +use super::OcK8sclient; use super::Router; use super::TftpServer; +use super::Topology; use super::Url; use super::openshift::OpenshiftClient; use std::sync::Arc; @@ -38,11 +40,20 @@ pub struct HAClusterTopology { pub switch: Vec, } -impl HAClusterTopology { - pub async fn oc_client(&self) -> Result, kube::Error> { +impl Topology for HAClusterTopology { + fn name(&self) -> &str { + todo!() + } +} + +#[async_trait] +impl OcK8sclient for HAClusterTopology { + async fn oc_client(&self) -> Result, kube::Error> { Ok(Arc::new(OpenshiftClient::try_default().await?)) } +} +impl HAClusterTopology { pub fn autoload() -> Self { let dummy_infra = Arc::new(DummyInfra {}); let dummy_host = LogicalHost { @@ -67,6 +78,7 @@ impl HAClusterTopology { } } +#[derive(Debug)] struct DummyInfra; const UNIMPLEMENTED_DUMMY_INFRA: &str = "This is a dummy infrastructure, no operation is supported"; diff --git a/harmony/src/domain/topology/mod.rs b/harmony/src/domain/topology/mod.rs index 9d5663c..e1c7f7c 100644 --- a/harmony/src/domain/topology/mod.rs +++ b/harmony/src/domain/topology/mod.rs @@ -16,6 +16,12 @@ pub use tftp::*; use std::net::IpAddr; +pub trait Topology { + fn name(&self) -> &str; +} + +pub trait Capability {} + pub type IpAddress = IpAddr; #[derive(Debug, Clone)] diff --git a/harmony/src/domain/topology/network.rs b/harmony/src/domain/topology/network.rs index f45c87d..523db2f 100644 --- a/harmony/src/domain/topology/network.rs +++ b/harmony/src/domain/topology/network.rs @@ -1,11 +1,11 @@ -use std::{net::Ipv4Addr, str::FromStr}; +use std::{net::Ipv4Addr, str::FromStr, sync::Arc}; use async_trait::async_trait; use harmony_types::net::MacAddress; use crate::executors::ExecutorError; -use super::{IpAddress, LogicalHost}; +use super::{openshift::OpenshiftClient, IpAddress, LogicalHost}; #[derive(Debug)] pub struct DHCPStaticEntry { @@ -40,9 +40,14 @@ impl std::fmt::Debug for dyn Firewall { pub struct NetworkDomain { pub name: String, } +#[async_trait] +pub trait OcK8sclient: Send + Sync + std::fmt::Debug { + async fn oc_client(&self) -> Result, kube::Error>; +} + #[async_trait] -pub trait DhcpServer: Send + Sync { +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)>; @@ -53,12 +58,6 @@ pub trait DhcpServer: Send + Sync { async fn commit_config(&self) -> Result<(), ExecutorError>; } -impl std::fmt::Debug for dyn DhcpServer { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!("DhcpServer {}", self.get_ip())) - } -} - #[async_trait] pub trait DnsServer: Send + Sync { async fn register_dhcp_leases(&self, register: bool) -> Result<(), ExecutorError>; diff --git a/harmony/src/modules/dhcp.rs b/harmony/src/modules/dhcp.rs index 604d624..bd332c1 100644 --- a/harmony/src/modules/dhcp.rs +++ b/harmony/src/modules/dhcp.rs @@ -8,7 +8,7 @@ use crate::{ domain::{data::Version, interpret::InterpretStatus}, interpret::{Interpret, InterpretError, InterpretName, Outcome}, inventory::Inventory, - topology::{DHCPStaticEntry, HAClusterTopology, HostBinding, IpAddress}, + topology::{DHCPStaticEntry, DhcpServer, HAClusterTopology, HostBinding, IpAddress, Topology}, }; use crate::domain::score::Score; @@ -20,18 +20,14 @@ pub struct DhcpScore { pub boot_filename: Option, } -impl Score for DhcpScore { - fn create_interpret(&self) -> Box { +impl Score for DhcpScore { + fn create_interpret(&self) -> Box> { Box::new(DhcpInterpret::new(self.clone())) } fn name(&self) -> String { "DhcpScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } // https://docs.opnsense.org/manual/dhcp.html#advanced-settings @@ -52,10 +48,10 @@ impl DhcpInterpret { status: InterpretStatus::QUEUED, } } - async fn add_static_entries( + async fn add_static_entries( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + dhcp_server: &D, ) -> Result { let dhcp_entries: Vec = self .score @@ -78,7 +74,6 @@ impl DhcpInterpret { .collect(); info!("DHCPStaticEntry : {:?}", dhcp_entries); - let dhcp_server = Arc::new(topology.dhcp_server.clone()); info!("DHCP server : {:?}", dhcp_server); let number_new_entries = dhcp_entries.len(); @@ -96,14 +91,13 @@ impl DhcpInterpret { )) } - async fn set_pxe_options( + async fn set_pxe_options( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + dhcp_server: &D, ) -> Result { let next_server_outcome = match self.score.next_server { Some(next_server) => { - let dhcp_server = Arc::new(topology.dhcp_server.clone()); dhcp_server.set_next_server(next_server).await?; Outcome::new( InterpretStatus::SUCCESS, @@ -115,7 +109,6 @@ impl DhcpInterpret { let boot_filename_outcome = match &self.score.boot_filename { Some(boot_filename) => { - let dhcp_server = Arc::new(topology.dhcp_server.clone()); dhcp_server.set_boot_filename(&boot_filename).await?; Outcome::new( InterpretStatus::SUCCESS, @@ -142,7 +135,7 @@ impl DhcpInterpret { } #[async_trait] -impl Interpret for DhcpInterpret { +impl Interpret for DhcpInterpret { fn get_name(&self) -> InterpretName { InterpretName::OPNSenseDHCP } @@ -162,15 +155,15 @@ impl Interpret for DhcpInterpret { async fn execute( &self, inventory: &Inventory, - topology: &HAClusterTopology, + topology: &T, ) -> Result { - info!("Executing {} on inventory {inventory:?}", self.get_name()); + info!("Executing DhcpInterpret on inventory {inventory:?}"); self.set_pxe_options(inventory, topology).await?; self.add_static_entries(inventory, topology).await?; - topology.dhcp_server.commit_config().await?; + topology.commit_config().await?; Ok(Outcome::new( InterpretStatus::SUCCESS, diff --git a/harmony/src/modules/dns.rs b/harmony/src/modules/dns.rs index 79c8870..1002a35 100644 --- a/harmony/src/modules/dns.rs +++ b/harmony/src/modules/dns.rs @@ -7,7 +7,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::{DnsRecord, HAClusterTopology}, + topology::{DnsRecord, DnsServer, HAClusterTopology, Topology}, }; #[derive(Debug, new, Clone)] @@ -16,18 +16,14 @@ pub struct DnsScore { register_dhcp_leases: Option, } -impl Score for DnsScore { - fn create_interpret(&self) -> Box { +impl Score for DnsScore { + fn create_interpret(&self) -> Box> { Box::new(DnsInterpret::new(self.clone())) } fn name(&self) -> String { "DnsScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } // https://docs.opnsense.org/manual/dhcp.html#advanced-settings @@ -48,12 +44,11 @@ impl DnsInterpret { status: InterpretStatus::QUEUED, } } - async fn serve_dhcp_entries( + async fn serve_dhcp_entries( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + dns: &T, ) -> Result { - let dns = topology.dns_server.clone(); if let Some(register) = self.score.register_dhcp_leases { dns.register_dhcp_leases(register).await?; } @@ -64,15 +59,12 @@ impl DnsInterpret { )) } - async fn ensure_hosts_registered( + async fn ensure_hosts_registered( &self, - topology: &HAClusterTopology, + dns_server: &D, ) -> Result { let entries = &self.score.dns_entries; - topology - .dns_server - .ensure_hosts_registered(entries.clone()) - .await?; + dns_server.ensure_hosts_registered(entries.clone()).await?; Ok(Outcome::new( InterpretStatus::SUCCESS, @@ -85,7 +77,7 @@ impl DnsInterpret { } #[async_trait] -impl Interpret for DnsInterpret { +impl Interpret for DnsInterpret { fn get_name(&self) -> InterpretName { InterpretName::OPNSenseDns } @@ -105,14 +97,14 @@ impl Interpret for DnsInterpret { async fn execute( &self, inventory: &Inventory, - topology: &HAClusterTopology, + topology: &T, ) -> Result { - info!("Executing {} on inventory {inventory:?}", self.get_name()); + info!("Executing {} on inventory {inventory:?}", >::get_name(self)); self.serve_dhcp_entries(inventory, topology).await?; - self.ensure_hosts_registered(&topology).await?; + self.ensure_hosts_registered(topology).await?; - topology.dns_server.commit_config().await?; + topology.commit_config().await?; Ok(Outcome::new( InterpretStatus::SUCCESS, diff --git a/harmony/src/modules/dummy.rs b/harmony/src/modules/dummy.rs index 0d2c327..99e2f12 100644 --- a/harmony/src/modules/dummy.rs +++ b/harmony/src/modules/dummy.rs @@ -5,7 +5,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::HAClusterTopology, + topology::{HAClusterTopology, Topology}, }; /// Score that always errors. This is only useful for development/testing purposes. It does nothing @@ -13,8 +13,8 @@ use crate::{ #[derive(Debug, Clone)] pub struct ErrorScore; -impl Score for ErrorScore { - fn create_interpret(&self) -> Box { +impl Score for ErrorScore { + fn create_interpret(&self) -> Box> { Box::new(DummyInterpret { result: Err(InterpretError::new("Error Score default error".to_string())), status: InterpretStatus::QUEUED, @@ -24,10 +24,6 @@ impl Score for ErrorScore { fn name(&self) -> String { "ErrorScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } /// Score that always succeeds. This is only useful for development/testing purposes. It does nothing @@ -35,8 +31,8 @@ impl Score for ErrorScore { #[derive(Debug, Clone)] pub struct SuccessScore; -impl Score for SuccessScore { - fn create_interpret(&self) -> Box { +impl Score for SuccessScore { + fn create_interpret(&self) -> Box> { Box::new(DummyInterpret { result: Ok(Outcome::success("SuccessScore default success".to_string())), status: InterpretStatus::QUEUED, @@ -46,10 +42,6 @@ impl Score for SuccessScore { fn name(&self) -> String { "SuccessScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } /// An interpret that only returns the result it is given when built. It does nothing else. Only @@ -61,7 +53,7 @@ struct DummyInterpret { } #[async_trait] -impl Interpret for DummyInterpret { +impl Interpret for DummyInterpret { fn get_name(&self) -> InterpretName { InterpretName::Dummy } @@ -81,7 +73,7 @@ impl Interpret for DummyInterpret { async fn execute( &self, _inventory: &Inventory, - _topology: &HAClusterTopology, + _topology: &T, ) -> Result { self.result.clone() } @@ -92,18 +84,14 @@ impl Interpret for DummyInterpret { #[derive(Debug, Clone)] pub struct PanicScore; -impl Score for PanicScore { - fn create_interpret(&self) -> Box { +impl Score for PanicScore { + fn create_interpret(&self) -> Box> { Box::new(PanicInterpret {}) } fn name(&self) -> String { "PanicScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } /// An interpret that always panics when executed. Useful for development/testing purposes. @@ -111,7 +99,7 @@ impl Score for PanicScore { struct PanicInterpret; #[async_trait] -impl Interpret for PanicInterpret { +impl Interpret for PanicInterpret { fn get_name(&self) -> InterpretName { InterpretName::Panic } @@ -131,7 +119,7 @@ impl Interpret for PanicInterpret { async fn execute( &self, _inventory: &Inventory, - _topology: &HAClusterTopology, + _topology: &T, ) -> Result { panic!("Panic interpret always panics when executed") } diff --git a/harmony/src/modules/http.rs b/harmony/src/modules/http.rs index 51eed3b..1d6df51 100644 --- a/harmony/src/modules/http.rs +++ b/harmony/src/modules/http.rs @@ -6,7 +6,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::{HAClusterTopology, Url}, + topology::{HAClusterTopology, HttpServer, Topology, Url}, }; #[derive(Debug, new, Clone)] @@ -14,18 +14,14 @@ pub struct HttpScore { files_to_serve: Url, } -impl Score for HttpScore { - fn create_interpret(&self) -> Box { +impl Score for HttpScore { + fn create_interpret(&self) -> Box> { Box::new(HttpInterpret::new(self.clone())) } fn name(&self) -> String { "HttpScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } #[derive(Debug, new, Clone)] @@ -34,13 +30,12 @@ pub struct HttpInterpret { } #[async_trait] -impl Interpret for HttpInterpret { +impl Interpret for HttpInterpret { async fn execute( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + http_server: &T, ) -> Result { - let http_server = &topology.http_server; http_server.ensure_initialized().await?; // http_server.set_ip(topology.router.get_gateway()).await?; http_server.serve_files(&self.score.files_to_serve).await?; diff --git a/harmony/src/modules/k8s/deployment.rs b/harmony/src/modules/k8s/deployment.rs index de93e3a..4528ed6 100644 --- a/harmony/src/modules/k8s/deployment.rs +++ b/harmony/src/modules/k8s/deployment.rs @@ -1,7 +1,7 @@ use k8s_openapi::api::apps::v1::Deployment; use serde_json::json; -use crate::{interpret::Interpret, score::Score}; +use crate::{interpret::Interpret, score::Score, topology::{OcK8sclient, Topology}}; use super::resource::{K8sResourceInterpret, K8sResourceScore}; @@ -11,8 +11,8 @@ pub struct K8sDeploymentScore { pub image: String, } -impl Score for K8sDeploymentScore { - fn create_interpret(&self) -> Box { +impl Score for K8sDeploymentScore { + fn create_interpret(&self) -> Box> { let deployment: Deployment = serde_json::from_value(json!( { "metadata": { @@ -51,8 +51,4 @@ impl Score for K8sDeploymentScore { fn name(&self) -> String { "K8sDeploymentScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/k8s/resource.rs b/harmony/src/modules/k8s/resource.rs index cf45be8..878da22 100644 --- a/harmony/src/modules/k8s/resource.rs +++ b/harmony/src/modules/k8s/resource.rs @@ -8,7 +8,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::HAClusterTopology, + topology::{HAClusterTopology, OcK8sclient, Topology}, }; #[derive(Debug, Clone)] @@ -34,21 +34,18 @@ impl< + 'static + Send + Clone, -> Score for K8sResourceScore + T: Topology, +> Score for K8sResourceScore where ::DynamicType: Default, { - fn create_interpret(&self) -> Box { + fn create_interpret(&self) -> Box> { todo!() } fn name(&self) -> String { "K8sResourceScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } #[derive(Debug)] @@ -66,14 +63,15 @@ impl< + Default + Send + Sync, -> Interpret for K8sResourceInterpret + T: Topology + OcK8sclient, +> Interpret for K8sResourceInterpret where ::DynamicType: Default, { async fn execute( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + topology: &T, ) -> Result { topology .oc_client() diff --git a/harmony/src/modules/lamp.rs b/harmony/src/modules/lamp.rs index e6b7612..d7cd495 100644 --- a/harmony/src/modules/lamp.rs +++ b/harmony/src/modules/lamp.rs @@ -8,7 +8,7 @@ use crate::{ inventory::Inventory, modules::k8s::deployment::K8sDeploymentScore, score::Score, - topology::{HAClusterTopology, Url}, + topology::{HAClusterTopology, OcK8sclient, Topology, Url}, }; #[derive(Debug, Clone)] @@ -34,18 +34,14 @@ impl Default for LAMPConfig { } } -impl Score for LAMPScore { - fn create_interpret(&self) -> Box { +impl Score for LAMPScore { + fn create_interpret(&self) -> Box> { todo!() } fn name(&self) -> String { "LampScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } #[derive(Debug)] @@ -54,14 +50,14 @@ pub struct LAMPInterpret { } #[async_trait] -impl Interpret for LAMPInterpret { +impl Interpret for LAMPInterpret { async fn execute( &self, inventory: &Inventory, - topology: &HAClusterTopology, + topology: &T, ) -> Result { let deployment_score = K8sDeploymentScore { - name: self.score.name(), + name: >::name(&self.score), image: "local_image".to_string(), }; diff --git a/harmony/src/modules/load_balancer.rs b/harmony/src/modules/load_balancer.rs index 75318ca..5358e84 100644 --- a/harmony/src/modules/load_balancer.rs +++ b/harmony/src/modules/load_balancer.rs @@ -6,7 +6,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::{HAClusterTopology, LoadBalancerService}, + topology::{HAClusterTopology, LoadBalancer, LoadBalancerService, Topology}, }; #[derive(Debug, Clone)] @@ -19,18 +19,14 @@ pub struct LoadBalancerScore { // uuid? } -impl Score for LoadBalancerScore { - fn create_interpret(&self) -> Box { +impl Score for LoadBalancerScore { + fn create_interpret(&self) -> Box> { Box::new(LoadBalancerInterpret::new(self.clone())) } fn name(&self) -> String { "LoadBalancerScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } #[derive(Debug)] @@ -51,37 +47,32 @@ impl LoadBalancerInterpret { } #[async_trait] -impl Interpret for LoadBalancerInterpret { +impl Interpret for LoadBalancerInterpret { async fn execute( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + load_balancer: &T, ) -> Result { info!( "Making sure Load Balancer is initialized: {:?}", - topology.load_balancer.ensure_initialized().await? + load_balancer.ensure_initialized().await? ); for service in self.score.public_services.iter() { info!("Ensuring service exists {service:?}"); - topology - .load_balancer - .ensure_service_exists(service) - .await?; + + load_balancer.ensure_service_exists(service).await?; } for service in self.score.private_services.iter() { info!("Ensuring private service exists {service:?}"); - topology - .load_balancer - .ensure_service_exists(service) - .await?; + load_balancer.ensure_service_exists(service).await?; } info!("Applying load balancer configuration"); - topology.load_balancer.commit_config().await?; + load_balancer.commit_config().await?; info!("Making a full reload and restart of haproxy"); - topology.load_balancer.reload_restart().await?; + load_balancer.reload_restart().await?; Ok(Outcome::success(format!( "Load balancer successfully configured {} services", self.score.public_services.len() + self.score.private_services.len() diff --git a/harmony/src/modules/okd/bootstrap_dhcp.rs b/harmony/src/modules/okd/bootstrap_dhcp.rs index 4f5c6ee..ebb0a9d 100644 --- a/harmony/src/modules/okd/bootstrap_dhcp.rs +++ b/harmony/src/modules/okd/bootstrap_dhcp.rs @@ -3,7 +3,7 @@ use crate::{ inventory::Inventory, modules::dhcp::DhcpScore, score::Score, - topology::{HAClusterTopology, HostBinding}, + topology::{DhcpServer, HAClusterTopology, HostBinding, Topology}, }; #[derive(Debug, Clone)] @@ -46,16 +46,12 @@ impl OKDBootstrapDhcpScore { } } -impl Score for OKDBootstrapDhcpScore { - fn create_interpret(&self) -> Box { +impl Score for OKDBootstrapDhcpScore { + fn create_interpret(&self) -> Box> { self.dhcp_score.create_interpret() } fn name(&self) -> String { "OKDBootstrapDhcpScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/okd/bootstrap_load_balancer.rs b/harmony/src/modules/okd/bootstrap_load_balancer.rs index 4c29026..d983eed 100644 --- a/harmony/src/modules/okd/bootstrap_load_balancer.rs +++ b/harmony/src/modules/okd/bootstrap_load_balancer.rs @@ -5,8 +5,7 @@ use crate::{ modules::load_balancer::LoadBalancerScore, score::Score, topology::{ - BackendServer, HAClusterTopology, HealthCheck, HttpMethod, HttpStatusCode, - LoadBalancerService, + BackendServer, HAClusterTopology, HealthCheck, HttpMethod, HttpStatusCode, LoadBalancer, LoadBalancerService, Topology }, }; @@ -69,16 +68,12 @@ impl OKDBootstrapLoadBalancerScore { } } -impl Score for OKDBootstrapLoadBalancerScore { - fn create_interpret(&self) -> Box { +impl Score for OKDBootstrapLoadBalancerScore { + fn create_interpret(&self) -> Box> { self.load_balancer_score.create_interpret() } fn name(&self) -> String { "OKDBootstrapLoadBalancerScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/okd/dhcp.rs b/harmony/src/modules/okd/dhcp.rs index c976f8d..e3e0e09 100644 --- a/harmony/src/modules/okd/dhcp.rs +++ b/harmony/src/modules/okd/dhcp.rs @@ -3,7 +3,7 @@ use crate::{ inventory::Inventory, modules::dhcp::DhcpScore, score::Score, - topology::{HAClusterTopology, HostBinding}, + topology::{DhcpServer, HAClusterTopology, HostBinding, Topology}, }; #[derive(Debug, Clone)] @@ -38,16 +38,12 @@ impl OKDDhcpScore { } } -impl Score for OKDDhcpScore { - fn create_interpret(&self) -> Box { +impl Score for OKDDhcpScore { + fn create_interpret(&self) -> Box> { self.dhcp_score.create_interpret() } fn name(&self) -> String { "OKDDhcpScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/okd/dns.rs b/harmony/src/modules/okd/dns.rs index f4e7f2c..34c2dc2 100644 --- a/harmony/src/modules/okd/dns.rs +++ b/harmony/src/modules/okd/dns.rs @@ -2,7 +2,7 @@ use crate::{ interpret::Interpret, modules::dns::DnsScore, score::Score, - topology::{DnsRecord, DnsRecordType, HAClusterTopology}, + topology::{DnsRecord, DnsRecordType, DnsServer, HAClusterTopology, Topology}, }; #[derive(Debug, Clone)] @@ -40,16 +40,12 @@ impl OKDDnsScore { } } -impl Score for OKDDnsScore { - fn create_interpret(&self) -> Box { +impl Score for OKDDnsScore { + fn create_interpret(&self) -> Box> { self.dns_score.create_interpret() } fn name(&self) -> String { "OKDDnsScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/okd/load_balancer.rs b/harmony/src/modules/okd/load_balancer.rs index 38a5d04..c3b5264 100644 --- a/harmony/src/modules/okd/load_balancer.rs +++ b/harmony/src/modules/okd/load_balancer.rs @@ -5,8 +5,7 @@ use crate::{ modules::load_balancer::LoadBalancerScore, score::Score, topology::{ - BackendServer, HAClusterTopology, HealthCheck, HttpMethod, HttpStatusCode, - LoadBalancerService, + BackendServer, HAClusterTopology, HealthCheck, HttpMethod, HttpStatusCode, LoadBalancer, LoadBalancerService, Topology }, }; @@ -80,16 +79,12 @@ impl OKDLoadBalancerScore { } } -impl Score for OKDLoadBalancerScore { - fn create_interpret(&self) -> Box { +impl Score for OKDLoadBalancerScore { + fn create_interpret(&self) -> Box> { self.load_balancer_score.create_interpret() } fn name(&self) -> String { "OKDLoadBalancerScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/opnsense/shell.rs b/harmony/src/modules/opnsense/shell.rs index 00fd131..f4cecad 100644 --- a/harmony/src/modules/opnsense/shell.rs +++ b/harmony/src/modules/opnsense/shell.rs @@ -8,7 +8,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::HAClusterTopology, + topology::{HAClusterTopology, Topology}, }; #[derive(Debug, Clone)] @@ -17,8 +17,8 @@ pub struct OPNsenseShellCommandScore { pub command: String, } -impl Score for OPNsenseShellCommandScore { - fn create_interpret(&self) -> Box { +impl Score for OPNsenseShellCommandScore { + fn create_interpret(&self) -> Box> { Box::new(OPNsenseShellInterpret { status: InterpretStatus::QUEUED, score: self.clone(), @@ -28,10 +28,6 @@ impl Score for OPNsenseShellCommandScore { fn name(&self) -> String { "OPNSenseShellCommandScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } #[derive(Debug)] @@ -41,11 +37,11 @@ pub struct OPNsenseShellInterpret { } #[async_trait] -impl Interpret for OPNsenseShellInterpret { +impl Interpret for OPNsenseShellInterpret { async fn execute( &self, _inventory: &Inventory, - _topology: &HAClusterTopology, + _topology: &T, ) -> Result { let output = self .score diff --git a/harmony/src/modules/opnsense/upgrade.rs b/harmony/src/modules/opnsense/upgrade.rs index 6b0637d..06d373f 100644 --- a/harmony/src/modules/opnsense/upgrade.rs +++ b/harmony/src/modules/opnsense/upgrade.rs @@ -5,6 +5,7 @@ use tokio::sync::RwLock; use crate::{ interpret::{Interpret, InterpretStatus}, score::Score, + topology::Topology, }; use super::{OPNsenseShellCommandScore, OPNsenseShellInterpret}; @@ -14,8 +15,8 @@ pub struct OPNSenseLaunchUpgrade { pub opnsense: Arc>, } -impl Score for OPNSenseLaunchUpgrade { - fn create_interpret(&self) -> Box { +impl Score for OPNSenseLaunchUpgrade { + fn create_interpret(&self) -> Box> { let score = OPNsenseShellCommandScore { opnsense: self.opnsense.clone(), command: "/usr/local/opnsense/scripts/firmware/update.sh".to_string(), @@ -30,8 +31,4 @@ impl Score for OPNSenseLaunchUpgrade { fn name(&self) -> String { "OPNSenseLaunchUpgrade".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } diff --git a/harmony/src/modules/tftp.rs b/harmony/src/modules/tftp.rs index a7c2167..504459a 100644 --- a/harmony/src/modules/tftp.rs +++ b/harmony/src/modules/tftp.rs @@ -6,7 +6,7 @@ use crate::{ interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, - topology::{HAClusterTopology, Url}, + topology::{HAClusterTopology, Router, TftpServer, Topology, Url}, }; #[derive(Debug, new, Clone)] @@ -14,18 +14,14 @@ pub struct TftpScore { files_to_serve: Url, } -impl Score for TftpScore { - fn create_interpret(&self) -> Box { +impl Score for TftpScore { + fn create_interpret(&self) -> Box> { Box::new(TftpInterpret::new(self.clone())) } fn name(&self) -> String { "TftpScore".to_string() } - - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } } #[derive(Debug, new, Clone)] @@ -34,18 +30,17 @@ pub struct TftpInterpret { } #[async_trait] -impl Interpret for TftpInterpret { +impl Interpret for TftpInterpret { async fn execute( &self, _inventory: &Inventory, - topology: &HAClusterTopology, + topology: &T, ) -> Result { - let tftp_server = &topology.tftp_server; - tftp_server.ensure_initialized().await?; - tftp_server.set_ip(topology.router.get_gateway()).await?; - tftp_server.serve_files(&self.score.files_to_serve).await?; - tftp_server.commit_config().await?; - tftp_server.reload_restart().await?; + topology.ensure_initialized().await?; + topology.set_ip(topology.get_gateway()).await?; + topology.serve_files(&self.score.files_to_serve).await?; + topology.commit_config().await?; + topology.reload_restart().await?; Ok(Outcome::success(format!( "TFTP Server running and serving files from {}", self.score.files_to_serve