From 3a30033090e6866a4050b4cc68cebd2ee228bb12 Mon Sep 17 00:00:00 2001 From: Brandon Sharp Date: Mon, 6 Jan 2020 23:28:17 -0600 Subject: [PATCH] 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 --- examples/httpClientFactory/Program.cs | 3 +- src/KubernetesClient/Kubernetes.ConfigInit.cs | 30 ++-------- ...esClientConfiguration.HttpClientHandler.cs | 56 +++++++++++++++++++ 3 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 src/KubernetesClient/KubernetesClientConfiguration.HttpClientHandler.cs diff --git a/examples/httpClientFactory/Program.cs b/examples/httpClientFactory/Program.cs index d167a03..b3a2d92 100644 --- a/examples/httpClientFactory/Program.cs +++ b/examples/httpClientFactory/Program.cs @@ -31,7 +31,8 @@ namespace httpClientFactory return new Kubernetes( serviceProvider.GetRequiredService(), httpClient); - }); + }) + .ConfigurePrimaryHttpMessageHandler(config.CreateDefaultHttpClientHandler); // Add the class that uses the client services.AddHostedService(); diff --git a/src/KubernetesClient/Kubernetes.ConfigInit.cs b/src/KubernetesClient/Kubernetes.ConfigInit.cs index ca01729..63bc79c 100644 --- a/src/KubernetesClient/Kubernetes.ConfigInit.cs +++ b/src/KubernetesClient/Kubernetes.ConfigInit.cs @@ -43,7 +43,7 @@ namespace k8s ValidateConfig(config); CaCerts = config.SslCaCerts; SkipTlsVerify = config.SkipTlsVerify; - InitializeFromConfig(config); + SetCredentials(config); } /// @@ -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 /// /// k8s client configuration - /// http client handler for the rest client - /// Task - 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 - } } /// diff --git a/src/KubernetesClient/KubernetesClientConfiguration.HttpClientHandler.cs b/src/KubernetesClient/KubernetesClientConfiguration.HttpClientHandler.cs new file mode 100644 index 0000000..c52f3e7 --- /dev/null +++ b/src/KubernetesClient/KubernetesClientConfiguration.HttpClientHandler.cs @@ -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 + } + } + } +} \ No newline at end of file