* Add support for HttpClientFactory with KubernetesClientConfiguration * Add an example with http client factory * ensure sample uses the latest version of C#
This commit is contained in:
committed by
Kubernetes Prow Robot
parent
fcd8c166da
commit
e00f67abd4
43
examples/httpClientFactory/PodListHostedService.cs
Normal file
43
examples/httpClientFactory/PodListHostedService.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using k8s;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace httpClientFactory
|
||||
{
|
||||
// Learn more about IHostedServices at https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2&tabs=visual-studio
|
||||
internal class PodListHostedService : IHostedService
|
||||
{
|
||||
private readonly IKubernetes _kubernetesClient;
|
||||
private readonly ILogger<PodListHostedService> _logger;
|
||||
|
||||
public PodListHostedService(IKubernetes kubernetesClient, ILogger<PodListHostedService> logger)
|
||||
{
|
||||
_kubernetesClient = kubernetesClient ?? throw new ArgumentNullException(nameof(kubernetesClient));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Starting Request!");
|
||||
|
||||
var list = await _kubernetesClient.ListNamespacedPodAsync("default", cancellationToken: cancellationToken);
|
||||
foreach (var item in list.Items)
|
||||
{
|
||||
_logger.LogInformation(item.Metadata.Name);
|
||||
}
|
||||
if (list.Items.Count == 0)
|
||||
{
|
||||
_logger.LogInformation("Empty!");
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Nothing to stop
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
examples/httpClientFactory/Program.cs
Normal file
46
examples/httpClientFactory/Program.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using k8s;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace httpClientFactory
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
// Learn more about generic hosts at https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host
|
||||
using (var host = new HostBuilder()
|
||||
.ConfigureLogging((logging) =>
|
||||
{
|
||||
logging.AddConsole();
|
||||
})
|
||||
.ConfigureServices((hostBuilderContext, services) =>
|
||||
{
|
||||
// Ideally this config would be read from the .net core config constructs,
|
||||
// but that has not been implemented in the KubernetesClient library at
|
||||
// the time this sample was created.
|
||||
var config = KubernetesClientConfiguration.BuildDefaultConfig();
|
||||
services.AddSingleton(config);
|
||||
|
||||
// Setup the http client
|
||||
services.AddHttpClient("K8s")
|
||||
.AddTypedClient<IKubernetes>((httpClient, serviceProvider) =>
|
||||
{
|
||||
return new Kubernetes(
|
||||
serviceProvider.GetRequiredService<KubernetesClientConfiguration>(),
|
||||
httpClient);
|
||||
});
|
||||
|
||||
// Add the class that uses the client
|
||||
services.AddHostedService<PodListHostedService>();
|
||||
})
|
||||
.Build())
|
||||
{
|
||||
await host.StartAsync().ConfigureAwait(false);
|
||||
await host.StopAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
examples/httpClientFactory/httpClientFactory.csproj
Normal file
19
examples/httpClientFactory/httpClientFactory.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\KubernetesClient\KubernetesClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.16
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29230.47
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B70AFB57-57C9-46DC-84BE-11B7DDD34B40}"
|
||||
EndProject
|
||||
@@ -31,7 +31,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{879F8787-C3B
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KubernetesWatchGenerator", "gen\KubernetesWatchGenerator\KubernetesWatchGenerator.csproj", "{542DC30E-FDF7-4A35-B026-6C21F435E8B1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "patch", "examples\patch\patch.csproj", "{04DE2C84-117D-4E21-8B45-B7AE627697BD}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "patch", "examples\patch\patch.csproj", "{04DE2C84-117D-4E21-8B45-B7AE627697BD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "httpClientFactory", "examples\httpClientFactory\httpClientFactory.csproj", "{A07314A0-02E8-4F36-B233-726D59D28F08}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -175,6 +177,18 @@ Global
|
||||
{04DE2C84-117D-4E21-8B45-B7AE627697BD}.Release|x64.Build.0 = Release|Any CPU
|
||||
{04DE2C84-117D-4E21-8B45-B7AE627697BD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04DE2C84-117D-4E21-8B45-B7AE627697BD}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -191,6 +205,7 @@ Global
|
||||
{806AD0E5-833F-42FB-A870-4BCEE7F4B17F} = {8AF4A5C2-F0CE-47D5-A4C5-FE4AB83CA509}
|
||||
{542DC30E-FDF7-4A35-B026-6C21F435E8B1} = {879F8787-C3BB-43F3-A92D-6D4C7D3A5285}
|
||||
{04DE2C84-117D-4E21-8B45-B7AE627697BD} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {049A763A-C891-4E8D-80CF-89DD3E22ADC7}
|
||||
|
||||
@@ -13,84 +13,68 @@ namespace k8s
|
||||
{
|
||||
public partial class Kubernetes
|
||||
{
|
||||
#if MONOANDROID8_1
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
|
||||
/// </summary>
|
||||
/// <param name='config'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// The kube config to use.
|
||||
/// </param>
|
||||
/// <param name="handlers">
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// <param name="httpClient">
|
||||
/// The <see cref="HttpClient" /> to use for all requests.
|
||||
/// </param>
|
||||
public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers) : this(new Xamarin.Android.Net.AndroidClientHandler(), handlers)
|
||||
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient) : this(config, httpClient, false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config.Host))
|
||||
{
|
||||
throw new KubeConfigException("Host url must be set");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BaseUri = new Uri(config.Host);
|
||||
}
|
||||
catch (UriFormatException e)
|
||||
{
|
||||
throw new KubeConfigException("Bad host url", e);
|
||||
}
|
||||
|
||||
CaCerts = config.SslCaCerts;
|
||||
SkipTlsVerify = config.SkipTlsVerify;
|
||||
|
||||
if (BaseUri.Scheme == "https")
|
||||
{
|
||||
if (config.SkipTlsVerify)
|
||||
{
|
||||
System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CaCerts == null)
|
||||
{
|
||||
throw new KubeConfigException("a CA must be set when SkipTlsVerify === false");
|
||||
}
|
||||
|
||||
var certList = new System.Collections.Generic.List<Java.Security.Cert.Certificate>();
|
||||
|
||||
foreach (X509Certificate2 caCert in CaCerts)
|
||||
{
|
||||
using (System.IO.MemoryStream certStream = new System.IO.MemoryStream(caCert.RawData))
|
||||
{
|
||||
Java.Security.Cert.Certificate cert = Java.Security.Cert.CertificateFactory.GetInstance("X509").GenerateCertificate(certStream);
|
||||
|
||||
certList.Add(cert);
|
||||
}
|
||||
}
|
||||
|
||||
Xamarin.Android.Net.AndroidClientHandler handler = (Xamarin.Android.Net.AndroidClientHandler)this.HttpClientHandler;
|
||||
|
||||
handler.TrustedCerts = certList;
|
||||
}
|
||||
}
|
||||
|
||||
// set credentails for the kubernernet client
|
||||
SetCredentials(config, HttpClientHandler);
|
||||
}
|
||||
#else
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
|
||||
/// </summary>
|
||||
/// <param name='config'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// The kube config to use.
|
||||
/// </param>
|
||||
/// <param name="httpClient">
|
||||
/// The <see cref="HttpClient" /> to use for all requests.
|
||||
/// </param>
|
||||
/// <param name="disposeHttpClient">
|
||||
/// Whether or not the <see cref="Kubernetes"/> object should own the lifetime of <paramref name="httpClient"/>.
|
||||
/// </param>
|
||||
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient, bool disposeHttpClient) : this(httpClient, disposeHttpClient)
|
||||
{
|
||||
ValidateConfig(config);
|
||||
CaCerts = config.SslCaCerts;
|
||||
SkipTlsVerify = config.SkipTlsVerify;
|
||||
InitializeFromConfig(config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
|
||||
/// </summary>
|
||||
/// <param name='config'>
|
||||
/// The kube config to use.
|
||||
/// </param>
|
||||
/// <param name="handlers">
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers) : this(handlers)
|
||||
public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers)
|
||||
#if MONOANDROID8_1
|
||||
: this(new Xamarin.Android.Net.AndroidClientHandler(), handlers)
|
||||
#else
|
||||
: this(handlers)
|
||||
#endif
|
||||
{
|
||||
ValidateConfig(config);
|
||||
CaCerts = config.SslCaCerts;
|
||||
SkipTlsVerify = config.SkipTlsVerify;
|
||||
InitializeFromConfig(config);
|
||||
}
|
||||
|
||||
private void ValidateConfig(KubernetesClientConfiguration config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new KubeConfigException("KubeConfig must be provided");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(config.Host))
|
||||
{
|
||||
throw new KubeConfigException("Host url must be set");
|
||||
@@ -104,10 +88,10 @@ namespace k8s
|
||||
{
|
||||
throw new KubeConfigException("Bad host url", e);
|
||||
}
|
||||
}
|
||||
|
||||
CaCerts = config.SslCaCerts;
|
||||
SkipTlsVerify = config.SkipTlsVerify;
|
||||
|
||||
private void InitializeFromConfig(KubernetesClientConfiguration config)
|
||||
{
|
||||
if (BaseUri.Scheme == "https")
|
||||
{
|
||||
if (config.SkipTlsVerify)
|
||||
@@ -115,7 +99,7 @@ namespace k8s
|
||||
#if NET452
|
||||
((WebRequestHandler) HttpClientHandler).ServerCertificateValidationCallback =
|
||||
(sender, certificate, chain, sslPolicyErrors) => true;
|
||||
#elif XAMARINIOS1_0
|
||||
#elif XAMARINIOS1_0 || MONOANDROID8_1
|
||||
System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
return true;
|
||||
@@ -129,9 +113,8 @@ namespace k8s
|
||||
{
|
||||
if (CaCerts == null)
|
||||
{
|
||||
throw new KubeConfigException("a CA must be set when SkipTlsVerify === false");
|
||||
throw new KubeConfigException("A CA must be set when SkipTlsVerify === false");
|
||||
}
|
||||
|
||||
#if NET452
|
||||
((WebRequestHandler) HttpClientHandler).ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
@@ -143,6 +126,22 @@ namespace k8s
|
||||
var cert = new X509Certificate2(certificate);
|
||||
return Kubernetes.CertificateValidationCallBack(sender, CaCerts, cert, chain, sslPolicyErrors);
|
||||
};
|
||||
#elif MONOANDROID8_1
|
||||
var certList = new System.Collections.Generic.List<Java.Security.Cert.Certificate>();
|
||||
|
||||
foreach (X509Certificate2 caCert in CaCerts)
|
||||
{
|
||||
using (var certStream = new System.IO.MemoryStream(caCert.RawData))
|
||||
{
|
||||
Java.Security.Cert.Certificate cert = Java.Security.Cert.CertificateFactory.GetInstance("X509").GenerateCertificate(certStream);
|
||||
|
||||
certList.Add(cert);
|
||||
}
|
||||
}
|
||||
|
||||
var handler = (Xamarin.Android.Net.AndroidClientHandler)this.HttpClientHandler;
|
||||
|
||||
handler.TrustedCerts = certList;
|
||||
#else
|
||||
HttpClientHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
@@ -155,7 +154,6 @@ namespace k8s
|
||||
// set credentails for the kubernernet client
|
||||
SetCredentials(config, HttpClientHandler);
|
||||
}
|
||||
#endif
|
||||
|
||||
private X509Certificate2Collection CaCerts { get; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user