Prevent NullReferenceException when using HttpClient to initialize Kubernetes client. Fixes #335 (#336)

* Preventing null ref exception when initializing with HttpClient and adding support for generating a default client handler from a config object

* Updating example to make use of config-based client handler generation
This commit is contained in:
Brandon Sharp
2020-01-06 23:28:17 -06:00
committed by Kubernetes Prow Robot
parent 3c3c6cab91
commit 3a30033090
3 changed files with 63 additions and 26 deletions

View File

@@ -31,7 +31,8 @@ namespace httpClientFactory
return new Kubernetes(
serviceProvider.GetRequiredService<KubernetesClientConfiguration>(),
httpClient);
});
})
.ConfigurePrimaryHttpMessageHandler(config.CreateDefaultHttpClientHandler);
// Add the class that uses the client
services.AddHostedService<PodListHostedService>();

View File

@@ -43,7 +43,7 @@ namespace k8s
ValidateConfig(config);
CaCerts = config.SslCaCerts;
SkipTlsVerify = config.SkipTlsVerify;
InitializeFromConfig(config);
SetCredentials(config);
}
/// <summary>
@@ -151,8 +151,9 @@ namespace k8s
}
}
// set credentails for the kubernernet client
SetCredentials(config, HttpClientHandler);
// set credentails for the kubernetes client
SetCredentials(config);
config.AddCertificates(HttpClientHandler);
}
private X509Certificate2Collection CaCerts { get; }
@@ -195,9 +196,7 @@ namespace k8s
/// Set credentials for the Client
/// </summary>
/// <param name="config">k8s client configuration</param>
/// <param name="handler">http client handler for the rest client</param>
/// <returns>Task</returns>
private void SetCredentials(KubernetesClientConfiguration config, HttpClientHandler handler)
private void SetCredentials(KubernetesClientConfiguration config)
{
// set the Credentails for token based auth
if (!string.IsNullOrWhiteSpace(config.AccessToken))
@@ -212,25 +211,6 @@ namespace k8s
Password = config.Password
};
}
#if XAMARINIOS1_0 || MONOANDROID8_1
// handle.ClientCertificates is not implemented in Xamarin.
return;
#endif
if ((!string.IsNullOrWhiteSpace(config.ClientCertificateData) ||
!string.IsNullOrWhiteSpace(config.ClientCertificateFilePath)) &&
(!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData) ||
!string.IsNullOrWhiteSpace(config.ClientKeyFilePath)))
{
var cert = CertUtils.GeneratePfx(config);
#if NET452
((WebRequestHandler) handler).ClientCertificates.Add(cert);
#else
handler.ClientCertificates.Add(cert);
#endif
}
}
/// <summary>

View File

@@ -0,0 +1,56 @@
using System;
using System.Net.Http;
namespace k8s
{
public partial class KubernetesClientConfiguration {
public HttpClientHandler CreateDefaultHttpClientHandler() {
var httpClientHandler = new HttpClientHandler();
#if !NET452
var uriScheme = new Uri(this.Host).Scheme;
if(uriScheme == "https")
{
if(this.SkipTlsVerify)
{
httpClientHandler.ServerCertificateCustomValidationCallback =
(sender, certificate, chain, sslPolicyErrors) => true;
}
else
{
httpClientHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
return Kubernetes.CertificateValidationCallBack(sender, this.SslCaCerts, certificate, chain, sslPolicyErrors);
};
}
}
#endif
AddCertificates(httpClientHandler);
return httpClientHandler;
}
public void AddCertificates(HttpClientHandler handler) {
#if XAMARINIOS1_0 || MONOANDROID8_1
// handle.ClientCertificates is not implemented in Xamarin.
return;
#endif
if ((!string.IsNullOrWhiteSpace(this.ClientCertificateData) ||
!string.IsNullOrWhiteSpace(this.ClientCertificateFilePath)) &&
(!string.IsNullOrWhiteSpace(this.ClientCertificateKeyData) ||
!string.IsNullOrWhiteSpace(this.ClientKeyFilePath)))
{
var cert = CertUtils.GeneratePfx(this);
#if NET452
((WebRequestHandler) handler).ClientCertificates.Add(cert);
#else
handler.ClientCertificates.Add(cert);
#endif
}
}
}
}