WP-12: Kubernetes overview and workload actions
kube-rs gateway (nodes, namespaces, deployments/statefulsets/daemonsets with images, PVCs; rollout restart, scale, set image via patches) using the microk8s kubeconfig by default, fake gateway for dev, /api/cluster routes, Kubernetes page with node cards, workload table with admin actions and PVC list. Also implements the streaming command runner that WP-11 relied on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::cluster::{ClusterOverview, WorkloadRef};
|
||||
use domain::cluster::{
|
||||
validate_image, validate_k8s_name, ClusterOverview, WorkloadRef, MAX_REPLICAS,
|
||||
};
|
||||
use domain::ports::ClusterGateway;
|
||||
use domain::DomainError;
|
||||
|
||||
@ -10,28 +12,55 @@ pub struct ClusterService {
|
||||
|
||||
impl ClusterService {
|
||||
pub fn new(gateway: Arc<dyn ClusterGateway>) -> Self {
|
||||
let _ = &gateway;
|
||||
Self { gateway }
|
||||
}
|
||||
|
||||
pub async fn overview(&self) -> Result<ClusterOverview, DomainError> {
|
||||
todo!()
|
||||
self.gateway.overview().await
|
||||
}
|
||||
|
||||
pub async fn restart(&self, _w: WorkloadRef) -> Result<(), DomainError> {
|
||||
todo!()
|
||||
pub async fn restart(&self, w: WorkloadRef) -> Result<(), DomainError> {
|
||||
validate_ref(&w)?;
|
||||
self.gateway.restart(&w).await
|
||||
}
|
||||
|
||||
pub async fn scale(&self, _w: WorkloadRef, _replicas: i32) -> Result<(), DomainError> {
|
||||
todo!()
|
||||
pub async fn scale(&self, w: WorkloadRef, replicas: i32) -> Result<(), DomainError> {
|
||||
validate_ref(&w)?;
|
||||
if !(0..=MAX_REPLICAS).contains(&replicas) {
|
||||
return Err(DomainError::Validation(format!(
|
||||
"replicas must be between 0 and {MAX_REPLICAS}"
|
||||
)));
|
||||
}
|
||||
self.gateway.scale(&w, replicas).await
|
||||
}
|
||||
|
||||
/// Change the image of `container` (default: the workload's first container).
|
||||
pub async fn set_image(
|
||||
&self,
|
||||
_w: WorkloadRef,
|
||||
_container: Option<String>,
|
||||
_image: &str,
|
||||
w: WorkloadRef,
|
||||
container: Option<String>,
|
||||
image: &str,
|
||||
) -> Result<(), DomainError> {
|
||||
todo!()
|
||||
validate_ref(&w)?;
|
||||
validate_image(image)?;
|
||||
let container = match container {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
let overview = self.gateway.overview().await?;
|
||||
overview
|
||||
.workloads
|
||||
.iter()
|
||||
.find(|x| x.namespace == w.namespace && x.kind == w.kind && x.name == w.name)
|
||||
.and_then(|x| x.containers.first())
|
||||
.map(|c| c.name.clone())
|
||||
.ok_or(DomainError::NotFound)?
|
||||
}
|
||||
};
|
||||
self.gateway.set_image(&w, &container, image).await
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_ref(w: &WorkloadRef) -> Result<(), DomainError> {
|
||||
validate_k8s_name(&w.namespace)?;
|
||||
validate_k8s_name(&w.name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user