Add a loadAll to load multiple objects from a single YAML. (and tests) (#344)

This commit is contained in:
Brendan Burns
2020-01-10 13:59:37 -08:00
committed by Kubernetes Prow Robot
parent 3a30033090
commit 67be97e74b
4 changed files with 140 additions and 1 deletions

26
examples/yaml/Program.cs Normal file
View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using k8s;
using k8s.Models;
namespace yaml
{
internal class Program
{
private async static Task Main(string[] args)
{
var typeMap = new Dictionary<String, Type>();
typeMap.Add("v1/Pod", typeof(V1Pod));
typeMap.Add("v1/Service", typeof(V1Service));
typeMap.Add("apps/v1beta1/Deployment", typeof(Appsv1beta1Deployment));
var objects = await Yaml.LoadAllFromFileAsync(args[0], typeMap);
foreach (var obj in objects) {
Console.WriteLine(obj);
}
}
}
}

12
examples/yaml/yaml.csproj Normal file
View File

@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\src\KubernetesClient\KubernetesClient.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -18,6 +18,81 @@ namespace k8s
/// </summary>
public class Yaml {
/// <summary>
/// Load a collection of objects from a stream asynchronously
/// </summary>
/// <param name="stream">
/// The stream to load the objects from.
/// </param>
/// <param name="typeMap">
/// A map from <apiVersion>/<kind> to Type. For example "v1/Pod" -> typeof(V1Pod)
/// </param>
public static async Task<List<object>> LoadAllFromStreamAsync(Stream stream, Dictionary<String, Type> typeMap) {
var reader = new StreamReader(stream);
var content = await reader.ReadToEndAsync();
return LoadAllFromString(content, typeMap);
}
/// <summary>
/// Load a collection of objects from a file asynchronously
/// </summary>
/// <param name="fileName">
/// The name of the file to load from.
/// </param>
/// <param name="typeMap">
/// A map from <apiVersion>/<kind> to Type. For example "v1/Pod" -> typeof(V1Pod)
/// </param>
public static Task<List<object>> LoadAllFromFileAsync(String fileName, Dictionary<String, Type> typeMap)
{
var reader = File.Open(fileName, FileMode.Open);
return LoadAllFromStreamAsync(reader, typeMap);
}
/// <summary>
/// Load a collection of objects from a string
/// </summary>
/// <param name="content">
/// The string to load the objects from.
/// </param>
/// <param name="typeMap">
/// A map from <apiVersion>/<kind> to Type. For example "v1/Pod" -> typeof(V1Pod)
/// </param>
public static List<object> LoadAllFromString(String content, Dictionary<String, Type> typeMap) {
var deserializer =
new DeserializerBuilder()
.WithNamingConvention(new CamelCaseNamingConvention())
.WithTypeInspector(ti => new AutoRestTypeInspector(ti))
.WithTypeConverter(new IntOrStringYamlConverter())
.IgnoreUnmatchedProperties()
.Build();
var types = new List<Type>();
var parser = new Parser(new StringReader(content));
parser.Expect<StreamStart>();
while (parser.Accept<DocumentStart>()) {
var obj = deserializer.Deserialize<KubernetesObject>(parser);
types.Add(typeMap[obj.ApiVersion + "/" + obj.Kind]);
}
deserializer =
new DeserializerBuilder()
.WithNamingConvention(new CamelCaseNamingConvention())
.WithTypeInspector(ti => new AutoRestTypeInspector(ti))
.WithTypeConverter(new IntOrStringYamlConverter())
.Build();
parser = new Parser(new StringReader(content));
parser.Expect<StreamStart>();
var ix = 0;
var results = new List<object>();
while (parser.Accept<DocumentStart>()) {
var objType = types[ix++];
var obj = deserializer.Deserialize(parser, objType);
results.Add(obj);
}
return results;
}
public static async Task<T> LoadFromStreamAsync<T>(Stream stream) {
var reader = new StreamReader(stream);
var content = await reader.ReadToEndAsync();

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using k8s;
using k8s.Models;
using Xunit;
@@ -9,6 +10,31 @@ namespace k8s.Tests
{
public class YamlTests
{
[Fact]
public void LoadAllFromString()
{
var content = @"apiVersion: v1
kind: Pod
metadata:
name: foo
---
apiVersion: v1
kind: Namespace
metadata:
name: ns";
var types = new Dictionary<String, Type>();
types.Add("v1/Pod", typeof(V1Pod));
types.Add("v1/Namespace", typeof(V1Namespace));
var objs = Yaml.LoadAllFromString(content, types);
Assert.Equal(objs.Count, 2);
Assert.IsType<V1Pod>(objs[0]);
Assert.IsType<V1Namespace>(objs[1]);
Assert.Equal(((V1Pod) objs[0]).Metadata.Name, "foo");
Assert.Equal(((V1Namespace) objs[1]).Metadata.Name, "ns");
}
[Fact]
public void LoadFromString()
{
@@ -292,7 +318,7 @@ spec:
};
var output = Yaml.SaveToString<V1Service>(obj);
Assert.True(ToLines(output).SequenceEqual(ToLines(content)));
Assert.True(ToLines(output).SequenceEqual(ToLines(content)));
}
}
}