Note
If you encounter any problems with the following "Migration from 4.x to 5.x" instructions, please let us know by creating an issue in our GitHub repository.
We value your feedback and will work to address your issue promptly. Your contribution is essential to improving our documentation, making our migration process smoother for everyone!
To reduce the number of classes generated by the client and the overall size of packages, Doneable interface, implementations, and implementation generator tasks have been removed.
Provided Doneable
implementations (especially for CustomResources) are no longer needed and can be safely removed.
As a result of the Doneable
interface removal,
createNew()
and createOrReplaceWithNew()
methods are no longer available.
Usages of these methods should be refactored to use the create(Resource... item)
or
createOrReplace(Resource... item)
methods instead.
// Deprecated
client.configMaps().inNamespace("default").createNew()
.withNewMetadata().withName("config-map-name").endMetadata()
.addToData("key", "value")
.done();
// Alternative
client.configMaps().inNamespace("default").create(
new ConfigMapBuilder()
.withNewMetadata().withName("config-map-name").endMetadata()
.addToData("key", "value")
.done();
);
// Deprecated
client.configMaps().inNamespace("default").createOrReplaceWithNew()
.withNewMetadata().withName("config-map-name").endMetadata()
.addToData("key", "value")
.done();
// Alternative
client.configMaps().inNamespace("default").createOrReplaceWithNew(
new ConfigMapBuilder()
.withNewMetadata().withName("config-map-name").endMetadata()
.addToData("key", "value")
.done();
);
As a result of the Doneable
interface removal, edit()
method is no longer available.
The lambda "friendly" T edit(UnaryOperator<T> function)
or the visitable approach
T edit(Class<V> visitorType, Visitor<V> visitor)
methods should be used instead.
// Deprecated
client.configMaps().inNamespace("default").withName("config-map-name").edit()
.addToData("key-2", "value-2")
done();
// Alternative
client.configMaps().inNamespace("default").withName("config-map-name").edit(
c -> new ConfigMapBuilder(c).addToData("key-2", "value-2").build()
);
// Alternative with visitable approach
client.configMaps().inNamespace("default").withName("config-map-name").edit(
ObjectMetaBuilder.class,
omb -> omb.addToAnnotations("key", "value")
);
Watcher#onClose(KubernetesClientException cause)
method has been replaced by Watcher#onClose(WatcherException cause)
and a new default Watcher#onClose()
method has been added.
The argument-less onClose method is always invoked upon Watcher completion, regardless if there is an exception
or not. The onClose
with exception argument is only invoked in case an exception occurs during the Watcher life-cycle
(once the watch connection is open and established).
For migration purposes, any onClose implementations resembling the following:
void onClose(KubernetesClientException cause) {
if (cause != null) {
// Do in case of exception
}
// Clean-up operations
}
Should be refactored to:
void onClose(WatcherException cause) {
// Do in case of exception
}
void onClose() {
// Clean-up operations
}
This release should be a drop-in replacement for v4 in terms of breaking changes. However, the new release includes many improvements that simplifies the usage of Custom Resources and Custom Resource Definitions in the client.
Allows to specify which version of the API the annotated class is defined under.
Together with @Group
, this allows to determine the apiVersion
field associated with the annotated resource.
See https://kubernetes.io/docs/reference/using-api/#api-versioning for more details.
Allows to specify which API group the annotated class is defined under.
Together with @Version
, this allows to determine the apiVersion
field associated with the annotated resource.
See https://kubernetes.io/docs/reference/using-api/#api-groups for more details.
Allows to specify which Kind
value should be used to refer to instance of the annotated class.
If not provided, a default value is computed based on the annotated class name.
See HasMetadata#getKind for more details.
Allows to specify the singular name of the resource.
Allows to specify the plural name of the resource to serve.
The custom resources are served under /apis/<group>/<version>/.../<plural>
The CustomResource
abstract class provides a default implementation for the convention fields
spec
and status
. The class is now parameterized and the Types for these fields can be specified through the new
Type parameters in the class.
New v1CRDFromCustomResourceType
and v1beta1CRDFromCustomResourceType
methods have been
introduced on CustomResourceDefinitionContext
to initialize a CustomResourceDefinitionBuilder
with the information provided by a specific CustomResource
implementation.
These methods simplify the creation of CustomResourceDefinition
s by inferring the boiler-plate spec values from
the annotations and other information already provided in the CustomResource
implementation.
We have added some minor improvements in shared informer APIs. Changes are as follows:
-
No List type required in
SharedInformerFactory.sharedIndexInformerFor
andSharedInformerFactory.sharedIndexInformerForCustomResource
methods. Now you don't need to provide any List type for creatinga new SharedIndexInformer. Now the method only accepts Type and resyncPeriod as parameter. Here is an example of 4.x and 5.x versions to give you a clear idea:4.x:
SharedIndexInformer<Pod> podInformer = sharedInformerFactory.sharedIndexInformerFor(Pod.class, PodList.class, resyncPeriod);
5.x:
SharedIndexInformer<Pod> podInformer = factory.sharedIndexInformerFor(Pod.class, resyncPeriod);
-
SharedInformerFactory.sharedIndexInformerForCustomResource
usesCustomResource
as base type rather thanHasMetadata
. Although we're already enforcing this in our CustomResource API for your CustomResource POJOs to extendCustomResource
; we've made this change more explicit in SharedInformer API. -
Utility methods for creating Namespaced Informers. Now you don't have to provide an explicit
OperationContext
for creating a Namespaced Informer. You can simply useinNamespace()
method for configuring namespace inSharedInformerFactory
. Here is an example:4.x:
SharedIndexInformer<Pod> podInformer = sharedInformerFactory.sharedIndexInformerFor( Pod.class, PodList.class, new OperationContext().withNamespace("default"), RESYNC_PERIOD);
5.x:
SharedIndexInformer<Pod> podInformer = factory.inNamespace("default").sharedIndexInformerFor(Pod.class, RESYNC_PERIOD);
-
No need to provide
CustomResourceDefinitionContext
inSharedInformerFactory.sharedIndexInformerForCustomResource
.CustomResourceDefinition
related information is now discovered automatically from CustomResource annotations or opinionated defaults. Here is an example of 4.x and 5.x versions for aCustomResource
calledDummy
, we're trying to create SharedIndexInformers.4.x
Dummy.java
import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.client.CustomResource; public class Dummy extends CustomResource implements Namespaced { private DummySpec spec; @Override public String toString() { return "Dummy{" + "apiVersion='" + getApiVersion() + '\'' + ", metadata=" + getMetadata() + ", spec=" + spec + '}'; } public DummySpec getSpec() { return spec; } public void setSpec(DummySpec spec) { this.spec = spec; } @Override public ObjectMeta getMetadata() { return super.getMetadata(); } }
Create SharedIndexInformer for
Dummy
:CustomResourceDefinitionContext crdContext = new CustomResourceDefinitionContext.Builder() .withVersion("v1") .withScope("Namespaced") .withGroup("demo.fabric8.io") .withPlural("dummies") .build(); SharedIndexInformer<Dummy> dummyInformer = sharedInformerFactory.sharedIndexInformerForCustomResource(crdContext, Dummy.class, DummyList.class, 60 * 1000L);
5.x:
Dummy.java
import io.fabric8.kubernetes.api.model.KubernetesResource; import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.model.annotation.Group; import io.fabric8.kubernetes.model.annotation.Version; @Version(Dummy.VERSION) @Group(Dummy.GROUP) public class Dummy extends CustomResource<DummySpec, KubernetesResource> implements Namespaced { public static final String GROUP = "demo.fabric8.io"; public static final String VERSION = "v1"; }
Create SharedIndexInformer for
Dummy
:SharedIndexInformer<Dummy> dummyInformer = sharedInformerFactory.sharedIndexInformerForCustomResource(Dummy.class, 60 * 1000L);
kube-validation-schema.json
files are no longer included in our model packaged. The equivalent file
is now named validation-schema.json
.
The schema URL has been updated to the latest compatible version
(http://json-schema.org/draft-05/schema#
)