forked from NationTech/harmony
fix: update Score trait implementation and TUI initialization
Update the `Score` trait implementations to return a `Box<dyn Interpret>` instead of concrete types or clones where necessary. Additionally, refactor the initialization and cleanup in `HarmonyTUI` to use utility functions provided by `ratatui`.
This commit is contained in:
parent
4bbe8e84d8
commit
651266d71c
@ -92,5 +92,5 @@ async fn main() {
|
|||||||
// maestro.interpret(dhcp_score).await.unwrap();
|
// maestro.interpret(dhcp_score).await.unwrap();
|
||||||
// maestro.interpret(load_balancer_score).await.unwrap();
|
// maestro.interpret(load_balancer_score).await.unwrap();
|
||||||
// maestro.interpret(tftp_score).await.unwrap();
|
// maestro.interpret(tftp_score).await.unwrap();
|
||||||
maestro.interpret(http_score).await.unwrap();
|
maestro.interpret(&http_score).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ impl std::fmt::Display for InterpretName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Interpret {
|
pub trait Interpret: std::fmt::Debug {
|
||||||
async fn execute(
|
async fn execute(
|
||||||
&self,
|
&self,
|
||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use derive_new::new;
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -8,20 +9,35 @@ use super::{
|
|||||||
topology::HAClusterTopology,
|
topology::HAClusterTopology,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(new)]
|
type ScoreVec = Vec<Box<dyn Score>>;
|
||||||
|
|
||||||
pub struct Maestro {
|
pub struct Maestro {
|
||||||
inventory: Inventory,
|
inventory: Inventory,
|
||||||
topology: HAClusterTopology,
|
topology: HAClusterTopology,
|
||||||
|
scores: Arc<RwLock<ScoreVec>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Maestro {
|
impl Maestro {
|
||||||
|
pub fn new(inventory: Inventory, topology: HAClusterTopology) -> Self {
|
||||||
|
Self {
|
||||||
|
inventory,
|
||||||
|
topology,
|
||||||
|
scores: Arc::new(RwLock::new(Vec::new())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
info!("Starting Maestro");
|
info!("Starting Maestro");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn interpret<S: Score>(&self, score: S) -> Result<Outcome, InterpretError> {
|
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<S: Score>(&self, score: &S) -> Result<Outcome, InterpretError> {
|
||||||
info!("Running score {score:?}");
|
info!("Running score {score:?}");
|
||||||
let interpret: S::InterpretType = score.create_interpret();
|
let interpret = score.create_interpret();
|
||||||
info!("Launching interpret {interpret:?}");
|
info!("Launching interpret {interpret:?}");
|
||||||
let result = interpret.execute(&self.inventory, &self.topology).await;
|
let result = interpret.execute(&self.inventory, &self.topology).await;
|
||||||
info!("Got result {result:?}");
|
info!("Got result {result:?}");
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
use super::interpret::Interpret;
|
use super::interpret::Interpret;
|
||||||
|
|
||||||
pub trait Score: std::fmt::Debug {
|
pub trait Score: std::fmt::Debug {
|
||||||
type InterpretType: Interpret + std::fmt::Debug;
|
fn create_interpret(&self) -> Box<dyn Interpret>;
|
||||||
fn create_interpret(self) -> Self::InterpretType;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,14 +33,14 @@ impl std::fmt::Debug for dyn LoadBalancer {
|
|||||||
f.write_fmt(format_args!("LoadBalancer {}", self.get_ip()))
|
f.write_fmt(format_args!("LoadBalancer {}", self.get_ip()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct LoadBalancerService {
|
pub struct LoadBalancerService {
|
||||||
pub backend_servers: Vec<BackendServer>,
|
pub backend_servers: Vec<BackendServer>,
|
||||||
pub listening_port: SocketAddr,
|
pub listening_port: SocketAddr,
|
||||||
pub health_check: Option<HealthCheck>,
|
pub health_check: Option<HealthCheck>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct BackendServer {
|
pub struct BackendServer {
|
||||||
pub address: String,
|
pub address: String,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
|
|||||||
@ -21,10 +21,8 @@ pub struct DhcpScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for DhcpScore {
|
impl Score for DhcpScore {
|
||||||
type InterpretType = DhcpInterpret;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
Box::new(DhcpInterpret::new(self.clone()))
|
||||||
fn create_interpret(self) -> DhcpInterpret {
|
|
||||||
DhcpInterpret::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,10 +17,8 @@ pub struct DnsScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for DnsScore {
|
impl Score for DnsScore {
|
||||||
type InterpretType = DnsInterpret;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
Box::new(DnsInterpret::new(self.clone()))
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
DnsInterpret::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,10 +15,8 @@ pub struct HttpScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for HttpScore {
|
impl Score for HttpScore {
|
||||||
type InterpretType = HttpInterpret;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
Box::new(HttpInterpret::new(self.clone()))
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
HttpInterpret::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use k8s_openapi::api::apps::v1::Deployment;
|
use k8s_openapi::api::apps::v1::Deployment;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::score::Score;
|
use crate::{interpret::Interpret, score::Score};
|
||||||
|
|
||||||
use super::resource::{K8sResourceInterpret, K8sResourceScore};
|
use super::resource::{K8sResourceInterpret, K8sResourceScore};
|
||||||
|
|
||||||
@ -12,9 +12,7 @@ pub struct K8sDeploymentScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for K8sDeploymentScore {
|
impl Score for K8sDeploymentScore {
|
||||||
type InterpretType = K8sResourceInterpret<Deployment>;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
let deployment: Deployment = serde_json::from_value(json!(
|
let deployment: Deployment = serde_json::from_value(json!(
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
@ -45,8 +43,8 @@ impl Score for K8sDeploymentScore {
|
|||||||
}
|
}
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
K8sResourceInterpret {
|
Box::new(K8sResourceInterpret {
|
||||||
score: K8sResourceScore::single(deployment),
|
score: K8sResourceScore::single(deployment.clone()),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,9 +36,7 @@ impl<
|
|||||||
where
|
where
|
||||||
<K as kube::Resource>::DynamicType: Default,
|
<K as kube::Resource>::DynamicType: Default,
|
||||||
{
|
{
|
||||||
type InterpretType = K8sResourceInterpret<K>;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use crate::{
|
|||||||
topology::{HAClusterTopology, LoadBalancerService},
|
topology::{HAClusterTopology, LoadBalancerService},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LoadBalancerScore {
|
pub struct LoadBalancerScore {
|
||||||
pub public_services: Vec<LoadBalancerService>,
|
pub public_services: Vec<LoadBalancerService>,
|
||||||
pub private_services: Vec<LoadBalancerService>,
|
pub private_services: Vec<LoadBalancerService>,
|
||||||
@ -20,10 +20,8 @@ pub struct LoadBalancerScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for LoadBalancerScore {
|
impl Score for LoadBalancerScore {
|
||||||
type InterpretType = LoadBalancerInterpret;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
Box::new(LoadBalancerInterpret::new(self.clone()))
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
LoadBalancerInterpret::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
interpret::Interpret,
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
modules::dhcp::DhcpScore,
|
modules::dhcp::DhcpScore,
|
||||||
score::Score,
|
score::Score,
|
||||||
@ -46,9 +47,7 @@ impl OKDBootstrapDhcpScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for OKDBootstrapDhcpScore {
|
impl Score for OKDBootstrapDhcpScore {
|
||||||
type InterpretType = <DhcpScore as Score>::InterpretType;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
self.dhcp_score.create_interpret()
|
self.dhcp_score.create_interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
interpret::Interpret,
|
||||||
modules::load_balancer::LoadBalancerScore,
|
modules::load_balancer::LoadBalancerScore,
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::{
|
topology::{
|
||||||
@ -69,9 +70,7 @@ impl OKDBootstrapLoadBalancerScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for OKDBootstrapLoadBalancerScore {
|
impl Score for OKDBootstrapLoadBalancerScore {
|
||||||
type InterpretType = <LoadBalancerScore as Score>::InterpretType;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
self.load_balancer_score.create_interpret()
|
self.load_balancer_score.create_interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
interpret::Interpret,
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
modules::dhcp::DhcpScore,
|
modules::dhcp::DhcpScore,
|
||||||
score::Score,
|
score::Score,
|
||||||
@ -38,9 +39,7 @@ impl OKDDhcpScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for OKDDhcpScore {
|
impl Score for OKDDhcpScore {
|
||||||
type InterpretType = <DhcpScore as Score>::InterpretType;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
self.dhcp_score.create_interpret()
|
self.dhcp_score.create_interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
interpret::Interpret,
|
||||||
modules::dns::DnsScore,
|
modules::dns::DnsScore,
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::{DnsRecord, DnsRecordType, HAClusterTopology},
|
topology::{DnsRecord, DnsRecordType, HAClusterTopology},
|
||||||
@ -40,9 +41,7 @@ impl OKDDnsScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for OKDDnsScore {
|
impl Score for OKDDnsScore {
|
||||||
type InterpretType = <DnsScore as Score>::InterpretType;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
self.dns_score.create_interpret()
|
self.dns_score.create_interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
interpret::Interpret,
|
||||||
modules::load_balancer::LoadBalancerScore,
|
modules::load_balancer::LoadBalancerScore,
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::{
|
topology::{
|
||||||
@ -80,9 +81,7 @@ impl OKDLoadBalancerScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for OKDLoadBalancerScore {
|
impl Score for OKDLoadBalancerScore {
|
||||||
type InterpretType = <LoadBalancerScore as Score>::InterpretType;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
self.load_balancer_score.create_interpret()
|
self.load_balancer_score.create_interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,9 +16,7 @@ impl OKDUpgradeScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// impl Score for OKDUpgradeScore {
|
// impl Score for OKDUpgradeScore {
|
||||||
// type InterpretType;
|
// fn create_interpret(self) -> Box<dyn Interpret> {
|
||||||
//
|
|
||||||
// fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
// // Should this be a specialized interpret for OKD upgrades or rather a set of interprets
|
// // Should this be a specialized interpret for OKD upgrades or rather a set of interprets
|
||||||
// // such as :
|
// // such as :
|
||||||
// //
|
// //
|
||||||
|
|||||||
@ -15,10 +15,8 @@ pub struct TftpScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Score for TftpScore {
|
impl Score for TftpScore {
|
||||||
type InterpretType = TftpInterpret;
|
fn create_interpret(&self) -> Box<dyn Interpret> {
|
||||||
|
Box::new(TftpInterpret::new(self.clone()))
|
||||||
fn create_interpret(self) -> Self::InterpretType {
|
|
||||||
TftpInterpret::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::io;
|
|
||||||
use crossterm::event::{self, Event};
|
use crossterm::event::{self, Event};
|
||||||
use harmony::maestro::Maestro;
|
use harmony::maestro::Maestro;
|
||||||
use ratatui::{self, layout::Position, prelude::CrosstermBackend, Frame, Terminal};
|
use ratatui::{self, layout::Position, prelude::CrosstermBackend, Frame, Terminal};
|
||||||
|
use std::io;
|
||||||
|
|
||||||
pub mod tui {
|
pub mod tui {
|
||||||
// Export any necessary modules or types from the internal tui module
|
// Export any necessary modules or types from the internal tui module
|
||||||
@ -43,8 +43,7 @@ impl HarmonyTUI {
|
|||||||
|
|
||||||
pub async fn init(self) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn init(self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
let backend = CrosstermBackend::new(io::stdout());
|
let mut terminal = ratatui::init();
|
||||||
let mut terminal = Terminal::new(backend)?;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
terminal.draw(|f| self.render(f))?;
|
terminal.draw(|f| self.render(f))?;
|
||||||
@ -53,6 +52,8 @@ impl HarmonyTUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ratatui::restore();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user