Version 17.0 + Generate 1.33 (#1626)
* generated based on 1.33 * Update version to 17.0 in version.json * Remove extra API endpoint from swagger.json * Remove ModelConverter and related AutoMapper components * Update package versions * Refactor code to use ConfigureAwait(false) for asynchronous calls and update target framework to net9.0 * Remove ConfigureAwait(false) from OidcAuthTests for consistency in async calls * Update SDK version in README to reflect support for net8.0 and net9.0 * Update dotnet SDK version to 9.0.x in build workflow * Revert Fractions package version to 7.3.0 in Directory.Packages.props * Update target framework to netstandard2.1 for improved compatibility * Update package references for Microsoft.CodeAnalysis in Directory.Packages.props and LibKubernetesGenerator.target * Refactor Worker class constructor documentation and standardize Dictionary type declaration in Program.cs
This commit is contained in:
2
.github/workflows/buildtest.yaml
vendored
2
.github/workflows/buildtest.yaml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
- name: Setup dotnet SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '9.0.x'
|
||||
- name: Restore nugets (msbuild)
|
||||
run: msbuild .\src\KubernetesClient\ -t:restore -p:RestorePackagesConfig=true
|
||||
- name: Build (msbuild)
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.0" />
|
||||
<PackageVersion Include="FluentAssertions" Version="7.0.0" />
|
||||
<PackageVersion Include="Fractions" Version="7.3.0" />
|
||||
<PackageVersion Include="JsonPatch.Net" Version="2.1.0" />
|
||||
<PackageVersion Include="MartinCostello.Logging.XUnit" Version="0.5.1" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageVersion Include="Microsoft.TestPlatform.ObjectModel" Version="17.12.0" />
|
||||
<PackageVersion Include="Moq" Version="4.20.72" />
|
||||
<PackageVersion Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.7.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
|
||||
<PackageVersion Include="Portable.BouncyCastle" Version="1.9.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.0" />
|
||||
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="21.2.1" />
|
||||
<PackageVersion Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
|
||||
<PackageVersion Include="Vecc.YamlDotNet.Analyzers.StaticGenerator" Version="16.3.0" />
|
||||
<PackageVersion Include="Wiremock.Net" Version="1.7.4" />
|
||||
<PackageVersion Include="xunit" Version="2.9.2" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0" />
|
||||
<PackageVersion Include="Xunit.StaFact" Version="1.1.11" />
|
||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Autofac" Version="8.2.0" />
|
||||
<PackageVersion Include="CaseExtensions" Version="1.1.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.4.0" />
|
||||
<PackageVersion Include="Namotion.Reflection" Version="3.0.1" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="NJsonSchema" Version="10.9.0" />
|
||||
<PackageVersion Include="NSwag.Core" Version="13.20.0" />
|
||||
<PackageVersion Include="Scriban" Version="5.9.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
|
||||
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
<GlobalPackageReference Include="Microsoft.VisualStudio.SlnGen" Version="12.0.3" />
|
||||
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.7.112" />
|
||||
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
|
||||
</ItemGroup>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.1" />
|
||||
<PackageVersion Include="FluentAssertions" Version="8.2.0" />
|
||||
<PackageVersion Include="Fractions" Version="7.3.0" />
|
||||
<PackageVersion Include="JsonPatch.Net" Version="3.3.0" />
|
||||
<PackageVersion Include="MartinCostello.Logging.XUnit" Version="0.5.1" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
|
||||
<PackageVersion Include="Microsoft.TestPlatform.ObjectModel" Version="17.13.0" />
|
||||
<PackageVersion Include="Moq" Version="4.20.72" />
|
||||
<PackageVersion Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.11.2" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.11.1" />
|
||||
<PackageVersion Include="Portable.BouncyCastle" Version="1.9.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
||||
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.4" />
|
||||
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="22.0.14" />
|
||||
<PackageVersion Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.4" />
|
||||
<PackageVersion Include="Vecc.YamlDotNet.Analyzers.StaticGenerator" Version="16.3.0" />
|
||||
<PackageVersion Include="Wiremock.Net" Version="1.7.4" />
|
||||
<PackageVersion Include="xunit" Version="2.9.3" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
|
||||
<PackageVersion Include="Xunit.StaFact" Version="1.2.69" />
|
||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Autofac" Version="8.2.1" />
|
||||
<PackageVersion Include="CaseExtensions" Version="1.1.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.13.0" />
|
||||
<PackageVersion Include="Namotion.Reflection" Version="3.3.0" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="NJsonSchema" Version="11.2.0" />
|
||||
<PackageVersion Include="NJsonSchema.Annotations" Version="11.2.0" />
|
||||
<PackageVersion Include="NSwag.Core" Version="14.3.0" />
|
||||
<PackageVersion Include="Scriban" Version="6.2.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
|
||||
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
<GlobalPackageReference Include="Microsoft.VisualStudio.SlnGen" Version="12.0.3" />
|
||||
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.7.112" />
|
||||
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -154,6 +154,7 @@ ${GEN_DIR}/openapi/csharp.sh ${REPO_DIR}/src/KubernetesClient ${REPO_DIR}/csharp
|
||||
|
||||
| SDK Version | Kubernetes Version | .NET Targeting |
|
||||
|-------------|--------------------|-----------------------------------------------------|
|
||||
| 17.0 | 1.33 | net8.0;net9.0;net48*;netstandard2.0* |
|
||||
| 16.0 | 1.32 | net8.0;net9.0;net48*;netstandard2.0* |
|
||||
| 15.0 | 1.31 | net6.0;net8.0;net48*;netstandard2.0* |
|
||||
| 14.0 | 1.30 | net6.0;net8.0;net48*;netstandard2.0* |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export KUBERNETES_BRANCH=v1.32.0
|
||||
export KUBERNETES_BRANCH=v1.33.0
|
||||
export CLIENT_VERSION=0.0.1
|
||||
export PACKAGE_NAME=k8s
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\Directory.Build.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\Directory.Build.targets" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\src\KubernetesClient\KubernetesClient.csproj" Condition="'$(PublishAot)' != 'true'" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using ICSharpCode.SharpZipLib.Tar;
|
||||
using ICSharpCode.SharpZipLib.Tar;
|
||||
using k8s;
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -7,110 +7,104 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace cp
|
||||
namespace cp;
|
||||
|
||||
internal class Cp
|
||||
{
|
||||
internal class Cp
|
||||
private static IKubernetes client;
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
private static IKubernetes client;
|
||||
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
|
||||
client = new Kubernetes(config);
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
|
||||
var pods = client.CoreV1.ListNamespacedPod("default", null, null, null, $"job-name=upload-demo");
|
||||
var pod = pods.Items.First();
|
||||
|
||||
await CopyFileToPodAsync(pod.Metadata.Name, "default", "upload-demo", args[0], $"home/{args[1]}").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static void ValidatePathParameters(string sourcePath, string destinationPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourcePath))
|
||||
{
|
||||
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
|
||||
client = new Kubernetes(config);
|
||||
|
||||
|
||||
var pods = client.CoreV1.ListNamespacedPod("default", null, null, null, $"job-name=upload-demo");
|
||||
var pod = pods.Items.First();
|
||||
|
||||
await CopyFileToPodAsync(pod.Metadata.Name, "default", "upload-demo", args[0], $"home/{args[1]}");
|
||||
|
||||
throw new ArgumentException($"{nameof(sourcePath)} cannot be null or whitespace");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static void ValidatePathParameters(string sourcePath, string destinationPath)
|
||||
if (string.IsNullOrWhiteSpace(destinationPath))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourcePath))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(sourcePath)} cannot be null or whitespace");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(destinationPath))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(destinationPath)} cannot be null or whitespace");
|
||||
}
|
||||
|
||||
throw new ArgumentException($"{nameof(destinationPath)} cannot be null or whitespace");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<int> CopyFileToPodAsync(string name, string @namespace, string container, string sourceFilePath, string destinationFilePath, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static async Task<int> CopyFileToPodAsync(string name, string @namespace, string container, string sourceFilePath, string destinationFilePath, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
// All other parameters are being validated by MuxedStreamNamespacedPodExecAsync called by NamespacedPodExecAsync
|
||||
ValidatePathParameters(sourceFilePath, destinationFilePath);
|
||||
|
||||
// The callback which processes the standard input, standard output and standard error of exec method
|
||||
var handler = new ExecAsyncCallback(async (stdIn, stdOut, stdError) =>
|
||||
{
|
||||
// All other parameters are being validated by MuxedStreamNamespacedPodExecAsync called by NamespacedPodExecAsync
|
||||
ValidatePathParameters(sourceFilePath, destinationFilePath);
|
||||
|
||||
// The callback which processes the standard input, standard output and standard error of exec method
|
||||
var handler = new ExecAsyncCallback(async (stdIn, stdOut, stdError) =>
|
||||
var fileInfo = new FileInfo(destinationFilePath);
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(destinationFilePath);
|
||||
try
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
using (var inputFileStream = File.OpenRead(sourceFilePath))
|
||||
using (var tarOutputStream = new TarOutputStream(memoryStream, Encoding.Default))
|
||||
{
|
||||
using (var inputFileStream = File.OpenRead(sourceFilePath))
|
||||
using (var tarOutputStream = new TarOutputStream(memoryStream, Encoding.Default))
|
||||
{
|
||||
tarOutputStream.IsStreamOwner = false;
|
||||
tarOutputStream.IsStreamOwner = false;
|
||||
|
||||
var fileSize = inputFileStream.Length;
|
||||
var entry = TarEntry.CreateTarEntry(fileInfo.Name);
|
||||
var fileSize = inputFileStream.Length;
|
||||
var entry = TarEntry.CreateTarEntry(fileInfo.Name);
|
||||
|
||||
entry.Size = fileSize;
|
||||
entry.Size = fileSize;
|
||||
|
||||
tarOutputStream.PutNextEntry(entry);
|
||||
await inputFileStream.CopyToAsync(tarOutputStream);
|
||||
tarOutputStream.CloseEntry();
|
||||
}
|
||||
|
||||
memoryStream.Position = 0;
|
||||
|
||||
await memoryStream.CopyToAsync(stdIn);
|
||||
await stdIn.FlushAsync();
|
||||
tarOutputStream.PutNextEntry(entry);
|
||||
await inputFileStream.CopyToAsync(tarOutputStream).ConfigureAwait(false);
|
||||
tarOutputStream.CloseEntry();
|
||||
}
|
||||
|
||||
memoryStream.Position = 0;
|
||||
|
||||
await memoryStream.CopyToAsync(stdIn).ConfigureAwait(false);
|
||||
await stdIn.FlushAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Copy command failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Copy command failed: {ex.Message}");
|
||||
}
|
||||
|
||||
using StreamReader streamReader = new StreamReader(stdError);
|
||||
while (streamReader.EndOfStream == false)
|
||||
{
|
||||
string error = await streamReader.ReadToEndAsync();
|
||||
throw new IOException($"Copy command failed: {error}");
|
||||
}
|
||||
});
|
||||
using StreamReader streamReader = new StreamReader(stdError);
|
||||
while (streamReader.EndOfStream == false)
|
||||
{
|
||||
string error = await streamReader.ReadToEndAsync().ConfigureAwait(false);
|
||||
throw new IOException($"Copy command failed: {error}");
|
||||
}
|
||||
});
|
||||
|
||||
string destinationFolder = GetFolderName(destinationFilePath);
|
||||
string destinationFolder = GetFolderName(destinationFilePath);
|
||||
|
||||
return await client.NamespacedPodExecAsync(
|
||||
name,
|
||||
@namespace,
|
||||
container,
|
||||
new string[] { "sh", "-c", $"tar xmf - -C {destinationFolder}" },
|
||||
false,
|
||||
handler,
|
||||
cancellationToken);
|
||||
}
|
||||
return await client.NamespacedPodExecAsync(
|
||||
name,
|
||||
@namespace,
|
||||
container,
|
||||
new string[] { "sh", "-c", $"tar xmf - -C {destinationFolder}" },
|
||||
false,
|
||||
handler,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
private static string GetFolderName(string filePath)
|
||||
{
|
||||
var folderName = Path.GetDirectoryName(filePath);
|
||||
|
||||
return string.IsNullOrEmpty(folderName) ? "." : folderName;
|
||||
}
|
||||
|
||||
private static string GetFolderName(string filePath)
|
||||
{
|
||||
var folderName = Path.GetDirectoryName(filePath);
|
||||
|
||||
return string.IsNullOrEmpty(folderName) ? "." : folderName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Json.Patch;
|
||||
using Json.Patch;
|
||||
using k8s;
|
||||
using k8s.Models;
|
||||
using System.Net;
|
||||
@@ -44,34 +44,34 @@ var request = new V1CertificateSigningRequest
|
||||
Kind = "CertificateSigningRequest",
|
||||
Metadata = new V1ObjectMeta
|
||||
{
|
||||
Name = name
|
||||
Name = name,
|
||||
},
|
||||
Spec = new V1CertificateSigningRequestSpec
|
||||
{
|
||||
Request = encodedCsr,
|
||||
SignerName = "kubernetes.io/kube-apiserver-client",
|
||||
Usages = new List<string> { "client auth" },
|
||||
ExpirationSeconds = 600 // minimum should be 10 minutes
|
||||
}
|
||||
ExpirationSeconds = 600, // minimum should be 10 minutes
|
||||
},
|
||||
};
|
||||
|
||||
await client.CertificatesV1.CreateCertificateSigningRequestAsync(request);
|
||||
await client.CertificatesV1.CreateCertificateSigningRequestAsync(request).ConfigureAwait(false);
|
||||
|
||||
var serializeOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
WriteIndented = true,
|
||||
};
|
||||
var readCert = await client.CertificatesV1.ReadCertificateSigningRequestAsync(name);
|
||||
var readCert = await client.CertificatesV1.ReadCertificateSigningRequestAsync(name).ConfigureAwait(false);
|
||||
var old = JsonSerializer.SerializeToDocument(readCert, serializeOptions);
|
||||
|
||||
var replace = new List<V1CertificateSigningRequestCondition>
|
||||
{
|
||||
new("True", "Approved", DateTime.UtcNow, DateTime.UtcNow, "This certificate was approved by k8s client", "Approve")
|
||||
new("True", "Approved", DateTime.UtcNow, DateTime.UtcNow, "This certificate was approved by k8s client", "Approve"),
|
||||
};
|
||||
readCert.Status.Conditions = replace;
|
||||
|
||||
var expected = JsonSerializer.SerializeToDocument(readCert, serializeOptions);
|
||||
|
||||
var patch = old.CreatePatch(expected);
|
||||
await client.CertificatesV1.PatchCertificateSigningRequestApprovalAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name);
|
||||
await client.CertificatesV1.PatchCertificateSigningRequestApprovalAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name).ConfigureAwait(false);
|
||||
|
||||
@@ -29,6 +29,7 @@ foreach (var item in list.Items)
|
||||
{
|
||||
Console.WriteLine(item.Metadata.Name);
|
||||
}
|
||||
|
||||
// Or empty if there are no pods
|
||||
if (list.Items.Count == 0)
|
||||
{
|
||||
|
||||
@@ -28,5 +28,6 @@ static void PrintLabels(V1Pod pod)
|
||||
{
|
||||
Console.WriteLine($"{k} : {v}");
|
||||
}
|
||||
|
||||
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=");
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ namespace portforward
|
||||
|
||||
var list = client.CoreV1.ListNamespacedPod("default");
|
||||
var pod = list.Items[0];
|
||||
await Forward(client, pod);
|
||||
await Forward(client, pod).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task Forward(IKubernetes client, V1Pod pod)
|
||||
{
|
||||
// Note this is single-threaded, it won't handle concurrent requests well...
|
||||
var webSocket = await client.WebSocketNamespacedPodPortForwardAsync(pod.Metadata.Name, "default", new int[] { 80 }, "v4.channel.k8s.io");
|
||||
var webSocket = await client.WebSocketNamespacedPodPortForwardAsync(pod.Metadata.Name, "default", new int[] { 80 }, "v4.channel.k8s.io").ConfigureAwait(false);
|
||||
var demux = new StreamDemuxer(webSocket, StreamType.PortForward);
|
||||
demux.Start();
|
||||
|
||||
@@ -67,12 +67,13 @@ namespace portforward
|
||||
}
|
||||
});
|
||||
|
||||
await accept;
|
||||
await copy;
|
||||
await accept.ConfigureAwait(false);
|
||||
await copy.ConfigureAwait(false);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.Close();
|
||||
}
|
||||
|
||||
listener.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
using Json.Patch;
|
||||
using Json.Patch;
|
||||
using k8s;
|
||||
using k8s.Models;
|
||||
using System.Text.Json;
|
||||
|
||||
async Task RestartDaemonSetAsync(string name, string @namespace, IKubernetes client)
|
||||
{
|
||||
var daemonSet = await client.AppsV1.ReadNamespacedDaemonSetAsync(name, @namespace);
|
||||
var daemonSet = await client.AppsV1.ReadNamespacedDaemonSetAsync(name, @namespace).ConfigureAwait(false);
|
||||
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true };
|
||||
var old = JsonSerializer.SerializeToDocument(daemonSet, options);
|
||||
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
var restart = new Dictionary<string, string>
|
||||
{
|
||||
["date"] = now.ToString()
|
||||
["date"] = now.ToString(),
|
||||
};
|
||||
|
||||
daemonSet.Spec.Template.Metadata.Annotations = restart;
|
||||
@@ -19,18 +19,18 @@ async Task RestartDaemonSetAsync(string name, string @namespace, IKubernetes cli
|
||||
var expected = JsonSerializer.SerializeToDocument(daemonSet);
|
||||
|
||||
var patch = old.CreatePatch(expected);
|
||||
await client.AppsV1.PatchNamespacedDaemonSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace);
|
||||
await client.AppsV1.PatchNamespacedDaemonSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
async Task RestartDeploymentAsync(string name, string @namespace, IKubernetes client)
|
||||
{
|
||||
var deployment = await client.AppsV1.ReadNamespacedDeploymentAsync(name, @namespace);
|
||||
var deployment = await client.AppsV1.ReadNamespacedDeploymentAsync(name, @namespace).ConfigureAwait(false);
|
||||
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true };
|
||||
var old = JsonSerializer.SerializeToDocument(deployment, options);
|
||||
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
var restart = new Dictionary<string, string>
|
||||
{
|
||||
["date"] = now.ToString()
|
||||
["date"] = now.ToString(),
|
||||
};
|
||||
|
||||
deployment.Spec.Template.Metadata.Annotations = restart;
|
||||
@@ -38,18 +38,18 @@ async Task RestartDeploymentAsync(string name, string @namespace, IKubernetes cl
|
||||
var expected = JsonSerializer.SerializeToDocument(deployment);
|
||||
|
||||
var patch = old.CreatePatch(expected);
|
||||
await client.AppsV1.PatchNamespacedDeploymentAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace);
|
||||
await client.AppsV1.PatchNamespacedDeploymentAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
async Task RestartStatefulSetAsync(string name, string @namespace, IKubernetes client)
|
||||
{
|
||||
var deployment = await client.AppsV1.ReadNamespacedStatefulSetAsync(name, @namespace);
|
||||
var deployment = await client.AppsV1.ReadNamespacedStatefulSetAsync(name, @namespace).ConfigureAwait(false);
|
||||
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true };
|
||||
var old = JsonSerializer.SerializeToDocument(deployment, options);
|
||||
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
var restart = new Dictionary<string, string>
|
||||
{
|
||||
["date"] = now.ToString()
|
||||
["date"] = now.ToString(),
|
||||
};
|
||||
|
||||
deployment.Spec.Template.Metadata.Annotations = restart;
|
||||
@@ -57,12 +57,12 @@ async Task RestartStatefulSetAsync(string name, string @namespace, IKubernetes c
|
||||
var expected = JsonSerializer.SerializeToDocument(deployment);
|
||||
|
||||
var patch = old.CreatePatch(expected);
|
||||
await client.AppsV1.PatchNamespacedStatefulSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace);
|
||||
await client.AppsV1.PatchNamespacedStatefulSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
|
||||
IKubernetes client = new Kubernetes(config);
|
||||
|
||||
await RestartDeploymentAsync("event-exporter", "monitoring", client);
|
||||
await RestartDaemonSetAsync("prometheus-exporter", "monitoring", client);
|
||||
await RestartStatefulSetAsync("argocd-application-controlle", "argocd", client);
|
||||
await RestartDeploymentAsync("event-exporter", "monitoring", client).ConfigureAwait(false);
|
||||
await RestartDaemonSetAsync("prometheus-exporter", "monitoring", client).ConfigureAwait(false);
|
||||
await RestartStatefulSetAsync("argocd-application-controlle", "argocd", client).ConfigureAwait(false);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace watch
|
||||
|
||||
var podlistResp = client.CoreV1.ListNamespacedPodWithHttpMessagesAsync("default", watch: true);
|
||||
// C# 8 required https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8
|
||||
await foreach (var (type, item) in podlistResp.WatchAsync<V1Pod, V1PodList>())
|
||||
await foreach (var (type, item) in podlistResp.WatchAsync<V1Pod, V1PodList>().ConfigureAwait(false))
|
||||
{
|
||||
Console.WriteLine("==on watch event==");
|
||||
Console.WriteLine(type);
|
||||
@@ -28,7 +28,9 @@ namespace watch
|
||||
// WatchUsingCallback(client);
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private members
|
||||
private static void WatchUsingCallback(IKubernetes client)
|
||||
#pragma warning restore IDE0051 // Remove unused private members
|
||||
{
|
||||
var podlistResp = client.CoreV1.ListNamespacedPodWithHttpMessagesAsync("default", watch: true);
|
||||
using (podlistResp.Watch<V1Pod, V1PodList>((type, item) =>
|
||||
|
||||
@@ -14,4 +14,4 @@ IHost host = Host.CreateDefaultBuilder(args)
|
||||
})
|
||||
.Build();
|
||||
|
||||
await host.RunAsync();
|
||||
await host.RunAsync().ConfigureAwait(false);
|
||||
|
||||
@@ -8,10 +8,11 @@ namespace workerServiceDependencyInjection
|
||||
private readonly IKubernetes kubernetesClient;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Worker"/> class.
|
||||
/// Inject in the constructor the IKubernetes interface.
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="kubernetesClient"></param>
|
||||
/// <param name="logger">The logger instance used for logging information.</param>
|
||||
/// <param name="kubernetesClient">The Kubernetes client used to interact with the Kubernetes API.</param>
|
||||
public Worker(ILogger<Worker> logger, IKubernetes kubernetesClient)
|
||||
{
|
||||
this.logger = logger;
|
||||
@@ -33,7 +34,7 @@ namespace workerServiceDependencyInjection
|
||||
Console.WriteLine(pod.Metadata.Name);
|
||||
}
|
||||
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ namespace yaml
|
||||
{
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
var typeMap = new Dictionary<String, Type>
|
||||
var typeMap = new Dictionary<string, Type>
|
||||
{
|
||||
{ "v1/Pod", typeof(V1Pod) },
|
||||
{ "v1/Service", typeof(V1Service) },
|
||||
{ "apps/v1/Deployment", typeof(V1Deployment) }
|
||||
{ "apps/v1/Deployment", typeof(V1Deployment) },
|
||||
};
|
||||
|
||||
var objects = await KubernetesYaml.LoadAllFromFileAsync(args[0], typeMap);
|
||||
var objects = await KubernetesYaml.LoadAllFromFileAsync(args[0], typeMap).ConfigureAwait(false);
|
||||
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using static k8s.Models.ModelVersionConverter;
|
||||
|
||||
namespace k8s.ModelConverter.AutoMapper;
|
||||
|
||||
public class AutoMapperModelVersionConverter : IModelVersionConverter
|
||||
{
|
||||
public static IModelVersionConverter Instance { get; } = new AutoMapperModelVersionConverter();
|
||||
|
||||
private AutoMapperModelVersionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public TTo Convert<TFrom, TTo>(TFrom from)
|
||||
{
|
||||
return VersionConverter.Mapper.Map<TTo>(from);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace k8s.ModelConverter.AutoMapper;
|
||||
|
||||
internal class KubernetesVersionComparer : IComparer<string>
|
||||
{
|
||||
public static KubernetesVersionComparer Instance { get; } = new KubernetesVersionComparer();
|
||||
private static readonly Regex KubernetesVersionRegex = new Regex(@"^v(?<major>[0-9]+)((?<stream>alpha|beta)(?<minor>[0-9]+))?$", RegexOptions.Compiled);
|
||||
|
||||
internal KubernetesVersionComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
if (x == null || y == null)
|
||||
{
|
||||
return StringComparer.CurrentCulture.Compare(x, y);
|
||||
}
|
||||
|
||||
var matchX = KubernetesVersionRegex.Match(x);
|
||||
if (!matchX.Success)
|
||||
{
|
||||
return StringComparer.CurrentCulture.Compare(x, y);
|
||||
}
|
||||
|
||||
var matchY = KubernetesVersionRegex.Match(y);
|
||||
if (!matchY.Success)
|
||||
{
|
||||
return StringComparer.CurrentCulture.Compare(x, y);
|
||||
}
|
||||
|
||||
var versionX = ExtractVersion(matchX);
|
||||
var versionY = ExtractVersion(matchY);
|
||||
return versionX.CompareTo(versionY);
|
||||
}
|
||||
|
||||
private Version ExtractVersion(Match match)
|
||||
{
|
||||
var major = int.Parse(match.Groups["major"].Value);
|
||||
if (!Enum.TryParse<Stream>(match.Groups["stream"].Value, true, out var stream))
|
||||
{
|
||||
stream = Stream.Final;
|
||||
}
|
||||
|
||||
_ = int.TryParse(match.Groups["minor"].Value, out var minor);
|
||||
return new Version(major, (int)stream, minor);
|
||||
}
|
||||
|
||||
private enum Stream
|
||||
{
|
||||
Alpha = 1,
|
||||
Beta = 2,
|
||||
Final = 3,
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
// WARNING: DO NOT LEAVE COMMENTED CODE IN THIS FILE. IT GETS SCANNED BY GEN PROJECT SO IT CAN EXCLUDE ANY MANUALLY DEFINED MAPS
|
||||
|
||||
using AutoMapper;
|
||||
#if NET6_0_OR_GREATER
|
||||
using AutoMapper.Internal;
|
||||
#endif
|
||||
using k8s.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace k8s.ModelConverter.AutoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Provides mappers that converts Kubernetes models between different versions
|
||||
/// </summary>
|
||||
internal static partial class VersionConverter
|
||||
{
|
||||
static VersionConverter()
|
||||
{
|
||||
UpdateMappingConfiguration(expression => { });
|
||||
}
|
||||
|
||||
public static IMapper Mapper { get; private set; }
|
||||
internal static MapperConfiguration MapperConfiguration { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Two level lookup of model types by Kind and then Version
|
||||
/// </summary>
|
||||
internal static Dictionary<string, Dictionary<string, Type>> KindVersionsMap { get; private set; }
|
||||
|
||||
public static Type GetTypeForVersion<T>(string version)
|
||||
{
|
||||
return GetTypeForVersion(typeof(T), version);
|
||||
}
|
||||
|
||||
public static Type GetTypeForVersion(Type type, string version)
|
||||
{
|
||||
return KindVersionsMap[type.GetKubernetesTypeMetadata().Kind][version];
|
||||
}
|
||||
|
||||
public static void UpdateMappingConfiguration(Action<IMapperConfigurationExpression> configuration)
|
||||
{
|
||||
MapperConfiguration = new MapperConfiguration(cfg =>
|
||||
{
|
||||
GetConfigurations(cfg);
|
||||
configuration(cfg);
|
||||
});
|
||||
Mapper = MapperConfiguration
|
||||
#if NET6_0_OR_GREATER
|
||||
.Internal()
|
||||
#endif
|
||||
.CreateMapper();
|
||||
KindVersionsMap = MapperConfiguration
|
||||
#if NET6_0_OR_GREATER
|
||||
.Internal()
|
||||
#endif
|
||||
.GetAllTypeMaps()
|
||||
.SelectMany(x => new[] { x.Types.SourceType, x.Types.DestinationType })
|
||||
.Where(x => x.GetCustomAttribute<KubernetesEntityAttribute>() != null)
|
||||
.Select(x =>
|
||||
{
|
||||
var attr = GetKubernetesEntityAttribute(x);
|
||||
return new { attr.Kind, attr.ApiVersion, Type = x };
|
||||
})
|
||||
.GroupBy(x => x.Kind)
|
||||
.ToDictionary(x => x.Key, kindGroup => kindGroup
|
||||
.GroupBy(x => x.ApiVersion)
|
||||
.ToDictionary(
|
||||
x => x.Key,
|
||||
versionGroup => versionGroup.Select(x => x.Type).Distinct().Single())); // should only be one type for each Kind/Version combination
|
||||
}
|
||||
|
||||
public static object ConvertToVersion(object source, string apiVersion)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
var type = source.GetType();
|
||||
var attr = GetKubernetesEntityAttribute(type);
|
||||
if (attr.ApiVersion == apiVersion)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
if (!KindVersionsMap.TryGetValue(attr.Kind, out var kindVersions))
|
||||
{
|
||||
throw new InvalidOperationException($"Version converter does not have any registered types for Kind `{attr.Kind}`");
|
||||
}
|
||||
|
||||
if (!kindVersions.TryGetValue(apiVersion, out var targetType) || !kindVersions.TryGetValue(attr.ApiVersion, out var sourceType) ||
|
||||
MapperConfiguration
|
||||
#if NET6_0_OR_GREATER
|
||||
.Internal()
|
||||
#endif
|
||||
.FindTypeMapFor(sourceType, targetType) == null)
|
||||
{
|
||||
throw new InvalidOperationException($"There is no conversion mapping registered for Kind `{attr.Kind}` from ApiVersion {attr.ApiVersion} to {apiVersion}");
|
||||
}
|
||||
|
||||
return Mapper.Map(source, sourceType, targetType);
|
||||
}
|
||||
|
||||
private static KubernetesEntityAttribute GetKubernetesEntityAttribute(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
var attr = type.GetCustomAttribute<KubernetesEntityAttribute>();
|
||||
if (attr == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Type {type} does not have {nameof(KubernetesEntityAttribute)}");
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
internal static void GetConfigurations(IMapperConfigurationExpression cfg)
|
||||
{
|
||||
AutoConfigurations(cfg);
|
||||
ManualConfigurations(cfg);
|
||||
}
|
||||
|
||||
private static void ManualConfigurations(IMapperConfigurationExpression cfg)
|
||||
{
|
||||
cfg.AllowNullCollections = true;
|
||||
cfg.DisableConstructorMapping();
|
||||
cfg
|
||||
#if NET6_0_OR_GREATER
|
||||
.Internal()
|
||||
#endif
|
||||
.ForAllMaps((typeMap, opt) =>
|
||||
{
|
||||
if (!typeof(IKubernetesObject).IsAssignableFrom(typeMap.Types.DestinationType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var metadata = typeMap.Types.DestinationType.GetKubernetesTypeMetadata();
|
||||
opt.ForMember(nameof(IKubernetesObject.ApiVersion), x => x.Ignore());
|
||||
opt.ForMember(nameof(IKubernetesObject.Kind), x => x.Ignore());
|
||||
opt.AfterMap((from, to) =>
|
||||
{
|
||||
var obj = (IKubernetesObject)to;
|
||||
obj.ApiVersion = !string.IsNullOrEmpty(metadata.Group) ? $"{metadata.Group}/{metadata.ApiVersion}" : metadata.ApiVersion;
|
||||
obj.Kind = metadata.Kind;
|
||||
});
|
||||
});
|
||||
|
||||
cfg.CreateMap<V1HorizontalPodAutoscalerSpec, V2HorizontalPodAutoscalerSpec>()
|
||||
.ForMember(dest => dest.Metrics, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Behavior, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
|
||||
|
||||
cfg.CreateMap<V1HorizontalPodAutoscalerStatus, V2HorizontalPodAutoscalerStatus>()
|
||||
.ForMember(dest => dest.Conditions, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.CurrentMetrics, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
|
||||
cfg.CreateMap<V1alpha3ResourceClaim, V1ResourceClaim>()
|
||||
.ForMember(dest => dest.Name, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Request, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
|
||||
cfg.CreateMap<V1beta1ResourceClaim, V1ResourceClaim>()
|
||||
.ForMember(dest => dest.Name, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Request, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<RootNamespace>k8s.ModelConverter</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LibKubernetesGenerator\generators\LibKubernetesGenerator.Automapper\LibKubernetesGenerator.Automapper.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\KubernetesClient\KubernetesClient.csproj" />
|
||||
<PackageReference Include="AutoMapper" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="KubernetesClient.Tests" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,12 +1,6 @@
|
||||
using Autofac;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using NSwag;
|
||||
#if GENERATE_AUTOMAPPER
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace LibKubernetesGenerator
|
||||
{
|
||||
@@ -68,7 +62,6 @@ namespace LibKubernetesGenerator
|
||||
builder.RegisterType<ModelGenerator>();
|
||||
builder.RegisterType<ApiGenerator>();
|
||||
builder.RegisterType<VersionConverterStubGenerator>();
|
||||
builder.RegisterType<VersionConverterAutoMapperGenerator>();
|
||||
builder.RegisterType<VersionGenerator>();
|
||||
|
||||
return builder.Build();
|
||||
@@ -90,33 +83,6 @@ namespace LibKubernetesGenerator
|
||||
});
|
||||
#endif
|
||||
|
||||
#if GENERATE_AUTOMAPPER
|
||||
var automappersrc = generatorContext.CompilationProvider.Select((c, _) => c.SyntaxTrees.First(s => PathSuffixMath(s.FilePath, "AutoMapper/VersionConverter.cs")));
|
||||
generatorContext.RegisterSourceOutput(automappersrc, (ctx, srctree) =>
|
||||
{
|
||||
var (swagger, container) = BuildContainer();
|
||||
container.Resolve<VersionConverterAutoMapperGenerator>().Generate(swagger, ctx, srctree);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GENERATE_AUTOMAPPER
|
||||
private IEnumerable<string> PathSplit(string path)
|
||||
{
|
||||
var p = path;
|
||||
|
||||
while (!string.IsNullOrEmpty(p))
|
||||
{
|
||||
yield return Path.GetFileName(p);
|
||||
p = Path.GetDirectoryName(p);
|
||||
}
|
||||
}
|
||||
|
||||
private bool PathSuffixMath(string path, string suffix)
|
||||
{
|
||||
var s = PathSplit(suffix).ToList();
|
||||
return PathSplit(path).Take(s.Count).SequenceEqual(s);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -30,8 +30,10 @@
|
||||
<!-- NSwag -->
|
||||
<PackageReference Include="NSwag.Core" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="NJsonSchema" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="NJsonSchema.Annotations" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="Namotion.Reflection" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
<PackageReference Include="System.Text.Json" GeneratePathProperty="true" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -48,8 +50,10 @@
|
||||
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGNSwag_Core)\lib\netstandard2.0\NSwag.Core.dll" IncludeRuntimeDependency="false" />
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGNJsonSchema)\lib\netstandard2.0\NJsonSchema.dll" IncludeRuntimeDependency="false" />
|
||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGNJsonSchema_Annotations)\lib\netstandard2.0\NJsonSchema.Annotations.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_Text_Json)\lib\netstandard2.0\System.Text.Json.dll" IncludeRuntimeDependency="false" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using NSwag;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace LibKubernetesGenerator
|
||||
{
|
||||
internal class VersionConverterAutoMapperGenerator
|
||||
{
|
||||
private readonly ClassNameHelper classNameHelper;
|
||||
|
||||
public VersionConverterAutoMapperGenerator(ClassNameHelper classNameHelper)
|
||||
{
|
||||
this.classNameHelper = classNameHelper;
|
||||
}
|
||||
|
||||
public void Generate(OpenApiDocument swagger, SourceProductionContext context, SyntaxTree manualconverter)
|
||||
{
|
||||
var allGeneratedModelClassNames = new List<string>();
|
||||
|
||||
foreach (var kv in swagger.Definitions)
|
||||
{
|
||||
var def = kv.Value;
|
||||
var clz = classNameHelper.GetClassNameForSchemaDefinition(def);
|
||||
allGeneratedModelClassNames.Add(clz);
|
||||
}
|
||||
|
||||
var manualMaps = new List<(string, string)>();
|
||||
|
||||
manualMaps = Regex.Matches(manualconverter.GetText().ToString(), @"\.CreateMap<(?<T1>.+?),\s?(?<T2>.+?)>")
|
||||
.OfType<Match>()
|
||||
.Select(x => (x.Groups["T1"].Value, x.Groups["T2"].Value))
|
||||
.ToList();
|
||||
|
||||
var versionRegex = @"(^V|v)[0-9]+((alpha|beta)[0-9]+)?";
|
||||
var typePairs = allGeneratedModelClassNames
|
||||
.OrderBy(x => x)
|
||||
.Select(x => new
|
||||
{
|
||||
Version = Regex.Match(x, versionRegex).Value?.ToLower(),
|
||||
Kinda = Regex.Replace(x, versionRegex, string.Empty),
|
||||
Type = x,
|
||||
})
|
||||
.Where(x => !string.IsNullOrEmpty(x.Version))
|
||||
.GroupBy(x => x.Kinda)
|
||||
.Where(x => x.Count() > 1)
|
||||
.SelectMany(x =>
|
||||
x.SelectMany((value, index) => x.Skip(index + 1), (first, second) => new { first, second }))
|
||||
.OrderBy(x => x.first.Kinda)
|
||||
.ThenBy(x => x.first.Version)
|
||||
.Select(x => (x.first.Type, x.second.Type))
|
||||
.ToList();
|
||||
|
||||
var versionConverterPairs = typePairs.Except(manualMaps).ToList();
|
||||
|
||||
var sbversion = new StringBuilder(@"// <auto-generated />
|
||||
using AutoMapper;
|
||||
using k8s.Models;
|
||||
|
||||
namespace k8s.ModelConverter.AutoMapper;
|
||||
|
||||
internal static partial class VersionConverter
|
||||
{
|
||||
private static void AutoConfigurations(IMapperConfigurationExpression cfg)
|
||||
{
|
||||
|
||||
");
|
||||
|
||||
foreach (var (t0, t1) in versionConverterPairs)
|
||||
{
|
||||
sbversion.AppendLine($@"cfg.CreateMap<{t0}, {t1}>().ReverseMap();");
|
||||
}
|
||||
|
||||
sbversion.AppendLine("}}");
|
||||
|
||||
context.AddSource($"VersionConverter.g.cs", SourceText.From(sbversion.ToString(), Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<DefineConstants>$(DefineConstants);GENERATE_AUTOMAPPER;</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../../LibKubernetesGenerator.target" />
|
||||
|
||||
</Project>
|
||||
@@ -3,6 +3,5 @@
|
||||
<ProjectReference Include="KubernetesClient/KubernetesClient.csproj" />
|
||||
<ProjectReference Include="KubernetesClient.Classic/KubernetesClient.Classic.csproj" />
|
||||
<ProjectReference Include="KubernetesClient.Aot/KubernetesClient.Aot.csproj" />
|
||||
<ProjectReference Include="KubernetesClient.ModelConverter/KubernetesClient.ModelConverter.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
10731
swagger.json
10731
swagger.json
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,10 @@
|
||||
<PackageReference Include="Xunit.StaFact" />
|
||||
<PackageReference Include="Moq" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Net.Http" Condition="'$(TargetFramework)' == 'net48'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\KubernetesClient.Classic\KubernetesClient.Classic.csproj" />
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using AutoMapper;
|
||||
using FluentAssertions;
|
||||
using k8s.ModelConverter.AutoMapper;
|
||||
using k8s.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace k8s.Tests
|
||||
{
|
||||
public class AutoMapperVersionConverterTests
|
||||
{
|
||||
[Fact]
|
||||
public void ConfigurationsAreValid()
|
||||
{
|
||||
var config = new MapperConfiguration(VersionConverter.GetConfigurations);
|
||||
config.AssertConfigurationIsValid();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("v1", "v1beta1", 1)]
|
||||
[InlineData("v1beta1", "v1", -1)]
|
||||
[InlineData("v1beta1", "v1alpha1", 1)]
|
||||
[InlineData("v1alpha1", "v1beta1", -1)]
|
||||
[InlineData("v1", "v1alpha1", 1)]
|
||||
[InlineData("v2alpha1", "v1", 1)]
|
||||
[InlineData("v1", "v2alpha1", -1)]
|
||||
[InlineData("v1", "v1", 0)]
|
||||
[InlineData("v2", "v2", 0)]
|
||||
[InlineData("v1beta1", "v1beta1", 0)]
|
||||
[InlineData("v1beta2", "v1beta2", 0)]
|
||||
[InlineData("v2beta2", "v2beta2", 0)]
|
||||
public void KubernetesVersionCompare(string x, string y, int expected)
|
||||
{
|
||||
KubernetesVersionComparer.Instance.Compare(x, y).Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ObjectMapAreValid()
|
||||
{
|
||||
ModelVersionConverter.Converter = AutoMapperModelVersionConverter.Instance;
|
||||
var from = new V2HorizontalPodAutoscalerSpec(); // TODO shuold auto load all objects
|
||||
from.MaxReplicas = 234;
|
||||
var to = (V1HorizontalPodAutoscalerSpec)from;
|
||||
|
||||
Assert.Equal(from.MaxReplicas, to.MaxReplicas);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,5 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\KubernetesClient\KubernetesClient.csproj" />
|
||||
<ProjectReference Include="..\..\src\KubernetesClient.ModelConverter\KubernetesClient.ModelConverter.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
|
||||
"version": "16.0",
|
||||
"version": "17.0",
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/master$",
|
||||
"^refs/tags/v\\d+\\.\\d+\\.\\d+"
|
||||
|
||||
Reference in New Issue
Block a user