diff --git a/harmony/src/domain/topology/k8s.rs b/harmony/src/domain/topology/k8s.rs index 388ff9d..1eae139 100644 --- a/harmony/src/domain/topology/k8s.rs +++ b/harmony/src/domain/topology/k8s.rs @@ -17,6 +17,7 @@ use kube::{ }; use log::{debug, error, trace}; use serde::{Serialize, de::DeserializeOwned}; +use serde_json::json; use similar::TextDiff; #[derive(new, Clone)] @@ -51,6 +52,38 @@ impl K8sClient { }) } + pub async fn get_pod(&self, name: &str, namespace: Option<&str>) -> Result, Error> { + let pods: Api = if let Some(ns) = namespace { + Api::namespaced(self.client.clone(), ns) + } else { + Api::default_namespaced(self.client.clone()) + }; + Ok(pods.get_opt(name).await?) + } + + pub async fn scale_deployment( + &self, + name: &str, + namespace: Option<&str>, + replicas: u32, + ) -> Result<(), Error> { + let deployments: Api = if let Some(ns) = namespace { + Api::namespaced(self.client.clone(), ns) + } else { + Api::default_namespaced(self.client.clone()) + }; + + let patch = json!({ + "spec": { + "replicas": replicas + } + }); + let pp = PatchParams::default(); + let scale = Patch::Apply(&patch); + deployments.patch_scale(name, &pp, &scale).await?; + Ok(()) + } + pub async fn wait_until_deployment_ready( &self, name: String, diff --git a/harmony/src/modules/mod.rs b/harmony/src/modules/mod.rs index e9b6c52..6df5c41 100644 --- a/harmony/src/modules/mod.rs +++ b/harmony/src/modules/mod.rs @@ -14,5 +14,6 @@ pub mod monitoring; pub mod okd; pub mod opnsense; pub mod prometheus; +pub mod storage; pub mod tenant; pub mod tftp; diff --git a/harmony/src/modules/storage/ceph/ceph_osd_replacement_score.rs b/harmony/src/modules/storage/ceph/ceph_osd_replacement_score.rs new file mode 100644 index 0000000..0223e62 --- /dev/null +++ b/harmony/src/modules/storage/ceph/ceph_osd_replacement_score.rs @@ -0,0 +1,79 @@ +use std::process::Command; + +use async_trait::async_trait; +use serde::Serialize; + +use crate::{ + data::{Id, Version}, + interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, + inventory::Inventory, + score::Score, + topology::{K8sclient, Topology}, +}; + +#[derive(Debug, Clone, Serialize)] +pub struct PrepCephOsdReplacement { + osd_name: String, + rook_ceph_namespace: String, +} + +impl Score for PrepCephOsdReplacement { + fn name(&self) -> String { + format!("CephOsdReplacementScore") + } + + #[doc(hidden)] + fn create_interpret(&self) -> Box> { + Box::new(PrepCephOsdReplacementInterpret { + score: self.clone(), + }) + } +} + +#[derive(Debug, Clone)] +pub struct PrepCephOsdReplacementInterpret { + score: PrepCephOsdReplacement, +} + +#[async_trait] +impl Interpret for PrepCephOsdReplacementInterpret { + async fn execute( + &self, + _inventory: &Inventory, + topology: &T, + ) -> Result { + let client = topology.k8s_client().await.unwrap(); + client + .scale_deployment( + &self.score.osd_name, + Some(&self.score.rook_ceph_namespace), + 0, + ) + .await?; + client + .get_pod(&self.score.osd_name, Some(&self.score.rook_ceph_namespace)) + .await?; + + Ok(Outcome::success( + "Successfully prepared rook-ceph-cluster for disk replacement".to_string(), + )) + } + + fn get_name(&self) -> InterpretName { + todo!() + } + + fn get_version(&self) -> Version { + todo!() + } + + fn get_status(&self) -> InterpretStatus { + todo!() + } + + fn get_children(&self) -> Vec { + todo!() + } +} + +impl PrepCephOsdReplacementInterpret {} diff --git a/harmony/src/modules/storage/ceph/mod.rs b/harmony/src/modules/storage/ceph/mod.rs new file mode 100644 index 0000000..a993c3d --- /dev/null +++ b/harmony/src/modules/storage/ceph/mod.rs @@ -0,0 +1 @@ +pub mod ceph_osd_replacement_score; diff --git a/harmony/src/modules/storage/mod.rs b/harmony/src/modules/storage/mod.rs new file mode 100644 index 0000000..ee3e235 --- /dev/null +++ b/harmony/src/modules/storage/mod.rs @@ -0,0 +1 @@ +pub mod ceph;