From c631ec834f410a359acffe32ed85cb61a78f0ccf Mon Sep 17 00:00:00 2001 From: Kevin Pullin Date: Sun, 21 Feb 2021 10:43:47 -0800 Subject: [PATCH 1/3] kube-config - Allow arbitrary 'extension' objects Prior to this change the type of `NamedExtension.extension` was `String`. However, the k8s golang type defines this as a `runtime.RawExtension`, which allows for setting arbitrary objects as the value of the extension key. For example, minikube sets the value to: ``` - extension: last-update: 'Thu, 18 Feb 2021 16:59:26 PST' provider: minikube.sigs.k8s.io version: v1.17.1 name: context_info ``` When `kube-rs` tries to parse this as a `String` you'll end up with an error like this: ``` thread 'config::file_config::tests::kubeconfig_deserialize' panicked at 'called `Result::unwrap()` on an `Err` value: ParseYaml(Message("invalid type: map, expected a string", Some(Pos { marker: Marker { index: 312, line: 12, col: 23 }, path: "clusters[1].cluster.extensions[0].extension" })))', kube/src/config/file_config.rs:407:14 ``` This PR changes the type from `String` to `serde_yaml::Value` to allow for parsing, reading, writing, and round-tripping any valid yaml value." --- kube/src/config/file_config.rs | 79 +++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/kube/src/config/file_config.rs b/kube/src/config/file_config.rs index f26985103..53055da3c 100644 --- a/kube/src/config/file_config.rs +++ b/kube/src/config/file_config.rs @@ -38,7 +38,7 @@ pub struct Preferences { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NamedExtension { pub name: String, - pub extension: String, + pub extension: serde_yaml::Mapping, } /// NamedCluster associates name with cluster. @@ -52,12 +52,17 @@ pub struct NamedCluster { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Cluster { pub server: String, + #[serde(rename = "tls-server-name")] + pub tls_server_name: Option, #[serde(rename = "insecure-skip-tls-verify")] pub insecure_skip_tls_verify: Option, #[serde(rename = "certificate-authority")] pub certificate_authority: Option, #[serde(rename = "certificate-authority-data")] pub certificate_authority_data: Option, + #[serde(rename = "proxy-url")] + pub proxy_url: Option, + pub extensions: Option>, } /// NamedAuthInfo associates name with authentication. @@ -289,6 +294,7 @@ impl AuthInfo { #[cfg(test)] mod tests { use super::*; + use serde_yaml::Value; #[test] fn kubeconfig_merge() { @@ -336,4 +342,75 @@ mod tests { // New named auth info is appended assert_eq!(merged.auth_infos[1].name, "green-user".to_owned()); } + + #[test] + fn kubeconfig_deserialize() { + let config_yaml = "apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: LS0tLS0tLQo= + server: https://ABCDEF0123456789.gr7.us-west-2.eks.amazonaws.com + name: eks +- cluster: + certificate-authority: /home/kevin/.minikube/ca.crt + extensions: + - extension: + last-update: Thu, 18 Feb 2021 16:59:26 PST + provider: minikube.sigs.k8s.io + version: v1.17.1 + name: cluster_info + server: https://192.168.49.2:8443 + name: minikube +contexts: +- context: + cluster: minikube + extensions: + - extension: + last-update: Thu, 18 Feb 2021 16:59:26 PST + provider: minikube.sigs.k8s.io + version: v1.17.1 + name: context_info + namespace: default + user: minikube + name: minikube +- context: + cluster: arn:aws:eks:us-west-2:012345678912:cluster/eks + user: arn:aws:eks:us-west-2:012345678912:cluster/eks + name: eks +current-context: minikube +kind: Config +preferences: {} +users: +- name: arn:aws:eks:us-west-2:012345678912:cluster/eks + user: + exec: + apiVersion: client.authentication.k8s.io/v1alpha1 + args: + - --region + - us-west-2 + - eks + - get-token + - --cluster-name + - eks + command: aws + env: null + provideClusterInfo: false +- name: minikube + user: + client-certificate: /home/kevin/.minikube/profiles/minikube/client.crt + client-key: /home/kevin/.minikube/profiles/minikube/client.key"; + + let config: Kubeconfig = serde_yaml::from_str(config_yaml) + .map_err(ConfigError::ParseYaml) + .unwrap(); + + assert_eq!(config.clusters[0].name, "eks"); + assert_eq!(config.clusters[1].name, "minikube"); + assert_eq!( + config.clusters[1].cluster.extensions.as_ref().unwrap()[0] + .extension + .get(&Value::String("provider".to_owned())), + Some(&Value::String("minikube.sigs.k8s.io".to_owned())) + ); + } } From d713f488e407bd6a43ecc523fa95217477846823 Mon Sep 17 00:00:00 2001 From: Kevin Pullin Date: Sun, 21 Feb 2021 12:10:30 -0800 Subject: [PATCH 2/3] kube-config - set 'extensions' type to 'serde_json' Change the `extensions` type from `serde_yaml::Mapping` to `serde_json::Value`. --- kube/src/config/file_config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kube/src/config/file_config.rs b/kube/src/config/file_config.rs index 53055da3c..5938369fa 100644 --- a/kube/src/config/file_config.rs +++ b/kube/src/config/file_config.rs @@ -38,7 +38,7 @@ pub struct Preferences { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NamedExtension { pub name: String, - pub extension: serde_yaml::Mapping, + pub extension: serde_json::Value, } /// NamedCluster associates name with cluster. @@ -294,7 +294,7 @@ impl AuthInfo { #[cfg(test)] mod tests { use super::*; - use serde_yaml::Value; + use serde_json::Value; #[test] fn kubeconfig_merge() { @@ -409,7 +409,7 @@ users: assert_eq!( config.clusters[1].cluster.extensions.as_ref().unwrap()[0] .extension - .get(&Value::String("provider".to_owned())), + .get("provider"), Some(&Value::String("minikube.sigs.k8s.io".to_owned())) ); } From d914e63bda2d35ccf0bb59eb4d713033f14432e8 Mon Sep 17 00:00:00 2001 From: Kevin Pullin Date: Sun, 21 Feb 2021 14:01:36 -0800 Subject: [PATCH 3/3] kube-config - Remove unsupported Cluster fields --- kube/src/config/file_config.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kube/src/config/file_config.rs b/kube/src/config/file_config.rs index 5938369fa..f485c94ed 100644 --- a/kube/src/config/file_config.rs +++ b/kube/src/config/file_config.rs @@ -52,16 +52,12 @@ pub struct NamedCluster { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Cluster { pub server: String, - #[serde(rename = "tls-server-name")] - pub tls_server_name: Option, #[serde(rename = "insecure-skip-tls-verify")] pub insecure_skip_tls_verify: Option, #[serde(rename = "certificate-authority")] pub certificate_authority: Option, #[serde(rename = "certificate-authority-data")] pub certificate_authority_data: Option, - #[serde(rename = "proxy-url")] - pub proxy_url: Option, pub extensions: Option>, }