use of io.strimzi.api.annotations.ApiVersion in project strimzi-kafka-operator by strimzi.
the class StructuralCrdIT method assertApiVersionsAreStructuralInApiextensionsV1.
private void assertApiVersionsAreStructuralInApiextensionsV1(String api, VersionRange<ApiVersion> shouldBeStructural) {
Pattern pattern = Pattern.compile("[^.]spec\\.versions\\[([0-9]+)\\]\\.[^,]*?");
CustomResourceDefinition crd = cluster.client().getClient().apiextensions().v1().customResourceDefinitions().withName(api).get();
// We can't make the following assertion because the current version of fabric8 always requests
// the CRD using v1beta1 api version, so the apiserver just replaces it and serves it.
// assertEquals(crdApiVersion, ApiVersion.parse(crd.getApiVersion().replace("apiextensions.k8s.io/", "")));
Set<ApiVersion> presentCrdApiVersions = crd.getSpec().getVersions().stream().map(v -> ApiVersion.parse(v.getName())).collect(Collectors.toSet());
assertTrue(presentCrdApiVersions.contains(shouldBeStructural.lower()), "CRD has versions " + presentCrdApiVersions + " which doesn't include " + shouldBeStructural.lower() + " which should be structural");
Map<Integer, ApiVersion> indexedVersions = new HashMap<>();
int i = 0;
for (CustomResourceDefinitionVersion version : crd.getSpec().getVersions()) {
indexedVersions.put(i, ApiVersion.parse(version.getName()));
}
Optional<CustomResourceDefinitionCondition> first = crd.getStatus().getConditions().stream().filter(cond -> "NonStructuralSchema".equals(cond.getType()) && "True".equals(cond.getStatus())).findFirst();
if (first.isPresent()) {
Matcher matcher = pattern.matcher(first.get().getMessage());
while (matcher.find()) {
Integer index = Integer.valueOf(matcher.group(1));
ApiVersion nonStructuralVersion = indexedVersions.get(index);
if (shouldBeStructural.contains(nonStructuralVersion)) {
fail(api + "/ " + nonStructuralVersion + " should be structural but there's a complaint about " + matcher.group());
}
}
}
}
use of io.strimzi.api.annotations.ApiVersion in project strimzi-kafka-operator by strimzi.
the class CrdGenerator method buildAdditionalPrinterColumns.
private ArrayNode buildAdditionalPrinterColumns(Crd.Spec crd, ApiVersion crApiVersion) {
ArrayNode cols = nf.arrayNode();
if (crd.additionalPrinterColumns().length != 0) {
for (Crd.Spec.AdditionalPrinterColumn col : Arrays.stream(crd.additionalPrinterColumns()).filter(col -> crApiVersion == null || ApiVersion.parseRange(col.apiVersion()).contains(crApiVersion)).collect(Collectors.toList())) {
ObjectNode colNode = cols.addObject();
colNode.put("name", col.name());
colNode.put("description", col.description());
colNode.put(crdApiVersion.compareTo(V1) >= 0 ? "jsonPath" : "JSONPath", col.jsonPath());
colNode.put("type", col.type());
if (col.priority() != 0) {
colNode.put("priority", col.priority());
}
if (!col.format().isEmpty()) {
colNode.put("format", col.format());
}
}
}
return cols;
}
use of io.strimzi.api.annotations.ApiVersion in project strimzi-kafka-operator by strimzi.
the class CrdGenerator method buildSpec.
@SuppressWarnings("NPathComplexity")
private ObjectNode buildSpec(ApiVersion crdApiVersion, Crd.Spec crd, Class<? extends CustomResource> crdClass) {
checkKubeVersionsSupportCrdVersion(crdApiVersion);
ObjectNode result = nf.objectNode();
result.put("group", crd.group());
ArrayNode versions = nf.arrayNode();
// Kube apiserver with CRD v1beta1 is picky about only using per-version subresources, schemas and printercolumns
// if they actually differ across the versions. If they're the same, it insists these things are
// declared top level
// With CRD v1 they have to be per-version :face-with-rolling-eyes:
Map<ApiVersion, ObjectNode> subresources = buildSubresources(crd);
boolean perVersionSubResources = needsPerVersion("subresources", subresources);
Map<ApiVersion, ObjectNode> schemas = buildSchemas(crd, crdClass);
boolean perVersionSchemas = needsPerVersion("schemas", schemas);
Map<ApiVersion, ArrayNode> printerColumns = buildPrinterColumns(crd);
boolean perVersionPrinterColumns = needsPerVersion("additionalPrinterColumns", printerColumns);
result.set("names", buildNames(crd.names()));
result.put("scope", crd.scope());
if (!perVersionPrinterColumns) {
ArrayNode cols = printerColumns.values().iterator().next();
if (!cols.isEmpty()) {
result.set("additionalPrinterColumns", cols);
}
}
if (!perVersionSubResources) {
ObjectNode subresource = subresources.values().iterator().next();
if (!subresource.isEmpty()) {
result.set("subresources", subresource);
}
}
if (conversionStrategy instanceof WebhookConversionStrategy) {
// "Webhook": must be None if spec.preserveUnknownFields is true
result.put("preserveUnknownFields", false);
}
result.set("conversion", buildConversion(crdApiVersion));
for (Crd.Spec.Version version : crd.versions()) {
ApiVersion crApiVersion = ApiVersion.parse(version.name());
if (!shouldIncludeVersion(crApiVersion)) {
continue;
}
ObjectNode versionNode = versions.addObject();
versionNode.put("name", crApiVersion.toString());
versionNode.put("served", servedVersion != null ? servedVersion.contains(crApiVersion) : version.served());
versionNode.put("storage", storageVersion != null ? crApiVersion.equals(storageVersion) : version.storage());
if (perVersionSubResources) {
ObjectNode subresourcesForVersion = subresources.get(crApiVersion);
if (!subresourcesForVersion.isEmpty()) {
versionNode.set("subresources", subresourcesForVersion);
}
}
if (perVersionPrinterColumns) {
ArrayNode cols = printerColumns.get(crApiVersion);
if (!cols.isEmpty()) {
versionNode.set("additionalPrinterColumns", cols);
}
}
if (perVersionSchemas) {
versionNode.set("schema", schemas.get(crApiVersion));
}
}
result.set("versions", versions);
if (crdApiVersion.compareTo(V1) < 0 && targetKubeVersions.intersects(KubeVersion.parseRange("1.11-1.15"))) {
result.put("version", Arrays.stream(crd.versions()).map(v -> ApiVersion.parse(v.name())).filter(this::shouldIncludeVersion).findFirst().map(ApiVersion::toString).orElseThrow());
}
if (!perVersionSchemas) {
result.set("validation", schemas.values().iterator().next());
}
return result;
}
use of io.strimzi.api.annotations.ApiVersion in project strimzi-kafka-operator by strimzi.
the class CrdGenerator method buildStatus.
private ObjectNode buildStatus(Crd.Spec crd, ApiVersion crApiVersion) {
ObjectNode status;
long length = Arrays.stream(crd.subresources().status()).filter(st -> ApiVersion.parseRange(st.apiVersion()).contains(crApiVersion)).count();
if (length == 1) {
status = nf.objectNode();
} else if (length > 1) {
err("Each custom resource definition can have only one status sub-resource.");
status = null;
} else {
status = null;
}
return status;
}
use of io.strimzi.api.annotations.ApiVersion in project strimzi-kafka-operator by strimzi.
the class DocGenerator method main.
public static void main(String[] args) throws IOException, ClassNotFoundException {
Linker linker = null;
File out = null;
List<Class<? extends CustomResource>> classes = new ArrayList<>();
outer: for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.startsWith("-")) {
if ("--linker".equals(arg)) {
String className = args[++i];
Class<? extends Linker> linkerClass = classInherits(Class.forName(className), Linker.class);
if (linkerClass != null) {
try {
linker = linkerClass.getConstructor(String.class).newInstance(args[++i]);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("--linker option can't be handled", e);
}
} else {
System.err.println(className + " is not a subclass of " + Linker.class.getName());
}
} else {
throw new RuntimeException("Unsupported option " + arg);
}
} else {
if (out == null) {
out = new File(arg);
} else {
String className = arg;
Class<? extends CustomResource> cls = classInherits(Class.forName(className), CustomResource.class);
if (cls != null) {
classes.add(cls);
} else {
System.err.println(className + " is not a subclass of " + CustomResource.class.getName());
}
}
}
}
ApiVersion crApiVersion = ApiVersion.V1BETA2;
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(out), StandardCharsets.UTF_8)) {
writer.append("// This file is auto-generated by ").append(DocGenerator.class.getName()).append(".").append(NL);
writer.append("// To change this documentation you need to edit the Java sources.").append(NL);
writer.append(NL);
DocGenerator dg = new DocGenerator(crApiVersion, 3, classes, writer, linker);
for (Class<? extends CustomResource> c : classes) {
dg.generate(c);
}
if (dg.numErrors > 0) {
System.err.println("There were " + dg.numErrors + " errors");
System.exit(1);
}
}
}
Aggregations