Skip to content

Commit

Permalink
support multi-doc kubeconfigs - fixes #440
Browse files Browse the repository at this point in the history
  • Loading branch information
clux committed Feb 27, 2021
1 parent a2d33fb commit 451429c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 25 deletions.
2 changes: 1 addition & 1 deletion examples/Cargo.toml
Expand Up @@ -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"] }
Expand Down
2 changes: 1 addition & 1 deletion kube-derive/Cargo.toml
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion kube/Cargo.toml
Expand Up @@ -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"
Expand Down
58 changes: 36 additions & 22 deletions 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};

Expand Down Expand Up @@ -139,40 +139,54 @@ const KUBECONFIG: &str = "KUBECONFIG";
impl Kubeconfig {
/// Read a Config from an arbitrary location
pub fn read_from<P: AsRef<Path>>(path: P) -> Result<Kubeconfig> {
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<Kubeconfig> = 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.
Expand Down

0 comments on commit 451429c

Please sign in to comment.