Update docs. Better error message when openssl fails. Simplifying
`KubernetesClientConfiguration`
This commit is contained in:
31
README.md
31
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
|
||||
```
|
||||
@@ -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);
|
||||
|
||||
@@ -16,17 +16,12 @@ namespace k8s
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="KubernetesClientConfiguration"/> class.
|
||||
/// Initializes a new instance of the ClientConfiguration class
|
||||
/// </summary>
|
||||
/// <param name="kubeconfig">kubeconfig file info</param>
|
||||
/// <param name="currentContext">Context to use from kube config</param>
|
||||
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,51 +103,41 @@ namespace k8s
|
||||
/// <param name="currentContext">Current Context</param>
|
||||
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))
|
||||
if (k8SConfig.Clusters == null)
|
||||
{
|
||||
throw new KubeConfigException($"No clusters found in kubeconfig");
|
||||
}
|
||||
|
||||
activeContext = k8SConfig.Contexts.FirstOrDefault(c => c.Name.Equals(currentContext, StringComparison.OrdinalIgnoreCase));
|
||||
if (activeContext != null)
|
||||
if (k8SConfig.Users == null)
|
||||
{
|
||||
this.CurrentContext = activeContext.Name;
|
||||
throw new KubeConfigException($"No users found in kubeconfig");
|
||||
}
|
||||
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));
|
||||
|
||||
// current context
|
||||
currentContext = currentContext ?? k8SConfig.CurrentContext;
|
||||
Context activeContext = k8SConfig.Contexts.FirstOrDefault(c => c.Name.Equals(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");
|
||||
}
|
||||
|
||||
// cluster
|
||||
var clusterDetails = k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.Cluster, StringComparison.OrdinalIgnoreCase));
|
||||
if (clusterDetails?.ClusterEndpoint != null)
|
||||
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");
|
||||
throw new KubeConfigException($"Server not found for current-context {activeContext} in kubeconfig");
|
||||
}
|
||||
|
||||
if (!clusterDetails.ClusterEndpoint.SkipTlsVerify &&
|
||||
@@ -163,31 +148,28 @@ namespace k8s
|
||||
}
|
||||
|
||||
this.Host = clusterDetails.ClusterEndpoint.Server;
|
||||
if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthorityData)) {
|
||||
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)) {
|
||||
else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority))
|
||||
{
|
||||
this.SslCaCert = new X509Certificate2(clusterDetails.ClusterEndpoint.CertificateAuthority, null);
|
||||
}
|
||||
this.SkipTlsVerify = clusterDetails.ClusterEndpoint.SkipTlsVerify;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new KubeConfigException($"Cluster details not found for current-context: {activeContext} in kubeconfig");
|
||||
|
||||
// user
|
||||
this.SetUserDetails(k8SConfig, activeContext);
|
||||
}
|
||||
|
||||
// set user details from kubeconfig
|
||||
private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext)
|
||||
{
|
||||
var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.User, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
this.SetUserDetails(userDetails);
|
||||
}
|
||||
|
||||
private void SetUserDetails(User userDetails)
|
||||
{
|
||||
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)
|
||||
|
||||
38
src/Utils.cs
38
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,11 +60,13 @@
|
||||
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))
|
||||
@@ -71,11 +75,12 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
using k8s;
|
||||
using Xunit;
|
||||
using System.IO;
|
||||
|
||||
namespace k8s.Tests
|
||||
|
||||
Reference in New Issue
Block a user