Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/KubernetesClient/KubeConfigModels/Context.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace k8s.KubeConfigModels
{
using System;
using YamlDotNet.Serialization;

/// <summary>
Expand All @@ -19,6 +20,7 @@ public class Context
[YamlMember(Alias = "name")]
public string Name { get; set; }

[Obsolete("This property is not set by the YAML config. Use ContextDetails.Namespace instead.")]
[YamlMember(Alias = "namespace")]
public string Namespace { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion src/KubernetesClient/KubeConfigModels/ContextDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ContextDetails
public string Cluster { get; set; }

/// <summary>
/// Gets or sets the anem of the user for this context.
/// Gets or sets the name of the user for this context.
/// </summary>
[YamlMember(Alias = "user")]
public string User { get; set; }
Expand Down
11 changes: 9 additions & 2 deletions src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ private void InitializeContext(K8SConfiguration k8SConfig, string currentContext
throw new KubeConfigException($"CurrentContext: {currentContext} not found in contexts in kubeconfig");
}

if (string.IsNullOrEmpty(activeContext.ContextDetails?.Cluster))
{
// This serves as validation for any of the properties of ContextDetails being set.
// Other locations in code assume that ContextDetails is non-null.
throw new KubeConfigException($"Cluster not set for context `{currentContext}` in kubeconfig");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this validation because I see a bunch of code running after this at assumes activeContext.ContextDetails is null, and it will crash with a null-ref based on invalid config data.


CurrentContext = activeContext.Name;

// cluster
Expand All @@ -202,7 +209,7 @@ private void InitializeContext(K8SConfiguration k8SConfig, string currentContext
SetUserDetails(k8SConfig, activeContext);

// namespace
Namespace = activeContext.Namespace;
Namespace = activeContext.ContextDetails?.Namespace;
}

private void SetClusterDetails(K8SConfiguration k8SConfig, Context activeContext)
Expand Down Expand Up @@ -254,7 +261,7 @@ private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext)

if (userDetails == null)
{
throw new KubeConfigException("User not found for context {activeContext.Name} in kubeconfig");
throw new KubeConfigException($"User not found for context {activeContext.Name} in kubeconfig");
}

if (userDetails.UserCredentials == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ public void ContextHost(string context, string host)
Assert.Equal(host, cfg.Host);
}

/// <summary>
/// Check if namespace is properly loaded, per context
/// </summary>
[Theory]
[InlineData("federal-context", "chisel-ns")]
[InlineData("queen-anne-context", "saw-ns")]
public void ContextNamespace(string context, string @namespace)
{
var fi = new FileInfo("assets/kubeconfig.yml");
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(fi, context, useRelativePaths: false);
Assert.Equal(@namespace, cfg.Namespace);
}

/// <summary>
/// Checks if user-based token is loaded properly from the config file, per context
/// </summary>
Expand Down Expand Up @@ -190,6 +203,16 @@ public void NoContextsExplicit()
KubernetesClientConfiguration.BuildConfigFromConfigFile(fi, "context"));
}

/// <summary>
/// Checks that a KubeConfigException is thrown when the current context exists but has no details specified
/// </summary>
[Fact]
public void ContextNoDetails()
{
var fi = new FileInfo("assets/kubeconfig.no-context-details.yml");
Assert.Throws<KubeConfigException>(() => KubernetesClientConfiguration.BuildConfigFromConfigFile(fi));
}

/// <summary>
/// Checks that a KubeConfigException is thrown when the server property is not set in cluster
/// </summary>
Expand Down Expand Up @@ -413,7 +436,6 @@ private void AssertConfigEqual(K8SConfiguration expected, K8SConfiguration actua
private void AssertContextEqual(Context expected, Context actual)
{
Assert.Equal(expected.Name, actual.Name);
Assert.Equal(expected.Namespace, actual.Namespace);
Assert.Equal(expected.ContextDetails.Cluster, actual.ContextDetails.Cluster);
Assert.Equal(expected.ContextDetails.User, actual.ContextDetails.User);
Assert.Equal(expected.ContextDetails.Namespace, actual.ContextDetails.Namespace);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
# WARNING: File includes minor fixes
---
current-context: federal-context
apiVersion: v1
clusters:
- cluster:
server: http://cow.org:8080
name: cow-cluster
- cluster:
certificate-authority: assets/ca.crt
server: https://horse.org:4443
name: horse-cluster
- cluster:
insecure-skip-tls-verify: true
server: https://pig.org:443
name: pig-cluster
contexts:
- name: federal-context
kind: Config
users:
- name: blue-user
user:
token: blue-token
- name: green-user
user:
client-certificate: assets/client.crt
client-key: assets/client.key
- name: black-user
user:
token: black-token