kube_client/config/
file_loader.rs1use super::{
2 file_config::{AuthInfo, Cluster, Context, Kubeconfig},
3 KubeconfigError,
4};
5
6#[derive(Default, Clone)]
8pub struct KubeConfigOptions {
9 pub context: Option<String>,
11 pub cluster: Option<String>,
13 pub user: Option<String>,
15}
16
17#[derive(Clone, Debug)]
20pub struct ConfigLoader {
21 pub current_context: Context,
22 pub cluster: Cluster,
23 pub user: AuthInfo,
24}
25
26impl ConfigLoader {
27 pub async fn new_from_options(options: &KubeConfigOptions) -> Result<Self, KubeconfigError> {
29 let config = Kubeconfig::read()?;
30 let loader = Self::load(
31 config,
32 options.context.as_ref(),
33 options.cluster.as_ref(),
34 options.user.as_ref(),
35 )
36 .await?;
37
38 Ok(loader)
39 }
40
41 pub async fn new_from_kubeconfig(
42 config: Kubeconfig,
43 options: &KubeConfigOptions,
44 ) -> Result<Self, KubeconfigError> {
45 let loader = Self::load(
46 config,
47 options.context.as_ref(),
48 options.cluster.as_ref(),
49 options.user.as_ref(),
50 )
51 .await?;
52
53 Ok(loader)
54 }
55
56 pub async fn load(
57 config: Kubeconfig,
58 context: Option<&String>,
59 cluster: Option<&String>,
60 user: Option<&String>,
61 ) -> Result<Self, KubeconfigError> {
62 let context_name = if let Some(name) = context {
63 name
64 } else if let Some(name) = &config.current_context {
65 name
66 } else {
67 return Err(KubeconfigError::CurrentContextNotSet);
68 };
69
70 let current_context = config
71 .contexts
72 .iter()
73 .find(|named_context| &named_context.name == context_name)
74 .and_then(|named_context| named_context.context.clone())
75 .ok_or_else(|| KubeconfigError::LoadContext(context_name.clone()))?;
76
77 let cluster_name = cluster.unwrap_or(¤t_context.cluster);
78 let cluster = config
79 .clusters
80 .iter()
81 .find(|named_cluster| &named_cluster.name == cluster_name)
82 .and_then(|named_cluster| named_cluster.cluster.clone())
83 .ok_or_else(|| KubeconfigError::LoadClusterOfContext(cluster_name.clone()))?;
84
85 let user_name = user.or_else(|| current_context.user.as_ref());
86
87 let mut auth_info = if let Some(user) = user_name {
90 config
91 .auth_infos
92 .iter()
93 .find(|named_user| &named_user.name == user)
94 .and_then(|named_user| named_user.auth_info.clone())
95 .unwrap_or_else(AuthInfo::default)
96 } else {
97 AuthInfo::default()
98 };
99
100 if let Some(exec_config) = &mut auth_info.exec {
101 if exec_config.provide_cluster_info {
102 exec_config.cluster = Some((&cluster).try_into()?);
103 }
104 }
105
106 Ok(ConfigLoader {
107 current_context,
108 cluster,
109 user: auth_info,
110 })
111 }
112
113 pub fn ca_bundle(&self) -> Result<Option<Vec<Vec<u8>>>, KubeconfigError> {
114 if let Some(bundle) = self.cluster.load_certificate_authority()? {
115 Ok(Some(
116 super::certs(&bundle).map_err(KubeconfigError::ParseCertificates)?,
117 ))
118 } else {
119 Ok(None)
120 }
121 }
122
123 pub fn proxy_url(&self) -> Result<Option<http::Uri>, KubeconfigError> {
124 let nonempty = |o: Option<String>| o.filter(|s| !s.is_empty());
125
126 if let Some(proxy) = nonempty(self.cluster.proxy_url.clone())
127 .or_else(|| nonempty(std::env::var("HTTPS_PROXY").ok()))
128 .or_else(|| nonempty(std::env::var("https_proxy").ok()))
129 {
130 Ok(Some(
131 proxy
132 .parse::<http::Uri>()
133 .map_err(KubeconfigError::ParseProxyUrl)?,
134 ))
135 } else {
136 Ok(None)
137 }
138 }
139}