Skip to content

Commit

Permalink
Fix fabric8io#2265: Refactor SubjectAccessReview API
Browse files Browse the repository at this point in the history
+ Added new entrypoint authorization() into DSL which only allows create() operations
+ Removed old subjectAccessReviewAuth() API

This should also fix fabric8io#2191
  • Loading branch information
rohanKanojia committed Aug 24, 2020
1 parent 0213db9 commit 77a0d51
Show file tree
Hide file tree
Showing 40 changed files with 2,298 additions and 1,036 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@
* 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
* Fix #2265: InAnyNamespace uses invalid api endpoint for SelfSubjectAccessReviews

#### Improvements
* Fix #2331: Fixed documentation for namespaced informer for all custom types implementing `Namespaced` interface
Expand All @@ -27,6 +28,10 @@
* Fix #2287: Add support for V1 and V1Beta1 CustomResourceDefinition
* Fix #2319: Create Config without using auto-configure functionality or setting env variables

_**Note**_: Some classes have been moved to other packages:
- CustomResourceDefinition has been moved to `io.fabric8.kubernetes.api.model.apiextensions.v1` and `io.fabric8.kubernetes.api.model.apiextensions.v1beta1`
- SubjectAccessReview, SelfSubjectAccessReview, LocalSubjectAccessReview and SelfSubjectRulesReview have been moved to `io.fabric8.kubernetes.api.model.authorization.v1` and `io.fabric8.kubernetes.api.model.authorization.v1beta1`

