using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using k8s.Models;
namespace k8s
{
///
/// This is a utility class that helps you load objects from YAML files.
///
public static class KubernetesYaml
{
private static readonly IDeserializer Deserializer =
new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithTypeConverter(new IntOrStringYamlConverter())
.WithTypeConverter(new ByteArrayStringYamlConverter())
.WithTypeConverter(new ResourceQuantityYamlConverter())
.WithOverridesFromJsonPropertyAttributes()
.IgnoreUnmatchedProperties()
.Build();
private static readonly IValueSerializer Serializer =
new SerializerBuilder()
.DisableAliases()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithTypeConverter(new IntOrStringYamlConverter())
.WithTypeConverter(new ByteArrayStringYamlConverter())
.WithTypeConverter(new ResourceQuantityYamlConverter())
.WithEventEmitter(e => new StringQuotingEmitter(e))
.ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull)
.WithOverridesFromJsonPropertyAttributes()
.BuildValueSerializer();
private static readonly IDictionary ModelTypeMap = typeof(KubernetesEntityAttribute).Assembly
.GetTypes()
.Where(t => t.GetCustomAttributes(typeof(KubernetesEntityAttribute), true).Any())
.ToDictionary(
t =>
{
var attr = (KubernetesEntityAttribute)t.GetCustomAttribute(
typeof(KubernetesEntityAttribute), true);
var groupPrefix = string.IsNullOrEmpty(attr.Group) ? "" : $"{attr.Group}/";
return $"{groupPrefix}{attr.ApiVersion}/{attr.Kind}";
},
t => t);
private class ByteArrayStringYamlConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
{
return type == typeof(byte[]);
}
public object ReadYaml(IParser parser, Type type)
{
if (parser?.Current is Scalar scalar)
{
try
{
if (string.IsNullOrEmpty(scalar.Value))
{
return null;
}
return Encoding.UTF8.GetBytes(scalar.Value);
}
finally
{
parser.MoveNext();
}
}
throw new InvalidOperationException(parser.Current?.ToString());
}
public void WriteYaml(IEmitter emitter, object value, Type type)
{
var obj = (byte[])value;
emitter?.Emit(new Scalar(Encoding.UTF8.GetString(obj)));
}
}
///
/// Load a collection of objects from a stream asynchronously
///
/// caller is responsible for closing the stream
///
///
/// The stream to load the objects from.
///
///
/// A map from apiVersion/kind to Type. For example "v1/Pod" -> typeof(V1Pod). If null, a default mapping will
/// be used.
///
/// collection of objects
public static async Task> LoadAllFromStreamAsync(Stream stream, IDictionary typeMap = null)
{
var reader = new StreamReader(stream);
var content = await reader.ReadToEndAsync().ConfigureAwait(false);
return LoadAllFromString(content, typeMap);
}
///
/// Load a collection of objects from a file asynchronously
///
/// The name of the file to load from.
///
/// A map from apiVersion/kind to Type. For example "v1/Pod" -> typeof(V1Pod). If null, a default mapping will
/// be used.
///
/// collection of objects
public static async Task> LoadAllFromFileAsync(string fileName, IDictionary typeMap = null)
{
using (var fileStream = File.OpenRead(fileName))
{
return await LoadAllFromStreamAsync(fileStream, typeMap).ConfigureAwait(false);
}
}
///
/// Load a collection of objects from a string
///
///
/// The string to load the objects from.
///
///
/// A map from apiVersion/kind to Type. For example "v1/Pod" -> typeof(V1Pod). If null, a default mapping will
/// be used.
///
/// collection of objects
public static List