diff --git a/examples/Cargo.toml b/examples/Cargo.toml index f8590df62..332a4c5f7 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -28,7 +28,7 @@ k8s-openapi = { version = "0.11.0", features = ["v1_20"], default-features = fal log = "0.4.11" serde = { version = "1.0.118", features = ["derive"] } serde_json = "1.0.61" -serde_yaml = "0.8.14" +serde_yaml = "0.8.17" tokio = { version = "1.0.1", features = ["full"] } color-eyre = "0.5.10" snafu = { version = "0.6.10", features = ["futures"] } diff --git a/kube-derive/Cargo.toml b/kube-derive/Cargo.toml index 690751fb6..683dfd7f5 100644 --- a/kube-derive/Cargo.toml +++ b/kube-derive/Cargo.toml @@ -28,7 +28,7 @@ schema = [] [dev-dependencies] serde = { version = "1.0.118", features = ["derive"] } -serde_yaml = "0.8.14" +serde_yaml = "0.8.17" k8s-openapi = { version = "0.11.0", default-features = false, features = ["v1_20"] } schemars = { version = "0.8.0", features = ["chrono"] } chrono = "0.4.19" diff --git a/kube/Cargo.toml b/kube/Cargo.toml index 47744ee6b..91bf80d9b 100644 --- a/kube/Cargo.toml +++ b/kube/Cargo.toml @@ -36,7 +36,7 @@ chrono = "0.4.19" dirs = { package = "dirs-next", version = "2.0.0" } serde = { version = "1.0.118", features = ["derive"] } serde_json = "1.0.61" -serde_yaml = "0.8.14" +serde_yaml = "0.8.17" http = "0.2.2" url = "2.2.0" log = "0.4.11" diff --git a/kube/src/config/file_config.rs b/kube/src/config/file_config.rs index f485c94ed..32943f709 100644 --- a/kube/src/config/file_config.rs +++ b/kube/src/config/file_config.rs @@ -1,6 +1,6 @@ #![allow(missing_docs)] -use std::{collections::HashMap, fs::File, path::Path}; +use std::{collections::HashMap, fs, path::Path}; use crate::{config::utils, error::ConfigError, Result}; @@ -139,40 +139,54 @@ const KUBECONFIG: &str = "KUBECONFIG"; impl Kubeconfig { /// Read a Config from an arbitrary location pub fn read_from>(path: P) -> Result { - let f = File::open(&path).map_err(|source| ConfigError::ReadFile { + let data = fs::read_to_string(&path).map_err(|source| ConfigError::ReadFile { path: path.as_ref().into(), source, })?; - let mut config: Kubeconfig = serde_yaml::from_reader(f).map_err(ConfigError::ParseYaml)?; + // support multiple documents + let mut documents: Vec = vec![]; + for doc in serde_yaml::Deserializer::from_str(&data) { + let value = serde_yaml::Value::deserialize(doc).map_err(ConfigError::ParseYaml)?; + let kconf = serde_yaml::from_value(value).map_err(ConfigError::ParseYaml)?; + documents.push(kconf) + } // Remap all files we read to absolute paths. - if let Some(dir) = path.as_ref().parent() { - for named in config.clusters.iter_mut() { - if let Some(path) = &named.cluster.certificate_authority { - if let Some(abs_path) = to_absolute(dir, path) { - named.cluster.certificate_authority = Some(abs_path); + let mut merged_docs = None; + for mut config in documents { + if let Some(dir) = path.as_ref().parent() { + for named in config.clusters.iter_mut() { + if let Some(path) = &named.cluster.certificate_authority { + if let Some(abs_path) = to_absolute(dir, path) { + named.cluster.certificate_authority = Some(abs_path); + } } } - } - for named in config.auth_infos.iter_mut() { - if let Some(path) = &named.auth_info.client_certificate { - if let Some(abs_path) = to_absolute(dir, path) { - named.auth_info.client_certificate = Some(abs_path); + for named in config.auth_infos.iter_mut() { + if let Some(path) = &named.auth_info.client_certificate { + if let Some(abs_path) = to_absolute(dir, path) { + named.auth_info.client_certificate = Some(abs_path); + } } - } - if let Some(path) = &named.auth_info.client_key { - if let Some(abs_path) = to_absolute(dir, path) { - named.auth_info.client_key = Some(abs_path); + if let Some(path) = &named.auth_info.client_key { + if let Some(abs_path) = to_absolute(dir, path) { + named.auth_info.client_key = Some(abs_path); + } } - } - if let Some(path) = &named.auth_info.token_file { - if let Some(abs_path) = to_absolute(dir, path) { - named.auth_info.token_file = Some(abs_path); + if let Some(path) = &named.auth_info.token_file { + if let Some(abs_path) = to_absolute(dir, path) { + named.auth_info.token_file = Some(abs_path); + } } } } + if let Some(c) = merged_docs { + merged_docs = Some(Kubeconfig::merge(c, config)?); + } else { + merged_docs = Some(config); + } } - Ok(config) + Ok(merged_docs.expect("Need at least one yaml document in KUBECONFIG file")) } /// Read a Config from `KUBECONFIG` or the the default location.