k8s_sync/config/
mod.rs

1pub mod utils;
2
3use crate::errors::KubernetesError;
4use serde::{Deserialize, Serialize};
5use serde_yaml;
6use std::collections::HashMap;
7use std::fs::File;
8use std::path::PathBuf;
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
11pub struct KubeConfig {
12    pub kind: Option<String>,
13    #[serde(rename = "apiVersion")]
14    pub api_version: Option<String>,
15    pub preferences: Option<Preferences>,
16    pub clusters: Vec<NamedCluster>,
17    #[serde(rename = "users")]
18    pub auth_infos: Vec<NamedAuthInfo>,
19    pub contexts: Vec<NamedContext>,
20    #[serde(rename = "current-context")]
21    pub current_context: String,
22    pub extensions: Option<Vec<NamedExtension>>,
23}
24
25impl KubeConfig {
26    pub fn load(path: Option<String>) -> Result<Self, KubernetesError> {
27        let mut kubeconfig_path = PathBuf::new();
28        match path {
29            Some(p) => kubeconfig_path.push(p),
30            None => kubeconfig_path.push("~/.kube/config"),
31        }
32        let f =
33            File::open(kubeconfig_path).map_err(|err| KubernetesError::IoError { source: err })?;
34        println!("Loading conf with serde");
35        let config = serde_yaml::from_reader(f).map_err(|_| KubernetesError::ConfigLoadError)?;
36        Ok(config)
37    }
38}
39
40/// Preferences stores extensions for cli.
41#[derive(Clone, Debug, Serialize, Deserialize)]
42pub struct Preferences {
43    pub colors: Option<bool>,
44    pub extensions: Option<Vec<NamedExtension>>,
45}
46
47/// NamedExtension associates name with extension.
48#[derive(Clone, Debug, Serialize, Deserialize)]
49pub struct NamedExtension {
50    pub name: String,
51    pub extension: String,
52}
53
54/// NamedCluster associates name with cluster.
55#[derive(Clone, Debug, Serialize, Deserialize)]
56pub struct NamedCluster {
57    pub name: String,
58    pub cluster: Cluster,
59}
60
61/// Cluster stores information to connect kubernetes cluster.
62#[derive(Clone, Debug, Serialize, Deserialize)]
63pub struct Cluster {
64    pub server: String,
65    #[serde(rename = "insecure-skip-tls-verify")]
66    pub insecure_skip_tls_verify: Option<bool>,
67    #[serde(rename = "certificate-authority")]
68    pub certificate_authority: Option<String>,
69    #[serde(rename = "certificate-authority-data")]
70    pub certificate_authority_data: Option<String>,
71}
72
73/// NamedAuthInfo associates name with authentication.
74#[derive(Clone, Debug, Serialize, Deserialize)]
75pub struct NamedAuthInfo {
76    pub name: String,
77    #[serde(rename = "user")]
78    pub auth_info: AuthInfo,
79}
80
81/// AuthInfo stores information to tell cluster who you are.
82#[derive(Clone, Debug, Serialize, Deserialize)]
83pub struct AuthInfo {
84    pub username: Option<String>,
85    pub password: Option<String>,
86
87    pub token: Option<String>,
88    #[serde(rename = "tokenFile")]
89    pub token_file: Option<String>,
90
91    #[serde(rename = "client-certificate")]
92    pub client_certificate: Option<String>,
93    #[serde(rename = "client-certificate-data")]
94    pub client_certificate_data: Option<String>,
95
96    #[serde(rename = "client-key")]
97    pub client_key: Option<String>,
98    #[serde(rename = "client-key-data")]
99    pub client_key_data: Option<String>,
100
101    #[serde(rename = "as")]
102    pub impersonate: Option<String>,
103    #[serde(rename = "as-groups")]
104    pub impersonate_groups: Option<Vec<String>>,
105
106    #[serde(rename = "auth-provider")]
107    pub auth_provider: Option<AuthProviderConfig>,
108
109    pub exec: Option<ExecConfig>,
110}
111
112/// AuthProviderConfig stores auth for specified cloud provider.
113#[derive(Clone, Debug, Serialize, Deserialize)]
114pub struct AuthProviderConfig {
115    pub name: String,
116    pub config: HashMap<String, String>,
117}
118
119/// ExecConfig stores credential-plugin configuration.
120#[derive(Clone, Debug, Serialize, Deserialize)]
121pub struct ExecConfig {
122    #[serde(rename = "apiVersion")]
123    pub api_version: Option<String>,
124    pub args: Option<Vec<String>>,
125    pub command: String,
126    pub env: Option<Vec<HashMap<String, String>>>,
127}
128
129/// NamedContext associates name with context.
130#[derive(Clone, Debug, Serialize, Deserialize)]
131pub struct NamedContext {
132    pub name: String,
133    pub context: Context,
134}
135
136/// Context stores tuple of cluster and user information.
137#[derive(Clone, Debug, Serialize, Deserialize)]
138pub struct Context {
139    pub cluster: String,
140    pub user: String,
141    pub namespace: Option<String>,
142    pub extensions: Option<Vec<NamedExtension>>,
143}
144
145impl Cluster {
146    pub fn load_certificate_authority(&self) -> Option<Result<Vec<u8>, KubernetesError>> {
147        if self.certificate_authority_data.is_some() || self.certificate_authority.is_some() {
148            Some(utils::data_or_file_with_base64(
149                &self.certificate_authority_data,
150                &self.certificate_authority,
151            ))
152        } else {
153            None
154        }
155    }
156}
157
158impl AuthInfo {
159    pub fn load_client_certificate(&self) -> Result<Vec<u8>, KubernetesError> {
160        utils::data_or_file_with_base64(&self.client_certificate_data, &self.client_certificate)
161    }
162
163    pub fn load_client_key(&self) -> Result<Vec<u8>, KubernetesError> {
164        utils::data_or_file_with_base64(&self.client_key_data, &self.client_key)
165    }
166}