diff --git a/packages/crypt/vault/src/key/asymmetric.rs b/packages/crypt/vault/src/key/asymmetric.rs index ea89740..903c8a1 100644 --- a/packages/crypt/vault/src/key/asymmetric.rs +++ b/packages/crypt/vault/src/key/asymmetric.rs @@ -3,6 +3,7 @@ use k256::{SecretKey, ecdh::diffie_hellman, elliptic_curve::sec1::ToEncodedPoint}; use sha2::Sha256; +use getrandom::fill; use crate::{error::CryptoError, key::symmetric::SymmetricKey}; @@ -22,7 +23,7 @@ impl AsymmetricKeypair { /// Generates a new random keypair pub fn new() -> Result { let mut raw_private = [0u8; 32]; - rand::fill(&mut raw_private); + fill(&mut raw_private); let sk = SecretKey::from_slice(&raw_private) .expect("Key is provided generated with fixed valid size"); let pk = sk.public_key(); diff --git a/packages/crypt/vault/src/key/signature.rs b/packages/crypt/vault/src/key/signature.rs index e83d364..c20d91f 100644 --- a/packages/crypt/vault/src/key/signature.rs +++ b/packages/crypt/vault/src/key/signature.rs @@ -4,6 +4,7 @@ use k256::ecdsa::{ Signature, SigningKey, VerifyingKey, signature::{Signer, Verifier}, }; +use getrandom::fill; use crate::error::CryptoError; @@ -19,7 +20,7 @@ impl SigningKeypair { /// Generates a new random keypair pub fn new() -> Result { let mut raw_private = [0u8; 32]; - rand::fill(&mut raw_private); + fill(&mut raw_private); let sk = SigningKey::from_slice(&raw_private) .expect("Key is provided generated with fixed valid size"); let vk = sk.verifying_key().to_owned(); diff --git a/packages/crypt/vault/src/key/symmetric.rs b/packages/crypt/vault/src/key/symmetric.rs index 00aaa96..a36aa1f 100644 --- a/packages/crypt/vault/src/key/symmetric.rs +++ b/packages/crypt/vault/src/key/symmetric.rs @@ -5,6 +5,7 @@ //! Keys are 32 bytes in size. use chacha20poly1305::{ChaCha20Poly1305, KeyInit, Nonce, aead::Aead}; +use getrandom::fill; use crate::error::CryptoError; @@ -18,7 +19,7 @@ impl SymmetricKey { /// Generate a new random SymmetricKey. pub fn new() -> Self { let mut key = [0u8; 32]; - rand::fill(&mut key); + fill(&mut key); Self(key) } @@ -47,7 +48,7 @@ impl SymmetricKey { // Generate random nonce let mut nonce_bytes = [0u8; NONCE_SIZE]; - rand::fill(&mut nonce_bytes); + fill(&mut nonce_bytes); let nonce = Nonce::from_slice(&nonce_bytes); // Encrypt message diff --git a/packages/system/kubernetes/src/lib.rs b/packages/system/kubernetes/src/lib.rs index 2bdebd3..b91cd01 100644 --- a/packages/system/kubernetes/src/lib.rs +++ b/packages/system/kubernetes/src/lib.rs @@ -43,6 +43,8 @@ pub mod rhai; pub use config::KubernetesConfig; pub use error::KubernetesError; pub use kubernetes_manager::KubernetesManager; +#[cfg(feature = "rhai")] +pub use rhai::register_kubernetes_module; // Re-export commonly used Kubernetes types pub use k8s_openapi::api::apps::v1::{Deployment, ReplicaSet}; diff --git a/packages/system/kubernetes/src/rhai.rs b/packages/system/kubernetes/src/rhai.rs index e5f360f..96b9acb 100644 --- a/packages/system/kubernetes/src/rhai.rs +++ b/packages/system/kubernetes/src/rhai.rs @@ -59,605 +59,12 @@ where rt.block_on(future).map_err(kubernetes_error_to_rhai_error) } -/// Create a new KubernetesManager for the specified namespace -/// -/// # Arguments -/// -/// * `namespace` - The Kubernetes namespace to operate on -/// -/// # Returns -/// -/// * `Result>` - The manager instance or an error -fn kubernetes_manager_new(namespace: String) -> Result> { - execute_async(KubernetesManager::new(namespace)) -} - -/// List all pods in the namespace -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Array of pod names or an error -fn pods_list(km: &mut KubernetesManager) -> Result> { - let pods = execute_async(km.pods_list())?; - - let pod_names: Array = pods - .iter() - .filter_map(|pod| pod.metadata.name.as_ref()) - .map(|name| Dynamic::from(name.clone())) - .collect(); - - Ok(pod_names) -} - -/// List all services in the namespace -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Array of service names or an error -fn services_list(km: &mut KubernetesManager) -> Result> { - let services = execute_async(km.services_list())?; - - let service_names: Array = services - .iter() - .filter_map(|service| service.metadata.name.as_ref()) - .map(|name| Dynamic::from(name.clone())) - .collect(); - - Ok(service_names) -} - -/// List all deployments in the namespace -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Array of deployment names or an error -fn deployments_list(km: &mut KubernetesManager) -> Result> { - let deployments = execute_async(km.deployments_list())?; - - let deployment_names: Array = deployments - .iter() - .filter_map(|deployment| deployment.metadata.name.as_ref()) - .map(|name| Dynamic::from(name.clone())) - .collect(); - - Ok(deployment_names) -} - -/// List all configmaps in the namespace -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Array of configmap names or an error -fn configmaps_list(km: &mut KubernetesManager) -> Result> { - let configmaps = execute_async(km.configmaps_list())?; - - let configmap_names: Array = configmaps - .iter() - .filter_map(|configmap| configmap.metadata.name.as_ref()) - .map(|name| Dynamic::from(name.clone())) - .collect(); - - Ok(configmap_names) -} - -/// List all secrets in the namespace -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Array of secret names or an error -fn secrets_list(km: &mut KubernetesManager) -> Result> { - let secrets = execute_async(km.secrets_list())?; - - let secret_names: Array = secrets - .iter() - .filter_map(|secret| secret.metadata.name.as_ref()) - .map(|name| Dynamic::from(name.clone())) - .collect(); - - Ok(secret_names) -} - -/// Delete resources matching a PCRE pattern -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// * `pattern` - PCRE pattern to match resource names against -/// -/// # Returns -/// -/// * `Result>` - Number of resources deleted or an error -/// -/// Create a pod with a single container (backward compatible version) -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the pod -/// * `image` - Container image to use -/// * `labels` - Optional labels as a Map -/// -/// # Returns -/// -/// * `Result>` - Pod name or an error -fn pod_create( - km: &mut KubernetesManager, - name: String, - image: String, - labels: Map, -) -> Result> { - let labels_map: Option> = if labels.is_empty() { - None - } else { - Some( - labels - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - }; - - let pod = execute_async(km.pod_create(&name, &image, labels_map, None))?; - Ok(pod.metadata.name.unwrap_or(name)) -} - -/// Create a pod with a single container and environment variables -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the pod -/// * `image` - Container image to use -/// * `labels` - Optional labels as a Map -/// * `env_vars` - Optional environment variables as a Map -/// -/// # Returns -/// -/// * `Result>` - Pod name or an error -fn pod_create_with_env( - km: &mut KubernetesManager, - name: String, - image: String, - labels: Map, - env_vars: Map, -) -> Result> { - let labels_map: Option> = if labels.is_empty() { - None - } else { - Some( - labels - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - }; - - let env_vars_map = convert_rhai_map_to_env_vars(env_vars); - - let pod = execute_async(km.pod_create(&name, &image, labels_map, env_vars_map))?; - Ok(pod.metadata.name.unwrap_or(name)) -} - -/// Create a service -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the service -/// * `selector` - Labels to select pods as a Map -/// * `port` - Port to expose -/// * `target_port` - Target port on pods (optional, defaults to port) -/// -/// # Returns -/// -/// * `Result>` - Service name or an error -fn service_create( - km: &mut KubernetesManager, - name: String, - selector: Map, - port: i64, - target_port: i64, -) -> Result> { - let selector_map: std::collections::HashMap = selector - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(); - - let target_port_opt = if target_port == 0 { - None - } else { - Some(target_port as i32) - }; - let service = - execute_async(km.service_create(&name, selector_map, port as i32, target_port_opt))?; - Ok(service.metadata.name.unwrap_or(name)) -} - -/// Create a deployment -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the deployment -/// * `image` - Container image to use -/// * `replicas` - Number of replicas -/// * `labels` - Optional labels as a Map -/// -/// # Returns -/// -/// * `Result>` - Deployment name or an error -fn deployment_create( - km: &mut KubernetesManager, - name: String, - image: String, - replicas: i64, - labels: Map, - env_vars: Map, -) -> Result> { - let labels_map: Option> = if labels.is_empty() { - None - } else { - Some( - labels - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - }; - - let env_vars_map = convert_rhai_map_to_env_vars(env_vars); - - let deployment = execute_async(km.deployment_create( - &name, - &image, - replicas as i32, - labels_map, - env_vars_map, - ))?; - Ok(deployment.metadata.name.unwrap_or(name)) -} - -/// Create a ConfigMap -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the ConfigMap -/// * `data` - Data as a Map -/// -/// # Returns -/// -/// * `Result>` - ConfigMap name or an error -fn configmap_create( - km: &mut KubernetesManager, - name: String, - data: Map, -) -> Result> { - let data_map: std::collections::HashMap = data - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(); - - let configmap = execute_async(km.configmap_create(&name, data_map))?; - Ok(configmap.metadata.name.unwrap_or(name)) -} - -/// Create a Secret -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the Secret -/// * `data` - Data as a Map (will be base64 encoded) -/// * `secret_type` - Type of secret (optional, defaults to "Opaque") -/// -/// # Returns -/// -/// * `Result>` - Secret name or an error -fn secret_create( - km: &mut KubernetesManager, - name: String, - data: Map, - secret_type: String, -) -> Result> { - let data_map: std::collections::HashMap = data - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(); - - let secret_type_opt = if secret_type.is_empty() { - None - } else { - Some(secret_type.as_str()) - }; - let secret = execute_async(km.secret_create(&name, data_map, secret_type_opt))?; - Ok(secret.metadata.name.unwrap_or(name)) -} - -/// Get a pod by name -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the pod to get -/// -/// # Returns -/// -/// * `Result>` - Pod name or an error -fn pod_get(km: &mut KubernetesManager, name: String) -> Result> { - let pod = execute_async(km.pod_get(&name))?; - Ok(pod.metadata.name.unwrap_or(name)) -} - -/// Get a service by name -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the service to get -/// -/// # Returns -/// -/// * `Result>` - Service name or an error -fn service_get(km: &mut KubernetesManager, name: String) -> Result> { - let service = execute_async(km.service_get(&name))?; - Ok(service.metadata.name.unwrap_or(name)) -} - -/// Get a deployment by name -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the deployment to get -/// -/// # Returns -/// -/// * `Result>` - Deployment name or an error -fn deployment_get(km: &mut KubernetesManager, name: String) -> Result> { - let deployment = execute_async(km.deployment_get(&name))?; - Ok(deployment.metadata.name.unwrap_or(name)) -} - -fn delete(km: &mut KubernetesManager, pattern: String) -> Result> { - let deleted_count = execute_async(km.delete(&pattern))?; - - Ok(deleted_count as i64) -} - -/// Create a namespace (idempotent operation) -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// * `name` - The name of the namespace to create -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn namespace_create(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.namespace_create(&name)) -} - -/// Delete a namespace (destructive operation) -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the namespace to delete -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn namespace_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.namespace_delete(&name)) -} - -/// Check if a namespace exists -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// * `name` - The name of the namespace to check -/// -/// # Returns -/// -/// * `Result>` - True if namespace exists, false otherwise -fn namespace_exists(km: &mut KubernetesManager, name: String) -> Result> { - execute_async(km.namespace_exists(&name)) -} - -/// List all namespaces -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Array of namespace names or an error -fn namespaces_list(km: &mut KubernetesManager) -> Result> { - let namespaces = execute_async(km.namespaces_list())?; - - let namespace_names: Array = namespaces - .iter() - .filter_map(|ns| ns.metadata.name.as_ref()) - .map(|name| Dynamic::from(name.clone())) - .collect(); - - Ok(namespace_names) -} - -/// Get resource counts for the namespace -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `Result>` - Map of resource counts by type or an error -fn resource_counts(km: &mut KubernetesManager) -> Result> { - let counts = execute_async(km.resource_counts())?; - - let mut rhai_map = Map::new(); - for (key, value) in counts { - rhai_map.insert(key.into(), Dynamic::from(value as i64)); - } - - Ok(rhai_map) -} - -/// Deploy a complete application with deployment and service -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the application -/// * `image` - Container image to use -/// * `replicas` - Number of replicas -/// * `port` - Port the application listens on -/// * `labels` - Optional labels as a Map -/// * `env_vars` - Optional environment variables as a Map -/// -/// # Returns -/// -/// * `Result>` - Success message or an error -fn deploy_application( - km: &mut KubernetesManager, - name: String, - image: String, - replicas: i64, - port: i64, - labels: Map, - env_vars: Map, -) -> Result> { - let labels_map: Option> = if labels.is_empty() { - None - } else { - Some( - labels - .into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - }; - - let env_vars_map = convert_rhai_map_to_env_vars(env_vars); - - execute_async(km.deploy_application( - &name, - &image, - replicas as i32, - port as i32, - labels_map, - env_vars_map, - ))?; - - Ok(format!("Successfully deployed application '{name}'")) -} - -/// Delete a specific pod by name -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// * `name` - The name of the pod to delete -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn pod_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.pod_delete(&name)) -} - -/// Delete a specific service by name -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// * `name` - The name of the service to delete -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn service_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.service_delete(&name)) -} - -/// Delete a specific deployment by name -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// * `name` - The name of the deployment to delete -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn deployment_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.deployment_delete(&name)) -} - -/// Delete a ConfigMap by name -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the ConfigMap to delete -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn configmap_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.configmap_delete(&name)) -} - -/// Delete a Secret by name -/// -/// # Arguments -/// -/// * `km` - Mutable reference to KubernetesManager -/// * `name` - Name of the Secret to delete -/// -/// # Returns -/// -/// * `Result<(), Box>` - Success or an error -fn secret_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { - execute_async(km.secret_delete(&name)) -} - -/// Get the namespace this manager operates on -/// -/// # Arguments -/// -/// * `km` - The KubernetesManager instance -/// -/// # Returns -/// -/// * `String` - The namespace name -fn kubernetes_manager_namespace(km: &mut KubernetesManager) -> String { - km.namespace().to_string() +/// Helper function for error conversion +fn kubernetes_error_to_rhai_error(error: KubernetesError) -> Box { + Box::new(EvalAltResult::ErrorRuntime( + format!("Kubernetes error: {error}").into(), + rhai::Position::NONE, + )) } /// Register Kubernetes module functions with the Rhai engine @@ -720,10 +127,293 @@ pub fn register_kubernetes_module(engine: &mut Engine) -> Result<(), Box Box { - Box::new(EvalAltResult::ErrorRuntime( - format!("Kubernetes error: {error}").into(), - rhai::Position::NONE, - )) +// KubernetesManager constructor and methods +fn kubernetes_manager_new(namespace: String) -> Result> { + execute_async(KubernetesManager::new(namespace)) +} + +fn kubernetes_manager_namespace(km: &mut KubernetesManager) -> String { + km.namespace().to_string() +} + +// Resource listing functions +fn pods_list(km: &mut KubernetesManager) -> Result> { + let pods = execute_async(km.pods_list())?; + let pod_names: Array = pods + .iter() + .filter_map(|pod| pod.metadata.name.as_ref()) + .map(|name| Dynamic::from(name.clone())) + .collect(); + Ok(pod_names) +} + +fn services_list(km: &mut KubernetesManager) -> Result> { + let services = execute_async(km.services_list())?; + let service_names: Array = services + .iter() + .filter_map(|service| service.metadata.name.as_ref()) + .map(|name| Dynamic::from(name.clone())) + .collect(); + Ok(service_names) +} + +fn deployments_list(km: &mut KubernetesManager) -> Result> { + let deployments = execute_async(km.deployments_list())?; + let deployment_names: Array = deployments + .iter() + .filter_map(|deployment| deployment.metadata.name.as_ref()) + .map(|name| Dynamic::from(name.clone())) + .collect(); + Ok(deployment_names) +} + +fn configmaps_list(km: &mut KubernetesManager) -> Result> { + let configmaps = execute_async(km.configmaps_list())?; + let configmap_names: Array = configmaps + .iter() + .filter_map(|configmap| configmap.metadata.name.as_ref()) + .map(|name| Dynamic::from(name.clone())) + .collect(); + Ok(configmap_names) +} + +fn secrets_list(km: &mut KubernetesManager) -> Result> { + let secrets = execute_async(km.secrets_list())?; + let secret_names: Array = secrets + .iter() + .filter_map(|secret| secret.metadata.name.as_ref()) + .map(|name| Dynamic::from(name.clone())) + .collect(); + Ok(secret_names) +} + +// Resource creation functions +fn pod_create( + km: &mut KubernetesManager, + name: String, + image: String, + labels: Map, +) -> Result> { + let labels_map: Option> = if labels.is_empty() { + None + } else { + Some( + labels + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + ) + }; + let pod = execute_async(km.pod_create(&name, &image, labels_map, None))?; + Ok(pod.metadata.name.unwrap_or(name)) +} + +fn pod_create_with_env( + km: &mut KubernetesManager, + name: String, + image: String, + labels: Map, + env_vars: Map, +) -> Result> { + let labels_map: Option> = if labels.is_empty() { + None + } else { + Some( + labels + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + ) + }; + let env_vars_map = convert_rhai_map_to_env_vars(env_vars); + let pod = execute_async(km.pod_create(&name, &image, labels_map, env_vars_map))?; + Ok(pod.metadata.name.unwrap_or(name)) +} + +fn service_create( + km: &mut KubernetesManager, + name: String, + selector: Map, + port: i64, + target_port: i64, +) -> Result> { + let selector_map: std::collections::HashMap = selector + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + let target_port_opt = if target_port == 0 { + None + } else { + Some(target_port as i32) + }; + let service = + execute_async(km.service_create(&name, selector_map, port as i32, target_port_opt))?; + Ok(service.metadata.name.unwrap_or(name)) +} + +fn deployment_create( + km: &mut KubernetesManager, + name: String, + image: String, + replicas: i64, + labels: Map, + env_vars: Map, +) -> Result> { + let labels_map: Option> = if labels.is_empty() { + None + } else { + Some( + labels + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + ) + }; + let env_vars_map = convert_rhai_map_to_env_vars(env_vars); + let deployment = execute_async(km.deployment_create( + &name, + &image, + replicas as i32, + labels_map, + env_vars_map, + ))?; + Ok(deployment.metadata.name.unwrap_or(name)) +} + +fn configmap_create( + km: &mut KubernetesManager, + name: String, + data: Map, +) -> Result> { + let data_map: std::collections::HashMap = data + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + let configmap = execute_async(km.configmap_create(&name, data_map))?; + Ok(configmap.metadata.name.unwrap_or(name)) +} + +fn secret_create( + km: &mut KubernetesManager, + name: String, + data: Map, + secret_type: String, +) -> Result> { + let data_map: std::collections::HashMap = data + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + let secret_type_opt = if secret_type.is_empty() { + None + } else { + Some(secret_type.as_str()) + }; + let secret = execute_async(km.secret_create(&name, data_map, secret_type_opt))?; + Ok(secret.metadata.name.unwrap_or(name)) +} + +// Resource get functions +fn pod_get(km: &mut KubernetesManager, name: String) -> Result> { + let pod = execute_async(km.pod_get(&name))?; + Ok(pod.metadata.name.unwrap_or(name)) +} + +fn service_get(km: &mut KubernetesManager, name: String) -> Result> { + let service = execute_async(km.service_get(&name))?; + Ok(service.metadata.name.unwrap_or(name)) +} + +fn deployment_get(km: &mut KubernetesManager, name: String) -> Result> { + let deployment = execute_async(km.deployment_get(&name))?; + Ok(deployment.metadata.name.unwrap_or(name)) +} + +// Resource deletion functions +fn delete(km: &mut KubernetesManager, pattern: String) -> Result> { + let deleted_count = execute_async(km.delete(&pattern))?; + Ok(deleted_count as i64) +} + +fn pod_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.pod_delete(&name)) +} + +fn service_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.service_delete(&name)) +} + +fn deployment_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.deployment_delete(&name)) +} + +fn configmap_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.configmap_delete(&name)) +} + +fn secret_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.secret_delete(&name)) +} + +// Namespace management functions +fn namespace_create(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.namespace_create(&name)) +} + +fn namespace_delete(km: &mut KubernetesManager, name: String) -> Result<(), Box> { + execute_async(km.namespace_delete(&name)) +} + +fn namespace_exists(km: &mut KubernetesManager, name: String) -> Result> { + execute_async(km.namespace_exists(&name)) +} + +fn namespaces_list(km: &mut KubernetesManager) -> Result> { + let namespaces = execute_async(km.namespaces_list())?; + let namespace_names: Array = namespaces + .iter() + .filter_map(|ns| ns.metadata.name.as_ref()) + .map(|name| Dynamic::from(name.clone())) + .collect(); + Ok(namespace_names) +} + +// Utility and convenience functions +fn resource_counts(km: &mut KubernetesManager) -> Result> { + let counts = execute_async(km.resource_counts())?; + let mut rhai_map = Map::new(); + for (key, value) in counts { + rhai_map.insert(key.into(), Dynamic::from(value as i64)); + } + Ok(rhai_map) +} + +fn deploy_application( + km: &mut KubernetesManager, + name: String, + image: String, + replicas: i64, + port: i64, + labels: Map, + env_vars: Map, +) -> Result> { + let labels_map: Option> = if labels.is_empty() { + None + } else { + Some( + labels + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + ) + }; + let env_vars_map = convert_rhai_map_to_env_vars(env_vars); + execute_async(km.deploy_application( + &name, + &image, + replicas as i32, + port as i32, + labels_map, + env_vars_map, + ))?; + Ok(format!("Successfully deployed application '{name}'")) }