feat: implement full Lens-like Kubernetes UI with resource discovery and management #75
@ -6,8 +6,10 @@ use lazy_static::lazy_static;
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use std::process::Stdio;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
@ -3609,44 +3611,257 @@ fn parse_hpas_json(json_str: &str) -> Result<Vec<HorizontalPodAutoscalerInfo>, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub async fn cordon_node(cluster_id: String, node_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
pub async fn cordon_node(cluster_id: String, node_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
// Implementation similar to other management commands
|
let clusters = state.clusters.lock().await;
|
||||||
|
let cluster = clusters
|
||||||
|
.get(&cluster_id)
|
||||||
|
.ok_or_else(|| format!("Cluster {} not found", cluster_id))?;
|
||||||
|
|
||||||
|
let kubeconfig_content = cluster.kubeconfig_content.as_ref();
|
||||||
|
let context = &cluster.context;
|
||||||
|
|
||||||
|
let temp_dir = std::env::temp_dir();
|
||||||
|
let temp_path = temp_dir.join(format!("kubeconfig-{}-cordon.yaml", cluster_id));
|
||||||
|
let _cleanup = TempFileCleanup(temp_path.clone());
|
||||||
|
|
||||||
|
std::fs::write(&temp_path, kubeconfig_content)
|
||||||
|
.map_err(|e| format!("Failed to write kubeconfig temp file: {e}"))?;
|
||||||
|
|
||||||
|
let kubectl_path = locate_kubectl()?;
|
||||||
|
|
||||||
|
let output = Command::new(kubectl_path)
|
||||||
|
.arg("cordon")
|
||||||
|
.arg(node_name)
|
||||||
|
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||||
|
.env("KUBERNETES_CONTEXT", context)
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(stderr.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub async fn uncordon_node(cluster_id: String, node_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
pub async fn uncordon_node(cluster_id: String, node_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
// Implementation similar to other management commands
|
let clusters = state.clusters.lock().await;
|
||||||
|
let cluster = clusters
|
||||||
|
.get(&cluster_id)
|
||||||
|
.ok_or_else(|| format!("Cluster {} not found", cluster_id))?;
|
||||||
|
|
||||||
|
let kubeconfig_content = cluster.kubeconfig_content.as_ref();
|
||||||
|
let context = &cluster.context;
|
||||||
|
|
||||||
|
let temp_dir = std::env::temp_dir();
|
||||||
|
let temp_path = temp_dir.join(format!("kubeconfig-{}-uncordon.yaml", cluster_id));
|
||||||
|
let _cleanup = TempFileCleanup(temp_path.clone());
|
||||||
|
|
||||||
|
std::fs::write(&temp_path, kubeconfig_content)
|
||||||
|
.map_err(|e| format!("Failed to write kubeconfig temp file: {e}"))?;
|
||||||
|
|
||||||
|
let kubectl_path = locate_kubectl()?;
|
||||||
|
|
||||||
|
let output = Command::new(kubectl_path)
|
||||||
|
.arg("uncordon")
|
||||||
|
.arg(node_name)
|
||||||
|
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||||
|
.env("KUBERNETES_CONTEXT", context)
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(stderr.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub async fn drain_node(cluster_id: String, node_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
pub async fn drain_node(cluster_id: String, node_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
// Implementation similar to other management commands
|
let clusters = state.clusters.lock().await;
|
||||||
|
let cluster = clusters
|
||||||
|
.get(&cluster_id)
|
||||||
|
.ok_or_else(|| format!("Cluster {} not found", cluster_id))?;
|
||||||
|
|
||||||
|
let kubeconfig_content = cluster.kubeconfig_content.as_ref();
|
||||||
|
let context = &cluster.context;
|
||||||
|
|
||||||
|
let temp_dir = std::env::temp_dir();
|
||||||
|
let temp_path = temp_dir.join(format!("kubeconfig-{}-drain.yaml", cluster_id));
|
||||||
|
let _cleanup = TempFileCleanup(temp_path.clone());
|
||||||
|
|
||||||
|
std::fs::write(&temp_path, kubeconfig_content)
|
||||||
|
.map_err(|e| format!("Failed to write kubeconfig temp file: {e}"))?;
|
||||||
|
|
||||||
|
let kubectl_path = locate_kubectl()?;
|
||||||
|
|
||||||
|
let output = Command::new(kubectl_path)
|
||||||
|
.arg("drain")
|
||||||
|
.arg(node_name)
|
||||||
|
.arg("--ignore-daemonsets")
|
||||||
|
.arg("--delete-emptydir-data")
|
||||||
|
.arg("--force")
|
||||||
|
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||||
|
.env("KUBERNETES_CONTEXT", context)
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(stderr.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub async fn rollback_deployment(cluster_id: String, namespace: String, deployment_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
pub async fn rollback_deployment(cluster_id: String, namespace: String, deployment_name: String, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
// Implementation similar to other management commands
|
let clusters = state.clusters.lock().await;
|
||||||
|
let cluster = clusters
|
||||||
|
.get(&cluster_id)
|
||||||
|
.ok_or_else(|| format!("Cluster {} not found", cluster_id))?;
|
||||||
|
|
||||||
|
let kubeconfig_content = cluster.kubeconfig_content.as_ref();
|
||||||
|
let context = &cluster.context;
|
||||||
|
|
||||||
|
let temp_dir = std::env::temp_dir();
|
||||||
|
let temp_path = temp_dir.join(format!("kubeconfig-{}-rollback.yaml", cluster_id));
|
||||||
|
let _cleanup = TempFileCleanup(temp_path.clone());
|
||||||
|
|
||||||
|
std::fs::write(&temp_path, kubeconfig_content)
|
||||||
|
.map_err(|e| format!("Failed to write kubeconfig temp file: {e}"))?;
|
||||||
|
|
||||||
|
let kubectl_path = locate_kubectl()?;
|
||||||
|
|
||||||
|
let output = Command::new(kubectl_path)
|
||||||
|
.arg("rollout")
|
||||||
|
.arg("undo")
|
||||||
|
.arg("deployment")
|
||||||
|
.arg(deployment_name)
|
||||||
|
.arg("-n")
|
||||||
|
.arg(namespace)
|
||||||
|
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||||
|
.env("KUBERNETES_CONTEXT", context)
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(stderr.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[allow(unused_variables)]
|
pub async fn create_resource(cluster_id: String, namespace: String, _resource_type: String, yaml_content: String, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
pub async fn create_resource(cluster_id: String, namespace: String, resource_type: String, yaml_content: String, state: State<'_, AppState>) -> Result<(), String> {
|
let clusters = state.clusters.lock().await;
|
||||||
// Implementation similar to other management commands
|
let cluster = clusters
|
||||||
|
.get(&cluster_id)
|
||||||
|
.ok_or_else(|| format!("Cluster {} not found", cluster_id))?;
|
||||||
|
|
||||||
|
let kubeconfig_content = cluster.kubeconfig_content.as_ref();
|
||||||
|
let context = &cluster.context;
|
||||||
|
|
||||||
|
let temp_dir = std::env::temp_dir();
|
||||||
|
let temp_path = temp_dir.join(format!("kubeconfig-{}-create.yaml", cluster_id));
|
||||||
|
let _cleanup = TempFileCleanup(temp_path.clone());
|
||||||
|
|
||||||
|
std::fs::write(&temp_path, kubeconfig_content)
|
||||||
|
.map_err(|e| format!("Failed to write kubeconfig temp file: {e}"))?;
|
||||||
|
|
||||||
|
let kubectl_path = locate_kubectl()?;
|
||||||
|
|
||||||
|
let mut cmd = Command::new(kubectl_path);
|
||||||
|
cmd.arg("create")
|
||||||
|
.arg("-f")
|
||||||
|
.arg("-")
|
||||||
|
.arg("-n")
|
||||||
|
.arg(namespace)
|
||||||
|
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||||
|
.env("KUBERNETES_CONTEXT", context)
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped());
|
||||||
|
|
||||||
|
let mut child = cmd.spawn()
|
||||||
|
.map_err(|e| format!("Failed to spawn kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if let Some(mut stdin) = child.stdin.take() {
|
||||||
|
stdin.write_all(yaml_content.as_bytes())
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to write yaml to stdin: {e}"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = child.wait_with_output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(stderr.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[allow(unused_variables)]
|
pub async fn edit_resource(cluster_id: String, namespace: String, _resource_type: String, _resource_name: String, yaml_content: String, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
pub async fn edit_resource(cluster_id: String, namespace: String, resource_type: String, resource_name: String, yaml_content: String, state: State<'_, AppState>) -> Result<(), String> {
|
let clusters = state.clusters.lock().await;
|
||||||
// Implementation similar to other management commands
|
let cluster = clusters
|
||||||
|
.get(&cluster_id)
|
||||||
|
.ok_or_else(|| format!("Cluster {} not found", cluster_id))?;
|
||||||
|
|
||||||
|
let kubeconfig_content = cluster.kubeconfig_content.as_ref();
|
||||||
|
let context = &cluster.context;
|
||||||
|
|
||||||
|
let temp_dir = std::env::temp_dir();
|
||||||
|
let temp_path = temp_dir.join(format!("kubeconfig-{}-edit.yaml", cluster_id));
|
||||||
|
let _cleanup = TempFileCleanup(temp_path.clone());
|
||||||
|
|
||||||
|
std::fs::write(&temp_path, kubeconfig_content)
|
||||||
|
.map_err(|e| format!("Failed to write kubeconfig temp file: {e}"))?;
|
||||||
|
|
||||||
|
let kubectl_path = locate_kubectl()?;
|
||||||
|
|
||||||
|
let mut cmd = Command::new(kubectl_path);
|
||||||
|
cmd.arg("apply")
|
||||||
|
.arg("-f")
|
||||||
|
.arg("-")
|
||||||
|
.arg("-n")
|
||||||
|
.arg(namespace)
|
||||||
|
.env("KUBECONFIG", temp_path.to_string_lossy().to_string())
|
||||||
|
.env("KUBERNETES_CONTEXT", context)
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped());
|
||||||
|
|
||||||
|
let mut child = cmd.spawn()
|
||||||
|
.map_err(|e| format!("Failed to spawn kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if let Some(mut stdin) = child.stdin.take() {
|
||||||
|
stdin.write_all(yaml_content.as_bytes())
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to write yaml to stdin: {e}"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = child.wait_with_output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to execute kubectl: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(stderr.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -947,3 +947,213 @@ export const deleteResourceCmd = (clusterId: string, resourceType: string, names
|
|||||||
|
|
||||||
export const execPodCmd = (clusterId: string, namespace: string, podName: string, containerName: string, command: string, shell?: string) =>
|
export const execPodCmd = (clusterId: string, namespace: string, podName: string, containerName: string, command: string, shell?: string) =>
|
||||||
invoke<ExecResponse>("exec_pod", { clusterId, namespace, podName, containerName, shell, command });
|
invoke<ExecResponse>("exec_pod", { clusterId, namespace, podName, containerName, shell, command });
|
||||||
|
|
||||||
|
// ─── Additional Kubernetes Resource Discovery Types ───────────────────────────
|
||||||
|
|
||||||
|
export interface ReplicaSetInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
replicas: number;
|
||||||
|
ready: string;
|
||||||
|
age: string;
|
||||||
|
labels: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JobInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
completions: string;
|
||||||
|
duration: string;
|
||||||
|
age: string;
|
||||||
|
labels: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CronJobInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
schedule: string;
|
||||||
|
active: number;
|
||||||
|
last_schedule: string;
|
||||||
|
age: string;
|
||||||
|
labels: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConfigMapInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
data_keys: number;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecretInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
type: string;
|
||||||
|
data_keys: number;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NodeInfo {
|
||||||
|
name: string;
|
||||||
|
status: string;
|
||||||
|
roles: string;
|
||||||
|
version: string;
|
||||||
|
internal_ip: string;
|
||||||
|
external_ip?: string;
|
||||||
|
os_image: string;
|
||||||
|
kernel_version: string;
|
||||||
|
kubelet_version: string;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EventInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
event_type: string;
|
||||||
|
reason: string;
|
||||||
|
object: string;
|
||||||
|
count: number;
|
||||||
|
first_seen: string;
|
||||||
|
last_seen: string;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IngressInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
class?: string;
|
||||||
|
host: string;
|
||||||
|
addresses: string[];
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PersistentVolumeClaimInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
status: string;
|
||||||
|
volume: string;
|
||||||
|
capacity: string;
|
||||||
|
access_modes: string[];
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PersistentVolumeInfo {
|
||||||
|
name: string;
|
||||||
|
status: string;
|
||||||
|
capacity: string;
|
||||||
|
access_modes: string[];
|
||||||
|
reclaim_policy: string;
|
||||||
|
storage_class: string;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceAccountInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
secrets: number;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoleInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClusterRoleInfo {
|
||||||
|
name: string;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoleBindingInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
role: string;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClusterRoleBindingInfo {
|
||||||
|
name: string;
|
||||||
|
cluster_role: string;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HorizontalPodAutoscalerInfo {
|
||||||
|
name: string;
|
||||||
|
namespace: string;
|
||||||
|
min_replicas: number;
|
||||||
|
max_replicas: number;
|
||||||
|
current_replicas: number;
|
||||||
|
desired_replicas: number;
|
||||||
|
age: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Additional Kubernetes Resource Discovery Commands ────────────────────────
|
||||||
|
|
||||||
|
export const listReplicasetsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<ReplicaSetInfo[]>("list_replicasets", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listJobsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<JobInfo[]>("list_jobs", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listCronjobsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<CronJobInfo[]>("list_cronjobs", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listConfigmapsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<ConfigMapInfo[]>("list_configmaps", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listSecretsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<SecretInfo[]>("list_secrets", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listNodesCmd = (clusterId: string) =>
|
||||||
|
invoke<NodeInfo[]>("list_nodes", { clusterId });
|
||||||
|
|
||||||
|
export const listEventsCmd = (clusterId: string, namespace?: string) =>
|
||||||
|
invoke<EventInfo[]>("list_events", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listIngressesCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<IngressInfo[]>("list_ingresses", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listPersistentvolumeclaimsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<PersistentVolumeClaimInfo[]>("list_persistentvolumeclaims", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listPersistentvolumesCmd = (clusterId: string) =>
|
||||||
|
invoke<PersistentVolumeInfo[]>("list_persistentvolumes", { clusterId });
|
||||||
|
|
||||||
|
export const listServiceaccountsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<ServiceAccountInfo[]>("list_serviceaccounts", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listRolesCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<RoleInfo[]>("list_roles", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listClusterrolesCmd = (clusterId: string) =>
|
||||||
|
invoke<ClusterRoleInfo[]>("list_clusterroles", { clusterId });
|
||||||
|
|
||||||
|
export const listRolebindingsCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<RoleBindingInfo[]>("list_rolebindings", { clusterId, namespace });
|
||||||
|
|
||||||
|
export const listClusterrolebindingsCmd = (clusterId: string) =>
|
||||||
|
invoke<ClusterRoleBindingInfo[]>("list_clusterrolebindings", { clusterId });
|
||||||
|
|
||||||
|
export const listHorizontalpodautoscalersCmd = (clusterId: string, namespace: string) =>
|
||||||
|
invoke<HorizontalPodAutoscalerInfo[]>("list_horizontalpodautoscalers", { clusterId, namespace });
|
||||||
|
|
||||||
|
// ─── Additional Kubernetes Resource Management Commands ───────────────────────
|
||||||
|
|
||||||
|
export const cordonNodeCmd = (clusterId: string, nodeName: string) =>
|
||||||
|
invoke<void>("cordon_node", { clusterId, nodeName });
|
||||||
|
|
||||||
|
export const uncordonNodeCmd = (clusterId: string, nodeName: string) =>
|
||||||
|
invoke<void>("uncordon_node", { clusterId, nodeName });
|
||||||
|
|
||||||
|
export const drainNodeCmd = (clusterId: string, nodeName: string) =>
|
||||||
|
invoke<void>("drain_node", { clusterId, nodeName });
|
||||||
|
|
||||||
|
export const rollbackDeploymentCmd = (clusterId: string, namespace: string, deploymentName: string) =>
|
||||||
|
invoke<void>("rollback_deployment", { clusterId, namespace, deploymentName });
|
||||||
|
|
||||||
|
export const createResourceCmd = (clusterId: string, namespace: string, resourceType: string, yamlContent: string) =>
|
||||||
|
invoke<void>("create_resource", { clusterId, namespace, resourceType, yamlContent });
|
||||||
|
|
||||||
|
export const editResourceCmd = (clusterId: string, namespace: string, resourceType: string, resourceName: string, yamlContent: string) =>
|
||||||
|
invoke<void>("edit_resource", { clusterId, namespace, resourceType, resourceName, yamlContent });
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user