kube_forward/
util.rs

1use crate::error::{PortForwardError, Result};
2use k8s_openapi::api::core::v1::Service;
3use kube::{Api, Client};
4
5#[derive(Clone, Debug, PartialEq)]
6pub struct ServiceInfo {
7    pub namespace: String,
8    pub name: String,
9    pub ports: Vec<u16>,
10}
11
12pub async fn resolve_service(client: Client, target: &str) -> Result<ServiceInfo> {
13    let parts: Vec<&str> = target.split('.').collect();
14
15    let client = client.clone();
16    // Fix the temporary value issue by getting the namespace first
17    let default_ns = client.default_namespace();
18    let (service_name, namespace) = match parts.len() {
19        1 => (parts[0], default_ns),
20        2 => (parts[0], parts[1]),
21        _ => parse_full_dns_name(&parts)?,
22    };
23
24    let client = client.clone();
25    let services: Api<Service> = Api::namespaced(client, namespace);
26    let service = services
27        .get(service_name)
28        .await
29        .map_err(PortForwardError::KubeError)?;
30
31    let ports = service
32        .spec
33        .as_ref()
34        .and_then(|spec| spec.ports.as_ref())
35        .map(|ports| ports.iter().map(|port| port.port as u16).collect())
36        .unwrap_or_default();
37
38    Ok(ServiceInfo {
39        namespace: namespace.to_string(),
40        name: service_name.to_string(),
41        ports,
42    })
43}
44
45pub fn parse_full_dns_name<'a>(parts: &'a [&'a str]) -> Result<(&'a str, &'a str)> {
46    if parts.len() >= 2 {
47        Ok((parts[0], parts[1]))
48    } else {
49        Err(PortForwardError::DnsError(
50            "Invalid DNS name format".to_string(),
51        ))
52    }
53}