7.1 remove old autorest (#785)
* init removal * clean up warning * bump ver to 7.1 * fix build * custom http client no long supported * cleanup unused types * fix npe * remove service client * modern ssl settings * fix test * fix client cert null * fix ctor * cleanup
This commit is contained in:
@@ -2,7 +2,7 @@ using System;
|
||||
using System.Threading.Tasks;
|
||||
using k8s;
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace attach
|
||||
{
|
||||
@@ -10,8 +10,6 @@ namespace attach
|
||||
{
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
ServiceClientTracing.IsEnabled = true;
|
||||
|
||||
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
|
||||
IKubernetes client = new Kubernetes(config);
|
||||
Console.WriteLine("Starting Request!");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using k8s;
|
||||
using k8s.Autorest;
|
||||
using k8s.Models;
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using System;
|
||||
@@ -35,14 +36,14 @@ namespace customResource
|
||||
myCr.Metadata.NamespaceProperty ?? "default",
|
||||
myCRD.PluralName).ConfigureAwait(false);
|
||||
}
|
||||
catch (Microsoft.Rest.HttpOperationException httpOperationException) when (httpOperationException.Message.Contains("422"))
|
||||
catch (HttpOperationException httpOperationException) when (httpOperationException.Message.Contains("422"))
|
||||
{
|
||||
var phase = httpOperationException.Response.ReasonPhrase;
|
||||
var content = httpOperationException.Response.Content;
|
||||
Console.WriteLine("response content: {0}", content);
|
||||
Console.WriteLine("response phase: {0}", phase);
|
||||
}
|
||||
catch (Microsoft.Rest.HttpOperationException)
|
||||
catch (HttpOperationException)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,7 +71,7 @@ namespace customResource
|
||||
myCRD.PluralName,
|
||||
myCr.Metadata.Name).ConfigureAwait(false);
|
||||
}
|
||||
catch (Microsoft.Rest.HttpOperationException httpOperationException)
|
||||
catch (HttpOperationException httpOperationException)
|
||||
{
|
||||
var phase = httpOperationException.Response.ReasonPhrase;
|
||||
var content = httpOperationException.Response.Content;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
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
|
||||
public 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).ConfigureAwait(false);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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);
|
||||
})
|
||||
.ConfigurePrimaryHttpMessageHandler(config.CreateDefaultHttpClientHandler);
|
||||
|
||||
// Add the class that uses the client
|
||||
services.AddHostedService<PodListHostedService>();
|
||||
})
|
||||
.Build())
|
||||
{
|
||||
await host.StartAsync().ConfigureAwait(false);
|
||||
await host.StopAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\KubernetesClient\KubernetesClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -35,9 +35,9 @@ namespace @namespace
|
||||
{
|
||||
foreach (var innerEx in ex.InnerExceptions)
|
||||
{
|
||||
if (innerEx is Microsoft.Rest.HttpOperationException)
|
||||
if (innerEx is k8s.Autorest.HttpOperationException)
|
||||
{
|
||||
var code = ((Microsoft.Rest.HttpOperationException)innerEx).Response.StatusCode;
|
||||
var code = ((k8s.Autorest.HttpOperationException)innerEx).Response.StatusCode;
|
||||
if (code == HttpStatusCode.NotFound)
|
||||
{
|
||||
return;
|
||||
@@ -47,7 +47,7 @@ namespace @namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Microsoft.Rest.HttpOperationException ex)
|
||||
catch (k8s.Autorest.HttpOperationException ex)
|
||||
{
|
||||
if (ex.Response.StatusCode == HttpStatusCode.NotFound)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using k8s;
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace watch
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
@@ -19,6 +19,7 @@
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="Namotion.Reflection" Version="2.0.9" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.7.1" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -35,6 +36,7 @@
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGMicrosoft_Bcl_AsyncInterfaces)\lib\netstandard2.0\Microsoft.Bcl.AsyncInterfaces.dll" IncludeRuntimeDependency="false" />
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGNewtonsoft_Json)\lib\netstandard1.0\Newtonsoft.Json.dll" IncludeRuntimeDependency="false" />
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGNamotion_Reflection)\lib\netstandard2.0\Namotion.Reflection.dll" IncludeRuntimeDependency="false" />
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_Diagnostics_DiagnosticSource)\lib\netstandard1.3\System.Diagnostics.DiagnosticSource.dll" IncludeRuntimeDependency="false" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using Models;
|
||||
|
||||
using System.Collections;
|
||||
@@ -17,19 +17,8 @@ namespace k8s
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public partial interface IKubernetes : System.IDisposable
|
||||
public partial interface IKubernetes
|
||||
{
|
||||
/// <summary>
|
||||
/// The base URI of the service.
|
||||
/// </summary>
|
||||
System.Uri BaseUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Subscription credentials which uniquely identify client
|
||||
/// subscription.
|
||||
/// </summary>
|
||||
ServiceClientCredentials Credentials { get; }
|
||||
|
||||
{{#.}}
|
||||
/// <summary>
|
||||
/// {{ToXmlDoc operation.description}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using Models;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -15,7 +15,7 @@ namespace k8s
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public partial class Kubernetes : ServiceClient<Kubernetes>, IKubernetes
|
||||
public partial class Kubernetes : IKubernetes
|
||||
{
|
||||
{{#.}}
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -31,8 +31,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{879F8787-C3B
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "patch", "examples\patch\patch.csproj", "{04DE2C84-117D-4E21-8B45-B7AE627697BD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "httpClientFactory", "examples\httpClientFactory\httpClientFactory.csproj", "{A07314A0-02E8-4F36-B233-726D59D28F08}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "metrics", "examples\metrics\metrics.csproj", "{B9647AD4-F6B0-406F-8B79-6781E31600EC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "E2E.Tests", "tests\E2E.Tests\E2E.Tests.csproj", "{5056C4A2-5E12-4C16-8DA7-8835DA58BFF2}"
|
||||
@@ -177,18 +175,6 @@ 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
|
||||
{B9647AD4-F6B0-406F-8B79-6781E31600EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B9647AD4-F6B0-406F-8B79-6781E31600EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B9647AD4-F6B0-406F-8B79-6781E31600EC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
@@ -288,7 +274,6 @@ Global
|
||||
{35DD7248-F9EC-4272-A32C-B0C59E5A6FA7} = {3D1864AA-1FFC-4512-BB13-46055E410F73}
|
||||
{806AD0E5-833F-42FB-A870-4BCEE7F4B17F} = {8AF4A5C2-F0CE-47D5-A4C5-FE4AB83CA509}
|
||||
{04DE2C84-117D-4E21-8B45-B7AE627697BD} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
|
||||
{A07314A0-02E8-4F36-B233-726D59D28F08} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
|
||||
{B9647AD4-F6B0-406F-8B79-6781E31600EC} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
|
||||
{5056C4A2-5E12-4C16-8DA7-8835DA58BFF2} = {8AF4A5C2-F0CE-47D5-A4C5-FE4AB83CA509}
|
||||
{4D2AE427-F856-49E5-B61D-EA6B17D89051} = {8AF4A5C2-F0CE-47D5-A4C5-FE4AB83CA509}
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using k8s.Exceptions;
|
||||
using k8s.KubeConfigModels;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s.Authentication
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using k8s.Exceptions;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s.Authentication
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using IdentityModel.OidcClient;
|
||||
using k8s.Exceptions;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Net.Http.Headers;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s.Authentication
|
||||
{
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic Auth credentials for use with a REST Service Client.
|
||||
/// </summary>
|
||||
public class BasicAuthenticationCredentials : ServiceClientCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic auth UserName.
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Basic auth password.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Add the Basic Authentication Header to each outgoing request
|
||||
/// </summary>
|
||||
/// <param name="request">The outgoing request</param>
|
||||
/// <param name="cancellationToken">A token to cancel the operation</param>
|
||||
/// <returns>void</returns>
|
||||
public override Task ProcessHttpRequestAsync(
|
||||
HttpRequestMessage request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new ArgumentNullException("request");
|
||||
}
|
||||
|
||||
// Add username and password to "Basic" header of each request.
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue(
|
||||
"Basic",
|
||||
Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0}:{1}",
|
||||
UserName,
|
||||
Password).ToCharArray())));
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/KubernetesClient/Autorest/HttpExtensions.cs
Normal file
45
src/KubernetesClient/Autorest/HttpExtensions.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions for manipulating HTTP request and response objects.
|
||||
/// </summary>
|
||||
internal static class HttpExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the content headers of an HtttRequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="request">The request message.</param>
|
||||
/// <returns>The content headers.</returns>
|
||||
public static HttpHeaders GetContentHeaders(this HttpRequestMessage request)
|
||||
{
|
||||
if (request != null && request.Content != null)
|
||||
{
|
||||
return request.Content.Headers;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the content headers of an HttpResponseMessage.
|
||||
/// </summary>
|
||||
/// <param name="response">The response message.</param>
|
||||
/// <returns>The content headers.</returns>
|
||||
public static HttpHeaders GetContentHeaders(this HttpResponseMessage response)
|
||||
{
|
||||
if (response != null && response.Content != null)
|
||||
{
|
||||
return response.Content.Headers;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/KubernetesClient/Autorest/HttpMessageWrapper.cs
Normal file
59
src/KubernetesClient/Autorest/HttpMessageWrapper.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class used to wrap HTTP requests and responses to preserve data after disposal of
|
||||
/// HttpClient.
|
||||
/// </summary>
|
||||
public abstract class HttpMessageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpMessageWrapper"/> class.
|
||||
/// </summary>
|
||||
protected HttpMessageWrapper()
|
||||
{
|
||||
Headers = new Dictionary<string, IEnumerable<string>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the HTTP message contents.
|
||||
/// </summary>
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of HTTP headers.
|
||||
/// </summary>
|
||||
public IDictionary<string, IEnumerable<string>> Headers { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Copies HTTP message headers to the error object.
|
||||
/// </summary>
|
||||
/// <param name="headers">Collection of HTTP headers.</param>
|
||||
protected void CopyHeaders(HttpHeaders headers)
|
||||
{
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, IEnumerable<string>> header in headers)
|
||||
{
|
||||
IEnumerable<string> values = null;
|
||||
if (Headers.TryGetValue(header.Key, out values))
|
||||
{
|
||||
values = Enumerable.Concat(values, header.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
values = header.Value;
|
||||
}
|
||||
|
||||
Headers[header.Key] = values;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/KubernetesClient/Autorest/HttpOperationException.cs
Normal file
68
src/KubernetesClient/Autorest/HttpOperationException.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception thrown for an invalid response with custom error information.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class HttpOperationException : RestException
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets information about the associated HTTP request.
|
||||
/// </summary>
|
||||
public HttpRequestMessageWrapper Request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the associated HTTP response.
|
||||
/// </summary>
|
||||
public HttpResponseMessageWrapper Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the response object.
|
||||
/// </summary>
|
||||
public object Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpOperationException"/> class.
|
||||
/// </summary>
|
||||
public HttpOperationException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpOperationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The exception message.</param>
|
||||
public HttpOperationException(string message)
|
||||
: this(message, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpOperationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The exception message.</param>
|
||||
/// <param name="innerException">Inner exception.</param>
|
||||
public HttpOperationException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpOperationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization info.</param>
|
||||
/// <param name="context">Streaming context.</param>
|
||||
protected HttpOperationException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
133
src/KubernetesClient/Autorest/HttpOperationResponse.cs
Normal file
133
src/KubernetesClient/Autorest/HttpOperationResponse.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the base return type of all ServiceClient REST operations without response body.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1649 // File name should match first type name
|
||||
public interface IHttpOperationResponse
|
||||
#pragma warning restore SA1649 // File name should match first type name
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets information about the associated HTTP request.
|
||||
/// </summary>
|
||||
HttpRequestMessage Request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the associated HTTP response.
|
||||
/// </summary>
|
||||
HttpResponseMessage Response { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the base return type of all ServiceClient REST operations with response body.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1618 // Generic type parameters should be documented
|
||||
public interface IHttpOperationResponse<T> : IHttpOperationResponse
|
||||
#pragma warning restore SA1618 // Generic type parameters should be documented
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the response object.
|
||||
/// </summary>
|
||||
T Body { get; set; }
|
||||
}
|
||||
|
||||
#pragma warning disable SA1622 // Generic type parameter documentation should have text
|
||||
/// <summary>
|
||||
/// Represents the base return type of all ServiceClient REST operations with a header response.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IHttpOperationHeaderResponse<T> : IHttpOperationResponse
|
||||
#pragma warning restore SA1622 // Generic type parameter documentation should have text
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the response header object.
|
||||
/// </summary>
|
||||
T Headers { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the base return type of all ServiceClient REST operations with response body and header.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1618 // Generic type parameters should be documented
|
||||
public interface IHttpOperationResponse<TBody, THeader> : IHttpOperationResponse<TBody>, IHttpOperationHeaderResponse<THeader>
|
||||
#pragma warning restore SA1618 // Generic type parameters should be documented
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the base return type of all ServiceClient REST operations without response body.
|
||||
/// </summary>
|
||||
public class HttpOperationResponse : IHttpOperationResponse, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the HttpOperationResponse has been disposed.
|
||||
/// </summary>
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the associated HTTP request.
|
||||
/// </summary>
|
||||
public HttpRequestMessage Request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the associated HTTP response.
|
||||
/// </summary>
|
||||
public HttpResponseMessage Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the HttpOperationResponse.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the HttpClient and Handlers.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True to release both managed and unmanaged resources; false to releases only unmanaged resources.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
// Dispose the request and response
|
||||
if (Request != null)
|
||||
{
|
||||
Request.Dispose();
|
||||
}
|
||||
|
||||
if (Response != null)
|
||||
{
|
||||
Response.Dispose();
|
||||
}
|
||||
|
||||
Request = null;
|
||||
Response = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the base return type of all ServiceClient REST operations.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
#pragma warning disable SA1618 // Generic type parameters should be documented
|
||||
public class HttpOperationResponse<T> : HttpOperationResponse, IHttpOperationResponse<T>
|
||||
#pragma warning restore SA1618 // Generic type parameters should be documented
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the response object.
|
||||
/// </summary>
|
||||
public T Body { get; set; }
|
||||
}
|
||||
}
|
||||
62
src/KubernetesClient/Autorest/HttpRequestMessageWrapper.cs
Normal file
62
src/KubernetesClient/Autorest/HttpRequestMessageWrapper.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper around HttpRequestMessage type that copies properties of HttpRequestMessage so that
|
||||
/// they are available after the HttpClient gets disposed.
|
||||
/// </summary>
|
||||
public class HttpRequestMessageWrapper : HttpMessageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpRequestMessageWrapper"/> class from HttpRequestMessage.
|
||||
/// and content.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1611 // Element parameters should be documented
|
||||
public HttpRequestMessageWrapper(HttpRequestMessage httpRequest, string content)
|
||||
#pragma warning restore SA1611 // Element parameters should be documented
|
||||
{
|
||||
if (httpRequest == null)
|
||||
{
|
||||
throw new ArgumentNullException("httpRequest");
|
||||
}
|
||||
|
||||
this.CopyHeaders(httpRequest.Headers);
|
||||
this.CopyHeaders(httpRequest.GetContentHeaders());
|
||||
|
||||
this.Content = content;
|
||||
this.Method = httpRequest.Method;
|
||||
this.RequestUri = httpRequest.RequestUri;
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (httpRequest.Properties != null)
|
||||
{
|
||||
Properties = new Dictionary<string, object>();
|
||||
foreach (KeyValuePair<string, object> pair in httpRequest.Properties)
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
{
|
||||
this.Properties[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP method used by the HTTP request message.
|
||||
/// </summary>
|
||||
public HttpMethod Method { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Uri used for the HTTP request.
|
||||
/// </summary>
|
||||
public Uri RequestUri { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a set of properties for the HTTP request.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Properties { get; private set; }
|
||||
}
|
||||
}
|
||||
47
src/KubernetesClient/Autorest/HttpResponseMessageWrapper.cs
Normal file
47
src/KubernetesClient/Autorest/HttpResponseMessageWrapper.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper around HttpResponseMessage type that copies properties of HttpResponseMessage so that
|
||||
/// they are available after the HttpClient gets disposed.
|
||||
/// </summary>
|
||||
public class HttpResponseMessageWrapper : HttpMessageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpResponseMessageWrapper"/> class from HttpResponseMessage.
|
||||
/// and content.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1611 // Element parameters should be documented
|
||||
public HttpResponseMessageWrapper(HttpResponseMessage httpResponse, string content)
|
||||
#pragma warning restore SA1611 // Element parameters should be documented
|
||||
{
|
||||
if (httpResponse == null)
|
||||
{
|
||||
throw new ArgumentNullException("httpResponse");
|
||||
}
|
||||
|
||||
this.CopyHeaders(httpResponse.Headers);
|
||||
this.CopyHeaders(httpResponse.GetContentHeaders());
|
||||
|
||||
this.Content = content;
|
||||
this.StatusCode = httpResponse.StatusCode;
|
||||
this.ReasonPhrase = httpResponse.ReasonPhrase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status code of the HTTP response.
|
||||
/// </summary>
|
||||
public HttpStatusCode StatusCode { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the reason phrase, typically sent along with the status code.
|
||||
/// </summary>
|
||||
public string ReasonPhrase { get; protected set; }
|
||||
}
|
||||
}
|
||||
26
src/KubernetesClient/Autorest/ITokenProvider.cs
Normal file
26
src/KubernetesClient/Autorest/ITokenProvider.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#pragma warning disable SA1606
|
||||
#pragma warning disable SA1614
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to a source of access tokens.
|
||||
/// </summary>
|
||||
public interface ITokenProvider
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>AuthenticationHeaderValue</returns>
|
||||
Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
#pragma warning restore SA1614
|
||||
#pragma warning restore SA1606
|
||||
51
src/KubernetesClient/Autorest/RestException.cs
Normal file
51
src/KubernetesClient/Autorest/RestException.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic exception for Microsoft Rest Client.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class RestException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RestException"/> class.
|
||||
/// </summary>
|
||||
public RestException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RestException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The exception message.</param>
|
||||
public RestException(string message)
|
||||
: this(message, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RestException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The exception message.</param>
|
||||
/// <param name="innerException">Inner exception.</param>
|
||||
public RestException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RestException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization info.</param>
|
||||
/// <param name="context">Streaming context.</param>
|
||||
protected RestException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/KubernetesClient/Autorest/ServiceClientCredentials.cs
Normal file
29
src/KubernetesClient/Autorest/ServiceClientCredentials.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// ServiceClientCredentials is the abstraction for credentials used by ServiceClients accessing REST services.
|
||||
/// </summary>
|
||||
public abstract class ServiceClientCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Apply the credentials to the HTTP request.
|
||||
/// </summary>
|
||||
/// <param name="request">The HTTP request message.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>
|
||||
/// Task that will complete when processing has finished.
|
||||
/// </returns>
|
||||
public virtual Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
// Return an empty task by default
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
src/KubernetesClient/Autorest/StringTokenProvider.cs
Normal file
50
src/KubernetesClient/Autorest/StringTokenProvider.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple token provider that always provides a static access token.
|
||||
/// </summary>
|
||||
public sealed class StringTokenProvider : ITokenProvider
|
||||
{
|
||||
private string _accessToken;
|
||||
private string _type;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StringTokenProvider"/> class.
|
||||
/// Create a token provider for the given token type that returns the given
|
||||
/// access token.
|
||||
/// </summary>
|
||||
/// <param name="accessToken">The access token to return.</param>
|
||||
/// <param name="tokenType">The token type of the given access token.</param>
|
||||
public StringTokenProvider(string accessToken, string tokenType)
|
||||
{
|
||||
_accessToken = accessToken;
|
||||
_type = tokenType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the token type of this access token.
|
||||
/// </summary>
|
||||
public string TokenType
|
||||
{
|
||||
get { return _type; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the static access token.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token for this action.
|
||||
/// This will not be used since the returned token is static.</param>
|
||||
/// <returns>The access token.</returns>
|
||||
public Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(new AuthenticationHeaderValue(_type, _accessToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
122
src/KubernetesClient/Autorest/TokenCredentials.cs
Normal file
122
src/KubernetesClient/Autorest/TokenCredentials.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace k8s.Autorest
|
||||
{
|
||||
/// <summary>
|
||||
/// Token based credentials for use with a REST Service Client.
|
||||
/// </summary>
|
||||
public class TokenCredentials : ServiceClientCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// The bearer token type, as serialized in an http Authentication header.
|
||||
/// </summary>
|
||||
private const string BearerTokenType = "Bearer";
|
||||
|
||||
/// <summary>
|
||||
/// Gets secure token used to authenticate against Microsoft Azure API.
|
||||
/// No anonymous requests are allowed.
|
||||
/// </summary>
|
||||
protected ITokenProvider TokenProvider { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets Tenant ID
|
||||
/// </summary>
|
||||
public string TenantId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets UserInfo.DisplayableId
|
||||
/// </summary>
|
||||
public string CallerId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TokenCredentials"/>
|
||||
/// class with the given 'Bearer' token.
|
||||
/// </summary>
|
||||
/// <param name="token">Valid JSON Web Token (JWT).</param>
|
||||
public TokenCredentials(string token)
|
||||
: this(token, BearerTokenType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TokenCredentials"/>
|
||||
/// class with the given token and token type.
|
||||
/// </summary>
|
||||
/// <param name="token">Valid JSON Web Token (JWT).</param>
|
||||
/// <param name="tokenType">The token type of the given token.</param>
|
||||
public TokenCredentials(string token, string tokenType)
|
||||
: this(new StringTokenProvider(token, tokenType))
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
throw new ArgumentNullException("token");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tokenType))
|
||||
{
|
||||
throw new ArgumentNullException("tokenType");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TokenCredentials"/> class.
|
||||
/// Create an access token credentials object, given an interface to a token source.
|
||||
/// </summary>
|
||||
/// <param name="tokenProvider">The source of tokens for these credentials.</param>
|
||||
public TokenCredentials(ITokenProvider tokenProvider)
|
||||
{
|
||||
if (tokenProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException("tokenProvider");
|
||||
}
|
||||
|
||||
this.TokenProvider = tokenProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TokenCredentials"/> class.
|
||||
/// Create an access token credentials object, given an interface to a token source.
|
||||
/// </summary>
|
||||
/// <param name="tokenProvider">The source of tokens for these credentials.</param>
|
||||
/// <param name="tenantId">Tenant ID from AuthenticationResult</param>
|
||||
/// <param name="callerId">UserInfo.DisplayableId field from AuthenticationResult</param>
|
||||
public TokenCredentials(ITokenProvider tokenProvider, string tenantId, string callerId)
|
||||
: this(tokenProvider)
|
||||
{
|
||||
this.TenantId = tenantId;
|
||||
this.CallerId = callerId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply the credentials to the HTTP request.
|
||||
/// </summary>
|
||||
/// <param name="request">The HTTP request.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>
|
||||
/// Task that will complete when processing has completed.
|
||||
/// </returns>
|
||||
public async override Task ProcessHttpRequestAsync(
|
||||
HttpRequestMessage request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
if (TokenProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(TokenProvider));
|
||||
}
|
||||
|
||||
request.Headers.Authorization = await TokenProvider.GetAuthenticationHeaderAsync(cancellationToken).ConfigureAwait(false);
|
||||
await base.ProcessHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using System.Net.Http;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
public partial interface IKubernetes
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="HttpClient"/> used for making HTTP requests.
|
||||
/// </summary>
|
||||
HttpClient HttpClient { get; }
|
||||
}
|
||||
}
|
||||
9
src/KubernetesClient/IKubernetes.cs
Normal file
9
src/KubernetesClient/IKubernetes.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace k8s;
|
||||
|
||||
public partial interface IKubernetes : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The base URI of the service.
|
||||
/// </summary>
|
||||
Uri BaseUri { get; set; }
|
||||
}
|
||||
@@ -4,12 +4,12 @@ namespace k8s.KubeConfigModels
|
||||
{
|
||||
public class ExecStatus
|
||||
{
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
public DateTime? Expiry { get; set; }
|
||||
public string? Token { get; set; }
|
||||
public string? ClientCertificateData { get; set; }
|
||||
public string? ClientKeyData { get; set; }
|
||||
#nullable disable
|
||||
#nullable disable
|
||||
|
||||
public bool IsValid()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using k8s.Exceptions;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
@@ -20,43 +20,6 @@ namespace k8s
|
||||
/// <value>timeout</value>
|
||||
public TimeSpan HttpClientTimeout { get; set; } = TimeSpan.FromSeconds(100);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
|
||||
/// </summary>
|
||||
/// <param name='config'>
|
||||
/// The kube config to use.
|
||||
/// </param>
|
||||
/// <param name="httpClient">
|
||||
/// The <see cref="HttpClient" /> to use for all requests.
|
||||
/// </param>
|
||||
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient)
|
||||
: this(config, httpClient, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
|
||||
/// </summary>
|
||||
/// <param name='config'>
|
||||
/// 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;
|
||||
ClientCert = CertUtils.GetClientCert(config);
|
||||
SetCredentials(config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes" /> class.
|
||||
/// </summary>
|
||||
@@ -105,7 +68,11 @@ namespace k8s
|
||||
{
|
||||
if (config.SkipTlsVerify)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
HttpClientHandler.SslOptions.RemoteCertificateValidationCallback =
|
||||
#else
|
||||
HttpClientHandler.ServerCertificateCustomValidationCallback =
|
||||
#endif
|
||||
(sender, certificate, chain, sslPolicyErrors) => true;
|
||||
}
|
||||
else
|
||||
@@ -115,7 +82,11 @@ namespace k8s
|
||||
throw new KubeConfigException("A CA must be set when SkipTlsVerify === false");
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
HttpClientHandler.SslOptions.RemoteCertificateValidationCallback =
|
||||
#else
|
||||
HttpClientHandler.ServerCertificateCustomValidationCallback =
|
||||
#endif
|
||||
(sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
return CertificateValidationCallBack(sender, CaCerts, certificate, chain,
|
||||
@@ -126,122 +97,44 @@ namespace k8s
|
||||
|
||||
// set credentails for the kubernetes client
|
||||
SetCredentials(config);
|
||||
config.AddCertificates(HttpClientHandler);
|
||||
|
||||
var clientCert = CertUtils.GetClientCert(config);
|
||||
if (clientCert != null)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
HttpClientHandler.SslOptions.ClientCertificates.Add(clientCert);
|
||||
#else
|
||||
HttpClientHandler.ClientCertificates.Add(clientCert);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private X509Certificate2Collection CaCerts { get; }
|
||||
|
||||
private X509Certificate2 ClientCert { get; }
|
||||
|
||||
private bool SkipTlsVerify { get; }
|
||||
|
||||
private void CustomInitialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>A <see cref="DelegatingHandler"/> that simply forwards a request with no further processing.</summary>
|
||||
private sealed class ForwardingHandler : DelegatingHandler
|
||||
{
|
||||
public ForwardingHandler(HttpMessageHandler handler)
|
||||
: base(handler)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendDelegatingHandler<T>()
|
||||
where T : DelegatingHandler, new()
|
||||
{
|
||||
var cur = FirstMessageHandler as DelegatingHandler;
|
||||
|
||||
while (cur != null)
|
||||
{
|
||||
var next = cur.InnerHandler as DelegatingHandler;
|
||||
|
||||
if (next == null)
|
||||
{
|
||||
// last one
|
||||
// append watcher handler between to last handler
|
||||
cur.InnerHandler = new T { InnerHandler = cur.InnerHandler };
|
||||
break;
|
||||
}
|
||||
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this method replicates the logic that the base ServiceClient uses except that it doesn't insert the RetryDelegatingHandler
|
||||
// and it does insert the WatcherDelegatingHandler. we don't want the RetryDelegatingHandler because it has a very broad definition
|
||||
// of what requests have failed. it considers everything outside 2xx to be failed, including 1xx (e.g. 101 Switching Protocols) and
|
||||
// 3xx. in particular, this prevents upgraded connections and certain generic/custom requests from working.
|
||||
private void CreateHttpClient(DelegatingHandler[] handlers, KubernetesClientConfiguration config)
|
||||
{
|
||||
FirstMessageHandler = HttpClientHandler = CreateRootHandler();
|
||||
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
// https://github.com/kubernetes-client/csharp/issues/587
|
||||
// let user control if tcp keep alive until better fix
|
||||
if (config.TcpKeepAlive)
|
||||
{
|
||||
// https://github.com/kubernetes-client/csharp/issues/533
|
||||
// net5 only
|
||||
// this is a temp fix to attach SocketsHttpHandler to HttpClient in order to set SO_KEEPALIVE
|
||||
// https://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
|
||||
//
|
||||
// _underlyingHandler is not a public accessible field
|
||||
// src of net5 HttpClientHandler and _underlyingHandler field defined here
|
||||
// https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs#L22
|
||||
//
|
||||
// Should remove after better solution
|
||||
|
||||
var sh = new SocketsHttpHandler
|
||||
FirstMessageHandler = HttpClientHandler = new SocketsHttpHandler
|
||||
{
|
||||
KeepAlivePingPolicy = HttpKeepAlivePingPolicy.WithActiveRequests,
|
||||
KeepAlivePingDelay = TimeSpan.FromMinutes(3),
|
||||
KeepAlivePingTimeout = TimeSpan.FromSeconds(30),
|
||||
};
|
||||
sh.ConnectCallback = async (context, token) =>
|
||||
{
|
||||
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
|
||||
{
|
||||
NoDelay = true,
|
||||
};
|
||||
|
||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
|
||||
|
||||
var host = context.DnsEndPoint.Host;
|
||||
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
// https://github.com/dotnet/runtime/issues/24917
|
||||
// GetHostAddresses will return {host} if host is an ip
|
||||
var ips = Dns.GetHostAddresses(host);
|
||||
if (ips.Length == 0)
|
||||
{
|
||||
throw new Exception($"{host} DNS lookup failed");
|
||||
}
|
||||
|
||||
host = ips[new Random().Next(ips.Length)].ToString();
|
||||
}
|
||||
|
||||
await socket.ConnectAsync(host, context.DnsEndPoint.Port, token).ConfigureAwait(false);
|
||||
return new NetworkStream(socket, ownsSocket: true);
|
||||
};
|
||||
|
||||
|
||||
// set HttpClientHandler's cert callback before replace _underlyingHandler
|
||||
// force HttpClientHandler use our callback
|
||||
InitializeFromConfig(config);
|
||||
|
||||
var p = HttpClientHandler.GetType().GetField("_underlyingHandler", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
p.SetValue(HttpClientHandler, (sh));
|
||||
}
|
||||
HttpClientHandler.SslOptions.ClientCertificates = new X509Certificate2Collection();
|
||||
#else
|
||||
FirstMessageHandler = HttpClientHandler = new HttpClientHandler();
|
||||
#endif
|
||||
|
||||
if (handlers == null || handlers.Length == 0)
|
||||
{
|
||||
// ensure we have at least one DelegatingHandler so AppendDelegatingHandler will work
|
||||
FirstMessageHandler = new ForwardingHandler(HttpClientHandler);
|
||||
}
|
||||
else
|
||||
if (handlers != null)
|
||||
{
|
||||
for (int i = handlers.Length - 1; i >= 0; i--)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.WebSockets;
|
||||
@@ -237,7 +237,11 @@ namespace k8s
|
||||
|
||||
if (this.HttpClientHandler != null)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
foreach (var cert in this.HttpClientHandler.SslOptions.ClientCertificates.OfType<X509Certificate2>())
|
||||
#else
|
||||
foreach (var cert in this.HttpClientHandler.ClientCertificates.OfType<X509Certificate2>())
|
||||
#endif
|
||||
{
|
||||
webSocketBuilder.AddClientCertificate(cert);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
@@ -29,197 +29,40 @@ namespace k8s
|
||||
/// </summary>
|
||||
public ServiceClientCredentials Credentials { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='httpClient'>
|
||||
/// HttpClient to be used
|
||||
/// </param>
|
||||
/// <param name='disposeHttpClient'>
|
||||
/// True: will dispose the provided httpClient on calling Kubernetes.Dispose(). False: will not dispose provided httpClient</param>
|
||||
protected Kubernetes(HttpClient httpClient, bool disposeHttpClient)
|
||||
: base(httpClient, disposeHttpClient)
|
||||
public HttpClient HttpClient { get; protected set; }
|
||||
|
||||
private IEnumerable<HttpMessageHandler> HttpMessageHandlers
|
||||
{
|
||||
Initialize();
|
||||
get
|
||||
{
|
||||
var handler = FirstMessageHandler;
|
||||
|
||||
while (handler != null)
|
||||
{
|
||||
yield return handler;
|
||||
|
||||
DelegatingHandler delegating = handler as DelegatingHandler;
|
||||
handler = delegating != null ? delegating.InnerHandler : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// Reference to the first HTTP handler (which is the start of send HTTP
|
||||
/// pipeline).
|
||||
/// </summary>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
protected Kubernetes(params DelegatingHandler[] handlers)
|
||||
: base(handlers)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
private HttpMessageHandler FirstMessageHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// Reference to the innermost HTTP handler (which is the end of send HTTP
|
||||
/// pipeline).
|
||||
/// </summary>
|
||||
/// <param name='rootHandler'>
|
||||
/// Optional. The http client handler used to handle http transport.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
protected Kubernetes(HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
|
||||
: base(rootHandler, handlers)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
#if NET5_0_OR_GREATER
|
||||
private SocketsHttpHandler HttpClientHandler { get; set; }
|
||||
#else
|
||||
private HttpClientHandler HttpClientHandler { get; set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='baseUri'>
|
||||
/// Optional. The base URI of the service.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
protected Kubernetes(Uri baseUri, params DelegatingHandler[] handlers)
|
||||
: this(handlers)
|
||||
{
|
||||
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='baseUri'>
|
||||
/// Optional. The base URI of the service.
|
||||
/// </param>
|
||||
/// <param name='rootHandler'>
|
||||
/// Optional. The http client handler used to handle http transport.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
protected Kubernetes(Uri baseUri, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
|
||||
: this(rootHandler, handlers)
|
||||
{
|
||||
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='credentials'>
|
||||
/// Required. Subscription credentials which uniquely identify client subscription.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
public Kubernetes(ServiceClientCredentials credentials, params DelegatingHandler[] handlers)
|
||||
: this(handlers)
|
||||
{
|
||||
Credentials = credentials ?? throw new ArgumentNullException(nameof(credentials));
|
||||
Credentials.InitializeServiceClient(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='credentials'>
|
||||
/// Required. Subscription credentials which uniquely identify client subscription.
|
||||
/// </param>
|
||||
/// <param name='httpClient'>
|
||||
/// HttpClient to be used
|
||||
/// </param>
|
||||
/// <param name='disposeHttpClient'>
|
||||
/// True: will dispose the provided httpClient on calling Kubernetes.Dispose(). False: will not dispose provided httpClient</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
[Obsolete]
|
||||
public Kubernetes(ServiceClientCredentials credentials, HttpClient httpClient, bool disposeHttpClient)
|
||||
: this(httpClient, disposeHttpClient)
|
||||
{
|
||||
Credentials = credentials ?? throw new ArgumentNullException(nameof(credentials));
|
||||
Credentials.InitializeServiceClient(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='credentials'>
|
||||
/// Required. Subscription credentials which uniquely identify client subscription.
|
||||
/// </param>
|
||||
/// <param name='rootHandler'>
|
||||
/// Optional. The http client handler used to handle http transport.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
public Kubernetes(ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
|
||||
: this(rootHandler, handlers)
|
||||
{
|
||||
Credentials = credentials ?? throw new ArgumentNullException(nameof(credentials));
|
||||
Credentials.InitializeServiceClient(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='baseUri'>
|
||||
/// Optional. The base URI of the service.
|
||||
/// </param>
|
||||
/// <param name='credentials'>
|
||||
/// Required. Subscription credentials which uniquely identify client subscription.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
public Kubernetes(Uri baseUri, ServiceClientCredentials credentials, params DelegatingHandler[] handlers)
|
||||
: this(handlers)
|
||||
{
|
||||
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
|
||||
Credentials = credentials ?? throw new ArgumentNullException(nameof(credentials));
|
||||
Credentials.InitializeServiceClient(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kubernetes"/> class.
|
||||
/// </summary>
|
||||
/// <param name='baseUri'>
|
||||
/// Optional. The base URI of the service.
|
||||
/// </param>
|
||||
/// <param name='credentials'>
|
||||
/// Required. Subscription credentials which uniquely identify client subscription.
|
||||
/// </param>
|
||||
/// <param name='rootHandler'>
|
||||
/// Optional. The http client handler used to handle http transport.
|
||||
/// </param>
|
||||
/// <param name='handlers'>
|
||||
/// Optional. The delegating handlers to add to the http client pipeline.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when a required parameter is null
|
||||
/// </exception>
|
||||
public Kubernetes(Uri baseUri, ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
|
||||
: this(rootHandler, handlers)
|
||||
{
|
||||
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
|
||||
Credentials = credentials ?? throw new ArgumentNullException(nameof(credentials));
|
||||
Credentials.InitializeServiceClient(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes client properties.
|
||||
@@ -227,7 +70,6 @@ namespace k8s
|
||||
private void Initialize()
|
||||
{
|
||||
BaseUri = new Uri("http://localhost");
|
||||
CustomInitialize();
|
||||
}
|
||||
|
||||
private async Task<HttpOperationResponse<T>> CreateResultAsync<T>(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse, bool? watch, CancellationToken cancellationToken)
|
||||
@@ -250,11 +92,11 @@ namespace k8s
|
||||
result.Body = KubernetesJson.Deserialize<T>(stream);
|
||||
}
|
||||
}
|
||||
catch (JsonException ex)
|
||||
catch (JsonException)
|
||||
{
|
||||
httpRequest.Dispose();
|
||||
httpResponse.Dispose();
|
||||
throw new SerializationException("Unable to deserialize the response.", ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -370,5 +212,37 @@ namespace k8s
|
||||
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the ServiceClient has been disposed.
|
||||
/// </summary>
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the ServiceClient.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the HttpClient and Handlers.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True to release both managed and unmanaged resources; false to releases only unmanaged resources.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
// Dispose the client
|
||||
HttpClient?.Dispose();
|
||||
HttpClient = null;
|
||||
FirstMessageHandler = null;
|
||||
HttpClientHandler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||
<PackageReference Include="IdentityModel.OidcClient" Version="4.0.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.23" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.0" Coondition="'$(TargetFramework)' == 'netstandard2.1'" />
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.Net.Http;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
public partial class KubernetesClientConfiguration
|
||||
{
|
||||
public HttpClientHandler CreateDefaultHttpClientHandler()
|
||||
{
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
|
||||
var uriScheme = new Uri(this.Host).Scheme;
|
||||
|
||||
if (uriScheme == "https")
|
||||
{
|
||||
if (SkipTlsVerify)
|
||||
{
|
||||
httpClientHandler.ServerCertificateCustomValidationCallback =
|
||||
(sender, certificate, chain, sslPolicyErrors) => true;
|
||||
}
|
||||
else
|
||||
{
|
||||
httpClientHandler.ServerCertificateCustomValidationCallback =
|
||||
(sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
return Kubernetes.CertificateValidationCallBack(sender, SslCaCerts, certificate, chain,
|
||||
sslPolicyErrors);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
AddCertificates(httpClientHandler);
|
||||
|
||||
return httpClientHandler;
|
||||
}
|
||||
|
||||
public void AddCertificates(HttpClientHandler handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(handler));
|
||||
}
|
||||
|
||||
var clientCert = CertUtils.GetClientCert(this);
|
||||
if (clientCert != null)
|
||||
{
|
||||
handler.ClientCertificates.Add(clientCert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
@@ -83,14 +83,6 @@ namespace k8s
|
||||
/// <value>The access token.</value>
|
||||
public ITokenProvider TokenProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set true to enable tcp keep alive
|
||||
/// You have to set https://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html as well
|
||||
/// </summary>
|
||||
/// <value>true or false</value>
|
||||
public bool TcpKeepAlive { get; set; } = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Timeout of REST calls to Kubernetes server
|
||||
/// Does not apply to watch related api
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s.Models
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s.LeaderElection
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
|
||||
namespace k8s.LeaderElection.ResourceLock
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using k8s.Models;
|
||||
using k8s.Util.Common.Generic.Options;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s.Util.Common.Generic
|
||||
{
|
||||
@@ -43,13 +43,6 @@ namespace k8s.Util.Common.Generic
|
||||
_client = apiClient ?? new Kubernetes(KubernetesClientConfiguration.BuildDefaultConfig());
|
||||
}
|
||||
|
||||
public TimeSpan ClientTimeout => _client.HttpClient.Timeout;
|
||||
|
||||
public void SetClientTimeout(TimeSpan value)
|
||||
{
|
||||
_client.HttpClient.Timeout = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get kubernetes object.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using k8s.Exceptions;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ using Json.Patch;
|
||||
using k8s.LeaderElection;
|
||||
using k8s.LeaderElection.ResourceLock;
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using Nito.AsyncEx;
|
||||
using Xunit;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ using k8s.Models;
|
||||
using k8s.Tests.Mock;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Https;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Pkcs;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
using k8s.Tests.Mock;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@@ -24,13 +24,12 @@ namespace k8s.Tests
|
||||
[Fact]
|
||||
public async Task WebSocketNamespacedPodExecAsync()
|
||||
{
|
||||
var credentials = new BasicAuthenticationCredentials()
|
||||
Kubernetes client = new Kubernetes(new KubernetesClientConfiguration()
|
||||
{
|
||||
UserName = "my-user",
|
||||
Host = "http://localhost",
|
||||
Username = "my-user",
|
||||
Password = "my-secret-password",
|
||||
};
|
||||
|
||||
Kubernetes client = new Kubernetes(credentials);
|
||||
});
|
||||
client.BaseUri = new Uri("http://localhost");
|
||||
|
||||
MockWebSocketBuilder mockWebSocketBuilder = new MockWebSocketBuilder();
|
||||
@@ -71,14 +70,12 @@ namespace k8s.Tests
|
||||
[Fact]
|
||||
public async Task WebSocketNamespacedPodPortForwardAsync()
|
||||
{
|
||||
var credentials = new BasicAuthenticationCredentials()
|
||||
Kubernetes client = new Kubernetes(new KubernetesClientConfiguration()
|
||||
{
|
||||
UserName = "my-user",
|
||||
Host = "http://localhost",
|
||||
Username = "my-user",
|
||||
Password = "my-secret-password",
|
||||
};
|
||||
|
||||
Kubernetes client = new Kubernetes(credentials);
|
||||
client.BaseUri = new Uri("http://localhost");
|
||||
});
|
||||
|
||||
MockWebSocketBuilder mockWebSocketBuilder = new MockWebSocketBuilder();
|
||||
client.CreateWebSocketBuilder = () => mockWebSocketBuilder;
|
||||
@@ -112,13 +109,12 @@ namespace k8s.Tests
|
||||
[Fact]
|
||||
public async Task WebSocketNamespacedPodAttachAsync()
|
||||
{
|
||||
var credentials = new BasicAuthenticationCredentials()
|
||||
Kubernetes client = new Kubernetes(new KubernetesClientConfiguration()
|
||||
{
|
||||
UserName = "my-user",
|
||||
Host = "http://localhost",
|
||||
Username = "my-user",
|
||||
Password = "my-secret-password",
|
||||
};
|
||||
|
||||
Kubernetes client = new Kubernetes(credentials);
|
||||
});
|
||||
client.BaseUri = new Uri("http://localhost");
|
||||
|
||||
MockWebSocketBuilder mockWebSocketBuilder = new MockWebSocketBuilder();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
using k8s.Models;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -193,7 +193,7 @@ namespace k8s.Tests
|
||||
muxedStream.Setup(m => m.GetStream(ChannelIndex.Error, null)).Returns(errorStream);
|
||||
|
||||
var kubernetesMock = new Moq.Mock<Kubernetes>(
|
||||
new object[] { Moq.Mock.Of<ServiceClientCredentials>(), new DelegatingHandler[] { } })
|
||||
new object[] { new KubernetesClientConfiguration() { Host = "http://localhost" }, new DelegatingHandler[] { } })
|
||||
{ CallBase = true };
|
||||
var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
|
||||
|
||||
@@ -216,7 +216,7 @@ namespace k8s.Tests
|
||||
public async Task NamespacedPodExecAsyncHttpExceptionWithStatus()
|
||||
{
|
||||
var kubernetesMock = new Moq.Mock<Kubernetes>(
|
||||
new object[] { Moq.Mock.Of<ServiceClientCredentials>(), new DelegatingHandler[] { } })
|
||||
new object[] { new KubernetesClientConfiguration() { Host = "http://localhost" }, new DelegatingHandler[] { } })
|
||||
{ CallBase = true };
|
||||
var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
|
||||
var handler = new ExecAsyncCallback((stdIn, stdOut, stdError) => Task.CompletedTask);
|
||||
@@ -241,7 +241,7 @@ namespace k8s.Tests
|
||||
public async Task NamespacedPodExecAsyncHttpExceptionNoStatus()
|
||||
{
|
||||
var kubernetesMock = new Moq.Mock<Kubernetes>(
|
||||
new object[] { Moq.Mock.Of<ServiceClientCredentials>(), new DelegatingHandler[] { } })
|
||||
new object[] { new KubernetesClientConfiguration() { Host = "http://localhost" }, new DelegatingHandler[] { } })
|
||||
{ CallBase = true };
|
||||
var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
|
||||
var handler = new ExecAsyncCallback((stdIn, stdOut, stdError) => Task.CompletedTask);
|
||||
@@ -265,7 +265,7 @@ namespace k8s.Tests
|
||||
public async Task NamespacedPodExecAsyncGenericException()
|
||||
{
|
||||
var kubernetesMock = new Moq.Mock<Kubernetes>(
|
||||
new object[] { Moq.Mock.Of<ServiceClientCredentials>(), new DelegatingHandler[] { } })
|
||||
new object[] { new KubernetesClientConfiguration() { Host = "http://localhost" }, new DelegatingHandler[] { } })
|
||||
{ CallBase = true };
|
||||
var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
|
||||
var handler = new ExecAsyncCallback((stdIn, stdOut, stdError) => Task.CompletedTask);
|
||||
@@ -319,7 +319,7 @@ namespace k8s.Tests
|
||||
muxedStream.Setup(m => m.GetStream(ChannelIndex.Error, null)).Returns(errorStream);
|
||||
|
||||
var kubernetesMock = new Moq.Mock<Kubernetes>(
|
||||
new object[] { Moq.Mock.Of<ServiceClientCredentials>(), new DelegatingHandler[] { } })
|
||||
new object[] { new KubernetesClientConfiguration() { Host = "http://localhost" }, new DelegatingHandler[] { } })
|
||||
{ CallBase = true };
|
||||
var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Rest;
|
||||
using k8s.Autorest;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.WebSockets;
|
||||
@@ -132,7 +132,10 @@ namespace k8s.Tests
|
||||
/// </returns>
|
||||
protected virtual Kubernetes CreateTestClient(ServiceClientCredentials credentials = null)
|
||||
{
|
||||
return new Kubernetes(credentials ?? AnonymousClientCredentials.Instance) { BaseUri = ServerBaseAddress };
|
||||
return new Kubernetes(new KubernetesClientConfiguration()
|
||||
{
|
||||
Host = ServerBaseAddress.ToString(),
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
|
||||
"version": "7.0",
|
||||
"version": "7.1",
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/master$", // we release out of master
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user