forked from kube-rs/kube
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file_loader.rs
129 lines (115 loc) · 4.25 KB
/
file_loader.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use super::{
file_config::{AuthInfo, Cluster, Context, Kubeconfig},
KubeconfigError,
};
/// KubeConfigOptions stores options used when loading kubeconfig file.
#[derive(Default, Clone)]
pub struct KubeConfigOptions {
/// The named context to load
pub context: Option<String>,
/// The cluster to load
pub cluster: Option<String>,
/// The user to load
pub user: Option<String>,
}
/// ConfigLoader loads current context, cluster, and authentication information
/// from a kubeconfig file.
#[derive(Clone, Debug)]
pub struct ConfigLoader {
pub current_context: Context,
pub cluster: Cluster,
pub user: AuthInfo,
}
impl ConfigLoader {
/// Returns a config loader based on the cluster information from the kubeconfig file.
pub async fn new_from_options(options: &KubeConfigOptions) -> Result<Self, KubeconfigError> {
let config = Kubeconfig::read()?;
let loader = Self::load(
config,
options.context.as_ref(),
options.cluster.as_ref(),
options.user.as_ref(),
)
.await?;
Ok(loader)
}
pub async fn new_from_kubeconfig(
config: Kubeconfig,
options: &KubeConfigOptions,
) -> Result<Self, KubeconfigError> {
let loader = Self::load(
config,
options.context.as_ref(),
options.cluster.as_ref(),
options.user.as_ref(),
)
.await?;
Ok(loader)
}
pub async fn load(
config: Kubeconfig,
context: Option<&String>,
cluster: Option<&String>,
user: Option<&String>,
) -> Result<Self, KubeconfigError> {
let current_context_name = &config.current_context.clone().unwrap_or_default();
let context_name = if let Some(name) = context {
name
} else {
current_context_name
};
let current_context = config
.contexts
.iter()
.find(|named_context| &named_context.name.clone().unwrap_or_default() == context_name)
.and_then(|named_context| named_context.context.clone())
.ok_or_else(|| KubeconfigError::LoadContext(context_name.clone()))?;
let current_cluster_name = ¤t_context.cluster.clone().unwrap_or_default();
let cluster_name = cluster.unwrap_or(current_cluster_name);
let cluster = config
.clusters
.iter()
.find(|named_cluster| &named_cluster.name.clone().unwrap_or_default() == cluster_name)
.and_then(|named_cluster| named_cluster.cluster.clone())
.ok_or_else(|| KubeconfigError::LoadClusterOfContext(cluster_name.clone()))?;
let current_user_name = ¤t_context.user.clone().unwrap_or_default();
let user_name = user.unwrap_or(¤t_user_name);
let user = config
.auth_infos
.iter()
.find(|named_user| &named_user.name.clone().unwrap_or_default() == user_name)
.and_then(|named_user| named_user.auth_info.clone())
.ok_or_else(|| KubeconfigError::FindUser(user_name.clone()))?;
Ok(ConfigLoader {
current_context: current_context.clone(),
cluster,
user,
})
}
pub fn ca_bundle(&self) -> Result<Option<Vec<Vec<u8>>>, KubeconfigError> {
if let Some(bundle) = self.cluster.load_certificate_authority()? {
Ok(Some(
super::certs(&bundle).map_err(KubeconfigError::ParseCertificates)?,
))
} else {
Ok(None)
}
}
pub fn proxy_url(&self) -> Result<Option<http::Uri>, KubeconfigError> {
let nonempty = |o: Option<String>| o.filter(|s| !s.is_empty());
if let Some(proxy) = nonempty(self.cluster.proxy_url.clone())
.or_else(|| nonempty(std::env::var("HTTP_PROXY").ok()))
.or_else(|| nonempty(std::env::var("http_proxy").ok()))
.or_else(|| nonempty(std::env::var("HTTPS_PROXY").ok()))
.or_else(|| nonempty(std::env::var("https_proxy").ok()))
{
Ok(Some(
proxy
.parse::<http::Uri>()
.map_err(KubeconfigError::ParseProxyUrl)?,
))
} else {
Ok(None)
}
}
}