From e63bbc2c7fe973cdfccacf3accc23f3434caa094 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Thu, 1 Oct 2020 21:01:36 +0530 Subject: [PATCH] Doc: Add documentation about customResource API change related to Namespaced interface We changed `customResource()` typed API to require POJOs to implement `io.fabric8.kubernetes.api.model.Namespaced` for Namespaced resources, but we didn't add any documentation about this breaking change. This PR tries to add documentation regarding this in javadocs and CHANGELOG --- CHANGELOG.md | 12 +- .../client/DefaultKubernetesClient.java | 160 +++++++++++++++++- .../kubernetes/client/KubernetesClient.java | 30 +++- 3 files changed, 196 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58b3d63cbc8..e3a4ba300c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -131,8 +131,16 @@ _**Note**_: Some classes have been moved to other packages: * Add support for Namespaced SharedInformers, fixed probelms with OperationContext argument * Fix #1821: ListOptions now supported when watching a Kubernetes Resource -_**Note**_: Some classes have been renamed: -- `io.fabric8.tekton.pipeline.v1beta1.WorkspacePipelineDeclaration` is now `io.fabric8.tekton.pipeline.v1beta1.PipelineWorkspaceDeclaration` +_**Note**_: +- Some classes have been renamed: + - `io.fabric8.tekton.pipeline.v1beta1.WorkspacePipelineDeclaration` is now `io.fabric8.tekton.pipeline.v1beta1.PipelineWorkspaceDeclaration` +- Breaking changes in `KubernetesClient` `customResource()` typed API: + - We've introduced a major breaking change in customResource(...) typed API. We have introduced a new interface `io.fabric8.kubernetes.api.model.Namespaced` which needs to + be added to your Custom Types using typed API. For example, for a custom resource named `Animals` which is a [Namespaced](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) resource; It should be declared like this: + ``` + public class Animals extends CustomResource implements Namespaced { ... } + ``` + You can also checkout an example in our test suite for this: [PodSet.java](https://github.com/fabric8io/kubernetes-client/blob/master/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/crd/PodSet.java#L22) ### 4.10.1 (2020-05-06) #### Bugs diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java index f323f6fb42d..d905dda4f17 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java @@ -158,100 +158,156 @@ public static DefaultKubernetesClient fromConfig(InputStream is) { return new DefaultKubernetesClient(Serialization.unmarshal(is, Config.class)); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> componentstatuses() { return new ComponentStatusOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable load(InputStream is) { return new NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<>(), is, null, true, DeletionPropagation.BACKGROUND) { }; } + /** + * {@inheritDoc} + */ @Override public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resourceList(KubernetesResourceList item) { return new NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<>(), item, null, DeletionPropagation.BACKGROUND, true) { }; } + /** + * {@inheritDoc} + */ @Override public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resourceList(HasMetadata... items) { return resourceList(new KubernetesListBuilder().withItems(items).build()); } + /** + * {@inheritDoc} + */ @Override public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resourceList(Collection items) { return resourceList(new KubernetesListBuilder().withItems(new ArrayList<>(items)).build()); } + /** + * {@inheritDoc} + */ @Override public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resourceList(String s) { return new NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<>(), s, null, DeletionPropagation.BACKGROUND, true) { }; } - + /** + * {@inheritDoc} + */ @Override public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(HasMetadata item) { return new NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<>(), item, -1, DeletionPropagation.BACKGROUND, true, Waitable.DEFAULT_INITIAL_BACKOFF_MILLIS, Waitable.DEFAULT_BACKOFF_MULTIPLIER); } + /** + * {@inheritDoc} + */ @Override public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(String s) { return new NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<>(), s, -1, DeletionPropagation.BACKGROUND, true, Waitable.DEFAULT_INITIAL_BACKOFF_MILLIS, Waitable.DEFAULT_BACKOFF_MULTIPLIER); } + /** + * {@inheritDoc} + */ @Override public MixedOperation, DoneableBinding, Resource> bindings() { return new BindingOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> endpoints() { return new EndpointsOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> events() { return new EventOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public NonNamespaceOperation> namespaces() { return new NamespaceOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public NonNamespaceOperation> nodes() { return new NodeOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public NonNamespaceOperation> persistentVolumes() { return new PersistentVolumeOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> persistentVolumeClaims() { return new PersistentVolumeClaimOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> pods() { return new PodOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> replicationControllers() { return new ReplicationControllerOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> resourceQuotas() { return new ResourceQuotaOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public SchedulingAPIGroupDSL scheduling() { return adapt(SchedulingAPIGroupClient.class); @@ -262,61 +318,97 @@ public MixedOperation> services() { return new ServiceOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> serviceAccounts() { return new ServiceAccountOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> apiServices() { return new APIServiceOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public KubernetesListMixedOperation lists() { return new KubernetesListOperationsImpl(httpClient, getConfiguration(), getNamespace()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> configMaps() { return new ConfigMapOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public MixedOperation> limitRanges() { return new LimitRangeOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public NonNamespaceOperation> customResourceDefinitions() { return new CustomResourceDefinitionOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public ApiextensionsAPIGroupDSL apiextensions() { return adapt(ApiextensionsAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public NonNamespaceOperation> certificateSigningRequests() { return new CertificateSigningRequestOperationsImpl(httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public AuthorizationAPIGroupDSL authorization() { return adapt(AuthorizationAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public Createable tokenReviews() { return new CreateOnlyResourceOperationsImpl<>(httpClient, getConfiguration(), "authentication.k8s.io", "v1", Utils.getPluralFromKind(TokenReview.class.getSimpleName()), TokenReview.class); } + /** + * {@inheritDoc} + */ @Override public , D extends Doneable> MixedOperation> customResources(CustomResourceDefinitionContext crdContext, Class resourceType, Class listClass, Class doneClass) { return new CustomResourceOperationsImpl<>(new CustomResourceOperationContext().withOkhttpClient(httpClient).withConfig(getConfiguration()) @@ -327,6 +419,9 @@ public , D extends Do .withDoneableType(doneClass)); } + /** + * {@inheritDoc} + */ @Override public , D extends Doneable> MixedOperation> customResources(CustomResourceDefinition crd, Class resourceType, Class listClass, Class doneClass) { return new CustomResourceOperationsImpl<>(new CustomResourceOperationContext().withOkhttpClient(httpClient).withConfig(getConfiguration()) @@ -337,16 +432,25 @@ public , D extends Do .withDoneableType(doneClass)); } + /** + * {@inheritDoc} + */ @Override public RawCustomResourceOperationsImpl customResource(CustomResourceDefinitionContext customResourceDefinition) { return new RawCustomResourceOperationsImpl(httpClient, getConfiguration(), customResourceDefinition); } + /** + * {@inheritDoc} + */ @Override public , D extends Doneable> MixedOperation> customResource(CustomResourceDefinition crd, Class resourceType, Class listClass, Class doneClass) { return customResources(crd, resourceType, listClass, doneClass); } + /** + * {@inheritDoc} + */ @Override public NamespacedKubernetesClient inNamespace(String namespace) { @@ -354,73 +458,124 @@ public NamespacedKubernetesClient inNamespace(String namespace) return new DefaultKubernetesClient(httpClient, updated); } + /** + * {@inheritDoc} + */ @Override public NamespacedKubernetesClient inAnyNamespace() { return inNamespace(null); } + /** + * {@inheritDoc} + */ @Override public FunctionCallable withRequestConfig(RequestConfig requestConfig) { return new WithRequestCallable<>(this, requestConfig); } + /** + * {@inheritDoc} + */ @Override public ExtensionsAPIGroupDSL extensions() { return adapt(ExtensionsAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public VersionInfo getVersion() { return new ClusterOperationsImpl(httpClient, getConfiguration(), ClusterOperationsImpl.KUBERNETES_VERSION_ENDPOINT).fetchVersion(); } + /** + * {@inheritDoc} + */ @Override public V1APIGroupDSL v1() { return adapt(V1APIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public AdmissionRegistrationAPIGroupDSL admissionRegistration() { return adapt(AdmissionRegistrationAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public AppsAPIGroupDSL apps() { return adapt(AppsAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public AutoscalingAPIGroupDSL autoscaling() { return adapt(AutoscalingAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public NetworkAPIGroupDSL network() { return adapt(NetworkAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public StorageAPIGroupDSL storage() { return adapt(StorageAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public BatchAPIGroupDSL batch() { return adapt(BatchAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public MetricAPIGroupDSL top() { return adapt(MetricAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public PolicyAPIGroupDSL policy() { return adapt(PolicyAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public RbacAPIGroupDSL rbac() { return adapt(RbacAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public SettingsAPIGroupDSL settings() { return adapt(SettingsAPIGroupClient.class); } + /** + * {@inheritDoc} + */ @Override public SharedInformerFactory informers() { return new SharedInformerFactory(ForkJoinPool.commonPool(), httpClient, getConfiguration()); } + /** + * {@inheritDoc} + */ @Override public SharedInformerFactory informers(ExecutorService executorService) { return new SharedInformerFactory(executorService, httpClient, getConfiguration()); @@ -442,6 +597,9 @@ public MixedOperation + * Note: your CustomResource POJO (T in this context) must implement + * + * io.fabric8.kubernetes.api.model.Namespaced + * if it is a Namespaced scoped resource. + *

+ * * @param crdContext CustomResourceDefinitionContext describes the core fields used to search for CustomResources * @param resourceType Class for CustomResource * @param listClass Class for list object for CustomResource * @param doneClass Class for Doneable CustomResource object - * @param T type represents CustomResource type + * @param T type represents CustomResource type. If it's Namespaced resource, it must implement + * io.fabric8.kubernetes.api.model.Namespaced * @param L type represents CustomResourceList type * @param D type represents DoneableCustomResource type * @return returns a MixedOperation object with which you can do basic CustomResource operations @@ -140,6 +148,13 @@ public interface KubernetesClient extends Client { * CustomResource into this and with it you would be able to instantiate a client * specific to CustomResource. * + *

+ * Note: your CustomResource POJO (T in this context) must implement + * + * io.fabric8.kubernetes.api.model.Namespaced + * if it is a Namespaced scoped resource. + *

+ * * @deprecated use {@link #customResources(CustomResourceDefinitionContext, Class, Class, Class)}, which takes a {@link CustomResourceDefinitionContext} * instead of a full {@link CustomResourceDefinition}. * @@ -147,7 +162,8 @@ public interface KubernetesClient extends Client { * @param resourceType Class for CustomResource * @param listClass Class for list object for CustomResource * @param doneClass Class for Doneable CustomResource object - * @param T type represents CustomResource type + * @param T type represents CustomResource type. If it's Namespaced resource, it must implement + * io.fabric8.kubernetes.api.model.Namespaced * @param L type represents CustomResourceList type * @param D type represents DoneableCustomResource type * @return returns a MixedOperation object with which you can do basic CustomResource operations @@ -161,11 +177,19 @@ public interface KubernetesClient extends Client { * @deprecated use {@link #customResources(CustomResourceDefinitionContext, Class, Class, Class)}, which takes a {@link CustomResourceDefinitionContext} * instead of a full {@link CustomResourceDefinition}. * + *

+ * Note: your CustomResource POJO (T in this context) must implement + * + * io.fabric8.kubernetes.api.model.Namespaced + * if it is a Namespaced scoped resource. + *

+ * * @param crd Custom Resource Definition * @param resourceType resource type Pojo * @param listClass list class Pojo * @param doneClass Done class Pojo - * @param template argument for resource + * @param template argument for resource. If it's Namespaced resource, it must implement + * io.fabric8.kubernetes.api.model.Namespaced * @param template argument for list * @param template argument for doneable resource * @return Kubernetes client object for manipulating custom resource.