migrate to record (#1665)
* migrate to record * chore: update project files and clean up unused references * refactor: convert classes to records and simplify constructors for IntOrString, ResourceQuantity, and V1Patch * fix: define IsExternalInit to resolve CS0518 error in IntOrString * refactor: change IntOrString and ResourceQuantity from records to structs, update implicit conversions, and simplify null checks * refactor: add JsonPropertyName attribute to Value property in IntOrString struct * refactor: simplify V1Patch constructor and improve argument validation * refactor: remove unnecessary CultureInfo parameter in ToInt method * Update src/KubernetesClient/Models/ResourceQuantity.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/KubernetesClient/Models/IntOrString.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Revert "Update src/KubernetesClient/Models/ResourceQuantity.cs" This reverts commit 62b20a691554659e28d419067220dc1a0620133b. * refactor: remove commented-out formatting check and simplify build command * refactor: remove IValidate.cs from project references in Aot and Classic --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
6
.github/workflows/buildtest.yaml
vendored
6
.github/workflows/buildtest.yaml
vendored
@@ -17,12 +17,8 @@ jobs:
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
9.0.x
|
||||
# - name: Check Format
|
||||
# # don't check formatting on Windows b/c of CRLF issues.
|
||||
# if: matrix.os == 'ubuntu-latest'
|
||||
# run: dotnet format --severity error --verify-no-changes --exclude ./src/KubernetesClient/generated/
|
||||
- name: Build
|
||||
run: dotnet build --configuration Release -v detailed
|
||||
run: dotnet build --configuration Release
|
||||
- name: Test
|
||||
run: dotnet test --configuration Release --collect:"Code Coverage;Format=Cobertura" --logger trx --results-directory TestResults --settings CodeCoverage.runsettings --no-build
|
||||
- name: Upload coverage to Codecov
|
||||
|
||||
@@ -67,7 +67,15 @@ var old = JsonSerializer.SerializeToDocument(readCert, serializeOptions);
|
||||
|
||||
var replace = new List<V1CertificateSigningRequestCondition>
|
||||
{
|
||||
new ("True", "Approved", DateTime.UtcNow, DateTime.UtcNow, "This certificate was approved by k8s client", "Approve"),
|
||||
new V1CertificateSigningRequestCondition
|
||||
{
|
||||
Type = "Approved",
|
||||
Status = "True",
|
||||
Reason = "Approve",
|
||||
Message = "This certificate was approved by k8s client",
|
||||
LastUpdateTime = DateTime.UtcNow,
|
||||
LastTransitionTime = DateTime.UtcNow,
|
||||
},
|
||||
};
|
||||
readCert.Status.Conditions = replace;
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ namespace customResource
|
||||
}
|
||||
}
|
||||
|
||||
public class CResourceSpec
|
||||
public record CResourceSpec
|
||||
{
|
||||
[JsonPropertyName("cityName")]
|
||||
public string CityName { get; set; }
|
||||
}
|
||||
|
||||
public class CResourceStatus : V1Status
|
||||
public record CResourceStatus : V1Status
|
||||
{
|
||||
[JsonPropertyName("temperature")]
|
||||
public string Temperature { get; set; }
|
||||
|
||||
@@ -23,7 +23,7 @@ var pod = new V1Pod
|
||||
{
|
||||
Requests = new Dictionary<string, ResourceQuantity>()
|
||||
{
|
||||
["cpu"] = new ResourceQuantity("100m"),
|
||||
["cpu"] = "100m",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -25,15 +25,13 @@
|
||||
<Compile Include="..\KubernetesClient\Models\IMetadata.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntOrStringJsonConverter.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntOrStringYamlConverter.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntstrIntOrString.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntOrString.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\ISpec.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IStatus.cs" />
|
||||
<Compile Include="..\KubernetesClient\IValidate.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\KubernetesEntityAttribute.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\KubernetesList.cs" />
|
||||
<Compile Include="..\KubernetesClient\KubernetesObject.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\ModelExtensions.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\ModelVersionConverter.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\NodeMetrics.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\NodeMetricsList.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\PodMetrics.cs" />
|
||||
|
||||
5
src/KubernetesClient.Classic/IsExternalInit.cs
Normal file
5
src/KubernetesClient.Classic/IsExternalInit.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
// IntOrString.cs(7,36): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
internal static class IsExternalInit { }
|
||||
}
|
||||
@@ -27,17 +27,15 @@
|
||||
<Compile Include="..\KubernetesClient\Models\IMetadata.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntOrStringJsonConverter.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntOrStringYamlConverter.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntstrIntOrString.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IntOrString.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\ISpec.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\IStatus.cs" />
|
||||
<Compile Include="..\KubernetesClient\IValidate.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\KubernetesEntityAttribute.cs" />
|
||||
<Compile Include="..\KubernetesClient\KubernetesJson.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\KubernetesList.cs" />
|
||||
<Compile Include="..\KubernetesClient\KubernetesObject.cs" />
|
||||
<Compile Include="..\KubernetesClient\KubernetesYaml.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\ModelExtensions.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\ModelVersionConverter.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\NodeMetrics.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\NodeMetricsList.cs" />
|
||||
<Compile Include="..\KubernetesClient\Models\PodMetrics.cs" />
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace k8s
|
||||
{
|
||||
/// <summary>
|
||||
/// Object that allows self validation
|
||||
/// </summary>
|
||||
public interface IValidate
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate the object.
|
||||
/// </summary>
|
||||
void Validate();
|
||||
}
|
||||
}
|
||||
38
src/KubernetesClient/Models/IntOrString.cs
Normal file
38
src/KubernetesClient/Models/IntOrString.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace k8s.Models
|
||||
{
|
||||
[JsonConverter(typeof(IntOrStringJsonConverter))]
|
||||
public struct IntOrString
|
||||
{
|
||||
public string? Value { get; private init; }
|
||||
|
||||
public static implicit operator IntOrString(int v)
|
||||
{
|
||||
return Convert.ToString(v);
|
||||
}
|
||||
|
||||
public static implicit operator IntOrString(long v)
|
||||
{
|
||||
return Convert.ToString(v);
|
||||
}
|
||||
|
||||
public static implicit operator string(IntOrString v)
|
||||
{
|
||||
return v.Value;
|
||||
}
|
||||
|
||||
public static implicit operator IntOrString(string v)
|
||||
{
|
||||
return new IntOrString { Value = v };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
public int ToInt()
|
||||
{
|
||||
return int.Parse(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
namespace k8s.Models
|
||||
{
|
||||
internal sealed class IntOrStringJsonConverter : JsonConverter<IntstrIntOrString>
|
||||
internal sealed class IntOrStringJsonConverter : JsonConverter<IntOrString>
|
||||
{
|
||||
public override IntstrIntOrString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
public override IntOrString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
@@ -17,14 +17,14 @@ namespace k8s.Models
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, IntstrIntOrString value, JsonSerializerOptions options)
|
||||
public override void Write(Utf8JsonWriter writer, IntOrString value, JsonSerializerOptions options)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
var s = value?.Value;
|
||||
var s = value.Value;
|
||||
|
||||
if (long.TryParse(s, out var intv))
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace k8s.Models
|
||||
{
|
||||
public bool Accepts(Type type)
|
||||
{
|
||||
return type == typeof(IntstrIntOrString);
|
||||
return type == typeof(IntOrString);
|
||||
}
|
||||
|
||||
public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer)
|
||||
@@ -21,7 +21,7 @@ namespace k8s.Models
|
||||
return null;
|
||||
}
|
||||
|
||||
return new IntstrIntOrString(scalar?.Value);
|
||||
return scalar?.Value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -34,8 +34,8 @@ namespace k8s.Models
|
||||
|
||||
public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer)
|
||||
{
|
||||
var obj = (IntstrIntOrString)value;
|
||||
emitter?.Emit(new YamlDotNet.Core.Events.Scalar(obj?.Value));
|
||||
var obj = (IntOrString)value;
|
||||
emitter?.Emit(new YamlDotNet.Core.Events.Scalar(obj.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
namespace k8s.Models
|
||||
{
|
||||
[JsonConverter(typeof(IntOrStringJsonConverter))]
|
||||
public partial class IntstrIntOrString
|
||||
{
|
||||
public static implicit operator IntstrIntOrString(int v)
|
||||
{
|
||||
return new IntstrIntOrString(Convert.ToString(v));
|
||||
}
|
||||
|
||||
public static implicit operator IntstrIntOrString(long v)
|
||||
{
|
||||
return new IntstrIntOrString(Convert.ToString(v));
|
||||
}
|
||||
|
||||
public static implicit operator string(IntstrIntOrString v)
|
||||
{
|
||||
return v?.Value;
|
||||
}
|
||||
|
||||
public static implicit operator IntstrIntOrString(string v)
|
||||
{
|
||||
return new IntstrIntOrString(v);
|
||||
}
|
||||
|
||||
protected bool Equals(IntstrIntOrString other)
|
||||
{
|
||||
return string.Equals(Value, other?.Value);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((IntstrIntOrString)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value != null ? Value.GetHashCode() : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,24 +40,5 @@ namespace k8s.Models
|
||||
/// </summary>
|
||||
[JsonPropertyName("metadata")]
|
||||
public V1ListMeta Metadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Validate the object.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
if (Items == null)
|
||||
{
|
||||
throw new ArgumentNullException("Items");
|
||||
}
|
||||
|
||||
if (Items != null)
|
||||
{
|
||||
foreach (var element in Items.OfType<IValidate>())
|
||||
{
|
||||
element.Validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace k8s.Models;
|
||||
|
||||
public static class ModelVersionConverter
|
||||
{
|
||||
public interface IModelVersionConverter
|
||||
{
|
||||
TTo Convert<TFrom, TTo>(TFrom from);
|
||||
}
|
||||
|
||||
public static IModelVersionConverter Converter { get; set; }
|
||||
|
||||
internal static TTo Convert<TFrom, TTo>(TFrom from)
|
||||
{
|
||||
if (Converter == null)
|
||||
{
|
||||
throw new InvalidOperationException("Converter is not set");
|
||||
}
|
||||
|
||||
return Converter.Convert<TFrom, TTo>(from);
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace k8s.Models
|
||||
/// cause implementors to also use a fixed point implementation.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(ResourceQuantityJsonConverter))]
|
||||
public partial class ResourceQuantity
|
||||
public struct ResourceQuantity
|
||||
{
|
||||
public enum SuffixFormat
|
||||
{
|
||||
@@ -97,39 +97,6 @@ namespace k8s.Models
|
||||
return CanonicalizeString();
|
||||
}
|
||||
|
||||
protected bool Equals(ResourceQuantity other)
|
||||
{
|
||||
return _unitlessValue.Equals(other?._unitlessValue);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((ResourceQuantity)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((int)Format * 397) ^ _unitlessValue.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CanonicalizeString = go version CanonicalizeBytes
|
||||
// CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity).
|
||||
@@ -157,10 +124,9 @@ namespace k8s.Models
|
||||
return Suffixer.AppendMaxSuffix(_unitlessValue, suffixFormat);
|
||||
}
|
||||
|
||||
// ctor
|
||||
partial void CustomInit()
|
||||
public ResourceQuantity(string v)
|
||||
{
|
||||
if (Value == null)
|
||||
if (v == null)
|
||||
{
|
||||
// No value has been defined, initialize to 0.
|
||||
_unitlessValue = new Fraction(0);
|
||||
@@ -168,7 +134,7 @@ namespace k8s.Models
|
||||
return;
|
||||
}
|
||||
|
||||
var value = Value.Trim();
|
||||
var value = v.Trim();
|
||||
|
||||
var si = value.IndexOfAny(SuffixChars);
|
||||
if (si == -1)
|
||||
@@ -188,6 +154,11 @@ namespace k8s.Models
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator ResourceQuantity(string v)
|
||||
{
|
||||
return new ResourceQuantity(v);
|
||||
}
|
||||
|
||||
private static bool HasMantissa(Fraction value)
|
||||
{
|
||||
if (value.IsZero)
|
||||
@@ -200,7 +171,7 @@ namespace k8s.Models
|
||||
|
||||
public static implicit operator decimal(ResourceQuantity v)
|
||||
{
|
||||
return v?.ToDecimal() ?? 0;
|
||||
return v.ToDecimal();
|
||||
}
|
||||
|
||||
public static implicit operator ResourceQuantity(decimal v)
|
||||
|
||||
@@ -8,16 +8,16 @@ namespace k8s.Models
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonTokenType.Null:
|
||||
return new ResourceQuantity(null);
|
||||
return null;
|
||||
case JsonTokenType.Number:
|
||||
if (reader.TryGetDouble(out var val))
|
||||
{
|
||||
return new ResourceQuantity(Convert.ToString(val));
|
||||
return Convert.ToString(val);
|
||||
}
|
||||
|
||||
return reader.GetDecimal();
|
||||
default:
|
||||
return new ResourceQuantity(reader.GetString());
|
||||
return reader.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace k8s.Models
|
||||
throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
writer.WriteStringValue(value?.ToString());
|
||||
writer.WriteStringValue(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace k8s.Models
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ResourceQuantity(scalar?.Value);
|
||||
return scalar?.Value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace k8s.Models
|
||||
public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer)
|
||||
{
|
||||
var obj = (ResourceQuantity)value;
|
||||
emitter?.Emit(new YamlDotNet.Core.Events.Scalar(obj?.ToString()));
|
||||
emitter?.Emit(new YamlDotNet.Core.Events.Scalar(obj.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace k8s.Models
|
||||
{
|
||||
[JsonConverter(typeof(V1PatchJsonConverter))]
|
||||
public partial class V1Patch
|
||||
public record V1Patch
|
||||
{
|
||||
public enum PatchType
|
||||
{
|
||||
@@ -31,26 +31,21 @@ namespace k8s.Models
|
||||
ApplyPatch,
|
||||
}
|
||||
|
||||
[JsonPropertyName("content")]
|
||||
[JsonInclude]
|
||||
public object Content { get; private set; }
|
||||
|
||||
public PatchType Type { get; private set; }
|
||||
|
||||
public V1Patch(object body, PatchType type)
|
||||
{
|
||||
Content = body;
|
||||
if (type == PatchType.Unknown)
|
||||
{
|
||||
throw new ArgumentException("patch type must be set", nameof(type));
|
||||
}
|
||||
|
||||
Content = body ?? throw new ArgumentNullException(nameof(body), "object must be set");
|
||||
Type = type;
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
partial void CustomInit()
|
||||
{
|
||||
if (Content == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Content), "object must be set");
|
||||
}
|
||||
|
||||
if (Type == PatchType.Unknown)
|
||||
{
|
||||
throw new ArgumentException("patch type must be set", nameof(Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace k8s.Models
|
||||
/// Partial implementation of the IMetadata interface
|
||||
/// to open this class up to ModelExtensions methods
|
||||
/// </summary>
|
||||
public partial class V1PodTemplateSpec : IMetadata<V1ObjectMeta>
|
||||
public partial record V1PodTemplateSpec : IMetadata<V1ObjectMeta>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace k8s.Models
|
||||
{
|
||||
public partial class V1Status
|
||||
public partial record V1Status
|
||||
{
|
||||
internal sealed class V1StatusObjectViewConverter : JsonConverter<V1Status>
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Net;
|
||||
|
||||
namespace k8s.Models
|
||||
{
|
||||
public partial class V1Status
|
||||
public partial record V1Status
|
||||
{
|
||||
/// <summary>Converts a <see cref="V1Status"/> object into a short description of the status.</summary>
|
||||
/// <returns>string description of the status</returns>
|
||||
|
||||
@@ -78,6 +78,12 @@ namespace LibKubernetesGenerator
|
||||
}
|
||||
|
||||
|
||||
if (definition.Format == "int-or-string")
|
||||
{
|
||||
return "IntOrString";
|
||||
}
|
||||
|
||||
|
||||
return schemaToNameMapCooked[definition];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +57,6 @@ namespace LibKubernetesGenerator
|
||||
}
|
||||
}
|
||||
|
||||
interfaces.Add("IValidate");
|
||||
|
||||
return string.Join(", ", interfaces);
|
||||
}
|
||||
|
||||
@@ -68,7 +66,7 @@ namespace LibKubernetesGenerator
|
||||
|
||||
if (init == "true" && !parameter.IsRequired)
|
||||
{
|
||||
name += " = null";
|
||||
name += " = default";
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
@@ -58,12 +58,10 @@ namespace LibKubernetesGenerator
|
||||
builder.RegisterType<ScriptObjectFactory>()
|
||||
;
|
||||
|
||||
builder.RegisterType<ModelExtGenerator>();
|
||||
builder.RegisterType<SourceGenerationContextGenerator>();
|
||||
builder.RegisterType<ModelGenerator>();
|
||||
builder.RegisterType<ApiGenerator>();
|
||||
builder.RegisterType<ClientSetGenerator>();
|
||||
builder.RegisterType<VersionConverterStubGenerator>();
|
||||
builder.RegisterType<VersionGenerator>();
|
||||
|
||||
return builder.Build();
|
||||
@@ -79,9 +77,7 @@ namespace LibKubernetesGenerator
|
||||
container.Resolve<VersionGenerator>().Generate(swagger, ctx);
|
||||
|
||||
container.Resolve<ModelGenerator>().Generate(swagger, ctx);
|
||||
container.Resolve<ModelExtGenerator>().Generate(swagger, ctx);
|
||||
container.Resolve<SourceGenerationContextGenerator>().Generate(swagger, ctx);
|
||||
container.Resolve<VersionConverterStubGenerator>().Generate(swagger, ctx);
|
||||
container.Resolve<ApiGenerator>().Generate(swagger, ctx);
|
||||
container.Resolve<ClientSetGenerator>().Generate(swagger, ctx);
|
||||
});
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using NSwag;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace LibKubernetesGenerator
|
||||
{
|
||||
internal class ModelExtGenerator
|
||||
{
|
||||
private readonly ClassNameHelper classNameHelper;
|
||||
private readonly ScriptObjectFactory scriptObjectFactory;
|
||||
|
||||
public ModelExtGenerator(ClassNameHelper classNameHelper, ScriptObjectFactory scriptObjectFactory)
|
||||
{
|
||||
this.classNameHelper = classNameHelper;
|
||||
this.scriptObjectFactory = scriptObjectFactory;
|
||||
}
|
||||
|
||||
public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
|
||||
{
|
||||
// Generate the interface declarations
|
||||
var skippedTypes = new HashSet<string> { "V1WatchEvent" };
|
||||
|
||||
var definitions = swagger.Definitions.Values
|
||||
.Where(
|
||||
d => d.ExtensionData != null
|
||||
&& d.ExtensionData.ContainsKey("x-kubernetes-group-version-kind")
|
||||
&& !skippedTypes.Contains(classNameHelper.GetClassName(d)));
|
||||
|
||||
var sc = scriptObjectFactory.CreateScriptObject();
|
||||
sc.SetValue("definitions", definitions, true);
|
||||
|
||||
context.RenderToContext("ModelExtensions.cs.template", sc, "ModelExtensions.g.cs");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using NSwag;
|
||||
|
||||
@@ -18,15 +19,49 @@ namespace LibKubernetesGenerator
|
||||
{
|
||||
var sc = scriptObjectFactory.CreateScriptObject();
|
||||
|
||||
var genSkippedTypes = new HashSet<string>
|
||||
{
|
||||
"IntOrString",
|
||||
"ResourceQuantity",
|
||||
"V1Patch",
|
||||
};
|
||||
|
||||
var extSkippedTypes = new HashSet<string>
|
||||
{
|
||||
"V1WatchEvent",
|
||||
};
|
||||
|
||||
var typeOverrides = new Dictionary<string, string>
|
||||
{
|
||||
// not used at the moment
|
||||
};
|
||||
|
||||
foreach (var kv in swagger.Definitions)
|
||||
{
|
||||
var def = kv.Value;
|
||||
var clz = classNameHelper.GetClassNameForSchemaDefinition(def);
|
||||
|
||||
if (genSkippedTypes.Contains(clz))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var hasExt = def.ExtensionData != null
|
||||
&& def.ExtensionData.ContainsKey("x-kubernetes-group-version-kind")
|
||||
&& !extSkippedTypes.Contains(clz);
|
||||
|
||||
|
||||
var typ = "record";
|
||||
if (typeOverrides.TryGetValue(clz, out var to))
|
||||
{
|
||||
typ = to;
|
||||
}
|
||||
|
||||
sc.SetValue("clz", clz, true);
|
||||
sc.SetValue("def", def, true);
|
||||
sc.SetValue("properties", def.Properties.Values, true);
|
||||
sc.SetValue("typ", typ, true);
|
||||
sc.SetValue("hasExt", hasExt, true);
|
||||
|
||||
context.RenderToContext("Model.cs.template", sc, $"Models_{clz}.g.cs");
|
||||
}
|
||||
|
||||
@@ -1,70 +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 VersionConverterStubGenerator
|
||||
{
|
||||
private readonly ClassNameHelper classNameHelper;
|
||||
|
||||
public VersionConverterStubGenerator(ClassNameHelper classNameHelper)
|
||||
{
|
||||
this.classNameHelper = classNameHelper;
|
||||
}
|
||||
|
||||
public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
|
||||
{
|
||||
var allGeneratedModelClassNames = new List<string>();
|
||||
|
||||
foreach (var kv in swagger.Definitions)
|
||||
{
|
||||
var def = kv.Value;
|
||||
var clz = classNameHelper.GetClassNameForSchemaDefinition(def);
|
||||
allGeneratedModelClassNames.Add(clz);
|
||||
}
|
||||
|
||||
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 sbmodel = new StringBuilder(@"// <auto-generated />
|
||||
namespace k8s.Models;
|
||||
");
|
||||
|
||||
foreach (var (t0, t1) in typePairs)
|
||||
{
|
||||
sbmodel.AppendLine($@"
|
||||
public partial class {t0}
|
||||
{{
|
||||
public static explicit operator {t0}({t1} s) => ModelVersionConverter.Convert<{t1}, {t0}>(s);
|
||||
}}
|
||||
public partial class {t1}
|
||||
{{
|
||||
public static explicit operator {t1}({t0} s) => ModelVersionConverter.Convert<{t0}, {t1}>(s);
|
||||
}}");
|
||||
}
|
||||
|
||||
context.AddSource($"ModelOperators.g.cs", SourceText.From(sbmodel.ToString(), Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,92 +4,29 @@
|
||||
// regenerated.
|
||||
// </auto-generated>
|
||||
|
||||
namespace k8s.Models
|
||||
{
|
||||
namespace k8s.Models;
|
||||
|
||||
/// <summary>
|
||||
/// {{ToXmlDoc def.description}}
|
||||
/// </summary>
|
||||
public partial class {{clz}}
|
||||
{{ if hasExt }}
|
||||
[KubernetesEntity(Group=KubeGroup, Kind=KubeKind, ApiVersion=KubeApiVersion, PluralName=KubePluralName)]
|
||||
{{ end }}
|
||||
public partial {{typ}} {{clz}} {{ if hasExt }} : {{ GetInterfaceName def }} {{ end }}
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the {{GetClassName def}} class.
|
||||
/// </summary>
|
||||
public {{clz}}()
|
||||
{
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the {{GetClassName def}} class.
|
||||
/// </summary>
|
||||
{{ for property in properties }}
|
||||
{{ if property.IsRequired }}
|
||||
/// <param name="{{GetDotNetName property.name "fieldctor"}}">
|
||||
/// {{ToXmlDoc property.description}}
|
||||
/// </param>
|
||||
{{ if hasExt}}
|
||||
public const string KubeApiVersion = "{{ GetApiVersion def }}";
|
||||
public const string KubeKind = "{{ GetKind def }}";
|
||||
public const string KubeGroup = "{{ GetGroup def }}";
|
||||
public const string KubePluralName = "{{ GetPlural def }}";
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ for property in properties }}
|
||||
{{ if !property.IsRequired }}
|
||||
/// <param name="{{GetDotNetName property.name "fieldctor"}}">
|
||||
/// {{ToXmlDoc property.description}}
|
||||
/// </param>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
public {{clz}}({{GetModelCtorParam def}})
|
||||
{
|
||||
{{ for property in properties }}
|
||||
{{GetDotNetName property.name "field"}} = {{GetDotNetName property.name "fieldctor"}};
|
||||
{{ end }}
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An initialization method that performs custom operations like setting defaults
|
||||
/// </summary>
|
||||
partial void CustomInit();
|
||||
|
||||
{{ for property in properties }}
|
||||
/// <summary>
|
||||
/// {{ToXmlDoc property.description}}
|
||||
/// </summary>
|
||||
[JsonPropertyName("{{property.name}}")]
|
||||
public {{GetDotNetType property}} {{GetDotNetName property.name "field"}} { get; set; }
|
||||
public {{ if property.IsRequired }} required {{ end }} {{GetDotNetType property}} {{GetDotNetName property.name "field"}} { get; set; }
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate the object.
|
||||
/// </summary>
|
||||
|
||||
public virtual void Validate()
|
||||
{
|
||||
{{ for property in properties }}
|
||||
{{if IfType property "object" }}
|
||||
{{ if property.IsRequired }}
|
||||
if ({{GetDotNetName property.name "field"}} == null)
|
||||
{
|
||||
throw new ArgumentNullException("{{GetDotNetName property.name "field"}}");
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ for property in properties }}
|
||||
{{if IfType property "object" }}
|
||||
{{GetDotNetName property.name "field"}}?.Validate();
|
||||
{{ end }}
|
||||
|
||||
{{if IfType property "objectarray" }}
|
||||
if ({{GetDotNetName property.name "field"}} != null){
|
||||
foreach(var obj in {{GetDotNetName property.name "field"}})
|
||||
{
|
||||
obj.Validate();
|
||||
}
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// <auto-generated>
|
||||
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// </auto-generated>
|
||||
namespace k8s.Models
|
||||
{
|
||||
{{ for definition in definitions }}
|
||||
[KubernetesEntity(Group=KubeGroup, Kind=KubeKind, ApiVersion=KubeApiVersion, PluralName=KubePluralName)]
|
||||
public partial class {{ GetClassName definition }} : {{ GetInterfaceName definition }}
|
||||
{
|
||||
public const string KubeApiVersion = "{{ GetApiVersion definition }}";
|
||||
public const string KubeKind = "{{ GetKind definition }}";
|
||||
public const string KubeGroup = "{{ GetGroup definition }}";
|
||||
public const string KubePluralName = "{{ GetPlural definition }}";
|
||||
}
|
||||
{{ end }}
|
||||
}
|
||||
@@ -172,27 +172,33 @@ namespace k8s.E2E
|
||||
using var kubernetes = CreateClient();
|
||||
|
||||
await kubernetes.CoreV1.CreateNamespacedEventAsync(
|
||||
new Corev1Event(
|
||||
new V1ObjectReference(
|
||||
"v1alpha1",
|
||||
kind: "Test",
|
||||
name: "test",
|
||||
namespaceProperty: "default",
|
||||
resourceVersion: "1",
|
||||
uid: "1"),
|
||||
new V1ObjectMeta()
|
||||
new Corev1Event
|
||||
{
|
||||
InvolvedObject = new V1ObjectReference
|
||||
{
|
||||
ApiVersion = "v1alpha1",
|
||||
Kind = "Test",
|
||||
Name = "test",
|
||||
NamespaceProperty = "default",
|
||||
ResourceVersion = "1",
|
||||
Uid = "1",
|
||||
},
|
||||
Metadata = new V1ObjectMeta
|
||||
{
|
||||
GenerateName = "started-",
|
||||
},
|
||||
action: "STARTED",
|
||||
type: "Normal",
|
||||
reason: "STARTED",
|
||||
message: "Started",
|
||||
eventTime: DateTime.Now,
|
||||
firstTimestamp: DateTime.Now,
|
||||
lastTimestamp: DateTime.Now,
|
||||
reportingComponent: "37",
|
||||
reportingInstance: "38"), "default").ConfigureAwait(false);
|
||||
Action = "STARTED",
|
||||
Type = "Normal",
|
||||
Reason = "STARTED",
|
||||
Message = "Started",
|
||||
EventTime = DateTime.Now,
|
||||
FirstTimestamp = DateTime.Now,
|
||||
LastTimestamp = DateTime.Now,
|
||||
ReportingComponent = "37",
|
||||
ReportingInstance = "38",
|
||||
},
|
||||
"default"
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[MinikubeFact]
|
||||
|
||||
@@ -451,27 +451,33 @@ namespace k8s.E2E
|
||||
using var kubernetes = CreateClient();
|
||||
|
||||
await kubernetes.CoreV1.CreateNamespacedEventAsync(
|
||||
new Corev1Event(
|
||||
new V1ObjectReference(
|
||||
"v1alpha1",
|
||||
kind: "Test",
|
||||
name: "test",
|
||||
namespaceProperty: "default",
|
||||
resourceVersion: "1",
|
||||
uid: "1"),
|
||||
new V1ObjectMeta()
|
||||
new Corev1Event
|
||||
{
|
||||
Metadata = new V1ObjectMeta
|
||||
{
|
||||
GenerateName = "started-",
|
||||
NamespaceProperty = "default",
|
||||
},
|
||||
action: "STARTED",
|
||||
type: "Normal",
|
||||
reason: "STARTED",
|
||||
message: "Started",
|
||||
eventTime: DateTime.Now,
|
||||
firstTimestamp: DateTime.Now,
|
||||
lastTimestamp: DateTime.Now,
|
||||
reportingComponent: "37",
|
||||
reportingInstance: "38"), "default").ConfigureAwait(false);
|
||||
InvolvedObject = new V1ObjectReference
|
||||
{
|
||||
ApiVersion = "v1alpha1",
|
||||
Kind = "Test",
|
||||
Name = "test",
|
||||
NamespaceProperty = "default",
|
||||
ResourceVersion = "1",
|
||||
Uid = "1",
|
||||
},
|
||||
Action = "STARTED",
|
||||
Type = "Normal",
|
||||
Reason = "STARTED",
|
||||
Message = "Started",
|
||||
EventTime = DateTime.Now,
|
||||
FirstTimestamp = DateTime.Now,
|
||||
LastTimestamp = DateTime.Now,
|
||||
ReportingComponent = "37",
|
||||
ReportingInstance = "38",
|
||||
},
|
||||
"default").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[MinikubeFact]
|
||||
|
||||
@@ -7,7 +7,7 @@ using Xunit;
|
||||
|
||||
namespace k8s.tests;
|
||||
|
||||
public class BasicTests
|
||||
public class SimpleTests
|
||||
{
|
||||
// TODO: fail to setup asp.net core 6 on net48
|
||||
private class DummyHttpServer : System.IDisposable
|
||||
|
||||
@@ -10,13 +10,13 @@ namespace k8s.Tests
|
||||
{
|
||||
{
|
||||
var v = 123;
|
||||
IntstrIntOrString intorstr = v;
|
||||
IntOrString intorstr = v;
|
||||
|
||||
Assert.Equal("123", KubernetesJson.Serialize(intorstr));
|
||||
}
|
||||
|
||||
{
|
||||
IntstrIntOrString intorstr = "12%";
|
||||
IntOrString intorstr = "12%";
|
||||
Assert.Equal("\"12%\"", KubernetesJson.Serialize(intorstr));
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,12 @@ namespace k8s.Tests
|
||||
public void Deserialize()
|
||||
{
|
||||
{
|
||||
var v = KubernetesJson.Deserialize<IntstrIntOrString>("1234");
|
||||
var v = KubernetesJson.Deserialize<IntOrString>("1234");
|
||||
Assert.Equal("1234", v.Value);
|
||||
}
|
||||
|
||||
{
|
||||
var v = KubernetesJson.Deserialize<IntstrIntOrString>("\"12%\"");
|
||||
var v = KubernetesJson.Deserialize<IntOrString>("\"12%\"");
|
||||
Assert.Equal("12%", v.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ metadata:
|
||||
}
|
||||
|
||||
#pragma warning disable CA1812 // Class is used for YAML deserialization tests
|
||||
private class MyPod : V1Pod
|
||||
private record MyPod : V1Pod
|
||||
{
|
||||
}
|
||||
#pragma warning restore CA1812
|
||||
@@ -531,7 +531,7 @@ spec:
|
||||
var obj = new V1Service
|
||||
{
|
||||
Kind = "Service",
|
||||
Metadata = new V1ObjectMeta(labels: labels, name: "test-svc"),
|
||||
Metadata = new V1ObjectMeta { Name = "test-svc", Labels = labels },
|
||||
ApiVersion = "v1",
|
||||
Spec = new V1ServiceSpec
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user