Skip to content

Commit

Permalink
Support oneOf constraint in CRD schemas
Browse files Browse the repository at this point in the history
Signed-off-by: Tom Bentley <[email protected]>
  • Loading branch information
tombentley committed Nov 26, 2019
1 parent cd6bff6 commit f87ae6b
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.strimzi.crdgenerator.annotations.Example;
import io.strimzi.crdgenerator.annotations.Maximum;
import io.strimzi.crdgenerator.annotations.Minimum;
import io.strimzi.crdgenerator.annotations.OneOf;
import io.strimzi.crdgenerator.annotations.Pattern;
import io.strimzi.crdgenerator.annotations.Type;

Expand Down Expand Up @@ -311,12 +312,40 @@ private void buildObjectSchema(ObjectNode result, Class<?> crdClass, boolean pri
}

result.set("properties", buildSchemaProperties(crdClass));
ArrayNode oneOf = buildSchemaOneOf(crdClass);
if (oneOf != null) {
result.set("oneOf", oneOf);
}
ArrayNode required = buildSchemaRequired(crdClass);
if (required.size() > 0) {
result.set("required", required);
}
}

private ArrayNode buildSchemaOneOf(Class<?> crdClass) {
ArrayNode alternatives;
OneOf oneOf = crdClass.getAnnotation(OneOf.class);
if (oneOf != null && oneOf.value().length > 0) {
alternatives = nf.arrayNode();
for (OneOf.Alternative alt : oneOf.value()) {
ObjectNode alternative = alternatives.addObject();
ObjectNode properties = alternative.putObject("properties");
for (OneOf.Alternative.Property prop: alt.value()) {
properties.putObject(prop.value());
}
ArrayNode required = alternative.putArray("required");
for (OneOf.Alternative.Property prop: alt.value()) {
if (prop.required()) {
required.add(prop.value());
}
}
}
} else {
alternatives = null;
}
return alternatives;
}

private void checkClass(Class<?> crdClass) {
if (!crdClass.isAnnotationPresent(JsonInclude.class)) {
err(crdClass + " is missing @JsonInclude");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright Strimzi authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.strimzi.crdgenerator.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface OneOf {
/** @return List of alternatives */
Alternative[] value();

@interface Alternative {

@interface Property {
/** @return The name of a property */
String value();
/** @return Whether this property is required */
boolean required() default true;
}

/** @return Properties in this alternative */
Property[] value();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
import java.util.LinkedHashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class CrdGeneratorTest {
@Test
Expand All @@ -24,7 +23,7 @@ public void simpleTest() throws IOException, URISyntaxException {
StringWriter w = new StringWriter();
crdGenerator.generate(ExampleCrd.class, w);
String s = w.toString();
assertThat(CrdTestUtils.readResource("simpleTest.yaml"), is(s));
assertEquals(CrdTestUtils.readResource("simpleTest.yaml"), s);
}

@Test
Expand All @@ -39,6 +38,6 @@ public void generateHelmMetadataLabels() throws IOException {
StringWriter w = new StringWriter();
crdGenerator.generate(ExampleCrd.class, w);
String s = w.toString();
assertThat(CrdTestUtils.readResource("simpleTestHelmMetadata.yaml"), is(s));
assertEquals(CrdTestUtils.readResource("simpleTestHelmMetadata.yaml"), s);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.strimzi.crdgenerator.annotations.Example;
import io.strimzi.crdgenerator.annotations.KubeLink;
import io.strimzi.crdgenerator.annotations.Minimum;
import io.strimzi.crdgenerator.annotations.OneOf;
import io.strimzi.crdgenerator.annotations.Pattern;

import java.util.List;
Expand Down Expand Up @@ -42,6 +43,7 @@
)
}
))
@OneOf({@OneOf.Alternative(@OneOf.Alternative.Property("either")), @OneOf.Alternative(@OneOf.Alternative.Property("or"))})
public class ExampleCrd<T, U extends Number, V extends U> extends CustomResource {

private String ignored;
Expand Down Expand Up @@ -107,6 +109,9 @@ public class ExampleCrd<T, U extends Number, V extends U> extends CustomResource

public List<? extends List<? extends U>> listOfWildcardTypeVar4;

private String either;
private String or;


@Description("Example of complex type.")
public static class ObjectProperty {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,5 +414,14 @@ spec:
stringProperty:
type: "string"
pattern: ".*"
oneOf:
- properties:
either: {}
required:
- "either"
- properties:
or: {}
required:
- "or"
required:
- "stringProperty"
Original file line number Diff line number Diff line change
Expand Up @@ -420,5 +420,14 @@ spec:
stringProperty:
type: "string"
pattern: ".*"
oneOf:
- properties:
either: {}
required:
- "either"
- properties:
or: {}
required:
- "or"
required:
- "stringProperty"

0 comments on commit f87ae6b

Please sign in to comment.