diff --git a/src/KubernetesClient/IntstrIntOrString.cs b/src/KubernetesClient/IntstrIntOrString.cs index 13d54ee..ec7509d 100644 --- a/src/KubernetesClient/IntstrIntOrString.cs +++ b/src/KubernetesClient/IntstrIntOrString.cs @@ -1,8 +1,43 @@ using System; using Newtonsoft.Json; +using YamlDotNet.Core; +using YamlDotNet.Core.Events; +using YamlDotNet.Core.Tokens; +using YamlDotNet.Serialization; namespace k8s.Models { + public class IntOrStringYamlConverter: IYamlTypeConverter + { + public bool Accepts(Type type) + { + return type == typeof(IntstrIntOrString); + } + + public object ReadYaml(IParser parser, Type type) + { + if (parser.Current is YamlDotNet.Core.Events.Scalar scalar) + { + try { + if (string.IsNullOrEmpty(scalar.Value)) + { + return null; + } + return new IntstrIntOrString(scalar.Value); + } finally { + parser.MoveNext(); + } + } + throw new InvalidOperationException(parser.Current?.ToString()); + } + + public void WriteYaml(IEmitter emitter, object value, Type type) + { + var obj = (IntstrIntOrString) value; + emitter.Emit(new YamlDotNet.Core.Events.Scalar(obj.Value)); + } + } + internal class IntOrStringConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) diff --git a/src/KubernetesClient/Yaml.cs b/src/KubernetesClient/Yaml.cs index e3bf0d9..1ca09d0 100644 --- a/src/KubernetesClient/Yaml.cs +++ b/src/KubernetesClient/Yaml.cs @@ -9,6 +9,7 @@ using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; +using k8s.Models; namespace k8s { @@ -34,6 +35,7 @@ namespace k8s new DeserializerBuilder() .WithNamingConvention(new CamelCaseNamingConvention()) .WithTypeInspector(ti => new AutoRestTypeInspector(ti)) + .WithTypeConverter(new IntOrStringYamlConverter()) .Build(); var obj = deserializer.Deserialize(content); return obj; @@ -47,8 +49,10 @@ namespace k8s var serializer = new SerializerBuilder() + .DisableAliases() .WithNamingConvention(new CamelCaseNamingConvention()) .WithTypeInspector(ti => new AutoRestTypeInspector(ti)) + .WithTypeConverter(new IntOrStringYamlConverter()) .BuildValueSerializer(); emitter.Emit(new StreamStart()); emitter.Emit(new DocumentStart()); diff --git a/tests/KubernetesClient.Tests/YamlTests.cs b/tests/KubernetesClient.Tests/YamlTests.cs index e6a5cf1..1a1cb89 100644 --- a/tests/KubernetesClient.Tests/YamlTests.cs +++ b/tests/KubernetesClient.Tests/YamlTests.cs @@ -7,7 +7,8 @@ using Xunit; namespace k8s.Tests { - public class YamlTests { + public class YamlTests + { [Fact] public void LoadFromString() { @@ -184,7 +185,7 @@ spec: { using (var reader = new StringReader(s)) { - for (;;) + for (; ; ) { var line = reader.ReadLine(); if (line == null) @@ -236,5 +237,62 @@ spec: Assert.Equal("cpu", cpuRequest.Key); Assert.Equal("500m", cpuRequest.Value.ToString()); } + + [Fact] + public void LoadIntOrString() + { + var content = @"apiVersion: v1 +kind: Service +spec: + ports: + - port: 3000 + targetPort: 3000 +"; + + var obj = Yaml.LoadFromString(content); + + Assert.Equal(3000, obj.Spec.Ports[0].Port); + Assert.Equal(3000, (int)obj.Spec.Ports[0].TargetPort); + } + + [Fact] + public void SerializeIntOrString() + { + var content = @"apiVersion: v1 +kind: Service +metadata: + labels: + app: test + name: test-svc +spec: + ports: + - port: 3000 + targetPort: 3000"; + + Dictionary labels = new Dictionary + { + {"app", "test"} + }; + var obj = new V1Service + { + Kind = "Service", + Metadata = new V1ObjectMeta(labels: labels, name: "test-svc"), + ApiVersion = "v1", + Spec = new V1ServiceSpec + { + Ports = new List + { + new V1ServicePort + { + Port = 3000, + TargetPort = 3000 + } + } + } + }; + + var output = Yaml.SaveToString(obj); + Assert.Equal(output, content); + } } }