Skip to content

Commit df4d5dc

Browse files
billprattbrendandburns
authored andcommitted
Make LoadKubeConfig public and refactor to use YAML helper methods (#133)
* Made LoadKubeConfig public and refactored to use YAML helper methods * Addressing Code review feedback
1 parent ea62ca0 commit df4d5dc

File tree

6 files changed

+192
-72
lines changed

6 files changed

+192
-72
lines changed

src/KubernetesClient/KubeConfigModels/ClusterEndpoint.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ public class ClusterEndpoint
1111
/// <summary>
1212
/// Gets or sets the path to a cert file for the certificate authority.
1313
/// </summary>
14-
[YamlMember(Alias = "certificate-authority")]
14+
[YamlMember(Alias = "certificate-authority", ApplyNamingConventions = false)]
1515
public string CertificateAuthority {get; set; }
1616

1717
/// <summary>
1818
/// Gets or sets =PEM-encoded certificate authority certificates. Overrides <see cref="CertificateAuthority"/>.
1919
/// </summary>
20-
[YamlMember(Alias = "certificate-authority-data")]
20+
[YamlMember(Alias = "certificate-authority-data", ApplyNamingConventions = false)]
2121
public string CertificateAuthorityData { get; set; }
2222

2323
/// <summary>
@@ -30,7 +30,7 @@ public class ClusterEndpoint
3030
/// Gets or sets a value indicating whether to skip the validity check for the server's certificate.
3131
/// This will make your HTTPS connections insecure.
3232
/// </summary>
33-
[YamlMember(Alias = "insecure-skip-tls-verify")]
33+
[YamlMember(Alias = "insecure-skip-tls-verify", ApplyNamingConventions = false)]
3434
public bool SkipTlsVerify { get; set; }
3535

3636
/// <summary>

src/KubernetesClient/KubeConfigModels/K8SConfiguration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class K8SConfiguration
2727
/// <summary>
2828
/// Gets or sets the name of the context that you would like to use by default.
2929
/// </summary>
30-
[YamlMember(Alias = "current-context")]
30+
[YamlMember(Alias = "current-context", ApplyNamingConventions = false)]
3131
public string CurrentContext { get; set; }
3232

3333
/// <summary>

src/KubernetesClient/KubeConfigModels/UserCredentials.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@ public class UserCredentials
1212
/// <summary>
1313
/// Gets or sets PEM-encoded data from a client cert file for TLS. Overrides <see cref="ClientCertificate"/>.
1414
/// </summary>
15-
[YamlMember(Alias = "client-certificate-data")]
15+
[YamlMember(Alias = "client-certificate-data", ApplyNamingConventions = false)]
1616
public string ClientCertificateData { get; set; }
1717

1818
/// <summary>
1919
/// Gets or sets the path to a client cert file for TLS.
2020
/// </summary>
21-
[YamlMember(Alias = "client-certificate")]
21+
[YamlMember(Alias = "client-certificate", ApplyNamingConventions = false)]
2222
public string ClientCertificate { get; set; }
2323

2424
/// <summary>
2525
/// Gets or sets PEM-encoded data from a client key file for TLS. Overrides <see cref="ClientKey"/>.
2626
/// </summary>
27-
[YamlMember(Alias = "client-key-data")]
27+
[YamlMember(Alias = "client-key-data", ApplyNamingConventions = false)]
2828
public string ClientKeyData { get; set; }
2929

3030
/// <summary>
3131
/// Gets or sets the path to a client key file for TLS.
3232
/// </summary>
33-
[YamlMember(Alias = "client-key")]
33+
[YamlMember(Alias = "client-key", ApplyNamingConventions = false)]
3434
public string ClientKey { get; set; }
3535

3636
/// <summary>
@@ -48,13 +48,13 @@ public class UserCredentials
4848
/// <summary>
4949
/// Gets or sets the groups to imperonate.
5050
/// </summary>
51-
[YamlMember(Alias = "as-groups")]
51+
[YamlMember(Alias = "as-groups", ApplyNamingConventions = false)]
5252
public IEnumerable<string> ImpersonateGroups { get; set; } = new string[0];
5353

5454
/// <summary>
5555
/// Gets or sets additional information for impersonated user.
5656
/// </summary>
57-
[YamlMember(Alias = "as-user-extra")]
57+
[YamlMember(Alias = "as-user-extra", ApplyNamingConventions = false)]
5858
public Dictionary<string, string> ImpersonateUserExtra { get; set; } = new Dictionary<string, string>();
5959

6060
/// <summary>
@@ -72,7 +72,7 @@ public class UserCredentials
7272
/// <summary>
7373
/// Gets or sets custom authentication plugin for the kubernetes cluster.
7474
/// </summary>
75-
[YamlMember(Alias = "auth-provider")]
75+
[YamlMember(Alias = "auth-provider", ApplyNamingConventions = false)]
7676
public Dictionary<string, dynamic> AuthProvider { get; set; }
7777

7878
/// <summary>

src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
using System.Linq;
44
using System.Runtime.InteropServices;
55
using System.Security.Cryptography.X509Certificates;
6+
using System.Threading.Tasks;
67
using k8s.Exceptions;
78
using k8s.KubeConfigModels;
8-
using YamlDotNet.Serialization;
9-
9+
1010
namespace k8s
1111
{
1212
public partial class KubernetesClientConfiguration
@@ -28,9 +28,9 @@ public partial class KubernetesClientConfiguration
2828
/// Initializes a new instance of the <see cref="KubernetesClientConfiguration" /> from config file
2929
/// </summary>
3030
/// <param name="masterUrl">kube api server endpoint</param>
31-
/// <param name="kubeconfigPath">kubeconfig filepath</param>
32-
public static KubernetesClientConfiguration BuildConfigFromConfigFile(string masterUrl = null,
33-
string kubeconfigPath = null)
31+
/// <param name="kubeconfigPath">Explicit file path to kubeconfig. Set to null to use the default file path</param>
32+
public static KubernetesClientConfiguration BuildConfigFromConfigFile(string kubeconfigPath,
33+
string currentContext = null, string masterUrl = null)
3434
{
3535
return BuildConfigFromConfigFile(new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation), null,
3636
masterUrl);
@@ -55,25 +55,6 @@ public static KubernetesClientConfiguration BuildConfigFromConfigFile(FileInfo k
5555
return k8SConfiguration;
5656
}
5757

58-
/// <summary>
59-
/// </summary>
60-
/// <param name="kubeconfig">Fileinfo of the kubeconfig, cannot be null, whitespaced or empty</param>
61-
/// <param name="currentContext">override the context in config file, set null if do not want to override</param>
62-
/// <param name="masterUrl">overrider kube api server endpoint, set null if do not want to override</param>
63-
public static KubernetesClientConfiguration BuildConfigFromConfigFile(string kubeconfig,
64-
string currentContext = null, string masterUrl = null)
65-
{
66-
if (string.IsNullOrWhiteSpace(kubeconfig))
67-
{
68-
throw new NullReferenceException(nameof(kubeconfig));
69-
}
70-
71-
var k8SConfig = LoadKubeConfig(kubeconfig);
72-
var k8SConfiguration = GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
73-
74-
return k8SConfiguration;
75-
}
76-
7758
/// <summary>
7859
/// </summary>
7960
/// <param name="kubeconfig">Fileinfo of the kubeconfig, cannot be null, whitespaced or empty</param>
@@ -94,7 +75,7 @@ public static KubernetesClientConfiguration BuildConfigFromConfigFile(Stream kub
9475

9576
kubeconfig.Position = 0;
9677

97-
var k8SConfig = LoadKubeConfig(kubeconfig);
78+
var k8SConfig = Yaml.LoadFromStreamAsync<K8SConfiguration>(kubeconfig).GetAwaiter().GetResult();
9879
var k8SConfiguration = GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
9980

10081
return k8SConfiguration;
@@ -259,53 +240,76 @@ private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext)
259240
throw new KubeConfigException(
260241
$"User: {userDetails.Name} does not have appropriate auth credentials in kubeconfig");
261242
}
262-
}
263-
243+
}
244+
264245
/// <summary>
246+
/// Loads entire Kube Config from default or explicit file path
247+
/// </summary>
248+
/// <param name="kubeconfigPath">Explicit file path to kubeconfig. Set to null to use the default file path</param>
249+
/// <returns></returns>
250+
public static async Task<K8SConfiguration> LoadKubeConfigAsync(string kubeconfigPath = null)
251+
{
252+
var fileInfo = new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation);
253+
254+
return await LoadKubeConfigAsync(fileInfo);
255+
}
256+
257+
/// <summary>
258+
/// Loads entire Kube Config from default or explicit file path
259+
/// </summary>
260+
/// <param name="kubeconfigPath">Explicit file path to kubeconfig. Set to null to use the default file path</param>
261+
/// <returns></returns>
262+
public static K8SConfiguration LoadKubeConfig(string kubeconfigPath = null)
263+
{
264+
return LoadKubeConfigAsync(kubeconfigPath).GetAwaiter().GetResult();
265+
}
266+
267+
// <summary>
265268
/// Loads Kube Config
266269
/// </summary>
267270
/// <param name="kubeconfig">Kube config file contents</param>
268271
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
269-
private static K8SConfiguration LoadKubeConfig(FileInfo kubeconfig)
272+
public static async Task<K8SConfiguration> LoadKubeConfigAsync(FileInfo kubeconfig)
270273
{
271274
if (!kubeconfig.Exists)
272275
{
273276
throw new KubeConfigException($"kubeconfig file not found at {kubeconfig.FullName}");
274-
}
275-
276-
var deserializeBuilder = new DeserializerBuilder();
277-
var deserializer = deserializeBuilder.Build();
278-
using (var kubeConfigTextStream = kubeconfig.OpenText())
279-
{
280-
return deserializer.Deserialize<K8SConfiguration>(kubeConfigTextStream);
277+
}
278+
279+
using (var stream = kubeconfig.OpenRead())
280+
{
281+
return await Yaml.LoadFromStreamAsync<K8SConfiguration>(stream);
281282
}
282283
}
283284

