Support round-trip CRD (de)serialization (#1034)
* Support round-trip CRD (de)serialization * Add a floating point emitter to fix UT * Unused using * Stylecop * Reduce warnings
This commit is contained in:
32
src/KubernetesClient.Models/FloatEmitter.cs
Normal file
32
src/KubernetesClient.Models/FloatEmitter.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using YamlDotNet.Core;
|
||||||
|
using YamlDotNet.Core.Events;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
using YamlDotNet.Serialization.EventEmitters;
|
||||||
|
|
||||||
|
namespace k8s
|
||||||
|
{
|
||||||
|
internal class FloatEmitter : ChainedEventEmitter
|
||||||
|
{
|
||||||
|
public FloatEmitter(IEventEmitter nextEmitter)
|
||||||
|
: base(nextEmitter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
|
||||||
|
{
|
||||||
|
switch (eventInfo.Source.Value)
|
||||||
|
{
|
||||||
|
// Floating point numbers should always render at least one zero (e.g. 1.0f => '1.0' not '1')
|
||||||
|
case double d:
|
||||||
|
emitter.Emit(new Scalar(d.ToString("0.0######################")));
|
||||||
|
break;
|
||||||
|
case float f:
|
||||||
|
emitter.Emit(new Scalar(f.ToString("0.0######################")));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
base.Emit(eventInfo, emitter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ namespace k8s
|
|||||||
.WithTypeConverter(new IntOrStringYamlConverter())
|
.WithTypeConverter(new IntOrStringYamlConverter())
|
||||||
.WithTypeConverter(new ByteArrayStringYamlConverter())
|
.WithTypeConverter(new ByteArrayStringYamlConverter())
|
||||||
.WithTypeConverter(new ResourceQuantityYamlConverter())
|
.WithTypeConverter(new ResourceQuantityYamlConverter())
|
||||||
|
.WithAttemptingUnquotedStringTypeDeserialization()
|
||||||
.WithOverridesFromJsonPropertyAttributes()
|
.WithOverridesFromJsonPropertyAttributes()
|
||||||
.IgnoreUnmatchedProperties()
|
.IgnoreUnmatchedProperties()
|
||||||
.Build();
|
.Build();
|
||||||
@@ -33,6 +34,7 @@ namespace k8s
|
|||||||
.WithTypeConverter(new ByteArrayStringYamlConverter())
|
.WithTypeConverter(new ByteArrayStringYamlConverter())
|
||||||
.WithTypeConverter(new ResourceQuantityYamlConverter())
|
.WithTypeConverter(new ResourceQuantityYamlConverter())
|
||||||
.WithEventEmitter(e => new StringQuotingEmitter(e))
|
.WithEventEmitter(e => new StringQuotingEmitter(e))
|
||||||
|
.WithEventEmitter(e => new FloatEmitter(e))
|
||||||
.ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull)
|
.ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull)
|
||||||
.WithOverridesFromJsonPropertyAttributes()
|
.WithOverridesFromJsonPropertyAttributes()
|
||||||
.BuildValueSerializer();
|
.BuildValueSerializer();
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ namespace k8s
|
|||||||
{
|
{
|
||||||
cert = new X509Certificate2(cert.Export(X509ContentType.Pkcs12));
|
cert = new X509Certificate2(cert.Export(X509ContentType.Pkcs12));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert;
|
return cert;
|
||||||
|
|||||||
@@ -841,5 +841,56 @@ spec:
|
|||||||
var ver = result.Spec.Versions[0];
|
var ver = result.Spec.Versions[0];
|
||||||
Assert.Equal(true, ver?.Schema?.OpenAPIV3Schema?.XKubernetesIntOrString);
|
Assert.Equal(true, ver?.Schema?.OpenAPIV3Schema?.XKubernetesIntOrString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1812 // Class is used for YAML deserialization tests
|
||||||
|
[KubernetesEntity(Group = KubeGroup, Kind = KubeKind, ApiVersion = KubeApiVersion, PluralName = KubePluralName)]
|
||||||
|
private sealed class V1AlphaFoo : IKubernetesObject<V1ObjectMeta>, ISpec<Dictionary<string, object>>
|
||||||
|
{
|
||||||
|
public const string KubeApiVersion = "v1alpha";
|
||||||
|
public const string KubeKind = "foo";
|
||||||
|
public const string KubeGroup = "foo.bar";
|
||||||
|
public const string KubePluralName = "foos";
|
||||||
|
|
||||||
|
public string ApiVersion { get; set; }
|
||||||
|
public string Kind { get; set; }
|
||||||
|
public V1ObjectMeta Metadata { get; set; }
|
||||||
|
public Dictionary<string, object> Spec { get; set; }
|
||||||
|
|
||||||
|
public V1AlphaFoo()
|
||||||
|
{
|
||||||
|
Metadata = new V1ObjectMeta();
|
||||||
|
Spec = new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma warning restore CA1812 // Class is used for YAML deserialization tests
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LoadAllFromStringWithTypeMapGenericCRD()
|
||||||
|
{
|
||||||
|
var content = @"apiVersion: foo.bar/v1alpha
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: foo
|
||||||
|
namespace: ns
|
||||||
|
spec:
|
||||||
|
bool: false
|
||||||
|
byte: 123
|
||||||
|
float: 12.0
|
||||||
|
";
|
||||||
|
|
||||||
|
var objs = KubernetesYaml.LoadAllFromString(content, new Dictionary<string, Type>
|
||||||
|
{
|
||||||
|
{ $"{V1AlphaFoo.KubeGroup}/{V1AlphaFoo.KubeApiVersion}/Foo", typeof(V1AlphaFoo) },
|
||||||
|
});
|
||||||
|
Assert.Single(objs);
|
||||||
|
var v1AlphaFoo = Assert.IsType<V1AlphaFoo>(objs[0]);
|
||||||
|
Assert.Equal("foo", v1AlphaFoo.Metadata.Name);
|
||||||
|
Assert.Equal("ns", v1AlphaFoo.Metadata.NamespaceProperty);
|
||||||
|
Assert.Equal(3, v1AlphaFoo.Spec.Count);
|
||||||
|
Assert.False(Assert.IsType<bool>(v1AlphaFoo.Spec["bool"]));
|
||||||
|
Assert.Equal(123, Assert.IsType<byte>(v1AlphaFoo.Spec["byte"]));
|
||||||
|
Assert.Equal(12.0, Assert.IsType<float>(v1AlphaFoo.Spec["float"]), 3);
|
||||||
|
Assert.Equal(content.Replace("\r\n", "\n"), KubernetesYaml.SerializeAll(objs).Replace("\r\n", "\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user