Skip to content

Commit 201e14e

Browse files
rgramaRazvan Gramabuehler
authored
fix: x-kubernetes-preserve-unknown-fields incorrectly applied on List<T> (#850)
### Describe the bug PreserveUnknownFieldsAttribute can currently only be applied to properties. If within my CRD I have a List<T> and I set the attribute, it will render in the CRD at the items level, not within the object itself. ### To reproduce ```csharp [KubernetesEntity(Group = "test.io", Kind = "Test", ApiVersion = "v1")] public partial class TestCrd : CustomKubernetesEntity<TestSpec> { } public class TestSpec { [PreserveUnknownFields] public List<Item> Items { get; set; } = default!; } public class Item { public string Name { get; set; } = default!; } ``` Generates ```yaml - name: v1 schema: openAPIV3Schema: properties: spec: properties: items: items: properties: name: type: string type: object type: array x-kubernetes-preserve-unknown-fields: true type: object type: object ``` ### Expected behavior x-kubernetes-preserve-unknown-fields: true should be applied to the object within items ```yaml - name: v1 schema: openAPIV3Schema: properties: spec: properties: items: items: properties: name: type: string type: object x-kubernetes-preserve-unknown-fields: true type: array type: object type: object ``` To achieve this result, the attribute should be allowed on classes ```csharp [KubernetesEntity(Group = "test.io", Kind = "Test", ApiVersion = "v1")] public partial class TestCrd : CustomKubernetesEntity<TestSpec> { } public class TestSpec { public List<Item> Items { get; set; } = default!; } [PreserveUnknownFields] public class Item { public string Name { get; set; } = default!; } ``` --------- Co-authored-by: Razvan Grama <[email protected]> Co-authored-by: Christoph Bühler <[email protected]>
1 parent 8268118 commit 201e14e

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

src/KubeOps.Abstractions/Entities/Attributes/PreserveUnknownFieldsAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
/// Defines that a property should keep unknown fields
55
/// so that kubernetes does not purge additional structures.
66
/// </summary>
7-
[AttributeUsage(AttributeTargets.Property)]
7+
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
88
public class PreserveUnknownFieldsAttribute : Attribute;

src/KubeOps.Transpiler/Crds.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ private static V1JSONSchemaProps MapObjectType(this MetadataLoadContext context,
422422
{ Count: > 0 } p => p,
423423
_ => null,
424424
},
425+
XKubernetesPreserveUnknownFields = type.GetCustomAttributeData<PreserveUnknownFieldsAttribute>() != null ? true : null,
425426
};
426427
}
427428
}

test/KubeOps.Transpiler.Test/Crds.Mlc.Test.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,24 @@ public void Should_Set_Preserve_Unknown_Fields_On_Dictionaries()
341341
specProperties.XKubernetesPreserveUnknownFields.Should().BeTrue();
342342
}
343343

344+
[Fact]
345+
public void Should_Set_Preserve_Unknown_Fields_On_Classes()
346+
{
347+
var crd = _mlc.Transpile(typeof(UnknownFieldsEntity));
348+
349+
var specProperties = crd.Spec.Versions.First().Schema.OpenAPIV3Schema.Properties["spec"];
350+
specProperties.XKubernetesPreserveUnknownFields.Should().BeTrue();
351+
}
352+
353+
[Fact]
354+
public void Should_Set_Preserve_Unknown_Fields_On_ObjectLists()
355+
{
356+
var crd = _mlc.Transpile(typeof(UnknownFieldsListEntity));
357+
358+
var specProperties = (V1JSONSchemaProps)crd.Spec.Versions.First().Schema.OpenAPIV3Schema.Properties["spec"].Properties["propertyList"].Items;
359+
specProperties.XKubernetesPreserveUnknownFields.Should().BeTrue();
360+
}
361+
344362
[Fact]
345363
public void Should_Not_Set_Preserve_Unknown_Fields_On_Generic_Dictionaries()
346364
{
@@ -688,6 +706,25 @@ private class SimpleDictionaryEntity : CustomKubernetesEntity
688706
public IDictionary Property { get; set; } = null!;
689707
}
690708

709+
[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
710+
private class UnknownFieldsEntity : CustomKubernetesEntity<UnknownFieldsEntity.EntitySpec>
711+
{
712+
[PreserveUnknownFields]
713+
public class EntitySpec;
714+
}
715+
716+
[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
717+
private class UnknownFieldsListEntity : CustomKubernetesEntity<UnknownFieldsListEntity.EntitySpec>
718+
{
719+
public class EntitySpec
720+
{
721+
public List<ObjectList> PropertyList { get; set; } = null!;
722+
723+
[PreserveUnknownFields]
724+
public class ObjectList;
725+
}
726+
}
727+
691728
[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
692729
private class DictionaryEntity : CustomKubernetesEntity
693730
{

0 commit comments

Comments
 (0)