Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(crd-generator): Deprecation warning for CRD versions #5787

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class CustomResourceInfo {
private final String[] shortNames;
private final boolean storage;
private final boolean served;
private final boolean deprecated;
private final String deprecationWarning;
private final Scope scope;
private final TypeDef definition;
private final String crClassName;
Expand All @@ -54,7 +56,7 @@ public class CustomResourceInfo {
private final String[] labels;

public CustomResourceInfo(String group, String version, String kind, String singular,
String plural, String[] shortNames, boolean storage, boolean served,
String plural, String[] shortNames, boolean storage, boolean served, boolean deprecated, String deprecationWarning,
Scope scope, TypeDef definition, String crClassName,
String specClassName, String statusClassName, String[] annotations, String[] labels) {
this.group = group;
Expand All @@ -65,6 +67,8 @@ public CustomResourceInfo(String group, String version, String kind, String sing
this.shortNames = shortNames;
this.storage = storage;
this.served = served;
this.deprecated = deprecated;
this.deprecationWarning = deprecationWarning;
this.scope = scope;
this.definition = definition;
this.crClassName = crClassName;
Expand All @@ -84,6 +88,14 @@ public boolean served() {
return served;
}

public boolean deprecated() {
return deprecated;
}

public String deprecationWarning() {
return deprecationWarning;
}

public String key() {
return crdName();
}
Expand Down Expand Up @@ -165,8 +177,9 @@ public static CustomResourceInfo fromClass(Class<? extends CustomResource<?, ?>>
}

return new CustomResourceInfo(instance.getGroup(), instance.getVersion(), instance.getKind(),
instance.getSingular(), instance.getPlural(), shortNames, instance.isStorage(), instance.isServed(), scope,
definition,
instance.getSingular(), instance.getPlural(), shortNames, instance.isStorage(), instance.isServed(),
instance.isDeprecated(), instance.getDeprecationWarning(),
scope, definition,
customResource.getCanonicalName(), specAndStatus.getSpecClassName(),
specAndStatus.getStatusClassName(), toStringArray(instance.getMetadata().getAnnotations()),
toStringArray(instance.getMetadata().getLabels()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.fabric8.crd.generator.v1.decorator.AddStatusSubresourceDecorator;
import io.fabric8.crd.generator.v1.decorator.AddSubresourcesDecorator;
import io.fabric8.crd.generator.v1.decorator.EnsureSingleStorageVersionDecorator;
import io.fabric8.crd.generator.v1.decorator.SetDeprecatedVersionDecorator;
import io.fabric8.crd.generator.v1.decorator.SetServedVersionDecorator;
import io.fabric8.crd.generator.v1.decorator.SetStorageVersionDecorator;
import io.fabric8.crd.generator.v1.decorator.SortPrinterColumnsDecorator;
Expand Down Expand Up @@ -89,6 +90,7 @@ protected void addDecorators(CustomResourceInfo config, TypeDef def, Optional<St

resources.decorate(new SetServedVersionDecorator(name, version, config.served()));
resources.decorate(new SetStorageVersionDecorator(name, version, config.storage()));
resources.decorate(new SetDeprecatedVersionDecorator(name, version, config.deprecated(), config.deprecationWarning()));
resources.decorate(new EnsureSingleStorageVersionDecorator(name));
resources.decorate(new SortPrinterColumnsDecorator(name, version));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.generator.v1.decorator;

import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionVersionFluent;

public class SetDeprecatedVersionDecorator
extends CustomResourceDefinitionVersionDecorator<CustomResourceDefinitionVersionFluent<?>> {

private final boolean deprecated;
private final String deprecationWarning;

public SetDeprecatedVersionDecorator(String name, String version, boolean deprecated, String deprecationWarning) {
super(name, version);
this.deprecated = deprecated;
this.deprecationWarning = deprecationWarning;
}

@Override
public void andThenVisit(CustomResourceDefinitionVersionFluent<?> version) {
if (deprecated) {
version.withDeprecated(true);
version.withDeprecationWarning(deprecationWarning);
}
}

@Override
public String toString() {
return getClass().getName() + " [name:" + getName() + ", version:" + getVersion()
+ ", deprecated:" + deprecated + ", deprecationWarning:" + deprecationWarning + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.fabric8.crd.generator.v1beta1.decorator.AddSubresourcesDecorator;
import io.fabric8.crd.generator.v1beta1.decorator.EnsureSingleStorageVersionDecorator;
import io.fabric8.crd.generator.v1beta1.decorator.PromoteSingleVersionAttributesDecorator;
import io.fabric8.crd.generator.v1beta1.decorator.SetDeprecatedVersionDecorator;
import io.fabric8.crd.generator.v1beta1.decorator.SetServedVersionDecorator;
import io.fabric8.crd.generator.v1beta1.decorator.SetStorageVersionDecorator;
import io.fabric8.crd.generator.v1beta1.decorator.SortPrinterColumnsDecorator;
Expand Down Expand Up @@ -90,6 +91,7 @@ protected void addDecorators(CustomResourceInfo config, TypeDef def,

resources.decorate(new SetServedVersionDecorator(name, version, config.served()));
resources.decorate(new SetStorageVersionDecorator(name, version, config.storage()));
resources.decorate(new SetDeprecatedVersionDecorator(name, version, config.deprecated(), config.deprecationWarning()));
resources.decorate(new EnsureSingleStorageVersionDecorator(name));
resources.decorate(new PromoteSingleVersionAttributesDecorator(name));
resources.decorate(new SortPrinterColumnsDecorator(name, version));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.generator.v1beta1.decorator;

import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinitionVersionFluent;

public class SetDeprecatedVersionDecorator
extends CustomResourceDefinitionVersionDecorator<CustomResourceDefinitionVersionFluent<?>> {

private final boolean deprecated;
private final String deprecationWarning;

public SetDeprecatedVersionDecorator(String name, String version, boolean deprecated, String deprecationWarning) {
super(name, version);
this.deprecated = deprecated;
this.deprecationWarning = deprecationWarning;
}

@Override
public void andThenVisit(CustomResourceDefinitionVersionFluent<?> version) {
if (deprecated) {
version.withDeprecated(true);
version.withDeprecationWarning(deprecationWarning);
}
}

@Override
public String toString() {
return getClass().getName() + " [name:" + getName() + ", version:" + getVersion()
+ ", deprecated:" + deprecated + ", deprecationWarning:" + deprecationWarning + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.example.deprecated.v1;

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("sample.fabric8.io")
@Version(value = "v1", storage = false, deprecated = true)
public class DeprecationExample extends CustomResource<DeprecationExampleSpec, Void> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.example.deprecated.v1;

public class DeprecationExampleSpec {
private String v1;

public String getV1() {
return v1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.example.deprecated.v1beta1;

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("sample.fabric8.io")
@Version(value = "v1beta1", storage = false, deprecated = true, deprecationWarning = "sample.fabric8.io/v1beta1 DeprecationExample is deprecated; Migrate to sample.fabric8.io/v2")
public class DeprecationExample extends CustomResource<DeprecationExampleSpec, Void> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.example.deprecated.v1beta1;

public class DeprecationExampleSpec {
private String v1beta1;

public String getV1() {
return v1beta1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.example.deprecated.v2;

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("sample.fabric8.io")
@Version("v2")
public class DeprecationExample extends CustomResource<DeprecationExampleSpec, Void> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.crd.example.deprecated.v2;

public class DeprecationExampleSpec {
private String v2;

public String getV2() {
return v2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.fabric8.crd.example.complex.Complex;
import io.fabric8.crd.example.cyclic.Cyclic;
import io.fabric8.crd.example.cyclic.CyclicList;
import io.fabric8.crd.example.deprecated.v2.DeprecationExample;
import io.fabric8.crd.example.inherited.BaseSpec;
import io.fabric8.crd.example.inherited.BaseStatus;
import io.fabric8.crd.example.inherited.Child;
Expand Down Expand Up @@ -220,6 +221,53 @@ void shouldProperlyGenerateMultipleVersionsOfCRDs() {
.forEach(c -> assertTrue(dependentClassNames.contains(c), "should contain " + c));
}

@Test
void checkDeprecated() {
CRDGenerator generator = newCRDGenerator();
final String specVersion = "v1";
final CRDGenerationInfo info = generator
.customResourceClasses(
io.fabric8.crd.example.deprecated.v1beta1.DeprecationExample.class,
io.fabric8.crd.example.deprecated.v1.DeprecationExample.class,
DeprecationExample.class)
.forCRDVersions(specVersion)
.withOutput(output)
.detailedGenerate();

assertEquals(1, info.numberOfGeneratedCRDs());
final Map<String, Map<String, CRDInfo>> details = info.getCRDDetailsPerNameAndVersion();
assertEquals(1, details.size());
// check multiple versions for same CR
final String crdName = CustomResource.getCRDName(DeprecationExample.class);
assertTrue(details.containsKey(crdName));
final Map<String, CRDInfo> infos = info.getCRDInfos(crdName);
assertEquals(1, infos.size());
assertTrue(infos.containsKey(specVersion));

final String outputName = CRDGenerator.getOutputName(crdName, specVersion);
CustomResourceDefinition definition = output.definition(outputName);
assertNotNull(definition);
assertEquals("apiextensions.k8s.io/" + specVersion, definition.getApiVersion());

CustomResourceDefinitionSpec spec = definition.getSpec();
final List<CustomResourceDefinitionVersion> versions = spec.getVersions();
assertEquals(3, versions.size());
assertEquals(1, versions.stream().filter(v -> v.getName().equals("v1beta1")).count());
assertEquals(1, versions.stream().filter(v -> v.getName().equals("v1")).count());
assertEquals(1, versions.stream().filter(v -> v.getName().equals("v2")).count());

CustomResourceDefinitionVersion v1Beta1 = versions.stream().filter(v -> v.getName().equals("v1beta1")).findFirst().get();
CustomResourceDefinitionVersion v1 = versions.stream().filter(v -> v.getName().equals("v1")).findFirst().get();
CustomResourceDefinitionVersion v2 = versions.stream().filter(v -> v.getName().equals("v2")).findFirst().get();
assertTrue(v1Beta1.getDeprecated());
assertEquals("sample.fabric8.io/v1beta1 DeprecationExample is deprecated; Migrate to sample.fabric8.io/v2",
v1Beta1.getDeprecationWarning());
assertTrue(v1.getDeprecated());
assertNull(v1.getDeprecationWarning());
assertNull(v2.getDeprecated());
assertNull(v2.getDeprecationWarning());
}

@Test
void notDefiningOutputShouldNotGenerateAnything() {
CRDGenerator generator = newCRDGenerator();
Expand Down