From a84ef120fd93ddbedd4fec9fa70fff9ecd6b6e0c Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Fri, 21 Aug 2020 20:46:17 +0530 Subject: [PATCH] Fix #2418: CertificateSigningRequest doesn't implement Namespaced + Add new resources in Cluster scope block in kubernetes model generator + Fix previous tests which were wrongly asserting Cluster Scoped resources as Namespaced resources + Add dsl entrypoint client.certificateSigningRequests() for dealing with CertificateSigningRequests --- CHANGELOG.md | 1 + doc/CHEATSHEET.md | 19 +++++ .../client/DefaultKubernetesClient.java | 9 +++ .../kubernetes/client/KubernetesClient.java | 10 +++ .../client/osgi/ManagedKubernetesClient.java | 8 ++ .../kubernetes/client/internal/UtilsTest.java | 14 ++-- .../main/resources/schema/kube-schema.json | 12 +-- .../resources/schema/validation-schema.json | 39 +++++----- .../main/resources/schema/kube-schema.json | 3 +- .../resources/schema/validation-schema.json | 3 +- .../main/resources/schema/kube-schema.json | 6 +- .../resources/schema/validation-schema.json | 6 +- .../pkg/schemagen/generate.go | 7 ++ .../mock/CertificateSigningRequestTest.java | 75 +++++++++++++++++++ .../src/test/resources/test-csr.yml | 26 +++++++ .../client/DefaultOpenShiftClient.java | 8 ++ .../client/osgi/ManagedOpenShiftClient.java | 8 ++ 17 files changed, 206 insertions(+), 48 deletions(-) create mode 100644 kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CertificateSigningRequestTest.java create mode 100644 kubernetes-tests/src/test/resources/test-csr.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index b9e50004a1..e245940aab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Fix #2354: Fix NullPointerException in ResourceCompare when no resource is returned from fromServer.get() * Fix #2389: KubernetesServer does not use value from https in crud mode * Fix #2306: Make KubernetesServer CRUD mode work with informers +* Fix #2418: CertificateSigningRequest doesn't implement Namespaced #### Improvements * Fix #2331: Fixed documentation for namespaced informer for all custom types implementing `Namespaced` interface diff --git a/doc/CHEATSHEET.md b/doc/CHEATSHEET.md index 43f98ef15d..a7be2a18b0 100644 --- a/doc/CHEATSHEET.md +++ b/doc/CHEATSHEET.md @@ -30,6 +30,7 @@ This document contains common usages of different resources using Fabric8 Kubern * [CustomResourceDefinition](#customresourcedefinition) * [CustomResource Typed API](#customresource-typed-api) * [CustomResource Typeless API](#customresource-typeless-api) + * [CertificateSigningRequest](#certificatesigningrequest) * [SharedInformers](#sharedinformers) * [List Options](#list-options) * [Delete Options](#delete-options) @@ -1904,6 +1905,24 @@ Map result = client.customResource(customResourceDefinitionConte closeLatch.await(10, TimeUnit.MINUTES); ``` +### CertificateSigningRequest +Kubernetes Client provides using `CertificateSigningRequest` via the `client.certificateSigningRequests()` DSL interface. Here is an example of creating `CertificateSigningRequest` using Fabric8 Kubernetes Client: +``` +try (KubernetesClient client = new DefaultKubernetesClient()) { + CertificateSigningRequest csr = new CertificateSigningRequestBuilder() + .withNewMetadata().withName("test-k8s-csr").endMetadata() + .withNewSpec() + .addNewGroup("system:authenticated") + .withRequest("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJRWJqQ0NBbFlDQVFBd0tURVBNQTBHQTFVRUF3d0dhMmxrYjI1bk1SWXdGQVlEVlFRS0RBMWtZWFJoTFdWdQpaMmx1WldWeU1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBc2dVZXl0S0F6ZDkyClN1S2pZL1RqbmRsZ0lkSFVVYWFxbHJIVW1nbTloKzY2RTJCNGs0TSt6Q0tOQmovemlMdWV6NFNUeHJ6SFk3RlUKNGUxWElBU3lMS0dmRGNPaks5NThURThwcXBRM21VdlpWMmxnK25BTVF5dlZUYWdZSmFId2JWUzVlNHgvRmpKcQoxTWpQZ1VoSGFXeEdIYTQrQnZYQU9Kdk5BdnV4alpZaVJET251dGxHVzloQkRKRlhoUk5jOGFKNnFiZWVBWnNiCmozWUFMaUcydWp1VmhoTUVRNEJxdFVHVGZCMzBQNGhRK2t2bWVKc2ZUU3Vsb2xiWFdIdVZGWnh1d0FJek5RbmQKMTd4VHd2cU04OGZFb3ZJazBJV0ZCWTk2aHRvaUVNdThZUms4SEZ6QkJralhsZGlkbVNNSHkwK0plcFRONmdQTQpEYVVsd1cxS0lCcW9TbnZNcjY4cFRVWEVhZVRjc040anMxTUIwK3FwR0JBS1puWWVxM0JmMkxVVFBNaG1VZ2VVCmFUTFlqODI2WVorZjJrOWJ1cngwK1NOSmVZbWoxVTl0N3A2YWM0dDIzZHVYQ1BzYkNrUFNKeGtrU3dudUlVVzkKdmJVVGtJNGtVMlFVMnE0NzRaMW1uMlkvejF2TEdQdEpsTDFYUVFVNEdsb2hrQkVkM1BsUTRtOGU1WGZSRkV6ZgpYZnhMRXFRczFTeEg1ekhjcnVaOWxJdnBkeEw5Tkc5WlR6M0tmT0tIbCtSUzdxMGdKaExac0RubUJKNXZab3p4CldXci9IRW9PamFYbGh0VitDN3M4TUg5Y0lKZENZNnpjcFVrZis1NmZ0Z1FuN0YrT1RYdDI0UVJQYWNFZnRFOTkKVERPb2luTGtOMm1kckxiMTgxQUZNUWJ0bTFLc1k2MENBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQwpBUUNQYU1WdDd4YWhkZlF1L1BySFVTTW5LK2I0SlJScEdEYlpWUXk4aUtkSmdHM0VrYnNBZ21qQmN4Q1IvL2t1CkVhU0plSGNWK20xVlFUTEp1ZFU3ZHFUeFBLOVFCNlB2aHlBbCttNnFaQkt1Q25VM1BKc2k5azBYSE5GWXBqRmYKVFNwTlpJSnRuanVEQWVtT05kcjJYMm1rODZmSmpWTEUvYnA1KzM5dFBkN0xjL3dZR2JoRU0xcExtUGpQK0Z6eQpzZnBiYW5PcmZFSG5NMmlsRFpGZURVSEpYL3F5Ykt1RC9BRmdoZk1Ua0x3ODNLNkNRdCtDQm05djRCeEtCS2xqCkdBWEQyUEhUTWlzektUbGpBM3czYUphanZzU0FwQXFCWnFocjB3QzdOb1dYM1h6S0p3ck9MaWVxemo3SXlpUGEKTEI5SmJveFpOQTdBSU5ucEdsa1hDZlRGT2RManZtQkVRQXV5Ym9wLzdqV2RiSzJHRkZKS2UwdlVlbWNUeGdHVwp5c0ZyV2pqMUlvdVBVNFZ6ck82QVBVQnZCZUFtdU1Bbm9yVng5emc4akhlT1pkd2RWdFRnOUwrK0VnWjlxK0htCjVtUlJGVHlZOWo4WVVvd2J6TzRlRUZnaVN0di84T1p0YmtOeDFROWFQWHJ3VUV1Q1I0SUthWG0wNlJUYXJOYXUKTWFsbk5oZm9WYi9Bc1R5d1ArNlc1dGErcTBpckR5cnVkZk5pRkFWbkRMZEU5a2hWZzVrU0lPRzhYbEZUMklwSQpkdVNpcUl0NlNUTlY3UmdaRzBGTFN5akxoc3laWnY2bitpUzl3Ky9OOFpoUzgvalViUUVidG1VTnNJU3Z5WS9JCmZqcHNZQUdleExvVW5mN2pDaUhkbTVhSnJ5SU1kdmZ2akJsMDhIVk5nWG1McVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K") + .addNewUsage("client auth") + .endSpec() + .build(); + + client.certificateSigningRequests().create(csr); +} +``` + + ### SharedInformers Kubernetes Client also provides `SharedInformer` support in order to stay updated to events happening to your resource inside Kubernetes. It's implementation is just list and watch operations after a certain interval of time. Here are some of the common usages: - Get `SharedInformerFactory`: 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 e508a49964..ae5ad858a0 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 @@ -73,6 +73,9 @@ import io.fabric8.kubernetes.api.model.ServiceAccount; import io.fabric8.kubernetes.api.model.ServiceAccountList; import io.fabric8.kubernetes.api.model.DoneableServiceAccount; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequestList; +import io.fabric8.kubernetes.api.model.certificates.DoneableCertificateSigningRequest; import io.fabric8.kubernetes.api.model.coordination.v1.DoneableLease; import io.fabric8.kubernetes.api.model.coordination.v1.Lease; import io.fabric8.kubernetes.api.model.coordination.v1.LeaseList; @@ -83,6 +86,7 @@ import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationContext; import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.KubernetesListOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.certificates.v1beta1.CertificateSigningRequestOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.APIServiceOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.ComponentStatusOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.NamespaceOperationsImpl; @@ -293,6 +297,11 @@ public ApiextensionsAPIGroupDSL apiextensions() { return adapt(ApiextensionsAPIGroupClient.class); } + @Override + public NonNamespaceOperation> certificateSigningRequests() { + return new CertificateSigningRequestOperationsImpl(httpClient, getConfiguration()); + } + @Override public , D extends Doneable> MixedOperation> customResources(CustomResourceDefinitionContext crdContext, Class resourceType, Class listClass, Class doneClass) { return new CustomResourceOperationsImpl<>(new CustomResourceOperationContext().withOkhttpClient(httpClient).withConfig(getConfiguration()) diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java index 773220ab17..c1f89d0c7e 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java @@ -69,6 +69,9 @@ import io.fabric8.kubernetes.api.model.ServiceAccount; import io.fabric8.kubernetes.api.model.ServiceAccountList; import io.fabric8.kubernetes.api.model.DoneableServiceAccount; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequestList; +import io.fabric8.kubernetes.api.model.certificates.DoneableCertificateSigningRequest; import io.fabric8.kubernetes.api.model.coordination.v1.DoneableLease; import io.fabric8.kubernetes.api.model.coordination.v1.Lease; import io.fabric8.kubernetes.api.model.coordination.v1.LeaseList; @@ -106,6 +109,13 @@ public interface KubernetesClient extends Client { */ ApiextensionsAPIGroupDSL apiextensions(); + /** + * API entrypoint for using CertificateSigningRequest(certificates.k8s.io/v1beta1) + * + * @return {@link NonNamespaceOperation} for CertificateSigningRequest class + */ + NonNamespaceOperation> certificateSigningRequests(); + /** * Typed API for managing CustomResources. You would need to provide POJOs for * CustomResource into this and with it you would be able to instantiate a client diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java index 853e83ac37..fcc8d251c3 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java @@ -72,6 +72,9 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinitionList; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.DoneableCustomResourceDefinition; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequestList; +import io.fabric8.kubernetes.api.model.certificates.DoneableCertificateSigningRequest; import io.fabric8.kubernetes.api.model.coordination.v1.DoneableLease; import io.fabric8.kubernetes.api.model.coordination.v1.Lease; import io.fabric8.kubernetes.api.model.coordination.v1.LeaseList; @@ -431,6 +434,11 @@ public ApiextensionsAPIGroupDSL apiextensions() { return delegate.apiextensions(); } + @Override + public NonNamespaceOperation> certificateSigningRequests() { + return delegate.certificateSigningRequests(); + } + @Override public , D extends Doneable> MixedOperation> customResources(CustomResourceDefinitionContext crdContext, Class resourceType, Class listClass, Class doneClass) { return delegate.customResources(crdContext, resourceType, listClass, doneClass); diff --git a/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/internal/UtilsTest.java b/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/internal/UtilsTest.java index f5a3d963f7..509a6efccc 100644 --- a/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/internal/UtilsTest.java +++ b/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/internal/UtilsTest.java @@ -254,15 +254,15 @@ void testWhetherNamespacedOrNot() { assertTrue(Utils.isResourceNamespaced(Deployment.class)); assertTrue(Utils.isResourceNamespaced(ReplicaSet.class)); assertTrue(Utils.isResourceNamespaced(StatefulSet.class)); - assertTrue(Utils.isResourceNamespaced(TokenReview.class)); + assertFalse(Utils.isResourceNamespaced(TokenReview.class)); assertTrue(Utils.isResourceNamespaced(LocalSubjectAccessReview.class)); - assertTrue(Utils.isResourceNamespaced(SelfSubjectAccessReview.class)); - assertTrue(Utils.isResourceNamespaced(SelfSubjectRulesReview.class)); - assertTrue(Utils.isResourceNamespaced(SubjectAccessReview.class)); + assertFalse(Utils.isResourceNamespaced(SelfSubjectAccessReview.class)); + assertFalse(Utils.isResourceNamespaced(SelfSubjectRulesReview.class)); + assertFalse(Utils.isResourceNamespaced(SubjectAccessReview.class)); assertTrue(Utils.isResourceNamespaced(HorizontalPodAutoscaler.class)); assertTrue(Utils.isResourceNamespaced(CronJob.class)); assertTrue(Utils.isResourceNamespaced(Job.class)); - assertTrue(Utils.isResourceNamespaced(CertificateSigningRequest.class)); + assertFalse(Utils.isResourceNamespaced(CertificateSigningRequest.class)); assertTrue(Utils.isResourceNamespaced(Lease.class)); assertTrue(Utils.isResourceNamespaced(EndpointSlice.class)); assertTrue(Utils.isResourceNamespaced(Ingress.class)); @@ -274,8 +274,8 @@ void testWhetherNamespacedOrNot() { assertTrue(Utils.isResourceNamespaced(RoleBinding.class)); assertTrue(Utils.isResourceNamespaced(Role.class)); assertFalse(Utils.isResourceNamespaced(PriorityClass.class)); - assertTrue(Utils.isResourceNamespaced(CSIDriver.class)); - assertTrue(Utils.isResourceNamespaced(CSINode.class)); + assertFalse(Utils.isResourceNamespaced(CSIDriver.class)); + assertFalse(Utils.isResourceNamespaced(CSINode.class)); assertFalse(Utils.isResourceNamespaced(StorageClass.class)); assertTrue(Utils.isResourceNamespaced(VolumeAttachment.class)); } diff --git a/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/kube-schema.json b/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/kube-schema.json index d4d68295df..f98841fda7 100644 --- a/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/kube-schema.json +++ b/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/kube-schema.json @@ -1984,8 +1984,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authentication.TokenReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authentication_TokenReviewSpec": { @@ -2285,8 +2284,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authorization.SelfSubjectAccessReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authorization_SelfSubjectAccessReviewSpec": { @@ -2340,8 +2338,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authorization.SelfSubjectRulesReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authorization_SelfSubjectRulesReviewSpec": { @@ -2391,8 +2388,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authorization.SubjectAccessReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authorization_SubjectAccessReviewSpec": { diff --git a/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/validation-schema.json b/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/validation-schema.json index 9e168bed7d..43cb519c2c 100644 --- a/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/validation-schema.json +++ b/kubernetes-model-generator/kubernetes-model-admissionregistration/src/main/resources/schema/validation-schema.json @@ -1984,8 +1984,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authentication.TokenReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authentication_TokenReviewSpec": { @@ -2285,8 +2284,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authorization.SelfSubjectAccessReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authorization_SelfSubjectAccessReviewSpec": { @@ -2340,8 +2338,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authorization.SelfSubjectRulesReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authorization_SelfSubjectRulesReviewSpec": { @@ -2391,8 +2388,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.authorization.SubjectAccessReview", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_authorization_SubjectAccessReviewSpec": { @@ -3323,7 +3319,7 @@ "apiVersion": { "type": "string", "description": "", - "default": "admissionregistration.k8s.io/v1", + "default": "admissionregistration.k8s.io/v1beta1", "required": true }, "kind": { @@ -3341,8 +3337,8 @@ "description": "", "javaOmitEmpty": true, "items": { - "$ref": "#/definitions/kubernetes_admissionregistration_v1_MutatingWebhook", - "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1.MutatingWebhook" + "$ref": "#/definitions/kubernetes_admissionregistration_v1beta1_MutatingWebhook", + "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1beta1.MutatingWebhook" } } }, @@ -3353,15 +3349,15 @@ "apiVersion": { "type": "string", "description": "", - "default": "admissionregistration.k8s.io/v1", + "default": "admissionregistration.k8s.io/v1beta1", "required": true }, "items": { "type": "array", "description": "", "items": { - "$ref": "#/definitions/kubernetes_admissionregistration_v1_MutatingWebhookConfiguration", - "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1.MutatingWebhookConfiguration" + "$ref": "#/definitions/kubernetes_admissionregistration_v1beta1_MutatingWebhookConfiguration", + "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1beta1.MutatingWebhookConfiguration" } }, "kind": { @@ -4261,14 +4257,15 @@ "admissionReviewVersions": { "type": "array", "description": "", + "javaOmitEmpty": true, "items": { "type": "string", "description": "" } }, "clientConfig": { - "$ref": "#/definitions/kubernetes_admissionregistration_v1_WebhookClientConfig", - "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1.WebhookClientConfig" + "$ref": "#/definitions/kubernetes_admissionregistration_v1beta1_WebhookClientConfig", + "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1beta1.WebhookClientConfig" }, "failurePolicy": { "type": "string", @@ -4295,8 +4292,8 @@ "description": "", "javaOmitEmpty": true, "items": { - "$ref": "#/definitions/kubernetes_admissionregistration_v1_RuleWithOperations", - "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1.RuleWithOperations" + "$ref": "#/definitions/kubernetes_admissionregistration_v1beta1_RuleWithOperations", + "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1beta1.RuleWithOperations" } }, "sideEffects": { @@ -4315,7 +4312,7 @@ "apiVersion": { "type": "string", "description": "", - "default": "admissionregistration.k8s.io/v1beta1", + "default": "admissionregistration.k8s.io/v1", "required": true }, "kind": { @@ -4333,8 +4330,8 @@ "description": "", "javaOmitEmpty": true, "items": { - "$ref": "#/definitions/kubernetes_admissionregistration_v1beta1_ValidatingWebhook", - "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1beta1.ValidatingWebhook" + "$ref": "#/definitions/kubernetes_admissionregistration_v1_ValidatingWebhook", + "javaType": "io.fabric8.kubernetes.api.model.admissionregistration.v1.ValidatingWebhook" } } }, diff --git a/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/kube-schema.json b/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/kube-schema.json index 57428b00af..cdddf70344 100644 --- a/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/kube-schema.json +++ b/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/kube-schema.json @@ -915,8 +915,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_certificates_CertificateSigningRequestCondition": { diff --git a/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/validation-schema.json b/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/validation-schema.json index 8ca8d0681f..5439f383f0 100644 --- a/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/validation-schema.json +++ b/kubernetes-model-generator/kubernetes-model-certificates/src/main/resources/schema/validation-schema.json @@ -915,8 +915,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_certificates_CertificateSigningRequestCondition": { diff --git a/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/kube-schema.json b/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/kube-schema.json index 545413dbc8..34bbcd05de 100644 --- a/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/kube-schema.json +++ b/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/kube-schema.json @@ -2330,8 +2330,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.storage.v1beta1.CSIDriver", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_storageclass_v1beta1_CSIDriverList": { @@ -2426,8 +2425,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.storage.v1beta1.CSINode", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_storageclass_v1beta1_CSINodeDriver": { diff --git a/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/validation-schema.json b/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/validation-schema.json index a057b12a79..f70e5d4ad9 100644 --- a/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/validation-schema.json +++ b/kubernetes-model-generator/kubernetes-model-storageclass/src/main/resources/schema/validation-schema.json @@ -2330,8 +2330,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.storage.v1beta1.CSIDriver", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_storageclass_v1beta1_CSIDriverList": { @@ -2426,8 +2425,7 @@ "additionalProperties": true, "javaType": "io.fabric8.kubernetes.api.model.storage.v1beta1.CSINode", "javaInterfaces": [ - "io.fabric8.kubernetes.api.model.HasMetadata", - "io.fabric8.kubernetes.api.model.Namespaced" + "io.fabric8.kubernetes.api.model.HasMetadata" ] }, "kubernetes_storageclass_v1beta1_CSINodeDriver": { diff --git a/kubernetes-model-generator/pkg/schemagen/generate.go b/kubernetes-model-generator/pkg/schemagen/generate.go index 4c045c7573..509481628e 100644 --- a/kubernetes-model-generator/pkg/schemagen/generate.go +++ b/kubernetes-model-generator/pkg/schemagen/generate.go @@ -574,6 +574,13 @@ func (g *schemaGenerator) crdScope(t reflect.Type) CrdScope { "ClusterRole", "PriorityClass", "StorageClass", + "TokenReview", + "SelfSubjectAccessReview", + "SelfSubjectRulesReview", + "SubjectAccessReview", + "CertificateSigningRequest", + "CSIDriver", + "CSINode", "APIService": return Cluster default: diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CertificateSigningRequestTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CertificateSigningRequestTest.java new file mode 100644 index 0000000000..6f5db2be40 --- /dev/null +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CertificateSigningRequestTest.java @@ -0,0 +1,75 @@ +/** + * 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.kubernetes.client.mock; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequestBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import org.junit.Rule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport; + +import java.net.HttpURLConnection; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@EnableRuleMigrationSupport +class CertificateSigningRequestTest { + @Rule + public KubernetesServer server = new KubernetesServer(); + + @Test + void testLoad() { + // Given + KubernetesClient client = server.getClient(); + + // When + List resources = client.load(getClass().getResourceAsStream("/test-csr.yml")).get(); + + // Then + assertEquals(1, resources.size()); + assertTrue(resources.get(0) instanceof CertificateSigningRequest); + } + + @Test + void testCreate() { + // Given + CertificateSigningRequest csr = new CertificateSigningRequestBuilder() + .withNewMetadata().withName("test-k8s-csr").endMetadata() + .withNewSpec() + .addNewGroup("system:authenticated") + .withRequest("RSBSRVFVRVNULS0tLS0KTUlJRWJqQ0NBbFlDQVFBd0tURVBNQTBHQTFVRUF3d0dhMmxrYjI1bk1SWXdGQVlEVlFRS0RBMWtZWFJoTFdWdQpaMmx1WldWeU1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBc2dVZXl0S0F6ZDkyClN1S2pZL1RqbmRsZ0lkSFVVYWFxbHJIVW1nbTloKzY2RTJCNGs0TSt6Q0tOQmovemlMdWV6NFNUeHJ6SFk3RlUKNGUxWElBU3lMS0dmRGNPaks5NThURThwcXBRM21VdlpWMmxnK25BTVF5dlZUYWdZSmFId2JWUzVlNHgvRmpKcQoxTWpQZ1VoSGFXeEdIYTQrQnZYQU9Kdk5BdnV4alpZaVJET251dGxHVzloQkRKRlhoUk5jOGFKNnFiZWVBWnNiCmozWUFMaUcydWp1VmhoTUVRNEJxdFVHVGZCMzBQNGhRK2t2bWVKc2ZUU3Vsb2xiWFdIdVZGWnh1d0FJek5RbmQKMTd4VHd2cU04OGZFb3ZJazBJV0ZCWTk2aHRvaUVNdThZUms4SEZ6QkJralhsZGlkbVNNSHkwK0plcFRONmdQTQpEYVVsd1cxS0lCcW9TbnZNcjY4cFRVWEVhZVRjc040anMxTUIwK3FwR0JBS1puWWVxM0JmMkxVVFBNaG1VZ2VVCmFUTFlqODI2WVorZjJrOWJ1cngwK1NOSmVZbWoxVTl0N3A2YWM0dDIzZHVYQ1BzYkNrUFNKeGtrU3dudUlVVzkKdmJVVGtJNGtVMlFVMnE0NzRaMW1uMlkvejF2TEdQdEpsTDFYUVFVNEdsb2hrQkVkM1BsUTRtOGU1WGZSRkV6ZgpYZnhMRXFRczFTeEg1ekhjcnVaOWxJdnBkeEw5Tkc5WlR6M0tmT0tIbCtSUzdxMGdKaExac0RubUJKNXZab3p4CldXci9IRW9PamFYbGh0VitDN3M4TUg5Y0lKZENZNnpjcFVrZis1NmZ0Z1FuN0YrT1RYdDI0UVJQYWNFZnRFOTkKVERPb2luTGtOMm1kckxiMTgxQUZNUWJ0bTFLc1k2MENBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQwpBUUNQYU1WdDd4YWhkZlF1L1BySFVTTW5LK2I0SlJScEdEYlpWUXk4aUtkSmdHM0VrYnNBZ21qQmN4Q1IvL2t1CkVhU0plSGNWK20xVlFUTEp1ZFU3ZHFUeFBLOVFCNlB2aHlBbCttNnFaQkt1Q25VM1BKc2k5azBYSE5GWXBqRmYKVFNwTlpJSnRuanVEQWVtT05kcjJYMm1rODZmSmpWTEUvYnA1KzM5dFBkN0xjL3dZR2JoRU0xcExtUGpQK0Z6eQpzZnBiYW5PcmZFSG5NMmlsRFpGZURVSEpYL3F5Ykt1RC9BRmdoZk1Ua0x3ODNLNkNRdCtDQm05djRCeEtCS2xqCkdBWEQyUEhUTWlzektUbGpBM3czYUphanZzU0FwQXFCWnFocjB3QzdOb1dYM1h6S0p3ck9MaWVxemo3SXlpUGEKTEI5SmJveFpOQTdBSU5ucEdsa1hDZlRGT2RManZtQkVRQXV5Ym9wLzdqV2RiSzJHRkZKS2UwdlVlbWNUeGdHVwp5c0ZyV2pqMUlvdVBVNFZ6ck82QVBVQnZCZUFtdU1Bbm9yVng5emc4akhlT1pkd2RWdFRnOUwrK0VnWjlxK0htCjVtUlJGVHlZOWo4WVVvd2J6TzRlRUZnaVN0di84T1p0YmtOeDFROWFQWHJ3VUV1Q1I0SUthWG0wNlJUYXJOYXUKTWFsbk5oZm9WYi9Bc1R5d1ArNlc1dGErcTBpckR5cnVkZk5pRkFWbkRMZEU5a2hWZzVrU0lPRzhYbEZUMklwSQpkdVNpcUl0NlNUTlY3UmdaRzBGTFN5akxoc3laWnY2bitpUzl3Ky9OOFpoUzgvalViUUVidG1VTnNJU3Z5WS9JCmZqcHNZQUdleExvVW5mN2pDaUhkbTVhSnJ5SU1kdmZ2akJsMDhIVk5nWG1McVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K") + .addNewUsage("client auth") + .endSpec() + .build(); + server.expect().post().withPath("/apis/certificates.k8s.io/v1beta1/certificatesigningrequests") + .andReturn(HttpURLConnection.HTTP_OK, csr) + .once(); + KubernetesClient client = server.getClient(); + + // When + csr = client.certificateSigningRequests().create(csr); + + // Then + assertNotNull(csr); + assertEquals("test-k8s-csr", csr.getMetadata().getName()); + } +} diff --git a/kubernetes-tests/src/test/resources/test-csr.yml b/kubernetes-tests/src/test/resources/test-csr.yml new file mode 100644 index 0000000000..82c82e0e1d --- /dev/null +++ b/kubernetes-tests/src/test/resources/test-csr.yml @@ -0,0 +1,26 @@ +# +# 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. +# + +apiVersion: certificates.k8s.io/v1beta1 +kind: CertificateSigningRequest +metadata: + name: test-k8s-csr +spec: + groups: + - system:authenticated + request: RSBSRVFVRVNULS0tLS0KTUlJRWJqQ0NBbFlDQVFBd0tURVBNQTBHQTFVRUF3d0dhMmxrYjI1bk1SWXdGQVlEVlFRS0RBMWtZWFJoTFdWdQpaMmx1WldWeU1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBc2dVZXl0S0F6ZDkyClN1S2pZL1RqbmRsZ0lkSFVVYWFxbHJIVW1nbTloKzY2RTJCNGs0TSt6Q0tOQmovemlMdWV6NFNUeHJ6SFk3RlUKNGUxWElBU3lMS0dmRGNPaks5NThURThwcXBRM21VdlpWMmxnK25BTVF5dlZUYWdZSmFId2JWUzVlNHgvRmpKcQoxTWpQZ1VoSGFXeEdIYTQrQnZYQU9Kdk5BdnV4alpZaVJET251dGxHVzloQkRKRlhoUk5jOGFKNnFiZWVBWnNiCmozWUFMaUcydWp1VmhoTUVRNEJxdFVHVGZCMzBQNGhRK2t2bWVKc2ZUU3Vsb2xiWFdIdVZGWnh1d0FJek5RbmQKMTd4VHd2cU04OGZFb3ZJazBJV0ZCWTk2aHRvaUVNdThZUms4SEZ6QkJralhsZGlkbVNNSHkwK0plcFRONmdQTQpEYVVsd1cxS0lCcW9TbnZNcjY4cFRVWEVhZVRjc040anMxTUIwK3FwR0JBS1puWWVxM0JmMkxVVFBNaG1VZ2VVCmFUTFlqODI2WVorZjJrOWJ1cngwK1NOSmVZbWoxVTl0N3A2YWM0dDIzZHVYQ1BzYkNrUFNKeGtrU3dudUlVVzkKdmJVVGtJNGtVMlFVMnE0NzRaMW1uMlkvejF2TEdQdEpsTDFYUVFVNEdsb2hrQkVkM1BsUTRtOGU1WGZSRkV6ZgpYZnhMRXFRczFTeEg1ekhjcnVaOWxJdnBkeEw5Tkc5WlR6M0tmT0tIbCtSUzdxMGdKaExac0RubUJKNXZab3p4CldXci9IRW9PamFYbGh0VitDN3M4TUg5Y0lKZENZNnpjcFVrZis1NmZ0Z1FuN0YrT1RYdDI0UVJQYWNFZnRFOTkKVERPb2luTGtOMm1kckxiMTgxQUZNUWJ0bTFLc1k2MENBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQwpBUUNQYU1WdDd4YWhkZlF1L1BySFVTTW5LK2I0SlJScEdEYlpWUXk4aUtkSmdHM0VrYnNBZ21qQmN4Q1IvL2t1CkVhU0plSGNWK20xVlFUTEp1ZFU3ZHFUeFBLOVFCNlB2aHlBbCttNnFaQkt1Q25VM1BKc2k5azBYSE5GWXBqRmYKVFNwTlpJSnRuanVEQWVtT05kcjJYMm1rODZmSmpWTEUvYnA1KzM5dFBkN0xjL3dZR2JoRU0xcExtUGpQK0Z6eQpzZnBiYW5PcmZFSG5NMmlsRFpGZURVSEpYL3F5Ykt1RC9BRmdoZk1Ua0x3ODNLNkNRdCtDQm05djRCeEtCS2xqCkdBWEQyUEhUTWlzektUbGpBM3czYUphanZzU0FwQXFCWnFocjB3QzdOb1dYM1h6S0p3ck9MaWVxemo3SXlpUGEKTEI5SmJveFpOQTdBSU5ucEdsa1hDZlRGT2RManZtQkVRQXV5Ym9wLzdqV2RiSzJHRkZKS2UwdlVlbWNUeGdHVwp5c0ZyV2pqMUlvdVBVNFZ6ck82QVBVQnZCZUFtdU1Bbm9yVng5emc4akhlT1pkd2RWdFRnOUwrK0VnWjlxK0htCjVtUlJGVHlZOWo4WVVvd2J6TzRlRUZnaVN0di84T1p0YmtOeDFROWFQWHJ3VUV1Q1I0SUthWG0wNlJUYXJOYXUKTWFsbk5oZm9WYi9Bc1R5d1ArNlc1dGErcTBpckR5cnVkZk5pRkFWbkRMZEU5a2hWZzVrU0lPRzhYbEZUMklwSQpkdVNpcUl0NlNUTlY3UmdaRzBGTFN5akxoc3laWnY2bitpUzl3Ky9OOFpoUzgvalViUUVidG1VTnNJU3Z5WS9JCmZqcHNZQUdleExvVW5mN2pDaUhkbTVhSnJ5SU1kdmZ2akJsMDhIVk5nWG1McVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K + usages: + - client auth diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java b/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java index 1940e113d9..465c660a54 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java @@ -37,6 +37,9 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinitionList; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.DoneableCustomResourceDefinition; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequestList; +import io.fabric8.kubernetes.api.model.certificates.DoneableCertificateSigningRequest; import io.fabric8.kubernetes.api.model.coordination.v1.DoneableLease; import io.fabric8.kubernetes.api.model.coordination.v1.Lease; import io.fabric8.kubernetes.api.model.coordination.v1.LeaseList; @@ -381,6 +384,11 @@ public ApiextensionsAPIGroupDSL apiextensions() { return delegate.apiextensions(); } + @Override + public NonNamespaceOperation> certificateSigningRequests() { + return delegate.certificateSigningRequests(); + } + public RawCustomResourceOperationsImpl customResource(CustomResourceDefinitionContext customResourceDefinition) { return new RawCustomResourceOperationsImpl(httpClient, getConfiguration(), customResourceDefinition); } diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java b/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java index 94bccd1978..ce7d63026e 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java @@ -26,6 +26,9 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinitionList; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.DoneableCustomResourceDefinition; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequest; +import io.fabric8.kubernetes.api.model.certificates.CertificateSigningRequestList; +import io.fabric8.kubernetes.api.model.certificates.DoneableCertificateSigningRequest; import io.fabric8.kubernetes.api.model.coordination.v1.DoneableLease; import io.fabric8.kubernetes.api.model.coordination.v1.Lease; import io.fabric8.kubernetes.api.model.coordination.v1.LeaseList; @@ -432,6 +435,11 @@ public ApiextensionsAPIGroupDSL apiextensions() { return delegate.apiextensions(); } + @Override + public NonNamespaceOperation> certificateSigningRequests() { + return delegate.certificateSigningRequests(); + } + @Override public RawCustomResourceOperationsImpl customResource(CustomResourceDefinitionContext customResourceDefinition) { return delegate.customResource(customResourceDefinition);