### 4.10.3 (2020-07-14)
#### Bugs
* Fix #2285: Raw CustomResource API createOrReplace does not propagate exceptions from create
Expand Down
85 changes: 85 additions & 0 deletions doc/CHEATSHEET.md
Expand Up @@ -24,6 +24,10 @@ This document contains common usages of different resources using Fabric8 Kubern
* [PersistentVolume](#persistentvolume)
* [NetworkPolicy](#networkpolicy)
* [PodDisruptionBudget](#poddisruptionbudget)
* [SelfSubjectAccessReview](#selfsubjectaccessreview)
* [SubjectAccessReview](#subjectaccessreview)
* [LocalSubjectAccessReview](#localsubjectaccessreview)
* [SelfSubjectRulesReview](#selfsubjectrulesreview)
* [Top/Metrics](#fetching-metrics)
* [Generic Resource API](#resource-api)
* [Generic ResourceList API](#resourcelist-api)
Expand Down Expand Up @@ -1566,6 +1570,87 @@ PodDisruptionBudgetList pdbList = client.policy().podDisruptionBudget().inNamesp
Boolean deleted = client.policy().podDisruptionBudget().inNamespace("default").withName("poddisruptionbudget1").delete();
```

### SelfSubjectAccessReview
- Create `SelfSubjectAccessReview`(equivalent of `kubectl auth can-i create deployments --namespace dev`):
```
try (KubernetesClient client = new DefaultKubernetesClient()) {
SelfSubjectAccessReview ssar = new SelfSubjectAccessReviewBuilder()
.withNewSpec()
.withNewResourceAttributes()
.withGroup("apps")
.withResource("deployments")
.withVerb("create")
.withNamespace("dev")
.endResourceAttributes()
.endSpec()
.build();
ssar = client.authorization().v1().selfSubjectAccessReview().create(ssar);
System.out.println("Allowed: "+ ssar.getStatus().getAllowed());
}
```

### SubjectAccessReview
- Create `SubjectAccessReview`:
```
try (KubernetesClient client = new DefaultKubernetesClient()) {
SubjectAccessReview sar = new SubjectAccessReviewBuilder()
.withNewSpec()
.withNewResourceAttributes()
.withGroup("apps")
.withResource("deployments")
.withVerb("create")
.withNamespace("default")
.endResourceAttributes()
.withUser("kubeadmin")
.endSpec()
.build();
sar = client.authorization().v1().subjectAccessReview().create(sar);
System.out.println("Allowed: "+ sar.getStatus().getAllowed());
}
```
### LocalSubjectAccessReview
- Create `LocalSubjectAccessReview`:
```
try (KubernetesClient client = new DefaultKubernetesClient()) {
LocalSubjectAccessReview lsar = new LocalSubjectAccessReviewBuilder()
.withNewMetadata().withNamespace("default").endMetadata()
.withNewSpec()
.withUser("foo")
.withNewResourceAttributes()
.withNamespace("default")
.withVerb("get")
.withGroup("apps")
.withResource("pods")
.endResourceAttributes()
.endSpec()
.build();
lsar = client.authorization().v1().localSubjectAccessReview().inNamespace("default").create(lsar);
System.out.println(lsar.getStatus().getAllowed());
}
```

### SelfSubjectRulesReview
- Create `SelfSubjectRulesReview`:
```
try (KubernetesClient client = new DefaultKubernetesClient()) {
SelfSubjectRulesReview selfSubjectRulesReview = new SelfSubjectRulesReviewBuilder()
.withNewMetadata().withName("foo").endMetadata()
.withNewSpec()
.withNamespace("default")
.endSpec()
.build();
selfSubjectRulesReview = client.authorization().v1().selfSubjectRulesReview().create(selfSubjectRulesReview);
System.out.println(selfSubjectRulesReview.getStatus().getIncomplete());
System.out.println("non resource rules: " + selfSubjectRulesReview.getStatus().getNonResourceRules().size());
System.out.println("resource rules: " + selfSubjectRulesReview.getStatus().getResourceRules().size());
}
```

### Fetching Metrics
Kubernetes Client also supports fetching metrics from API server if metrics are enabled on it. You can access metrics via `client.top()`. Here are some examples of its usage:
- Get `NodeMetrics` for all nodes:
Expand Down
@@ -0,0 +1,39 @@
/**
* 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.AuthorizationAPIGroupDSL;
import okhttp3.OkHttpClient;

public class AuthorizationAPIGroupClient extends BaseClient implements AuthorizationAPIGroupDSL {
public AuthorizationAPIGroupClient() {
super();
}

public AuthorizationAPIGroupClient(OkHttpClient httpClient, final Config config) {
super(httpClient, config);
}

@Override
public V1AuthorizationAPIGroupDSL v1() {
return adapt(V1AuthorizationAPIGroupClient.class);
}

@Override
public V1beta1AuthorizationAPIGroupDSL v1beta1() {
return adapt(V1beta1AuthorizationAPIGroupClient.class);
}
}
@@ -0,0 +1,37 @@
/**
* 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 okhttp3.OkHttpClient;

public class AuthorizationAPIGroupExtensionAdapter extends APIGroupExtensionAdapter<AuthorizationAPIGroupClient> {

@Override
protected String getAPIGroupName() {
return "authorization";
}

@Override
public Class<AuthorizationAPIGroupClient> getExtensionType() {
return AuthorizationAPIGroupClient.class;
}

@Override
protected AuthorizationAPIGroupClient newInstance(Client client) {
return new AuthorizationAPIGroupClient(client.adapt(OkHttpClient.class), client.getConfiguration());
}

}
Expand Up @@ -136,6 +136,11 @@ public AutoscalingAPIGroupDSL autoscaling() {
return delegate.autoscaling();
}

@Override
public AuthorizationAPIGroupDSL authorization() {
return delegate.authorization();
}

@Override
public NetworkAPIGroupDSL network() { return delegate.network(); }

Expand Down Expand Up @@ -251,11 +256,6 @@ public MixedOperation<ConfigMap, ConfigMapList, DoneableConfigMap, Resource<Conf
return delegate.configMaps();
}

@Override
public SubjectAccessReviewDSL subjectAccessReviewAuth() {
return delegate.subjectAccessReviewAuth();
}

@Override
public MixedOperation<LimitRange, LimitRangeList, DoneableLimitRange, Resource<LimitRange, DoneableLimitRange>> limitRanges() {
return delegate.limitRanges();
Expand Down
Expand Up @@ -98,7 +98,6 @@
import io.fabric8.kubernetes.client.dsl.internal.RawCustomResourceOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.core.v1.ReplicationControllerOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.core.v1.ServiceOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.SubjectAccessReviewDSLImpl;
import io.fabric8.kubernetes.client.dsl.internal.coordination.v1.LeaseOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.core.v1.BindingOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.core.v1.ConfigMapOperationsImpl;
Expand Down Expand Up @@ -302,6 +301,11 @@ public NonNamespaceOperation<CertificateSigningRequest, CertificateSigningReques
return new CertificateSigningRequestOperationsImpl(httpClient, getConfiguration());
}

@Override
public AuthorizationAPIGroupDSL authorization() {
return adapt(AuthorizationAPIGroupClient.class);
}

@Override
public <T extends HasMetadata, L extends KubernetesResourceList<T>, D extends Doneable<T>> MixedOperation<T, L, D, Resource<T, D>> customResources(CustomResourceDefinitionContext crdContext, Class<T> resourceType, Class<L> listClass, Class<D> doneClass) {
return new CustomResourceOperationsImpl<>(new CustomResourceOperationContext().withOkhttpClient(httpClient).withConfig(getConfiguration())
Expand Down Expand Up @@ -401,11 +405,6 @@ public AutoscalingAPIGroupDSL autoscaling() {
@Override
public SettingsAPIGroupDSL settings() { return adapt(SettingsAPIGroupClient.class); }

@Override
public SubjectAccessReviewDSL subjectAccessReviewAuth() {
return new SubjectAccessReviewDSLImpl(httpClient, getConfiguration());
}

@Override
public SharedInformerFactory informers() {
return new SharedInformerFactory(ForkJoinPool.commonPool(), httpClient, getConfiguration());
Expand Down
Expand Up @@ -457,11 +457,11 @@ public interface KubernetesClient extends Client {
MixedOperation<LimitRange, LimitRangeList, DoneableLimitRange, Resource<LimitRange, DoneableLimitRange>> limitRanges();

/**
* SubjectAccessReview operations. (authorization/v1)
* Authorization operations. (authorization.k8s.io/v1 and authorization.k8s.io/v1beta1)
*
* @return SubjectAccessReviewDSL object for dealing with SubjectAccessReviewOperations
* @return AuthorizationAPIGroupDSL object for dealing with Authorization objects
*/
SubjectAccessReviewDSL subjectAccessReviewAuth();
AuthorizationAPIGroupDSL authorization();

/**
* Get an instance of Kubernetes Client informer factory. It allows you to construct and
Expand Down
Expand Up @@ -13,18 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.kubernetes.client;

package io.fabric8.openshift.client.dsl;

import io.fabric8.kubernetes.api.model.Doneable;
import io.fabric8.kubernetes.client.dsl.Createable;
import io.fabric8.openshift.api.model.LocalSubjectAccessReview;
import io.fabric8.openshift.api.model.LocalSubjectAccessReviewFluentImpl;
import io.fabric8.openshift.api.model.SubjectAccessReviewResponse;

public abstract class CreateableLocalSubjectAccessReview extends
LocalSubjectAccessReviewFluentImpl<CreateableLocalSubjectAccessReview>
implements
Doneable<SubjectAccessReviewResponse>,
Createable<LocalSubjectAccessReview, SubjectAccessReviewResponse, CreateableLocalSubjectAccessReview> {
public interface SubjectAccessOperations<T, D> extends Createable<T, T, D> {
}
@@ -0,0 +1,62 @@
/**
* 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.api.model.authorization.v1.DoneableLocalSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.v1.DoneableSelfSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.v1.DoneableSelfSubjectRulesReview;
import io.fabric8.kubernetes.api.model.authorization.v1.DoneableSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.v1.LocalSubjectAccessReview;
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.utils.Utils;
import okhttp3.OkHttpClient;

public class V1AuthorizationAPIGroupClient extends BaseClient implements V1AuthorizationAPIGroupDSL {
public static final String AUTHORIZATION_APIGROUP = "authorization.k8s.io";
public static final String AUTHORIZATION_APIVERSION = "v1";

public V1AuthorizationAPIGroupClient() {
super();
}

public V1AuthorizationAPIGroupClient(OkHttpClient httpClient, final Config config) {
super(httpClient, config);
}

@Override
public SubjectAccessOperations<SelfSubjectAccessReview, DoneableSelfSubjectAccessReview> selfSubjectAccessReview() {
return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectAccessReview.class.getSimpleName()), SelfSubjectAccessReview.class);
}

@Override
public SubjectAccessOperations<SubjectAccessReview, DoneableSubjectAccessReview> subjectAccessReview() {
return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SubjectAccessReview.class.getSimpleName()), SubjectAccessReview.class);
}

@Override
public LocalSubjectAccessReviewOperationsImpl<LocalSubjectAccessReview, DoneableLocalSubjectAccessReview> localSubjectAccessReview() {
return new LocalSubjectAccessReviewOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.LocalSubjectAccessReview.class.getSimpleName()), LocalSubjectAccessReview.class);
}

@Override
public SubjectAccessOperations<SelfSubjectRulesReview, DoneableSelfSubjectRulesReview> selfSubjectRulesReview() {
return new SubjectAccessOperationsImpl<>(getHttpClient(), getConfiguration(), AUTHORIZATION_APIGROUP, AUTHORIZATION_APIVERSION, Utils.getPluralFromKind(io.fabric8.kubernetes.api.model.authorization.v1beta1.SelfSubjectRulesReview.class.getSimpleName()), SelfSubjectRulesReview.class);
}
}
@@ -0,0 +1,33 @@
/**
* 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.api.model.authorization.v1.DoneableLocalSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.v1.DoneableSelfSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.v1.DoneableSelfSubjectRulesReview;
import io.fabric8.kubernetes.api.model.authorization.v1.DoneableSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.v1.LocalSubjectAccessReview;
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;

public interface V1AuthorizationAPIGroupDSL extends Client{
SubjectAccessOperations<SelfSubjectAccessReview, DoneableSelfSubjectAccessReview> selfSubjectAccessReview();
SubjectAccessOperations<SubjectAccessReview, DoneableSubjectAccessReview> subjectAccessReview();
LocalSubjectAccessReviewOperationsImpl<LocalSubjectAccessReview, DoneableLocalSubjectAccessReview> localSubjectAccessReview();
SubjectAccessOperations<SelfSubjectRulesReview, DoneableSelfSubjectRulesReview> selfSubjectRulesReview();
}

0 comments on commit 77a0d51

Please sign in to comment.