284285
/// <summary>
285-
/// Loads Kube Config from string
286+
/// Loads Kube Config
286287
/// </summary>
287288
/// <param name="kubeconfig">Kube config file contents</param>
288289
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
289-
private static K8SConfiguration LoadKubeConfig(string kubeconfig)
290-
{
291-
292-
var deserializeBuilder = new DeserializerBuilder();
293-
var deserializer = deserializeBuilder.Build();
294-
return deserializer.Deserialize<K8SConfiguration>(kubeconfig);
290+
public static K8SConfiguration LoadKubeConfig(FileInfo kubeconfig)
291+
{
292+
return LoadKubeConfigAsync(kubeconfig).GetAwaiter().GetResult();
293+
}
294+
295+
// <summary>
296+
/// Loads Kube Config
297+
/// </summary>
298+
/// <param name="kubeconfigStream">Kube config file contents stream</param>
299+
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
300+
public static async Task<K8SConfiguration> LoadKubeConfigAsync(Stream kubeconfigStream)
301+
{
302+
return await Yaml.LoadFromStreamAsync<K8SConfiguration>(kubeconfigStream);
295303
}
296304

297305
/// <summary>
298-
/// Loads Kube Config from stream.
306+
/// Loads Kube Config
299307
/// </summary>
300-
/// <param name="kubeconfig">Kube config file contents</param>
308+
/// <param name="kubeconfig">Kube config file contents stream</param>
301309
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
302-
private static K8SConfiguration LoadKubeConfig(Stream kubeconfig)
310+
public static K8SConfiguration LoadKubeConfig(Stream kubeconfigStream)
303311
{
304-
using (var sr = new StreamReader(kubeconfig))
305-
{
306-
var strKubeConfig = sr.ReadToEnd();
307-
return LoadKubeConfig(strKubeConfig);
308-
}
312+
return LoadKubeConfigAsync(kubeconfigStream).GetAwaiter().GetResult();
309313
}
310314
}
311315
}

tests/KubernetesClient.Tests/CertUtilsTests.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ public class CertUtilsTests
1818
[Fact]
1919
public void LoadFromFiles()
2020
{
21-
var fi = new FileInfo(kubeConfigFileName);
22-
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(fi, "federal-context");
21+
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(kubeConfigFileName, "federal-context");
2322

2423
// Just validate that this doesn't throw and private key is non-null
2524
var cert = CertUtils.GeneratePfx(cfg);
@@ -32,8 +31,7 @@ public void LoadFromFiles()
3231
[Fact]
3332
public void LoadFromInlineData()
3433
{
35-
var fi = new FileInfo(kubeConfigFileName);
36-
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(fi, "victorian-context");
34+
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(kubeConfigFileName, "victorian-context");
3735

3836
// Just validate that this doesn't throw and private key is non-null
3937
var cert = CertUtils.GeneratePfx(cfg);

0 commit comments

Comments
 (0)