From 653f98fb43b19a25e3dd0dc64fcb37cd59f970d0 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Sun, 16 Aug 2020 14:58:10 +0530 Subject: [PATCH] Fix #1978: Add support for creating TokenReview TokenReview also are create only resources like SubjectAccess* operations in which same object is returned in response with status object modified. It's support can be added easily with current support added for SubjectAccessReview. --- .../client/DefaultKubernetesClient.java | 9 +++ .../kubernetes/client/KubernetesClient.java | 9 +++ .../client/SubjectAccessOperations.java | 21 ----- .../client/V1AuthorizationAPIGroupClient.java | 21 ++--- .../client/V1AuthorizationAPIGroupDSL.java | 11 +-- .../V1beta1AuthorizationAPIGroupClient.java | 21 ++--- .../V1beta1AuthorizationAPIGroupDSL.java | 11 +-- ... => CreateOnlyResourceOperationsImpl.java} | 10 +-- ...eateOnlyResourceReviewOperationsImpl.java} | 10 +-- .../client/osgi/ManagedKubernetesClient.java | 8 ++ .../client/mock/TokenReviewTest.java | 79 +++++++++++++++++++ .../client/DefaultOpenShiftClient.java | 11 ++- .../openshift/client/OpenShiftClient.java | 3 +- ...ocalSubjectAccessReviewOperationsImpl.java | 48 +++++++++-- .../OpenshiftSubjectAccessOperations.java | 22 ------ ...hiftSubjectAccessReviewOperationsImpl.java | 41 +++++++++- .../client/osgi/ManagedOpenShiftClient.java | 11 ++- 17 files changed, 249 insertions(+), 97 deletions(-) delete mode 100644 kubernetes-client/src/main/java/io/fabric8/kubernetes/client/SubjectAccessOperations.java rename kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/{SubjectAccessOperationsImpl.java => CreateOnlyResourceOperationsImpl.java} (80%) rename kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/{LocalSubjectAccessReviewOperationsImpl.java => LocalCreateOnlyResourceReviewOperationsImpl.java} (67%) create mode 100644 kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/TokenReviewTest.java delete mode 100644 openshift-client/src/main/java/io/fabric8/openshift/client/OpenshiftSubjectAccessOperations.java 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 f380fa5c64..01b1fcea89 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 @@ -76,12 +76,15 @@ 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.authentication.DoneableTokenReview; +import io.fabric8.kubernetes.api.model.authentication.TokenReview; 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; import io.fabric8.kubernetes.client.dsl.*; import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.dsl.internal.ClusterOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.CreateOnlyResourceOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.apiextensions.v1beta1.CustomResourceDefinitionOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationContext; import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationsImpl; @@ -111,6 +114,7 @@ import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectorBuilder; import io.fabric8.kubernetes.client.utils.Serialization; import io.fabric8.kubernetes.client.informers.SharedInformerFactory; +import io.fabric8.kubernetes.client.utils.Utils; import okhttp3.OkHttpClient; import java.io.InputStream; @@ -306,6 +310,11 @@ public AuthorizationAPIGroupDSL authorization() { return adapt(AuthorizationAPIGroupClient.class); } + @Override + public Createable tokenReviews() { + return new CreateOnlyResourceOperationsImpl<>(httpClient, getConfiguration(), "authentication.k8s.io", "v1", Utils.getPluralFromKind(TokenReview.class.getSimpleName()), TokenReview.class); + } + @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 db629dd248..d8a2e09203 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 @@ -72,6 +72,8 @@ 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.authentication.DoneableTokenReview; +import io.fabric8.kubernetes.api.model.authentication.TokenReview; 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; @@ -463,6 +465,13 @@ public interface KubernetesClient extends Client { */ AuthorizationAPIGroupDSL authorization(); + /** + * API for creating authentication.k8s.io/v1 TokenReviews + * + * @return CreateOnlyResourceOperations instance for creating TokenReview object + */ + Createable tokenReviews(); + /** * Get an instance of Kubernetes Client informer factory. It allows you to construct and * cache informers for API types. With it you can subscribe to all the events related to diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/SubjectAccessOperations.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/SubjectAccessOperations.java deleted file mode 100644 index d91bb91fa2..0000000000 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/SubjectAccessOperations.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 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; - -import io.fabric8.kubernetes.client.dsl.Createable; - -public interface SubjectAccessOperations extends Createable { -} diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupClient.java index 87f37b5fe8..d509f5c60e 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupClient.java @@ -23,8 +23,9 @@ import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview; import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReview; import io.fabric8.kubernetes.api.model.authorization.v1.SubjectAccessReview; -import io.fabric8.kubernetes.client.dsl.internal.LocalSubjectAccessReviewOperationsImpl; -import io.fabric8.kubernetes.client.dsl.internal.SubjectAccessOperationsImpl; +import io.fabric8.kubernetes.client.dsl.Createable; +import io.fabric8.kubernetes.client.dsl.internal.LocalCreateOnlyResourceReviewOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.CreateOnlyResourceOperationsImpl; import io.fabric8.kubernetes.client.utils.Utils; import okhttp3.OkHttpClient; @@ -41,22 +42,22 @@ public V1AuthorizationAPIGroupClient(OkHttpClient httpClient, final Config confi } @Override - public SubjectAccessOperations selfSubjectAccessReview() { - return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectAccessReview.class.getSimpleName()), SelfSubjectAccessReview.class); + public Createable selfSubjectAccessReview() { + return new CreateOnlyResourceOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectAccessReview.class.getSimpleName()), SelfSubjectAccessReview.class); } @Override - public SubjectAccessOperations subjectAccessReview() { - return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SubjectAccessReview.class.getSimpleName()), SubjectAccessReview.class); + public Createable subjectAccessReview() { + return new CreateOnlyResourceOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SubjectAccessReview.class.getSimpleName()), SubjectAccessReview.class); } @Override - public LocalSubjectAccessReviewOperationsImpl localSubjectAccessReview() { - return new LocalSubjectAccessReviewOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.LocalSubjectAccessReview.class.getSimpleName()), LocalSubjectAccessReview.class); + public LocalCreateOnlyResourceReviewOperationsImpl localSubjectAccessReview() { + return new LocalCreateOnlyResourceReviewOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.LocalSubjectAccessReview.class.getSimpleName()), LocalSubjectAccessReview.class); } @Override - public SubjectAccessOperations selfSubjectRulesReview() { - return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectRulesReview.class.getSimpleName()), SelfSubjectRulesReview.class); + public Createable selfSubjectRulesReview() { + return new CreateOnlyResourceOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectRulesReview.class.getSimpleName()), SelfSubjectRulesReview.class); } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupDSL.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupDSL.java index 4956fede38..6d98b3bdf3 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupDSL.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1AuthorizationAPIGroupDSL.java @@ -23,11 +23,12 @@ import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview; import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReview; import io.fabric8.kubernetes.api.model.authorization.v1.SubjectAccessReview; -import io.fabric8.kubernetes.client.dsl.internal.LocalSubjectAccessReviewOperationsImpl; +import io.fabric8.kubernetes.client.dsl.Createable; +import io.fabric8.kubernetes.client.dsl.internal.LocalCreateOnlyResourceReviewOperationsImpl; public interface V1AuthorizationAPIGroupDSL extends Client{ - SubjectAccessOperations selfSubjectAccessReview(); - SubjectAccessOperations subjectAccessReview(); - LocalSubjectAccessReviewOperationsImpl localSubjectAccessReview(); - SubjectAccessOperations selfSubjectRulesReview(); + Createable selfSubjectAccessReview(); + Createable subjectAccessReview(); + LocalCreateOnlyResourceReviewOperationsImpl localSubjectAccessReview(); + Createable selfSubjectRulesReview(); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupClient.java index cf68adf565..5ffbda0440 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupClient.java @@ -23,8 +23,9 @@ import io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectAccessReview; import io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectRulesReview; import io.fabric8.kubernetes.api.model.authorization.v1beta1.SubjectAccessReview; -import io.fabric8.kubernetes.client.dsl.internal.LocalSubjectAccessReviewOperationsImpl; -import io.fabric8.kubernetes.client.dsl.internal.SubjectAccessOperationsImpl; +import io.fabric8.kubernetes.client.dsl.Createable; +import io.fabric8.kubernetes.client.dsl.internal.LocalCreateOnlyResourceReviewOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.CreateOnlyResourceOperationsImpl; import io.fabric8.kubernetes.client.utils.Utils; import okhttp3.OkHttpClient; @@ -42,22 +43,22 @@ public V1beta1AuthorizationAPIGroupClient(OkHttpClient httpClient, final Config } @Override - public SubjectAccessOperations selfSubjectAccessReview() { - return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(SelfSubjectAccessReview.class.getSimpleName()), SelfSubjectAccessReview.class); + public Createable selfSubjectAccessReview() { + return new CreateOnlyResourceOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(SelfSubjectAccessReview.class.getSimpleName()), SelfSubjectAccessReview.class); } @Override - public SubjectAccessOperations subjectAccessReview() { - return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(SubjectAccessReview.class.getSimpleName()), SubjectAccessReview.class); + public Createable subjectAccessReview() { + return new CreateOnlyResourceOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(SubjectAccessReview.class.getSimpleName()), SubjectAccessReview.class); } @Override - public LocalSubjectAccessReviewOperationsImpl localSubjectAccessReview() { - return new LocalSubjectAccessReviewOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(LocalSubjectAccessReview.class.getSimpleName()), LocalSubjectAccessReview.class); + public LocalCreateOnlyResourceReviewOperationsImpl localSubjectAccessReview() { + return new LocalCreateOnlyResourceReviewOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(LocalSubjectAccessReview.class.getSimpleName()), LocalSubjectAccessReview.class); } @Override - public SubjectAccessOperations selfSubjectRulesReview() { - return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(SelfSubjectRulesReview.class.getSimpleName()), SelfSubjectRulesReview.class); + public Createable selfSubjectRulesReview() { + return new CreateOnlyResourceOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(SelfSubjectRulesReview.class.getSimpleName()), SelfSubjectRulesReview.class); } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupDSL.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupDSL.java index 64e901c0f3..a74690b1e8 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupDSL.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/V1beta1AuthorizationAPIGroupDSL.java @@ -23,11 +23,12 @@ import io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectAccessReview; import io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectRulesReview; import io.fabric8.kubernetes.api.model.authorization.v1beta1.SubjectAccessReview; -import io.fabric8.kubernetes.client.dsl.internal.LocalSubjectAccessReviewOperationsImpl; +import io.fabric8.kubernetes.client.dsl.Createable; +import io.fabric8.kubernetes.client.dsl.internal.LocalCreateOnlyResourceReviewOperationsImpl; public interface V1beta1AuthorizationAPIGroupDSL extends Client { - SubjectAccessOperations selfSubjectAccessReview(); - SubjectAccessOperations subjectAccessReview(); - LocalSubjectAccessReviewOperationsImpl localSubjectAccessReview(); - SubjectAccessOperations selfSubjectRulesReview(); + Createable selfSubjectAccessReview(); + Createable subjectAccessReview(); + LocalCreateOnlyResourceReviewOperationsImpl localSubjectAccessReview(); + Createable selfSubjectRulesReview(); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/SubjectAccessOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/CreateOnlyResourceOperationsImpl.java similarity index 80% rename from kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/SubjectAccessOperationsImpl.java rename to kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/CreateOnlyResourceOperationsImpl.java index 49fbcc2b61..c05da895f1 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/SubjectAccessOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/CreateOnlyResourceOperationsImpl.java @@ -17,7 +17,6 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.SubjectAccessOperations; import io.fabric8.kubernetes.client.dsl.base.OperationContext; import io.fabric8.kubernetes.client.dsl.base.OperationSupport; import okhttp3.OkHttpClient; @@ -25,15 +24,14 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; -public class SubjectAccessOperationsImpl extends OperationSupport implements SubjectAccessOperations { - private Class subjectAccessRequestClass; +public class CreateOnlyResourceOperationsImpl extends OperationSupport implements io.fabric8.kubernetes.client.dsl.Createable { + private final Class subjectAccessRequestClass; - public SubjectAccessOperationsImpl(OkHttpClient client, Config config, String apiGroupName, String apiGroupVersion, String plural, Class subjectAccessRequestClass) { + public CreateOnlyResourceOperationsImpl(OkHttpClient client, Config config, String apiGroupName, String apiGroupVersion, String plural, Class subjectAccessRequestClass) { this(new OperationContext().withOkhttpClient(client).withConfig(config), apiGroupName, apiGroupVersion, plural, subjectAccessRequestClass); - this.subjectAccessRequestClass = subjectAccessRequestClass; } - public SubjectAccessOperationsImpl(OperationContext context, String apiGroupName, String apiGroupVersion, String plural, Class subjectAccessRequestClass) { + public CreateOnlyResourceOperationsImpl(OperationContext context, String apiGroupName, String apiGroupVersion, String plural, Class subjectAccessRequestClass) { super(context.withApiGroupName(apiGroupName) .withApiGroupVersion(apiGroupVersion) .withPlural(plural)); diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LocalSubjectAccessReviewOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LocalCreateOnlyResourceReviewOperationsImpl.java similarity index 67% rename from kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LocalSubjectAccessReviewOperationsImpl.java rename to kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LocalCreateOnlyResourceReviewOperationsImpl.java index 812f8021de..4d9315b72e 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LocalSubjectAccessReviewOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LocalCreateOnlyResourceReviewOperationsImpl.java @@ -20,13 +20,13 @@ import io.fabric8.kubernetes.client.dsl.base.OperationContext; import okhttp3.OkHttpClient; -public class LocalSubjectAccessReviewOperationsImpl extends SubjectAccessOperationsImpl implements Namespaceable> { +public class LocalCreateOnlyResourceReviewOperationsImpl extends CreateOnlyResourceOperationsImpl implements Namespaceable> { private Class subjectAccessRequestClass; private String subjectAccessApiGroupName; private String subjectAccessApiGroupVersion; private String plural; - public LocalSubjectAccessReviewOperationsImpl(OkHttpClient client, Config config, String subjectAccessApiGroupName, String subjectAccessApiGroupVersion, String plural, Class subjectAccessRequestClass) { + public LocalCreateOnlyResourceReviewOperationsImpl(OkHttpClient client, Config config, String subjectAccessApiGroupName, String subjectAccessApiGroupVersion, String plural, Class subjectAccessRequestClass) { super(client, config, subjectAccessApiGroupName, subjectAccessApiGroupVersion, plural, subjectAccessRequestClass); this.subjectAccessRequestClass = subjectAccessRequestClass; this.subjectAccessApiGroupName = subjectAccessApiGroupName; @@ -34,7 +34,7 @@ public LocalSubjectAccessReviewOperationsImpl(OkHttpClient client, Config config this.plural = plural; } - public LocalSubjectAccessReviewOperationsImpl(OperationContext context, String subjectAccessApiGroupName, String subjectAccessApiGroupVersion, String plural, Class subjectAccessRequestClass) { + public LocalCreateOnlyResourceReviewOperationsImpl(OperationContext context, String subjectAccessApiGroupName, String subjectAccessApiGroupVersion, String plural, Class subjectAccessRequestClass) { super(context, subjectAccessApiGroupName, subjectAccessApiGroupVersion, plural, subjectAccessRequestClass); this.subjectAccessRequestClass = subjectAccessRequestClass; this.subjectAccessApiGroupName = subjectAccessApiGroupName; @@ -43,9 +43,9 @@ public LocalSubjectAccessReviewOperationsImpl(OperationContext context, String s } @Override - public LocalSubjectAccessReviewOperationsImpl inNamespace(String namespace) { + public LocalCreateOnlyResourceReviewOperationsImpl inNamespace(String namespace) { this.namespace = namespace; - return new LocalSubjectAccessReviewOperationsImpl<>(context.withNamespace(namespace), subjectAccessApiGroupName, subjectAccessApiGroupVersion, plural, subjectAccessRequestClass); + return new LocalCreateOnlyResourceReviewOperationsImpl<>(context.withNamespace(namespace), subjectAccessApiGroupName, subjectAccessApiGroupVersion, plural, subjectAccessRequestClass); } @Override 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 4d62b7ede6..558aa2cc71 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 @@ -75,6 +75,8 @@ 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.authentication.DoneableTokenReview; +import io.fabric8.kubernetes.api.model.authentication.TokenReview; 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; @@ -97,6 +99,7 @@ import io.fabric8.kubernetes.client.dsl.AuthorizationAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.AutoscalingAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.BatchAPIGroupDSL; +import io.fabric8.kubernetes.client.dsl.Createable; import io.fabric8.kubernetes.client.dsl.ExtensionsAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.FunctionCallable; import io.fabric8.kubernetes.client.dsl.KubernetesListMixedOperation; @@ -439,6 +442,11 @@ public AuthorizationAPIGroupDSL authorization() { return delegate.authorization(); } + @Override + public Createable tokenReviews() { + return delegate.tokenReviews(); + } + @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-tests/src/test/java/io/fabric8/kubernetes/client/mock/TokenReviewTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/TokenReviewTest.java new file mode 100644 index 0000000000..d32bf05ed3 --- /dev/null +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/TokenReviewTest.java @@ -0,0 +1,79 @@ +/** + * 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.authentication.TokenReview; +import io.fabric8.kubernetes.api.model.authentication.TokenReviewBuilder; +import io.fabric8.kubernetes.api.model.authentication.TokenReviewStatusBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import io.fabric8.kubernetes.client.utils.Serialization; +import org.junit.Rule; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport; + +import java.net.HttpURLConnection; +import java.nio.charset.Charset; + +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 TokenReviewTest { + @Rule + public KubernetesServer server = new KubernetesServer(); + + @Test + @DisplayName("Should create TokenReview") + void testCreate() { + // Given + TokenReview tokenReview = new TokenReviewBuilder() + .withNewSpec() + .withToken("eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJhdWQiOlsidmF1bHQiXSwiZXhwIjoxNTUyNjc1") + .endSpec() + .build(); + server.expect().post().withPath("/apis/authentication.k8s.io/v1/tokenreviews") + .andReply(HttpURLConnection.HTTP_OK, recordedRequest -> { + TokenReview tokenReviewReq = Serialization.unmarshal(recordedRequest.getBody().readString(Charset.defaultCharset()), TokenReview.class); + tokenReviewReq.setStatus(new TokenReviewStatusBuilder() + .withAuthenticated(true) + .withNewUser() + .withUsername("system:serviceaccount:dev:http-svc-test") + .withUid("4afdf4d0-46d2-11e9-8716-005056bf4b40") + .withGroups("system:serviceaccounts", "system:serviceaccounts:dev", "system:authenticated") + .endUser() + .addNewAudience("factors") + .build()); + + return tokenReviewReq; + }).once(); + + KubernetesClient client = server.getClient(); + + // When + tokenReview = client.tokenReviews().create(tokenReview); + + // Then + assertNotNull(tokenReview); + assertNotNull(tokenReview.getStatus()); + assertTrue(tokenReview.getStatus().getAuthenticated()); + assertEquals("system:serviceaccount:dev:http-svc-test", tokenReview.getStatus().getUser().getUsername()); + assertEquals("4afdf4d0-46d2-11e9-8716-005056bf4b40", tokenReview.getStatus().getUser().getUid()); + assertEquals(3, tokenReview.getStatus().getUser().getGroups().size()); + } +} 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 1727f2f6a6..375d03bb92 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 @@ -40,6 +40,8 @@ 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.authentication.DoneableTokenReview; +import io.fabric8.kubernetes.api.model.authentication.TokenReview; 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; @@ -79,6 +81,7 @@ import io.fabric8.openshift.api.model.DoneableRoleBinding; import io.fabric8.openshift.api.model.DoneableRoute; import io.fabric8.openshift.api.model.DoneableSecurityContextConstraints; +import io.fabric8.openshift.api.model.DoneableSubjectAccessReview; import io.fabric8.openshift.api.model.DoneableTemplate; import io.fabric8.openshift.api.model.DoneableUser; import io.fabric8.openshift.api.model.Group; @@ -105,6 +108,7 @@ import io.fabric8.openshift.api.model.SecurityContextConstraints; import io.fabric8.openshift.api.model.SecurityContextConstraintsList; import io.fabric8.openshift.api.model.SubjectAccessReview; +import io.fabric8.openshift.api.model.SubjectAccessReviewResponse; import io.fabric8.openshift.api.model.Template; import io.fabric8.openshift.api.model.TemplateList; import io.fabric8.openshift.api.model.User; @@ -392,6 +396,11 @@ public AuthorizationAPIGroupDSL authorization() { return delegate.authorization(); } + @Override + public Createable tokenReviews() { + return delegate.tokenReviews(); + } + public RawCustomResourceOperationsImpl customResource(CustomResourceDefinitionContext customResourceDefinition) { return new RawCustomResourceOperationsImpl(httpClient, getConfiguration(), customResourceDefinition); } @@ -540,7 +549,7 @@ public AutoscalingAPIGroupDSL autoscaling() { public SettingsAPIGroupDSL settings() { return adapt(SettingsAPIGroupClient.class); } @Override - public OpenshiftSubjectAccessOperations subjectAccessReviews() { + public Createable subjectAccessReviews() { return new OpenShiftSubjectAccessReviewOperationsImpl(httpClient, getConfiguration(), "authorization.openshift.io", "v1", Utils.getPluralFromKind(SubjectAccessReview.class.getSimpleName())); } diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftClient.java b/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftClient.java index 48b3edf85a..e471a487f3 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftClient.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftClient.java @@ -36,6 +36,7 @@ import io.fabric8.openshift.api.model.DoneableRoleBinding; import io.fabric8.openshift.api.model.DoneableRoute; import io.fabric8.openshift.api.model.DoneableSecurityContextConstraints; +import io.fabric8.openshift.api.model.DoneableSubjectAccessReview; import io.fabric8.openshift.api.model.DoneableTemplate; import io.fabric8.openshift.api.model.DoneableUser; import io.fabric8.openshift.client.dsl.*; @@ -101,7 +102,7 @@ public interface OpenShiftClient extends KubernetesClient { NonNamespaceOperation> securityContextConstraints(); - OpenshiftSubjectAccessOperations subjectAccessReviews(); + Createable subjectAccessReviews(); OpenShiftLocalSubjectAccessReviewOperationsImpl localSubjectAccessReviews(); diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftLocalSubjectAccessReviewOperationsImpl.java b/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftLocalSubjectAccessReviewOperationsImpl.java index 2046fd004d..78b42fbba5 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftLocalSubjectAccessReviewOperationsImpl.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftLocalSubjectAccessReviewOperationsImpl.java @@ -17,9 +17,11 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.dsl.Createable; import io.fabric8.kubernetes.client.dsl.Namespaceable; import io.fabric8.kubernetes.client.dsl.base.OperationContext; import io.fabric8.kubernetes.client.dsl.base.OperationSupport; +import io.fabric8.openshift.api.model.DoneableLocalSubjectAccessReview; import io.fabric8.openshift.api.model.LocalSubjectAccessReview; import io.fabric8.openshift.api.model.SubjectAccessReviewResponse; import okhttp3.OkHttpClient; @@ -27,16 +29,13 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; -public class OpenShiftLocalSubjectAccessReviewOperationsImpl extends OperationSupport implements OpenshiftSubjectAccessOperations, Namespaceable { - private String subjectAccessApiGroupName; - private String subjectAccessApiGroupVersion; - private String plural; +public class OpenShiftLocalSubjectAccessReviewOperationsImpl extends OperationSupport implements Createable, Namespaceable { + private final String subjectAccessApiGroupName; + private final String subjectAccessApiGroupVersion; + private final String plural; public OpenShiftLocalSubjectAccessReviewOperationsImpl(OkHttpClient client, Config config, String apiGroupName, String apiGroupVersion, String plural) { this(new OperationContext().withOkhttpClient(client).withConfig(config), apiGroupName, apiGroupVersion, plural); - this.subjectAccessApiGroupName = apiGroupName; - this.subjectAccessApiGroupVersion = apiGroupVersion; - this.plural = plural; } public OpenShiftLocalSubjectAccessReviewOperationsImpl(OperationContext context, String apiGroupName, String apiGroupVersion, String plural) { @@ -48,6 +47,26 @@ public OpenShiftLocalSubjectAccessReviewOperationsImpl(OperationContext context, this.plural = plural; } + @Override + public SubjectAccessReviewResponse create(LocalSubjectAccessReview... resources) { + try { + if (resources.length > 1) { + throw new IllegalArgumentException("Too many items to create."); + } else if (resources.length == 1) { + return handleCreate(updateApiVersion(resources[0]), SubjectAccessReviewResponse.class); + } else if (getItem() == null) { + throw new IllegalArgumentException("Nothing to create."); + } else { + return handleCreate(updateApiVersion(getItem()), SubjectAccessReviewResponse.class); + } + } catch (ExecutionException | IOException e) { + throw KubernetesClientException.launderThrowable(e); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw KubernetesClientException.launderThrowable(ie); + } + } + @Override public SubjectAccessReviewResponse create(LocalSubjectAccessReview item) { try { @@ -60,11 +79,26 @@ public SubjectAccessReviewResponse create(LocalSubjectAccessReview item) { } } + @Override + public DoneableLocalSubjectAccessReview createNew() { + throw new IllegalStateException("This operation is not currently supported"); + } + @Override public OpenShiftLocalSubjectAccessReviewOperationsImpl inNamespace(String namespace) { this.namespace = namespace; return new OpenShiftLocalSubjectAccessReviewOperationsImpl(context.withNamespace(namespace), subjectAccessApiGroupName, subjectAccessApiGroupVersion, this.plural); } + private LocalSubjectAccessReview updateApiVersion(LocalSubjectAccessReview p) { + if (p.getApiVersion() == null) { + p.setApiVersion(this.apiGroupVersion); + } + return p; + } + + public LocalSubjectAccessReview getItem() { + return (LocalSubjectAccessReview) context.getItem(); + } } diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/OpenshiftSubjectAccessOperations.java b/openshift-client/src/main/java/io/fabric8/openshift/client/OpenshiftSubjectAccessOperations.java deleted file mode 100644 index 45a0f4694d..0000000000 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/OpenshiftSubjectAccessOperations.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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.openshift.client; - -import io.fabric8.openshift.api.model.SubjectAccessReviewResponse; - -public interface OpenshiftSubjectAccessOperations { - SubjectAccessReviewResponse create(T item); -} diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/OpenShiftSubjectAccessReviewOperationsImpl.java b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/OpenShiftSubjectAccessReviewOperationsImpl.java index 850c805af0..c366404ead 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/OpenShiftSubjectAccessReviewOperationsImpl.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/OpenShiftSubjectAccessReviewOperationsImpl.java @@ -17,18 +17,19 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.dsl.Createable; import io.fabric8.kubernetes.client.dsl.base.OperationContext; import io.fabric8.kubernetes.client.dsl.base.OperationSupport; +import io.fabric8.openshift.api.model.DoneableSubjectAccessReview; import io.fabric8.openshift.api.model.SubjectAccessReview; import io.fabric8.openshift.api.model.SubjectAccessReviewResponse; -import io.fabric8.openshift.client.OpenshiftSubjectAccessOperations; import okhttp3.OkHttpClient; import java.io.IOException; import java.util.concurrent.ExecutionException; -public class OpenShiftSubjectAccessReviewOperationsImpl extends OperationSupport implements OpenshiftSubjectAccessOperations { +public class OpenShiftSubjectAccessReviewOperationsImpl extends OperationSupport implements Createable { public OpenShiftSubjectAccessReviewOperationsImpl(OkHttpClient client, Config config, String apiGroupName, String apiGroupVersion, String plural) { this(new OperationContext().withOkhttpClient(client).withConfig(config), apiGroupName, apiGroupVersion, plural); @@ -40,6 +41,26 @@ public OpenShiftSubjectAccessReviewOperationsImpl(OperationContext context, Stri .withPlural(plural)); } + @Override + public SubjectAccessReviewResponse create(SubjectAccessReview... resources) { + try { + if (resources.length > 1) { + throw new IllegalArgumentException("Too many items to create."); + } else if (resources.length == 1) { + return handleCreate(updateApiVersion(resources[0]), SubjectAccessReviewResponse.class); + } else if (getItem() == null) { + throw new IllegalArgumentException("Nothing to create."); + } else { + return handleCreate(updateApiVersion(getItem()), SubjectAccessReviewResponse.class); + } + } catch (ExecutionException | IOException e) { + throw KubernetesClientException.launderThrowable(e); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw KubernetesClientException.launderThrowable(ie); + } + } + @Override public SubjectAccessReviewResponse create(SubjectAccessReview item) { try { @@ -52,8 +73,24 @@ public SubjectAccessReviewResponse create(SubjectAccessReview item) { } } + @Override + public DoneableSubjectAccessReview createNew() { + throw new IllegalStateException("This operation is not currently supported"); + } + @Override public boolean isResourceNamespaced() { return false; } + + private SubjectAccessReview updateApiVersion(SubjectAccessReview p) { + if (p.getApiVersion() == null) { + p.setApiVersion(this.apiGroupVersion); + } + return p; + } + + public SubjectAccessReview getItem() { + return (SubjectAccessReview) context.getItem(); + } } 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 b588842d2d..1eaac6ce59 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 @@ -29,6 +29,8 @@ 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.authentication.DoneableTokenReview; +import io.fabric8.kubernetes.api.model.authentication.TokenReview; 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; @@ -46,12 +48,12 @@ import io.fabric8.openshift.api.model.*; import io.fabric8.openshift.api.model.DoneableRole; import io.fabric8.openshift.api.model.DoneableRoleBinding; +import io.fabric8.openshift.api.model.DoneableSubjectAccessReview; import io.fabric8.openshift.client.DefaultOpenShiftClient; import io.fabric8.openshift.client.NamespacedOpenShiftClient; import io.fabric8.openshift.client.OpenShiftClient; import io.fabric8.openshift.client.OpenShiftConfigBuilder; import io.fabric8.openshift.client.OpenShiftLocalSubjectAccessReviewOperationsImpl; -import io.fabric8.openshift.client.OpenshiftSubjectAccessOperations; import io.fabric8.openshift.client.dsl.*; import org.apache.felix.scr.annotations.*; import org.apache.felix.scr.annotations.Service; @@ -437,6 +439,11 @@ public AuthorizationAPIGroupDSL authorization() { return delegate.authorization(); } + @Override + public Createable tokenReviews() { + return delegate.tokenReviews(); + } + @Override public RawCustomResourceOperationsImpl customResource(CustomResourceDefinitionContext customResourceDefinition) { return delegate.customResource(customResourceDefinition); @@ -532,7 +539,7 @@ public AutoscalingAPIGroupDSL autoscaling() { public SettingsAPIGroupDSL settings() { return delegate.settings(); } @Override - public OpenshiftSubjectAccessOperations subjectAccessReviews() { + public Createable subjectAccessReviews() { return delegate.subjectAccessReviews(); }