Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal static class EntityToCrdExtensions
private const string Float = "float";
private const string Double = "double";
private const string DateTime = "date-time";
private const string Map = "map[{0}]{1}";

private static readonly string[] IgnoredToplevelProperties = { "metadata", "apiversion", "kind" };

Expand Down Expand Up @@ -238,9 +239,26 @@ private static V1JSONSchemaProps MapType(
additionalColumns,
jsonPath);
}
else if (!isSimpleType
&& type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
{
var genericTypes = type.GenericTypeArguments;
var keyType = MapType(genericTypes[0], additionalColumns, jsonPath).Type;
var valueType = MapType(genericTypes[1], additionalColumns, jsonPath).Type;
props.Type = string.Format(Map, keyType, valueType);
}
else if (!isSimpleType
&& type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)
&& type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.Single().IsGenericType
&& type.GenericTypeArguments.Single().GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
{
var genericTypes = type.GenericTypeArguments.Single().GenericTypeArguments;
var keyType = MapType(genericTypes[0], additionalColumns, jsonPath).Type;
var valueType = MapType(genericTypes[1], additionalColumns, jsonPath).Type;
props.Type = string.Format(Map, keyType, valueType);
}
else if (!isSimpleType &&
(typeof(IDictionary).IsAssignableFrom(type) ||
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) ||
(type.IsGenericType &&
type.GetGenericArguments().FirstOrDefault()?.IsGenericType == true &&
type.GetGenericArguments().FirstOrDefault()?.GetGenericTypeDefinition() ==
Expand Down
12 changes: 7 additions & 5 deletions tests/KubeOps.Test/Operator/Entities/CrdGeneration.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public void Should_Not_Add_Status_SubResource_If_Absent()
[InlineData("Bool", "boolean", null)]
[InlineData("DateTime", "string", "date-time")]
[InlineData("Enum", "string", null)]
[InlineData(nameof(TestSpecEntitySpec.GenericDictionary), "map[string]string", null)]
[InlineData(nameof(TestSpecEntitySpec.KeyValueEnumerable), "map[string]string", null)]
public void Should_Set_The_Correct_Type_And_Format_For_Types(string fieldName, string typeName, string? format)
{
var crd = _testSpecEntity.CreateCrd();
Expand Down Expand Up @@ -272,21 +274,21 @@ public void Should_Set_Preserve_Unknown_Fields_On_Dictionaries()
}

[Fact]
public void Should_Set_Preserve_Unknown_Fields_On_Generic_Dictionaries()
public void Should_Not_Set_Preserve_Unknown_Fields_On_Generic_Dictionaries()
{
var crd = _testSpecEntity.CreateCrd();

var specProperties = crd.Spec.Versions.First().Schema.OpenAPIV3Schema.Properties["spec"];
specProperties.Properties["genericDictionary"].XKubernetesPreserveUnknownFields.Should().BeTrue();
specProperties.Properties["genericDictionary"].XKubernetesPreserveUnknownFields.Should().BeNull();
}

[Fact]
public void Should_Set_Preserve_Unknown_Fields_On_KeyValuePair_Enumerable()
public void Should_Not_Set_Preserve_Unknown_Fields_On_KeyValuePair_Enumerable()
{
var crd = _testSpecEntity.CreateCrd();

var specProperties = crd.Spec.Versions.First().Schema.OpenAPIV3Schema.Properties["spec"];
specProperties.Properties["keyValueEnumerable"].XKubernetesPreserveUnknownFields.Should().BeTrue();
specProperties.Properties["keyValueEnumerable"].XKubernetesPreserveUnknownFields.Should().BeNull();
}

[Fact]
Expand Down
6 changes: 6 additions & 0 deletions tests/KubeOps.Test/TestEntities/TestSpecEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,15 @@ public class TestSpecEntitySpec
public IDictionary Dictionary { get; set; } = new Dictionary<string, string>();

public IDictionary<string, string> GenericDictionary { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string> NormalGenericDictionary { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string>? NullableGenericDictionary { get; set; } = new Dictionary<string, string>();

public IEnumerable<KeyValuePair<string, string>> KeyValueEnumerable { get; set; } =
new Dictionary<string, string>();
public IEnumerable<KeyValuePair<string, string>> NormalKeyValueEnumerable { get; set; } =
new Dictionary<string, string>();
public IEnumerable<KeyValuePair<string, string>>? NullableKeyValueEnumerable { get; set; } =
new Dictionary<string, string>();

[PreserveUnknownFields]
public object PreserveUnknownFields { get; set; } = new object();
Expand Down