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 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}