Skip to content

Commit 3d294ff

Browse files
author
Christoph Bühler
committed
feat(crd generation): Throw an error on unsupported crd type.
This closes #80.
1 parent fe181d3 commit 3d294ff

File tree

5 files changed

+88
-4
lines changed

5 files changed

+88
-4
lines changed

src/KubeOps/Operator/Entities/Extensions/EntityToCrdExtensions.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using k8s;
77
using k8s.Models;
88
using KubeOps.Operator.Entities.Annotations;
9+
using KubeOps.Operator.Errors;
910
using Namotion.Reflection;
1011

1112
namespace KubeOps.Operator.Entities.Extensions
@@ -55,7 +56,6 @@ internal static V1CustomResourceDefinition CreateCrd(this Type entityType)
5556
var version = new V1CustomResourceDefinitionVersion();
5657
spec.Versions = new[] { version };
5758

58-
// TODO: versions?
5959
version.Name = entityDefinition.Version;
6060
version.Served = true;
6161
version.Storage = true;
@@ -72,7 +72,18 @@ internal static V1CustomResourceDefinition CreateCrd(this Type entityType)
7272

7373
private static V1JSONSchemaProps MapProperty(PropertyInfo info)
7474
{
75-
var props = MapType(info.PropertyType);
75+
V1JSONSchemaProps props;
76+
try
77+
{
78+
props = MapType(info.PropertyType);
79+
}
80+
catch (Exception ex)
81+
{
82+
throw new CrdConversionException(
83+
$@"During conversion of the property ""{info.Name}"" with type ""{info.PropertyType.Name}"", an error occured.",
84+
ex);
85+
}
86+
7687
var contextual = info.ToContextualProperty();
7788

7889
// Check for nullability and nullable types
@@ -186,13 +197,16 @@ private static V1JSONSchemaProps MapType(Type type)
186197
(typeof(IDictionary).IsAssignableFrom(type) ||
187198
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) ||
188199
(type.IsGenericType &&
189-
type.GetGenericArguments().FirstOrDefault()?.IsGenericType == true && type.GetGenericArguments().FirstOrDefault()?.GetGenericTypeDefinition() ==
200+
type.GetGenericArguments().FirstOrDefault()?.IsGenericType == true &&
201+
type.GetGenericArguments().FirstOrDefault()?.GetGenericTypeDefinition() ==
190202
typeof(KeyValuePair<,>))))
191203
{
192204
props.Type = Object;
193205
props.XKubernetesPreserveUnknownFields = true;
194206
}
195-
else if (!IsSimpleType(type) && type.IsGenericType && typeof(IEnumerable<>).IsAssignableFrom(type.GetGenericTypeDefinition()))
207+
else if (!IsSimpleType(type) &&
208+
type.IsGenericType &&
209+
typeof(IEnumerable<>).IsAssignableFrom(type.GetGenericTypeDefinition()))
196210
{
197211
props.Type = Array;
198212
props.Items = MapType(type.GetGenericArguments()[0]);
@@ -248,6 +262,10 @@ private static V1JSONSchemaProps MapType(Type type)
248262
props.Type = String;
249263
props.EnumProperty = new List<object>(Enum.GetNames(Nullable.GetUnderlyingType(type)!));
250264
}
265+
else
266+
{
267+
throw new CrdPropertyTypeException();
268+
}
251269

252270
return props;
253271
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
3+
namespace KubeOps.Operator.Errors
4+
{
5+
internal class CrdConversionException : Exception
6+
{
7+
public CrdConversionException()
8+
{
9+
}
10+
11+
public CrdConversionException(string message)
12+
: base(message)
13+
{
14+
}
15+
16+
public CrdConversionException(string message, Exception innerException)
17+
: base(message, innerException)
18+
{
19+
}
20+
}
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
3+
namespace KubeOps.Operator.Errors
4+
{
5+
internal class CrdPropertyTypeException : Exception
6+
{
7+
public CrdPropertyTypeException()
8+
: this("The given property has an invalid type.")
9+
{
10+
}
11+
12+
public CrdPropertyTypeException(string message)
13+
: base(message)
14+
{
15+
}
16+
17+
public CrdPropertyTypeException(string message, Exception innerException)
18+
: base(message, innerException)
19+
{
20+
}
21+
}
22+
}

tests/KubeOps.Test/Operator/Entities/CrdGeneration.Test.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using k8s.Models;
66
using KubeOps.Operator.Commands.Generators;
77
using KubeOps.Operator.Entities.Extensions;
8+
using KubeOps.Operator.Errors;
89
using KubeOps.Test.TestEntities;
910
using Xunit;
1011

@@ -327,5 +328,12 @@ public void Should_Map_Embedded_Resources()
327328
specProperties.Properties["kubernetesObject"].XKubernetesPreserveUnknownFields.Should().BeTrue();
328329
specProperties.Properties["kubernetesObject"].XKubernetesEmbeddedResource.Should().BeTrue();
329330
}
331+
332+
[Fact]
333+
public void Should_Throw_On_Not_Supported_Type()
334+
{
335+
var ex = Assert.Throws<CrdConversionException>(() => typeof(TestInvalidEntity).CreateCrd());
336+
ex.InnerException.Should().BeOfType<CrdPropertyTypeException>();
337+
}
330338
}
331339
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using k8s.Models;
2+
using KubeOps.Operator.Entities;
3+
using KubeOps.Operator.Entities.Annotations;
4+
5+
namespace KubeOps.Test.TestEntities
6+
{
7+
[IgnoreEntity]
8+
[KubernetesEntity(Group = "kubeops.test.dev", ApiVersion = "V1")]
9+
public class TestInvalidEntity : CustomKubernetesEntity
10+
{
11+
public ulong Unsupported { get; set; }
12+
13+
public ulong? NullableUnsupported { get; set; }
14+
}
15+
}

0 commit comments

Comments
 (0)