diff --git a/README.md b/README.md
index e148315..5e229f1 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,58 @@
# csharp
Work In Progress
-Currently only supported on Linux
[](https://travis-ci.org/kubernetes-client/csharp)
-# Generating the client code
+# Generating the Client Code
## Prerequisites
Check out the generator project into some other directory
(henceforth `$GEN_DIR`)
-```
+```bash
cd $GEN_DIR/..
git clone https://github.com/kubernetes-client/gen
```
Install the [`autorest` tool](https://github.com/azure/autorest):
-```
+```bash
npm install autorest
```
## Generating code
-```
+```bash
# Where REPO_DIR points to the root of the csharp repository
cd ${REPO_DIR}/csharp/src
${GEN_DIR}/openapi/csharp.sh generated csharp.settings
```
-# Testing
+# Usage
+
+## Prerequisities
+
+* [OpenSSL](https://www.openssl.org/)
+* For Linux/Mac:
+ * LibCurl built with OpenSSL (Mac: `brew install curl --with-nghttp2`)
+
+## Running the Examples
+
+```bash
+git clone git@github.com:kubernetes-client/csharp.git
+cd csharp\examples\simple
+dotnet run
+```
+
+## Testing
The project uses [XUnit](https://xunit.github.io) as unit testing framework.
-To run the tests you need to:
+To run the tests
```bash
-cd tests
+cd csharp\tests
dotnet restore
dotnet xunit
```
\ No newline at end of file
diff --git a/src/Kubernetes.Auth.cs b/src/Kubernetes.Auth.cs
index 7ea4fcd..02767a4 100644
--- a/src/Kubernetes.Auth.cs
+++ b/src/Kubernetes.Auth.cs
@@ -71,10 +71,6 @@
!string.IsNullOrWhiteSpace(config.ClientKey)))
{
var pfxFilePath = await Utils.GeneratePfxAsync(config).ConfigureAwait(false);
- if (string.IsNullOrWhiteSpace(pfxFilePath))
- {
- throw new KubernetesClientException("Failed to generate pfx file");
- }
var cert = new X509Certificate2(pfxFilePath, string.Empty, X509KeyStorageFlags.PersistKeySet);
handler.ClientCertificates.Add(cert);
diff --git a/src/KubernetesClientConfiguration.cs b/src/KubernetesClientConfiguration.cs
index 71fcb42..916504e 100644
--- a/src/KubernetesClientConfiguration.cs
+++ b/src/KubernetesClientConfiguration.cs
@@ -16,17 +16,12 @@ namespace k8s
{
///
/// Initializes a new instance of the class.
- /// Initializes a new instance of the ClientConfiguration class
///
/// kubeconfig file info
/// Context to use from kube config
public KubernetesClientConfiguration(FileInfo kubeconfig = null, string currentContext = null)
{
- if (kubeconfig == null)
- {
- kubeconfig = new FileInfo(KubeConfigDefaultLocation);
- }
- var k8SConfig = this.LoadKubeConfig(kubeconfig);
+ var k8SConfig = this.LoadKubeConfig(kubeconfig ?? new FileInfo(KubeConfigDefaultLocation));
this.Initialize(k8SConfig, currentContext);
}
@@ -108,86 +103,73 @@ namespace k8s
/// Current Context
private void Initialize(K8SConfiguration k8SConfig, string currentContext = null)
{
- Context activeContext;
-
if (k8SConfig.Contexts == null)
{
throw new KubeConfigException("No contexts found in kubeconfig");
- }
-
- // set the currentCOntext to passed context if not null
- if (!string.IsNullOrWhiteSpace(currentContext))
- {
-
- activeContext = k8SConfig.Contexts.FirstOrDefault(c => c.Name.Equals(currentContext, StringComparison.OrdinalIgnoreCase));
- if (activeContext != null)
- {
- this.CurrentContext = activeContext.Name;
- }
- else
- {
- throw new KubeConfigException($"CurrentContext: {0} not found in contexts in kubeconfig");
- }
- }
- // otherwise set current context from kubeconfig
- else
- {
- activeContext = k8SConfig.Contexts.FirstOrDefault(c => c.Name.Equals(k8SConfig.CurrentContext, StringComparison.OrdinalIgnoreCase));
-
- if (activeContext == null)
- {
- throw new KubeConfigException($"CurrentContext: {currentContext} not found in contexts in kubeconfig");
- }
-
- this.CurrentContext = activeContext.Name;
}
if (k8SConfig.Clusters == null)
{
- throw new KubeConfigException($"clusters not found for current-context :{activeContext} in kubeconfig");
+ throw new KubeConfigException($"No clusters found in kubeconfig");
}
-
- var clusterDetails = k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.Cluster, StringComparison.OrdinalIgnoreCase));
- if (clusterDetails?.ClusterEndpoint != null)
+
+ if (k8SConfig.Users == null)
{
- if (string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.Server))
- {
- throw new KubeConfigException($"server not found for current-context :{activeContext} in kubeconfig");
- }
-
- if (!clusterDetails.ClusterEndpoint.SkipTlsVerify &&
- string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.CertificateAuthorityData) &&
- string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.CertificateAuthority))
- {
- throw new KubeConfigException($"neither certificate-authority-data nor certificate-authority not found for current-context :{activeContext} in kubeconfig");
- }
-
- this.Host = clusterDetails.ClusterEndpoint.Server;
- if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthorityData)) {
- string data = clusterDetails.ClusterEndpoint.CertificateAuthorityData;
- this.SslCaCert = new X509Certificate2(System.Text.Encoding.UTF8.GetBytes(Utils.Base64Decode(data)));
- }
- else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority)) {
- this.SslCaCert = new X509Certificate2(clusterDetails.ClusterEndpoint.CertificateAuthority, null);
- }
- this.SkipTlsVerify = clusterDetails.ClusterEndpoint.SkipTlsVerify;
+ throw new KubeConfigException($"No users found in kubeconfig");
}
- else
+
+ // current context
+ currentContext = currentContext ?? k8SConfig.CurrentContext;
+ Context activeContext = k8SConfig.Contexts.FirstOrDefault(c => c.Name.Equals(currentContext, StringComparison.OrdinalIgnoreCase));
+ if (activeContext == null)
{
- throw new KubeConfigException($"Cluster details not found for current-context: {activeContext} in kubeconfig");
+ throw new KubeConfigException($"CurrentContext: {currentContext} not found in contexts in kubeconfig");
}
- // set user details from kubeconfig
- var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.User, StringComparison.OrdinalIgnoreCase));
+ this.CurrentContext = activeContext.Name;
- this.SetUserDetails(userDetails);
+ // cluster
+ var clusterDetails = k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.Cluster, StringComparison.OrdinalIgnoreCase));
+ if (clusterDetails?.ClusterEndpoint == null)
+ {
+ throw new KubeConfigException($"Cluster not found for context {activeContext} in kubeconfig");
+ }
+
+ if (string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.Server))
+ {
+ throw new KubeConfigException($"Server not found for current-context {activeContext} in kubeconfig");
+ }
+
+ if (!clusterDetails.ClusterEndpoint.SkipTlsVerify &&
+ string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.CertificateAuthorityData) &&
+ string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.CertificateAuthority))
+ {
+ throw new KubeConfigException($"neither certificate-authority-data nor certificate-authority not found for current-context :{activeContext} in kubeconfig");
+ }
+
+ this.Host = clusterDetails.ClusterEndpoint.Server;
+ if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthorityData))
+ {
+ string data = clusterDetails.ClusterEndpoint.CertificateAuthorityData;
+ this.SslCaCert = new X509Certificate2(System.Text.Encoding.UTF8.GetBytes(Utils.Base64Decode(data)));
+ }
+ else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority))
+ {
+ this.SslCaCert = new X509Certificate2(clusterDetails.ClusterEndpoint.CertificateAuthority, null);
+ }
+ this.SkipTlsVerify = clusterDetails.ClusterEndpoint.SkipTlsVerify;
+
+ // user
+ this.SetUserDetails(k8SConfig, activeContext);
}
- private void SetUserDetails(User userDetails)
+ private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext)
{
+ var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.User, StringComparison.OrdinalIgnoreCase));
+
if (userDetails == null)
{
- throw new KubeConfigException("User not found for the current context in kubeconfig");
+ throw new KubeConfigException("User not found for context {activeContext.Name} in kubeconfig");
}
if (userDetails.UserCredentials == null)
@@ -229,7 +211,7 @@ namespace k8s
if (!userCredentialsFound)
{
- throw new KubeConfigException($"User: {userDetails.Name} does not have appropriate auth credentials in kube config");
+ throw new KubeConfigException($"User: {userDetails.Name} does not have appropriate auth credentials in kubeconfig");
}
}
diff --git a/src/Utils.cs b/src/Utils.cs
index 4db4fa6..af3801f 100644
--- a/src/Utils.cs
+++ b/src/Utils.cs
@@ -1,8 +1,9 @@
namespace k8s
{
+ using k8s.Exceptions;
using System;
+ using System.ComponentModel;
using System.Diagnostics;
- using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@@ -50,7 +51,8 @@
var filePrefix = config.CurrentContext;
var pfxFilePath = Path.Combine(certDirPath, filePrefix + "pfx");
- if (!string.IsNullOrWhiteSpace(config.ClientCertificateKey)) {
+ if (!string.IsNullOrWhiteSpace(config.ClientCertificateKey))
+ {
keyFilePath = Path.Combine(certDirPath, filePrefix + "key");
using (FileStream fs = File.Create(keyFilePath))
{
@@ -58,24 +60,27 @@
await fs.WriteAsync(info, 0, info.Length).ConfigureAwait(false);
}
}
- if (!string.IsNullOrWhiteSpace(config.ClientKey)) {
+ if (!string.IsNullOrWhiteSpace(config.ClientKey))
+ {
keyFilePath = config.ClientKey;
}
- if (!string.IsNullOrWhiteSpace(config.ClientCertificateData)) {
+ if (!string.IsNullOrWhiteSpace(config.ClientCertificateData))
+ {
certFilePath = Path.Combine(certDirPath, filePrefix + "cert");
-
+
using (FileStream fs = File.Create(certFilePath))
{
byte[] info = Convert.FromBase64String(config.ClientCertificateData);
await fs.WriteAsync(info, 0, info.Length).ConfigureAwait(false);
}
}
- if (!string.IsNullOrWhiteSpace(config.ClientCertificate)) {
+ if (!string.IsNullOrWhiteSpace(config.ClientCertificate))
+ {
certFilePath = config.ClientCertificate;
}
- var process = new Process();
- process.StartInfo = new ProcessStartInfo()
+
+ var processStartInfo = new ProcessStartInfo
{
FileName = @"openssl",
Arguments = $"pkcs12 -export -out {pfxFilePath} -inkey {keyFilePath} -in {certFilePath} -passout pass:",
@@ -84,14 +89,23 @@
RedirectStandardOutput = true
};
- process.Start();
- process.WaitForExit();
- if (process.ExitCode == 0)
+ try
{
- return pfxFilePath;
+ using (Process process = Process.Start(processStartInfo))
+ {
+ process.WaitForExit();
+ if (process.ExitCode != 0)
+ {
+ throw new KubernetesClientException($"Failed to generate pfx file with openssl. ExitCode = {process.ExitCode}.");
+ }
+ }
+ }
+ catch (Win32Exception e)
+ {
+ throw new KubernetesClientException("Failed to generate pfx file with openssl.", e);
}
- return null;
+ return pfxFilePath;
}
}
}
diff --git a/tests/KubernetesClientConfigurationTests.cs b/tests/KubernetesClientConfigurationTests.cs
index c4baefb..2ac872f 100755
--- a/tests/KubernetesClientConfigurationTests.cs
+++ b/tests/KubernetesClientConfigurationTests.cs
@@ -1,6 +1,4 @@
-using System;
-using Xunit;
-using k8s;
+using Xunit;
using System.IO;
namespace k8s.Tests