diff --git a/.github/workflows/buildtest.yaml b/.github/workflows/buildtest.yaml index a31e0e50f..ea79ee222 100644 --- a/.github/workflows/buildtest.yaml +++ b/.github/workflows/buildtest.yaml @@ -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) diff --git a/Directory.Packages.props b/Directory.Packages.props index f083f5a48..45f27d6cf 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,53 +1,53 @@ - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 58bfe650b..f92d95e61 100644 --- a/README.md +++ b/README.md @@ -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* | diff --git a/csharp.settings b/csharp.settings index 5bf31f681..1cc92da6d 100644 --- a/csharp.settings +++ b/csharp.settings @@ -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 diff --git a/examples/Directory.Build.props b/examples/Directory.Build.props index edc5738f1..b87fe6aaa 100644 --- a/examples/Directory.Build.props +++ b/examples/Directory.Build.props @@ -1,6 +1,7 @@ + - net8.0 + net9.0 diff --git a/examples/Directory.Build.targets b/examples/Directory.Build.targets index 65c630b6d..bf5f5ee49 100644 --- a/examples/Directory.Build.targets +++ b/examples/Directory.Build.targets @@ -1,4 +1,5 @@ + diff --git a/examples/cp/Cp.cs b/examples/cp/Cp.cs index b7dd5b207..43e769490 100644 --- a/examples/cp/Cp.cs +++ b/examples/cp/Cp.cs @@ -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.Threading; using System.Threading.Tasks; -namespace cp -{ - internal class Cp - { - private static IKubernetes client; +namespace cp; - private static async Task Main(string[] args) - { - var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); - client = new Kubernetes(config); +internal class Cp +{ + private static IKubernetes client; + private static async Task Main(string[] args) + { + 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]}"); + 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) + private static void ValidatePathParameters(string sourcePath, string destinationPath) + { + if (string.IsNullOrWhiteSpace(sourcePath)) { - 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(sourcePath)} cannot be null or whitespace"); } - public static async Task CopyFileToPodAsync(string name, string @namespace, string container, string sourceFilePath, string destinationFilePath, CancellationToken cancellationToken = default(CancellationToken)) + if (string.IsNullOrWhiteSpace(destinationPath)) { - // All other parameters are being validated by MuxedStreamNamespacedPodExecAsync called by NamespacedPodExecAsync - ValidatePathParameters(sourceFilePath, destinationFilePath); + throw new ArgumentException($"{nameof(destinationPath)} cannot be null or whitespace"); + } + } + + public static async Task 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) => + // 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; - - var fileSize = inputFileStream.Length; - var entry = TarEntry.CreateTarEntry(fileInfo.Name); - - entry.Size = fileSize; + tarOutputStream.IsStreamOwner = false; - tarOutputStream.PutNextEntry(entry); - await inputFileStream.CopyToAsync(tarOutputStream); - tarOutputStream.CloseEntry(); - } + var fileSize = inputFileStream.Length; + var entry = TarEntry.CreateTarEntry(fileInfo.Name); - memoryStream.Position = 0; + entry.Size = fileSize; - await memoryStream.CopyToAsync(stdIn); - await stdIn.FlushAsync(); + tarOutputStream.PutNextEntry(entry); + await inputFileStream.CopyToAsync(tarOutputStream).ConfigureAwait(false); + tarOutputStream.CloseEntry(); } - } - catch (Exception ex) - { - throw new IOException($"Copy command failed: {ex.Message}"); - } + memoryStream.Position = 0; - using StreamReader streamReader = new StreamReader(stdError); - while (streamReader.EndOfStream == false) - { - string error = await streamReader.ReadToEndAsync(); - throw new IOException($"Copy command failed: {error}"); + await memoryStream.CopyToAsync(stdIn).ConfigureAwait(false); + await stdIn.FlushAsync().ConfigureAwait(false); } - }); - - string destinationFolder = GetFolderName(destinationFilePath); - - return await client.NamespacedPodExecAsync( - name, - @namespace, - container, - new string[] { "sh", "-c", $"tar xmf - -C {destinationFolder}" }, - false, - handler, - cancellationToken); - } - + } + catch (Exception ex) + { + throw new IOException($"Copy command failed: {ex.Message}"); + } - private static string GetFolderName(string filePath) - { - var folderName = Path.GetDirectoryName(filePath); + 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); + + return await client.NamespacedPodExecAsync( + name, + @namespace, + container, + new string[] { "sh", "-c", $"tar xmf - -C {destinationFolder}" }, + false, + handler, + cancellationToken).ConfigureAwait(false); + } - return string.IsNullOrEmpty(folderName) ? "." : folderName; - } + private static string GetFolderName(string filePath) + { + var folderName = Path.GetDirectoryName(filePath); + return string.IsNullOrEmpty(folderName) ? "." : folderName; } } diff --git a/examples/csrApproval/Program.cs b/examples/csrApproval/Program.cs index b4f154864..a16a9d5f9 100644 --- a/examples/csrApproval/Program.cs +++ b/examples/csrApproval/Program.cs @@ -1,4 +1,4 @@ -using Json.Patch; +using Json.Patch; using k8s; using k8s.Models; using System.Net; @@ -44,34 +44,34 @@ string GenerateCertificate(string name) Kind = "CertificateSigningRequest", Metadata = new V1ObjectMeta { - Name = name + Name = name, }, Spec = new V1CertificateSigningRequestSpec { Request = encodedCsr, SignerName = "kubernetes.io/kube-apiserver-client", Usages = new List { "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 { - 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); diff --git a/examples/openTelemetryConsole/Program.cs b/examples/openTelemetryConsole/Program.cs index 9a5460dcb..4587d76ee 100644 --- a/examples/openTelemetryConsole/Program.cs +++ b/examples/openTelemetryConsole/Program.cs @@ -29,6 +29,7 @@ { Console.WriteLine(item.Metadata.Name); } + // Or empty if there are no pods if (list.Items.Count == 0) { diff --git a/examples/patch-aot/Program.cs b/examples/patch-aot/Program.cs index 06a693dde..e72f6a4d2 100644 --- a/examples/patch-aot/Program.cs +++ b/examples/patch-aot/Program.cs @@ -28,5 +28,6 @@ static void PrintLabels(V1Pod pod) { Console.WriteLine($"{k} : {v}"); } + Console.WriteLine("=-=-=-=-=-=-=-=-=-=-="); } diff --git a/examples/portforward/PortForward.cs b/examples/portforward/PortForward.cs index fe9485d86..ed1bd02c2 100644 --- a/examples/portforward/PortForward.cs +++ b/examples/portforward/PortForward.cs @@ -18,13 +18,13 @@ private static async Task Main(string[] args) 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 @@ private static async Task Forward(IKubernetes client, V1Pod pod) } }); - await accept; - await copy; + await accept.ConfigureAwait(false); + await copy.ConfigureAwait(false); if (handler != null) { handler.Close(); } + listener.Close(); } } diff --git a/examples/restart/Program.cs b/examples/restart/Program.cs index b6e7a6f22..894e305a6 100644 --- a/examples/restart/Program.cs +++ b/examples/restart/Program.cs @@ -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 { - ["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 { - ["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 { - ["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); diff --git a/examples/watch/Program.cs b/examples/watch/Program.cs index 525cbec5c..d5452e2cc 100644 --- a/examples/watch/Program.cs +++ b/examples/watch/Program.cs @@ -16,7 +16,7 @@ private static async Task Main(string[] args) 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()) + await foreach (var (type, item) in podlistResp.WatchAsync().ConfigureAwait(false)) { Console.WriteLine("==on watch event=="); Console.WriteLine(type); @@ -28,7 +28,9 @@ private static async Task Main(string[] args) // 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((type, item) => diff --git a/examples/workerServiceDependencyInjection/Program.cs b/examples/workerServiceDependencyInjection/Program.cs index 59bf3cf25..a894a33fe 100644 --- a/examples/workerServiceDependencyInjection/Program.cs +++ b/examples/workerServiceDependencyInjection/Program.cs @@ -14,4 +14,4 @@ }) .Build(); -await host.RunAsync(); +await host.RunAsync().ConfigureAwait(false); diff --git a/examples/workerServiceDependencyInjection/Worker.cs b/examples/workerServiceDependencyInjection/Worker.cs index 87d2ecfe2..cb2f82386 100644 --- a/examples/workerServiceDependencyInjection/Worker.cs +++ b/examples/workerServiceDependencyInjection/Worker.cs @@ -8,10 +8,11 @@ public class Worker : BackgroundService private readonly IKubernetes kubernetesClient; /// + /// Initializes a new instance of the class. /// Inject in the constructor the IKubernetes interface. /// - /// - /// + /// The logger instance used for logging information. + /// The Kubernetes client used to interact with the Kubernetes API. public Worker(ILogger logger, IKubernetes kubernetesClient) { this.logger = logger; @@ -33,7 +34,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) Console.WriteLine(pod.Metadata.Name); } - await Task.Delay(1000, stoppingToken); + await Task.Delay(1000, stoppingToken).ConfigureAwait(false); } } } diff --git a/examples/yaml/Program.cs b/examples/yaml/Program.cs index 04676b16f..ef7feba7f 100644 --- a/examples/yaml/Program.cs +++ b/examples/yaml/Program.cs @@ -10,14 +10,14 @@ internal class Program { private static async Task Main(string[] args) { - var typeMap = new Dictionary + var typeMap = new Dictionary { { "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) { diff --git a/src/KubernetesClient.ModelConverter/AutoMapper/AutoMapperModelVersionConverter.cs b/src/KubernetesClient.ModelConverter/AutoMapper/AutoMapperModelVersionConverter.cs deleted file mode 100644 index c44190a46..000000000 --- a/src/KubernetesClient.ModelConverter/AutoMapper/AutoMapperModelVersionConverter.cs +++ /dev/null @@ -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 from) - { - return VersionConverter.Mapper.Map(from); - } -} diff --git a/src/KubernetesClient.ModelConverter/AutoMapper/KubernetesVersionComparer.cs b/src/KubernetesClient.ModelConverter/AutoMapper/KubernetesVersionComparer.cs deleted file mode 100644 index de22d25e1..000000000 --- a/src/KubernetesClient.ModelConverter/AutoMapper/KubernetesVersionComparer.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace k8s.ModelConverter.AutoMapper; - -internal class KubernetesVersionComparer : IComparer -{ - public static KubernetesVersionComparer Instance { get; } = new KubernetesVersionComparer(); - private static readonly Regex KubernetesVersionRegex = new Regex(@"^v(?[0-9]+)((?alpha|beta)(?[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(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, - } -} diff --git a/src/KubernetesClient.ModelConverter/AutoMapper/VersionConverter.cs b/src/KubernetesClient.ModelConverter/AutoMapper/VersionConverter.cs deleted file mode 100644 index ebc1b214e..000000000 --- a/src/KubernetesClient.ModelConverter/AutoMapper/VersionConverter.cs +++ /dev/null @@ -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; - -/// -/// Provides mappers that converts Kubernetes models between different versions -/// -internal static partial class VersionConverter -{ - static VersionConverter() - { - UpdateMappingConfiguration(expression => { }); - } - - public static IMapper Mapper { get; private set; } - internal static MapperConfiguration MapperConfiguration { get; private set; } - - /// - /// Two level lookup of model types by Kind and then Version - /// - internal static Dictionary> KindVersionsMap { get; private set; } - - public static Type GetTypeForVersion(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 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() != 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(); - 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() - .ForMember(dest => dest.Metrics, opt => opt.Ignore()) - .ForMember(dest => dest.Behavior, opt => opt.Ignore()) - .ReverseMap(); - - - cfg.CreateMap() - .ForMember(dest => dest.Conditions, opt => opt.Ignore()) - .ForMember(dest => dest.CurrentMetrics, opt => opt.Ignore()) - .ReverseMap(); - - cfg.CreateMap() - .ForMember(dest => dest.Name, opt => opt.Ignore()) - .ForMember(dest => dest.Request, opt => opt.Ignore()) - .ReverseMap(); - - cfg.CreateMap() - .ForMember(dest => dest.Name, opt => opt.Ignore()) - .ForMember(dest => dest.Request, opt => opt.Ignore()) - .ReverseMap(); - } -} diff --git a/src/KubernetesClient.ModelConverter/KubernetesClient.ModelConverter.csproj b/src/KubernetesClient.ModelConverter/KubernetesClient.ModelConverter.csproj deleted file mode 100644 index cbd90f79d..000000000 --- a/src/KubernetesClient.ModelConverter/KubernetesClient.ModelConverter.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - net8.0;net9.0 - k8s.ModelConverter - - - - - - - - - - - - - - - - diff --git a/src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs b/src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs index 8dd368e03..0e6278fb4 100644 --- a/src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs +++ b/src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs @@ -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 @@ private static IContainer BuildContainer(OpenApiDocument swagger) builder.RegisterType(); builder.RegisterType(); builder.RegisterType(); - builder.RegisterType(); builder.RegisterType(); return builder.Build(); @@ -90,33 +83,6 @@ public void Initialize(IncrementalGeneratorInitializationContext generatorContex }); #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().Generate(swagger, ctx, srctree); - }); -#endif - } - -#if GENERATE_AUTOMAPPER - private IEnumerable 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 } } diff --git a/src/LibKubernetesGenerator/LibKubernetesGenerator.target b/src/LibKubernetesGenerator/LibKubernetesGenerator.target index ee9aeb083..d9240bcdd 100644 --- a/src/LibKubernetesGenerator/LibKubernetesGenerator.target +++ b/src/LibKubernetesGenerator/LibKubernetesGenerator.target @@ -12,7 +12,7 @@ - + @@ -30,8 +30,10 @@ + + @@ -48,8 +50,10 @@ + + diff --git a/src/LibKubernetesGenerator/VersionConverterAutoMapperGenerator.cs b/src/LibKubernetesGenerator/VersionConverterAutoMapperGenerator.cs deleted file mode 100644 index 9a2c95cbc..000000000 --- a/src/LibKubernetesGenerator/VersionConverterAutoMapperGenerator.cs +++ /dev/null @@ -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(); - - 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<(?.+?),\s?(?.+?)>") - .OfType() - .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(@"// -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)); - } - } -} diff --git a/src/LibKubernetesGenerator/generators/LibKubernetesGenerator.Automapper/LibKubernetesGenerator.Automapper.csproj b/src/LibKubernetesGenerator/generators/LibKubernetesGenerator.Automapper/LibKubernetesGenerator.Automapper.csproj deleted file mode 100644 index 1cf7ecd42..000000000 --- a/src/LibKubernetesGenerator/generators/LibKubernetesGenerator.Automapper/LibKubernetesGenerator.Automapper.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - $(DefineConstants);GENERATE_AUTOMAPPER; - - - - - diff --git a/src/nuget.proj b/src/nuget.proj index feec6cda8..1f4213256 100644 --- a/src/nuget.proj +++ b/src/nuget.proj @@ -3,6 +3,5 @@ - diff --git a/swagger.json b/swagger.json index c933c42b2..7bb0ceeee 100644 --- a/swagger.json +++ b/swagger.json @@ -907,7 +907,7 @@ "description": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", "properties": { "excludeResourceRules": { - "description": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "description": "ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", "items": { "$ref": "#/definitions/v1alpha1.NamedRuleWithOperations" }, @@ -915,7 +915,7 @@ "x-kubernetes-list-type": "atomic" }, "matchPolicy": { - "description": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"", + "description": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy does not consider requests to apps/v1beta1 or extensions/v1beta1 API groups.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy **does** consider requests made to apps/v1beta1 or extensions/v1beta1 API groups. The API server translates the request to a matched resource API if necessary.\n\nDefaults to \"Equivalent\"", "type": "string" }, "namespaceSelector": { @@ -924,10 +924,10 @@ }, "objectSelector": { "$ref": "#/definitions/v1.LabelSelector", - "description": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything." + "description": "ObjectSelector decides whether to run the policy based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the policy's expression (CEL), and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything." }, "resourceRules": { - "description": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", + "description": "ResourceRules describes what operations on what resources/subresources the admission policy matches. The policy cares about an operation if it matches _any_ Rule.", "items": { "$ref": "#/definitions/v1alpha1.NamedRuleWithOperations" }, @@ -2357,7 +2357,7 @@ "description": "DeploymentStatus is the most recently observed status of the Deployment.", "properties": { "availableReplicas": { - "description": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", + "description": "Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment.", "format": "int32", "type": "integer" }, @@ -2385,12 +2385,17 @@ "type": "integer" }, "readyReplicas": { - "description": "readyReplicas is the number of pods targeted by this Deployment with a Ready Condition.", + "description": "Total number of non-terminating pods targeted by this Deployment with a Ready Condition.", "format": "int32", "type": "integer" }, "replicas": { - "description": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", + "description": "Total number of non-terminating pods targeted by this deployment (their labels match the selector).", + "format": "int32", + "type": "integer" + }, + "terminatingReplicas": { + "description": "Total number of terminating pods targeted by this deployment. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "format": "int32", "type": "integer" }, @@ -2400,7 +2405,7 @@ "type": "integer" }, "updatedReplicas": { - "description": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", + "description": "Total number of non-terminating pods targeted by this deployment that have the desired template spec.", "format": "int32", "type": "integer" } @@ -2493,7 +2498,7 @@ "type": "string" }, "items": { - "description": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller", + "description": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", "items": { "$ref": "#/definitions/v1.ReplicaSet" }, @@ -2529,7 +2534,7 @@ "type": "integer" }, "replicas": { - "description": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "description": "Replicas is the number of desired pods. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", "format": "int32", "type": "integer" }, @@ -2539,7 +2544,7 @@ }, "template": { "$ref": "#/definitions/v1.PodTemplateSpec", - "description": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template" + "description": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template" } }, "required": [ @@ -2551,7 +2556,7 @@ "description": "ReplicaSetStatus represents the current status of a ReplicaSet.", "properties": { "availableReplicas": { - "description": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", + "description": "The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set.", "format": "int32", "type": "integer" }, @@ -2569,7 +2574,7 @@ "x-kubernetes-patch-strategy": "merge" }, "fullyLabeledReplicas": { - "description": "The number of pods that have labels matching the labels of the pod template of the replicaset.", + "description": "The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset.", "format": "int32", "type": "integer" }, @@ -2579,12 +2584,17 @@ "type": "integer" }, "readyReplicas": { - "description": "readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition.", + "description": "The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition.", "format": "int32", "type": "integer" }, "replicas": { - "description": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "description": "Replicas is the most recently observed number of non-terminating pods. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", + "format": "int32", + "type": "integer" + }, + "terminatingReplicas": { + "description": "The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "format": "int32", "type": "integer" } @@ -2818,8 +2828,7 @@ }, "required": [ "selector", - "template", - "serviceName" + "template" ], "type": "object" }, @@ -3156,45 +3165,6 @@ }, "type": "object" }, - "v1beta1.SelfSubjectReview": { - "description": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/v1.ObjectMeta", - "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" - }, - "status": { - "$ref": "#/definitions/v1beta1.SelfSubjectReviewStatus", - "description": "Status is filled in by the server with the user attributes." - } - }, - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "authentication.k8s.io", - "kind": "SelfSubjectReview", - "version": "v1beta1" - } - ] - }, - "v1beta1.SelfSubjectReviewStatus": { - "description": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", - "properties": { - "userInfo": { - "$ref": "#/definitions/v1.UserInfo", - "description": "User attributes of the user making this request." - } - }, - "type": "object" - }, "v1.FieldSelectorAttributes": { "description": "FieldSelectorAttributes indicates a field limited access. Webhook authors are encouraged to * ensure rawSelector and requirements are not both set * consider the requirements field if set * not try to parse or consider the rawSelector field if set. This is to avoid another CVE-2022-2880 (i.e. getting different systems to agree on how exactly to parse a query is not something we want), see https://www.oxeye.io/resources/golang-parameter-smuggling-attack for more details. For the *SubjectAccessReview endpoints of the kube-apiserver: * If rawSelector is empty and requirements are empty, the request is not limited. * If rawSelector is present and requirements are empty, the rawSelector will be parsed and limited if the parsing succeeds. * If rawSelector is empty and requirements are present, the requirements should be honored * If rawSelector is present and requirements are present, the request is invalid.", "properties": { @@ -3968,10 +3938,10 @@ "type": "object" }, "v2.HPAScalingRules": { - "description": "HPAScalingRules configures the scaling behavior for one direction. These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.", + "description": "HPAScalingRules configures the scaling behavior for one direction via scaling Policy Rules and a configurable metric tolerance.\n\nScaling Policy Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.\n\nThe tolerance is applied to the metric values and prevents scaling too eagerly for small metric variations. (Note that setting a tolerance requires enabling the alpha HPAConfigurableTolerance feature gate.)", "properties": { "policies": { - "description": "policies is a list of potential scaling polices which can be used during scaling. At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid", + "description": "policies is a list of potential scaling polices which can be used during scaling. If not set, use the default values: - For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window. - For scale down: allow all pods to be removed in a 15s window.", "items": { "$ref": "#/definitions/v2.HPAScalingPolicy" }, @@ -3986,6 +3956,10 @@ "description": "stabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", "format": "int32", "type": "integer" + }, + "tolerance": { + "$ref": "#/definitions/resource.Quantity", + "description": "tolerance is the tolerance on the ratio between the current and desired metric value under which no updates are made to the desired number of replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not set, the default cluster-wide tolerance is applied (by default 10%).\n\nFor example, if autoscaling is configured with a memory consumption target of 100Mi, and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be triggered when the actual consumption falls below 95Mi or exceeds 101Mi.\n\nThis is an alpha field and requires enabling the HPAConfigurableTolerance feature gate." } }, "type": "object" @@ -4690,7 +4664,7 @@ "type": "integer" }, "backoffLimitPerIndex": { - "description": "Specifies the limit for the number of retries within an index before marking this index as failed. When enabled the number of failures per index is kept in the pod's batch.kubernetes.io/job-index-failure-count annotation. It can only be set when Job's completionMode=Indexed, and the Pod's restart policy is Never. The field is immutable. This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).", + "description": "Specifies the limit for the number of retries within an index before marking this index as failed. When enabled the number of failures per index is kept in the pod's batch.kubernetes.io/job-index-failure-count annotation. It can only be set when Job's completionMode=Indexed, and the Pod's restart policy is Never. The field is immutable.", "format": "int32", "type": "integer" }, @@ -4712,7 +4686,7 @@ "type": "boolean" }, "maxFailedIndexes": { - "description": "Specifies the maximal number of failed indexes before marking the Job as failed, when backoffLimitPerIndex is set. Once the number of failed indexes exceeds this number the entire Job is marked as Failed and its execution is terminated. When left as null the job continues execution of all of its indexes and is marked with the `Complete` Job condition. It can only be specified when backoffLimitPerIndex is set. It can be null or up to completions. It is required and must be less than or equal to 10^4 when is completions greater than 10^5. This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).", + "description": "Specifies the maximal number of failed indexes before marking the Job as failed, when backoffLimitPerIndex is set. Once the number of failed indexes exceeds this number the entire Job is marked as Failed and its execution is terminated. When left as null the job continues execution of all of its indexes and is marked with the `Complete` Job condition. It can only be specified when backoffLimitPerIndex is set. It can be null or up to completions. It is required and must be less than or equal to 10^4 when is completions greater than 10^5.", "format": "int32", "type": "integer" }, @@ -4735,7 +4709,7 @@ }, "successPolicy": { "$ref": "#/definitions/v1.SuccessPolicy", - "description": "successPolicy specifies the policy when the Job can be declared as succeeded. If empty, the default behavior applies - the Job is declared as succeeded only when the number of succeeded pods equals to the completions. When the field is specified, it must be immutable and works only for the Indexed Jobs. Once the Job meets the SuccessPolicy, the lingering pods are terminated.\n\nThis field is beta-level. To use this field, you must enable the `JobSuccessPolicy` feature gate (enabled by default)." + "description": "successPolicy specifies the policy when the Job can be declared as succeeded. If empty, the default behavior applies - the Job is declared as succeeded only when the number of succeeded pods equals to the completions. When the field is specified, it must be immutable and works only for the Indexed Jobs. Once the Job meets the SuccessPolicy, the lingering pods are terminated." }, "suspend": { "description": "suspend specifies whether the Job controller should create Pods or not. If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false.", @@ -4789,7 +4763,7 @@ "type": "integer" }, "failedIndexes": { - "description": "FailedIndexes holds the failed indexes when spec.backoffLimitPerIndex is set. The indexes are represented in the text format analogous as for the `completedIndexes` field, ie. they are kept as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the failed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\". The set of failed indexes cannot overlap with the set of completed indexes.\n\nThis field is beta-level. It can be used when the `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).", + "description": "FailedIndexes holds the failed indexes when spec.backoffLimitPerIndex is set. The indexes are represented in the text format analogous as for the `completedIndexes` field, ie. they are kept as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the failed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\". The set of failed indexes cannot overlap with the set of completed indexes.", "type": "string" }, "ready": { @@ -4899,7 +4873,7 @@ "description": "PodFailurePolicyRule describes how a pod failure is handled when the requirements are met. One of onExitCodes and onPodConditions, but not both, can be used in each rule.", "properties": { "action": { - "description": "Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are:\n\n- FailJob: indicates that the pod's job is marked as Failed and all\n running pods are terminated.\n- FailIndex: indicates that the pod's index is marked as Failed and will\n not be restarted.\n This value is beta-level. It can be used when the\n `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).\n- Ignore: indicates that the counter towards the .backoffLimit is not\n incremented and a replacement pod is created.\n- Count: indicates that the pod is handled in the default way - the\n counter towards the .backoffLimit is incremented.\nAdditional values are considered to be added in the future. Clients should react to an unknown action by skipping the rule.", + "description": "Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are:\n\n- FailJob: indicates that the pod's job is marked as Failed and all\n running pods are terminated.\n- FailIndex: indicates that the pod's index is marked as Failed and will\n not be restarted.\n- Ignore: indicates that the counter towards the .backoffLimit is not\n incremented and a replacement pod is created.\n- Count: indicates that the pod is handled in the default way - the\n counter towards the .backoffLimit is incremented.\nAdditional values are considered to be added in the future. Clients should react to an unknown action by skipping the rule.", "type": "string" }, "onExitCodes": { @@ -5245,6 +5219,90 @@ ], "type": "object" }, + "v1beta1.ClusterTrustBundle": { + "description": "ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors (root certificates).\n\nClusterTrustBundle objects are considered to be readable by any authenticated user in the cluster, because they can be mounted by pods using the `clusterTrustBundle` projection. All service accounts have read access to ClusterTrustBundles by default. Users who only have namespace-level access to a cluster can read ClusterTrustBundles by impersonating a serviceaccount that they have access to.\n\nIt can be optionally associated with a particular assigner, in which case it contains one valid set of trust anchors for that signer. Signers may have multiple associated ClusterTrustBundles; each is an independent set of trust anchors for that signer. Admission control is used to enforce that only users with permissions on the signer can create or modify the corresponding bundle.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ObjectMeta", + "description": "metadata contains the object metadata." + }, + "spec": { + "$ref": "#/definitions/v1beta1.ClusterTrustBundleSpec", + "description": "spec contains the signer (if any) and trust anchors." + } + }, + "required": [ + "spec" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "certificates.k8s.io", + "kind": "ClusterTrustBundle", + "version": "v1beta1" + } + ] + }, + "v1beta1.ClusterTrustBundleList": { + "description": "ClusterTrustBundleList is a collection of ClusterTrustBundle objects", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "items is a collection of ClusterTrustBundle objects", + "items": { + "$ref": "#/definitions/v1beta1.ClusterTrustBundle" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ListMeta", + "description": "metadata contains the list metadata." + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "certificates.k8s.io", + "kind": "ClusterTrustBundleList", + "version": "v1beta1" + } + ] + }, + "v1beta1.ClusterTrustBundleSpec": { + "description": "ClusterTrustBundleSpec contains the signer and trust anchors.", + "properties": { + "signerName": { + "description": "signerName indicates the associated signer, if any.\n\nIn order to create or update a ClusterTrustBundle that sets signerName, you must have the following cluster-scoped permission: group=certificates.k8s.io resource=signers resourceName= verb=attest.\n\nIf signerName is not empty, then the ClusterTrustBundle object must be named with the signer name as a prefix (translating slashes to colons). For example, for the signer name `example.com/foo`, valid ClusterTrustBundle object names include `example.com:foo:abc` and `example.com:foo:v1`.\n\nIf signerName is empty, then the ClusterTrustBundle object's name must not have such a prefix.\n\nList/watch requests for ClusterTrustBundles can filter on this field using a `spec.signerName=NAME` field selector.", + "type": "string" + }, + "trustBundle": { + "description": "trustBundle contains the individual X.509 trust anchors for this bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.\n\nThe data must consist only of PEM certificate blocks that parse as valid X.509 certificates. Each certificate must include a basic constraints extension with the CA bit set. The API server will reject objects that contain duplicate certificates, or that use PEM block headers.\n\nUsers of ClusterTrustBundles, including Kubelet, are free to reorder and deduplicate certificate blocks in this file according to their own logic, as well as to drop PEM block headers and inter-block data.", + "type": "string" + } + }, + "required": [ + "trustBundle" + ], + "type": "object" + }, "v1.Lease": { "description": "Lease defines a lease concept.", "properties": { @@ -5437,7 +5495,108 @@ "type": "string" }, "strategy": { - "description": "Strategy is the strategy that coordinated leader election will use for picking the leader. If multiple candidates for the same Lease return different strategies, the strategy provided by the candidate with the latest BinaryVersion will be used. If there is still conflict, this is a user error and coordinated leader election will not operate the Lease until resolved. (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.", + "description": "Strategy is the strategy that coordinated leader election will use for picking the leader. If multiple candidates for the same Lease return different strategies, the strategy provided by the candidate with the latest BinaryVersion will be used. If there is still conflict, this is a user error and coordinated leader election will not operate the Lease until resolved.", + "type": "string" + } + }, + "required": [ + "leaseName", + "binaryVersion", + "strategy" + ], + "type": "object" + }, + "v1beta1.LeaseCandidate": { + "description": "LeaseCandidate defines a candidate for a Lease object. Candidates are created such that coordinated leader election will pick the best leader from the list of candidates.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ObjectMeta", + "description": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "spec": { + "$ref": "#/definitions/v1beta1.LeaseCandidateSpec", + "description": "spec contains the specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "coordination.k8s.io", + "kind": "LeaseCandidate", + "version": "v1beta1" + } + ] + }, + "v1beta1.LeaseCandidateList": { + "description": "LeaseCandidateList is a list of Lease objects.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "items is a list of schema objects.", + "items": { + "$ref": "#/definitions/v1beta1.LeaseCandidate" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ListMeta", + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "coordination.k8s.io", + "kind": "LeaseCandidateList", + "version": "v1beta1" + } + ] + }, + "v1beta1.LeaseCandidateSpec": { + "description": "LeaseCandidateSpec is a specification of a Lease.", + "properties": { + "binaryVersion": { + "description": "BinaryVersion is the binary version. It must be in a semver format without leading `v`. This field is required.", + "type": "string" + }, + "emulationVersion": { + "description": "EmulationVersion is the emulation version. It must be in a semver format without leading `v`. EmulationVersion must be less than or equal to BinaryVersion. This field is required when strategy is \"OldestEmulationVersion\"", + "type": "string" + }, + "leaseName": { + "description": "LeaseName is the name of the lease for which this candidate is contending. The limits on this field are the same as on Lease.name. Multiple lease candidates may reference the same Lease.name. This field is immutable.", + "type": "string" + }, + "pingTime": { + "description": "PingTime is the last time that the server has requested the LeaseCandidate to renew. It is only done during leader election to check if any LeaseCandidates have become ineligible. When PingTime is updated, the LeaseCandidate will respond by updating RenewTime.", + "format": "date-time", + "type": "string" + }, + "renewTime": { + "description": "RenewTime is the time that the LeaseCandidate was last updated. Any time a Lease needs to do leader election, the PingTime field is updated to signal to the LeaseCandidate that they should update the RenewTime. Old LeaseCandidate objects are also garbage collected if it has been hours since the last renew. The PingTime field is updated regularly to prevent garbage collection for still active LeaseCandidates.", + "format": "date-time", + "type": "string" + }, + "strategy": { + "description": "Strategy is the strategy that coordinated leader election will use for picking the leader. If multiple candidates for the same Lease return different strategies, the strategy provided by the candidate with the latest BinaryVersion will be used. If there is still conflict, this is a user error and coordinated leader election will not operate the Lease until resolved.", "type": "string" } }, @@ -6588,6 +6747,10 @@ "$ref": "#/definitions/v1.ContainerState", "description": "State holds details about the container's current condition." }, + "stopSignal": { + "description": "StopSignal reports the effective stop signal for this container", + "type": "string" + }, "user": { "$ref": "#/definitions/v1.ContainerUser", "description": "User represents user identity information initially attached to the first process of the container" @@ -6713,7 +6876,7 @@ "type": "object" }, "v1.EndpointAddress": { - "description": "EndpointAddress is a tuple that describes single IP address.", + "description": "EndpointAddress is a tuple that describes single IP address. Deprecated: This API is deprecated in v1.33+.", "properties": { "hostname": { "description": "The Hostname of this endpoint", @@ -6739,7 +6902,7 @@ "x-kubernetes-map-type": "atomic" }, "core.v1.EndpointPort": { - "description": "EndpointPort is a tuple that describes a single port.", + "description": "EndpointPort is a tuple that describes a single port. Deprecated: This API is deprecated in v1.33+.", "properties": { "appProtocol": { "description": "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-\n * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455\n * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", @@ -6766,7 +6929,7 @@ "x-kubernetes-map-type": "atomic" }, "v1.EndpointSubset": { - "description": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n\n\t{\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t}\n\nThe resulting set of endpoints can be viewed as:\n\n\ta: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n\tb: [ 10.10.1.1:309, 10.10.2.2:309 ]", + "description": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n\n\t{\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t}\n\nThe resulting set of endpoints can be viewed as:\n\n\ta: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n\tb: [ 10.10.1.1:309, 10.10.2.2:309 ]\n\nDeprecated: This API is deprecated in v1.33+.", "properties": { "addresses": { "description": "IP addresses which offer the related ports that are marked as ready. These endpoints should be considered safe for load balancers and clients to utilize.", @@ -6796,7 +6959,7 @@ "type": "object" }, "v1.Endpoints": { - "description": "Endpoints is a collection of endpoints that implement the actual service. Example:\n\n\t Name: \"mysvc\",\n\t Subsets: [\n\t {\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t },\n\t {\n\t Addresses: [{\"ip\": \"10.10.3.3\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n\t },\n\t]", + "description": "Endpoints is a collection of endpoints that implement the actual service. Example:\n\n\t Name: \"mysvc\",\n\t Subsets: [\n\t {\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t },\n\t {\n\t Addresses: [{\"ip\": \"10.10.3.3\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n\t },\n\t]\n\nEndpoints is a legacy API and does not contain information about all Service features. Use discoveryv1.EndpointSlice for complete information about Service endpoints.\n\nDeprecated: This API is deprecated in v1.33+. Use discoveryv1.EndpointSlice.", "properties": { "apiVersion": { "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", @@ -6829,7 +6992,7 @@ ] }, "v1.EndpointsList": { - "description": "EndpointsList is a list of endpoints.", + "description": "EndpointsList is a list of endpoints. Deprecated: This API is deprecated in v1.33+.", "properties": { "apiVersion": { "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", @@ -6864,14 +7027,14 @@ ] }, "v1.EnvFromSource": { - "description": "EnvFromSource represents the source of a set of ConfigMaps", + "description": "EnvFromSource represents the source of a set of ConfigMaps or Secrets", "properties": { "configMapRef": { "$ref": "#/definitions/v1.ConfigMapEnvSource", "description": "The ConfigMap to select from" }, "prefix": { - "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", + "description": "Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.", "type": "string" }, "secretRef": { @@ -7759,6 +7922,10 @@ "preStop": { "$ref": "#/definitions/v1.LifecycleHandler", "description": "PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod's termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod's termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks" + }, + "stopSignal": { + "description": "StopSignal defines which signal will be sent to a container when it is being stopped. If not specified, the default is defined by the container runtime in use. StopSignal can only be set for Pods with a non-empty .spec.os.name", + "type": "string" } }, "type": "object" @@ -8614,6 +8781,17 @@ }, "type": "object" }, + "v1.NodeSwapStatus": { + "description": "NodeSwapStatus represents swap memory information.", + "properties": { + "capacity": { + "description": "Total amount of swap memory in bytes.", + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, "v1.NodeSystemInfo": { "description": "NodeSystemInfo is a set of ids/uuids to uniquely identify the node.", "properties": { @@ -8653,6 +8831,10 @@ "description": "OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)).", "type": "string" }, + "swap": { + "$ref": "#/definitions/v1.NodeSwapStatus", + "description": "Swap Info reported by the node." + }, "systemUUID": { "description": "SystemUUID reported by the node. For unique machine identification MachineID is preferred. This field is specific to Red Hat hosts https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid", "type": "string" @@ -9283,7 +9465,7 @@ "description": "A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods." }, "matchLabelKeys": { - "description": "MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).", + "description": "MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set.", "items": { "type": "string" }, @@ -9291,7 +9473,7 @@ "x-kubernetes-list-type": "atomic" }, "mismatchLabelKeys": { - "description": "MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).", + "description": "MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.", "items": { "type": "string" }, @@ -9359,6 +9541,11 @@ "description": "Human-readable message indicating details about last transition.", "type": "string" }, + "observedGeneration": { + "description": "If set, this represents the .metadata.generation that the pod condition was set based upon. This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field.", + "format": "int64", + "type": "integer" + }, "reason": { "description": "Unique, one-word, CamelCase reason for the condition's last transition.", "type": "string" @@ -9718,7 +9905,7 @@ "x-kubernetes-patch-strategy": "merge" }, "initContainers": { - "description": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + "description": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "items": { "$ref": "#/definitions/v1.Container" }, @@ -9948,6 +10135,11 @@ "description": "nominatedNodeName is set only when this pod preempts other pods on the node, but it cannot be scheduled right away as preemption victims receive their graceful termination periods. This field does not guarantee that the pod will be scheduled on this node. Scheduler may decide to place the pod elsewhere if other nodes become available sooner. Scheduler may also decide to give the resources on this node to a higher priority pod that is created after preemption. As a result, this field may be different than PodSpec.nodeName when the pod is scheduled.", "type": "string" }, + "observedGeneration": { + "description": "If set, this represents the .metadata.generation that the pod status was set based upon. This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field.", + "format": "int64", + "type": "integer" + }, "phase": { "description": "The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. The conditions array, the reason and message fields, and the individual container status arrays contain more detail about the pod's status. There are five possible phase values:\n\nPending: The pod has been accepted by the Kubernetes system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while. Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting. Succeeded: All containers in the pod have terminated in success, and will not be restarted. Failed: All containers in the pod have terminated, and at least one container has terminated in failure. The container either exited with non-zero status or was terminated by the system. Unknown: For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase", "type": "string" @@ -9978,7 +10170,7 @@ "type": "string" }, "resize": { - "description": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\"", + "description": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\" Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress. PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources. PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources.", "type": "string" }, "resourceClaimStatuses": { @@ -11484,7 +11676,7 @@ "description": "sessionAffinityConfig contains the configurations of session affinity." }, "trafficDistribution": { - "description": "TrafficDistribution offers a way to express preferences for how traffic is distributed to Service endpoints. Implementations can use this field as a hint, but are not required to guarantee strict adherence. If the field is not set, the implementation will apply its default routing strategy. If set to \"PreferClose\", implementations should prioritize endpoints that are topologically close (e.g., same zone). This is a beta field and requires enabling ServiceTrafficDistribution feature.", + "description": "TrafficDistribution offers a way to express preferences for how traffic is distributed to Service endpoints. Implementations can use this field as a hint, but are not required to guarantee strict adherence. If the field is not set, the implementation will apply its default routing strategy. If set to \"PreferClose\", implementations should prioritize endpoints that are in the same zone.", "type": "string" }, "type": { @@ -11745,11 +11937,11 @@ "type": "integer" }, "nodeAffinityPolicy": { - "description": "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\nIf this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.", + "description": "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\nIf this value is nil, the behavior is equivalent to the Honor policy.", "type": "string" }, "nodeTaintsPolicy": { - "description": "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included.\n\nIf this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.", + "description": "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included.\n\nIf this value is nil, the behavior is equivalent to the Ignore policy.", "type": "string" }, "topologyKey": { @@ -11890,7 +12082,7 @@ }, "image": { "$ref": "#/definitions/v1.ImageVolumeSource", - "description": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n- Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\nThe volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. The volume will be mounted read-only (ro) and non-executable files (noexec). Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath). The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type." + "description": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n- Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\nThe volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. The volume will be mounted read-only (ro) and non-executable files (noexec). Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type." }, "iscsi": { "$ref": "#/definitions/v1.ISCSIVolumeSource", @@ -12158,7 +12350,7 @@ "description": "Endpoint represents a single logical \"backend\" implementing a service.", "properties": { "addresses": { - "description": "addresses of this endpoint. The contents of this field are interpreted according to the corresponding EndpointSlice addressType field. Consumers must handle different types of addresses in the context of their own capabilities. This must contain at least one address but no more than 100. These are all assumed to be fungible and clients may choose to only use the first element. Refer to: https://issue.k8s.io/106267", + "description": "addresses of this endpoint. For EndpointSlices of addressType \"IPv4\" or \"IPv6\", the values are IP addresses in canonical form. The syntax and semantics of other addressType values are not defined. This must contain at least one address but no more than 100. EndpointSlices generated by the EndpointSlice controller will always have exactly 1 address. No semantics are defined for additional addresses beyond the first, and kube-proxy does not look at them.", "items": { "type": "string" }, @@ -12206,15 +12398,15 @@ "description": "EndpointConditions represents the current condition of an endpoint.", "properties": { "ready": { - "description": "ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be \"true\" for terminating endpoints, except when the normal readiness behavior is being explicitly overridden, for example when the associated Service has set the publishNotReadyAddresses flag.", + "description": "ready indicates that this endpoint is ready to receive traffic, according to whatever system is managing the endpoint. A nil value should be interpreted as \"true\". In general, an endpoint should be marked ready if it is serving and not terminating, though this can be overridden in some cases, such as when the associated Service has set the publishNotReadyAddresses flag.", "type": "boolean" }, "serving": { - "description": "serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition.", + "description": "serving indicates that this endpoint is able to receive traffic, according to whatever system is managing the endpoint. For endpoints backed by pods, the EndpointSlice controller will mark the endpoint as serving if the pod's Ready condition is True. A nil value should be interpreted as \"true\".", "type": "boolean" }, "terminating": { - "description": "terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating.", + "description": "terminating indicates that this endpoint is terminating. A nil value should be interpreted as \"false\".", "type": "boolean" } }, @@ -12223,8 +12415,16 @@ "v1.EndpointHints": { "description": "EndpointHints provides hints describing how an endpoint should be consumed.", "properties": { + "forNodes": { + "description": "forNodes indicates the node(s) this endpoint should be consumed by when using topology aware routing. May contain a maximum of 8 entries. This is an Alpha feature and is only used when the PreferSameTrafficDistribution feature gate is enabled.", + "items": { + "$ref": "#/definitions/v1.ForNode" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, "forZones": { - "description": "forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing.", + "description": "forZones indicates the zone(s) this endpoint should be consumed by when using topology aware routing. May contain a maximum of 8 entries.", "items": { "$ref": "#/definitions/v1.ForZone" }, @@ -12246,7 +12446,7 @@ "type": "string" }, "port": { - "description": "port represents the port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.", + "description": "port represents the port number of the endpoint. If the EndpointSlice is derived from a Kubernetes service, this must be set to the service's target port. EndpointSlices used for other purposes may have a nil port.", "format": "int32", "type": "integer" }, @@ -12259,10 +12459,10 @@ "x-kubernetes-map-type": "atomic" }, "v1.EndpointSlice": { - "description": "EndpointSlice represents a subset of the endpoints that implement a service. For a given service there may be multiple EndpointSlice objects, selected by labels, which must be joined to produce the full set of endpoints.", + "description": "EndpointSlice represents a set of service endpoints. Most EndpointSlices are created by the EndpointSlice controller to represent the Pods selected by Service objects. For a given service there may be multiple EndpointSlice objects which must be joined to produce the full set of endpoints; you can find all of the slices for a given service by listing EndpointSlices in the service's namespace whose `kubernetes.io/service-name` label contains the service's name.", "properties": { "addressType": { - "description": "addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.", + "description": "addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name. (Deprecated) The EndpointSlice controller only generates, and kube-proxy only processes, slices of addressType \"IPv4\" and \"IPv6\". No semantics are defined for the \"FQDN\" type.", "type": "string" }, "apiVersion": { @@ -12286,7 +12486,7 @@ "description": "Standard object's metadata." }, "ports": { - "description": "ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates \"all ports\". Each slice may include a maximum of 100 ports.", + "description": "ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. Each slice may include a maximum of 100 ports. Services always have at least 1 port, so EndpointSlices generated by the EndpointSlice controller will likewise always have at least 1 port. EndpointSlices used for other purposes may have an empty ports list.", "items": { "$ref": "#/definitions/discovery.v1.EndpointPort" }, @@ -12342,6 +12542,19 @@ } ] }, + "v1.ForNode": { + "description": "ForNode provides information about which nodes should consume this endpoint.", + "properties": { + "name": { + "description": "name represents the name of the node.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, "v1.ForZone": { "description": "ForZone provides information about which zones should consume this endpoint.", "properties": { @@ -13123,6 +13336,83 @@ ], "type": "object" }, + "v1.IPAddress": { + "description": "IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. An IP address can be represented in different formats, to guarantee the uniqueness of the IP, the name of the object is the IP address in canonical format, four decimal digits separated by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 Invalid: 10.01.2.3 or 2001:db8:0:0:0::1", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ObjectMeta", + "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "spec": { + "$ref": "#/definitions/v1.IPAddressSpec", + "description": "spec is the desired state of the IPAddress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "networking.k8s.io", + "kind": "IPAddress", + "version": "v1" + } + ] + }, + "v1.IPAddressList": { + "description": "IPAddressList contains a list of IPAddress.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "items is the list of IPAddresses.", + "items": { + "$ref": "#/definitions/v1.IPAddress" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ListMeta", + "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "networking.k8s.io", + "kind": "IPAddressList", + "version": "v1" + } + ] + }, + "v1.IPAddressSpec": { + "description": "IPAddressSpec describe the attributes in an IP Address.", + "properties": { + "parentRef": { + "$ref": "#/definitions/v1.ParentReference", + "description": "ParentRef references the resource that an IPAddress is attached to. An IPAddress must reference a parent object." + } + }, + "required": [ + "parentRef" + ], + "type": "object" + }, "v1.IPBlock": { "description": "IPBlock describes a particular CIDR (Ex. \"192.168.1.0/24\",\"2001:db8::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", "properties": { @@ -13663,6 +13953,32 @@ ], "type": "object" }, + "v1.ParentReference": { + "description": "ParentReference describes a reference to a parent object.", + "properties": { + "group": { + "description": "Group is the group of the object being referenced.", + "type": "string" + }, + "name": { + "description": "Name is the name of the object being referenced.", + "type": "string" + }, + "namespace": { + "description": "Namespace is the namespace of the object being referenced.", + "type": "string" + }, + "resource": { + "description": "Resource is the resource of the object being referenced.", + "type": "string" + } + }, + "required": [ + "resource", + "name" + ], + "type": "object" + }, "v1.ServiceBackendPort": { "description": "ServiceBackendPort is the service port being referenced.", "properties": { @@ -13679,6 +13995,107 @@ "type": "object", "x-kubernetes-map-type": "atomic" }, + "v1.ServiceCIDR": { + "description": "ServiceCIDR defines a range of IP addresses using CIDR format (e.g. 192.168.0.0/24 or 2001:db2::/64). This range is used to allocate ClusterIPs to Service objects.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ObjectMeta", + "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "spec": { + "$ref": "#/definitions/v1.ServiceCIDRSpec", + "description": "spec is the desired state of the ServiceCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status" + }, + "status": { + "$ref": "#/definitions/v1.ServiceCIDRStatus", + "description": "status represents the current state of the ServiceCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "networking.k8s.io", + "kind": "ServiceCIDR", + "version": "v1" + } + ] + }, + "v1.ServiceCIDRList": { + "description": "ServiceCIDRList contains a list of ServiceCIDR objects.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "items is the list of ServiceCIDRs.", + "items": { + "$ref": "#/definitions/v1.ServiceCIDR" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ListMeta", + "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "networking.k8s.io", + "kind": "ServiceCIDRList", + "version": "v1" + } + ] + }, + "v1.ServiceCIDRSpec": { + "description": "ServiceCIDRSpec define the CIDRs the user wants to use for allocating ClusterIPs for Services.", + "properties": { + "cidrs": { + "description": "CIDRs defines the IP blocks in CIDR notation (e.g. \"192.168.0.0/24\" or \"2001:db8::/64\") from which to assign service cluster IPs. Max of two CIDRs is allowed, one of each IP family. This field is immutable.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "type": "object" + }, + "v1.ServiceCIDRStatus": { + "description": "ServiceCIDRStatus describes the current state of the ServiceCIDR.", + "properties": { + "conditions": { + "description": "conditions holds an array of metav1.Condition that describe the state of the ServiceCIDR. Current service state", + "items": { + "$ref": "#/definitions/v1.Condition" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge" + } + }, + "type": "object" + }, "v1beta1.IPAddress": { "description": "IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. An IP address can be represented in different formats, to guarantee the uniqueness of the IP, the name of the object is the IP address in canonical format, four decimal digits separated by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 Invalid: 10.01.2.3 or 2001:db8:0:0:0::1", "properties": { @@ -14107,7 +14524,7 @@ "x-kubernetes-patch-strategy": "replace" }, "unhealthyPodEvictionPolicy": { - "description": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", + "description": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.", "type": "string" } }, @@ -14580,7 +14997,7 @@ "description": "AllocatedDeviceStatus contains the status of an allocated device, if the driver chooses to report it. This may include driver-specific information.", "properties": { "conditions": { - "description": "Conditions contains the latest observation of the device's state. If the device has been configured according to the class and claim config references, the `Ready` condition should be True.", + "description": "Conditions contains the latest observation of the device's state. If the device has been configured according to the class and claim config references, the `Ready` condition should be True.\n\nMust not contain more than 8 entries.", "items": { "$ref": "#/definitions/v1.Condition" }, @@ -14635,6 +15052,10 @@ "v1alpha3.BasicDevice": { "description": "BasicDevice defines one device instance.", "properties": { + "allNodes": { + "description": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "type": "boolean" + }, "attributes": { "additionalProperties": { "$ref": "#/definitions/v1alpha3.DeviceAttribute" @@ -14648,6 +15069,30 @@ }, "description": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", "type": "object" + }, + "consumesCounters": { + "description": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe total number of device counter consumption entries must be <= 32. In addition, the total number in the entire ResourceSlice must be <= 1024 (for example, 64 devices with 16 counters each).", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceCounterConsumption" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "nodeName": { + "description": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "type": "string" + }, + "nodeSelector": { + "$ref": "#/definitions/v1.NodeSelector", + "description": "NodeSelector defines the nodes where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set." + }, + "taints": { + "description": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 4.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceTaint" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" } }, "type": "object" @@ -14665,6 +15110,40 @@ ], "type": "object" }, + "v1alpha3.Counter": { + "description": "Counter describes a quantity associated with a device.", + "properties": { + "value": { + "$ref": "#/definitions/resource.Quantity", + "description": "Value defines how much of a certain device counter is available." + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "v1alpha3.CounterSet": { + "description": "CounterSet defines a named set of counters that are available to be used by devices defined in the ResourceSlice.\n\nThe counters are not allocatable by themselves, but can be referenced by devices. When a device is allocated, the portion of counters it uses will no longer be available for use by other devices.", + "properties": { + "counters": { + "additionalProperties": { + "$ref": "#/definitions/v1alpha3.Counter" + }, + "description": "Counters defines the counters that will be consumed by the device. The name of each counter must be unique in that set and must be a DNS label.\n\nTo ensure this uniqueness, capacities defined by the vendor must be listed without the driver name as domain prefix in their name. All others must be listed with their domain prefix.\n\nThe maximum number of counters is 32.", + "type": "object" + }, + "name": { + "description": "CounterSet is the name of the set from which the counters defined will be consumed.", + "type": "string" + } + }, + "required": [ + "name", + "counters" + ], + "type": "object" + }, "v1alpha3.Device": { "description": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", "properties": { @@ -14690,7 +15169,7 @@ "description": "Opaque provides driver-specific configuration parameters." }, "requests": { - "description": "Requests lists the names of requests where the configuration applies. If empty, its applies to all requests.", + "description": "Requests lists the names of requests where the configuration applies. If empty, its applies to all requests.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the configuration applies to all subrequests.", "items": { "type": "string" }, @@ -14790,7 +15269,7 @@ "description": "Opaque provides driver-specific configuration parameters." }, "requests": { - "description": "Requests lists the names of requests where the configuration applies. If empty, it applies to all requests.", + "description": "Requests lists the names of requests where the configuration applies. If empty, it applies to all requests.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the configuration applies to all subrequests.", "items": { "type": "string" }, @@ -14907,7 +15386,7 @@ "type": "string" }, "requests": { - "description": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.", + "description": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the constraint applies to all subrequests.", "items": { "type": "string" }, @@ -14917,42 +15396,78 @@ }, "type": "object" }, + "v1alpha3.DeviceCounterConsumption": { + "description": "DeviceCounterConsumption defines a set of counters that a device will consume from a CounterSet.", + "properties": { + "counterSet": { + "description": "CounterSet defines the set from which the counters defined will be consumed.", + "type": "string" + }, + "counters": { + "additionalProperties": { + "$ref": "#/definitions/v1alpha3.Counter" + }, + "description": "Counters defines the Counter that will be consumed by the device.\n\nThe maximum number counters in a device is 32. In addition, the maximum number of all counters in all devices is 1024 (for example, 64 devices with 16 counters each).", + "type": "object" + } + }, + "required": [ + "counterSet", + "counters" + ], + "type": "object" + }, "v1alpha3.DeviceRequest": { - "description": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.\n\nA DeviceClassName is currently required. Clients must check that it is indeed set. It's absence indicates that something changed in a way that is not supported by the client yet, in which case it must refuse to handle the request.", + "description": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.", "properties": { "adminAccess": { - "description": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "description": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", "type": "boolean" }, "allocationMode": { - "description": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AlloctionMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", + "description": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n At least one device must exist on the node for the allocation to succeed.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", "type": "string" }, "count": { - "description": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", + "description": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", "format": "int64", "type": "integer" }, "deviceClassName": { - "description": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", + "description": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required if no subrequests are specified in the firstAvailable list and no class can be set if subrequests are specified in the firstAvailable list. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", "type": "string" }, + "firstAvailable": { + "description": "FirstAvailable contains subrequests, of which exactly one will be satisfied by the scheduler to satisfy this request. It tries to satisfy them in the order in which they are listed here. So if there are two entries in the list, the scheduler will only check the second one if it determines that the first one cannot be used.\n\nThis field may only be set in the entries of DeviceClaim.Requests.\n\nDRA does not yet implement scoring, so the scheduler will select the first set of devices that satisfies all the requests in the claim. And if the requirements can be satisfied on more than one node, other scheduling features will determine which node is chosen. This means that the set of devices allocated to a claim might not be the optimal set available to the cluster. Scoring will be implemented later.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceSubRequest" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, "name": { "description": "Name can be used to reference this request in a pod.spec.containers[].resources.claims entry and in a constraint of the claim.\n\nMust be a DNS label.", "type": "string" }, "selectors": { - "description": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.", + "description": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", "items": { "$ref": "#/definitions/v1alpha3.DeviceSelector" }, "type": "array", "x-kubernetes-list-type": "atomic" + }, + "tolerations": { + "description": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceToleration" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" } }, "required": [ - "name", - "deviceClassName" + "name" ], "type": "object" }, @@ -14976,8 +15491,16 @@ "type": "string" }, "request": { - "description": "Request is the name of the request in the claim which caused this device to be allocated. Multiple devices may have been allocated per request.", + "description": "Request is the name of the request in the claim which caused this device to be allocated. If it references a subrequest in the firstAvailable list on a DeviceRequest, this field must include both the name of the main request and the subrequest using the format
/.\n\nMultiple devices may have been allocated per request.", "type": "string" + }, + "tolerations": { + "description": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceToleration" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" } }, "required": [ @@ -14998,6 +15521,217 @@ }, "type": "object" }, + "v1alpha3.DeviceSubRequest": { + "description": "DeviceSubRequest describes a request for device provided in the claim.spec.devices.requests[].firstAvailable array. Each is typically a request for a single resource like a device, but can also ask for several identical devices.\n\nDeviceSubRequest is similar to Request, but doesn't expose the AdminAccess or FirstAvailable fields, as those can only be set on the top-level request. AdminAccess is not supported for requests with a prioritized list, and recursive FirstAvailable fields are not supported.", + "properties": { + "allocationMode": { + "description": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", + "type": "string" + }, + "count": { + "description": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", + "format": "int64", + "type": "integer" + }, + "deviceClassName": { + "description": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this subrequest.\n\nA class is required. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", + "type": "string" + }, + "name": { + "description": "Name can be used to reference this subrequest in the list of constraints or the list of configurations for the claim. References must use the format
/.\n\nMust be a DNS label.", + "type": "string" + }, + "selectors": { + "description": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceSelector" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "tolerations": { + "description": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceToleration" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "name", + "deviceClassName" + ], + "type": "object" + }, + "v1alpha3.DeviceTaint": { + "description": "The device this taint is attached to has the \"effect\" on any claim which does not tolerate the taint and, through the claim, to pods using the claim.", + "properties": { + "effect": { + "description": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them. Valid effects are NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here.", + "type": "string" + }, + "key": { + "description": "The taint key to be applied to a device. Must be a label name.", + "type": "string" + }, + "timeAdded": { + "description": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", + "format": "date-time", + "type": "string" + }, + "value": { + "description": "The taint value corresponding to the taint key. Must be a label value.", + "type": "string" + } + }, + "required": [ + "key", + "effect" + ], + "type": "object" + }, + "v1alpha3.DeviceTaintRule": { + "description": "DeviceTaintRule adds one taint to all devices which match the selector. This has the same effect as if the taint was specified directly in the ResourceSlice by the DRA driver.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ObjectMeta", + "description": "Standard object metadata" + }, + "spec": { + "$ref": "#/definitions/v1alpha3.DeviceTaintRuleSpec", + "description": "Spec specifies the selector and one taint.\n\nChanging the spec automatically increments the metadata.generation number." + } + }, + "required": [ + "spec" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "DeviceTaintRule", + "version": "v1alpha3" + } + ] + }, + "v1alpha3.DeviceTaintRuleList": { + "description": "DeviceTaintRuleList is a collection of DeviceTaintRules.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of DeviceTaintRules.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceTaintRule" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1.ListMeta", + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "DeviceTaintRuleList", + "version": "v1alpha3" + } + ] + }, + "v1alpha3.DeviceTaintRuleSpec": { + "description": "DeviceTaintRuleSpec specifies the selector and one taint.", + "properties": { + "deviceSelector": { + "$ref": "#/definitions/v1alpha3.DeviceTaintSelector", + "description": "DeviceSelector defines which device(s) the taint is applied to. All selector criteria must be satified for a device to match. The empty selector matches all devices. Without a selector, no devices are matches." + }, + "taint": { + "$ref": "#/definitions/v1alpha3.DeviceTaint", + "description": "The taint that gets applied to matching devices." + } + }, + "required": [ + "taint" + ], + "type": "object" + }, + "v1alpha3.DeviceTaintSelector": { + "description": "DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. The empty selector matches all devices. Without a selector, no devices are matched.", + "properties": { + "device": { + "description": "If device is set, only devices with that name are selected. This field corresponds to slice.spec.devices[].name.\n\nSetting also driver and pool may be required to avoid ambiguity, but is not required.", + "type": "string" + }, + "deviceClassName": { + "description": "If DeviceClassName is set, the selectors defined there must be satisfied by a device to be selected. This field corresponds to class.metadata.name.", + "type": "string" + }, + "driver": { + "description": "If driver is set, only devices from that driver are selected. This fields corresponds to slice.spec.driver.", + "type": "string" + }, + "pool": { + "description": "If pool is set, only devices in that pool are selected.\n\nAlso setting the driver name may be useful to avoid ambiguity when different drivers use the same pool name, but this is not required because selecting pools from different drivers may also be useful, for example when drivers with node-local devices use the node name as their pool name.", + "type": "string" + }, + "selectors": { + "description": "Selectors contains the same selection criteria as a ResourceClaim. Currently, CEL expressions are supported. All of these selectors must be satisfied.", + "items": { + "$ref": "#/definitions/v1alpha3.DeviceSelector" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "type": "object" + }, + "v1alpha3.DeviceToleration": { + "description": "The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches the triple using the matching operator .", + "properties": { + "effect": { + "description": "Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule and NoExecute.", + "type": "string" + }, + "key": { + "description": "Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. Must be a label name.", + "type": "string" + }, + "operator": { + "description": "Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a ResourceClaim can tolerate all taints of a particular category.", + "type": "string" + }, + "tolerationSeconds": { + "description": "TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. If larger than zero, the time when the pod needs to be evicted is calculated as