Skip to content

Commit

Permalink
Adding support for using SubjectAccessReview (#1466)
Browse files Browse the repository at this point in the history
* Adding support for using SubjectAccessReview and LocalSubjectAccessReview in kubernetes client

* Adding missing files

* Adding integration test for subject access reviews, editing changelog, removing wildcard imports

* Adding license
  • Loading branch information
raiRaiyan authored and rohanKanojia committed Apr 8, 2019
1 parent 25944e5 commit d1f2e77
Show file tree
Hide file tree
Showing 11 changed files with 337 additions and 10 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Fix #1297: wrong result produced when exec in used and params contains '&'. Url string not encoded properly.

Improvements
* Fix #1455: Use SubjectAccessReview and LocalSubjectAccessReview in kubernetes client using subjectAccessReviewAuth()


Dependency Upgrade
Expand All @@ -19,7 +20,6 @@
#### 4.1-SNAPSHOT

Bugs

* Fix #1387: ValidatingWebhookConfigurationOperationsImpl should be a NonNamespaceOperation
* Fix #1429: Fixes JsonMappingException: No resource type found for:v1#List when reading a Kubernetes List YAML
* Fix #760: Api get pod from yaml issue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ 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
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,9 @@ public AutoscalingAPIGroupDSL autoscaling() {
@Override
public SettingsAPIGroupDSL settings() { return adapt(SettingsAPIGroupClient.class); }

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,6 @@ public interface KubernetesClient extends Client {

MixedOperation<LimitRange, LimitRangeList, DoneableLimitRange, Resource<LimitRange, DoneableLimitRange>> limitRanges();

SubjectAccessReviewDSL subjectAccessReviewAuth();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 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.dsl;

import io.fabric8.kubernetes.api.model.authorization.DoneableLocalSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.DoneableSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.LocalSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.SubjectAccessReview;

public interface SubjectAccessReviewDSL extends
Createable<SubjectAccessReview, SubjectAccessReview, DoneableSubjectAccessReview>,
Namespaceable<Createable<LocalSubjectAccessReview, LocalSubjectAccessReview, DoneableLocalSubjectAccessReview>> {


}
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,23 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.fabric8.kubernetes.client.internal.VersionUsageUtils;
import io.fabric8.kubernetes.client.utils.Serialization;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import io.fabric8.kubernetes.api.model.DeleteOptions;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Status;
import io.fabric8.kubernetes.api.model.StatusBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.internal.VersionUsageUtils;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.utils.URLUtils;
import io.fabric8.kubernetes.client.utils.Utils;
import io.fabric8.zjsonpatch.JsonDiff;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

import java.io.IOException;
import java.io.InputStream;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* 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.dsl.internal;

import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.authorization.*;
import io.fabric8.kubernetes.api.model.authorization.DoneableLocalSubjectAccessReview;
import io.fabric8.kubernetes.api.model.authorization.DoneableSubjectAccessReview;
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.SubjectAccessReviewDSL;
import io.fabric8.kubernetes.client.dsl.base.OperationContext;
import io.fabric8.kubernetes.client.dsl.base.OperationSupport;
import io.fabric8.kubernetes.client.utils.Utils;
import okhttp3.OkHttpClient;

import java.io.IOException;
import java.util.concurrent.ExecutionException;

public class SubjectAccessReviewDSLImpl extends OperationSupport implements SubjectAccessReviewDSL {

private static final String AUTHORIZATION = "authorization.k8s.io/v1";
private static final String SAR_PLURAL = "subjectaccessreviews";
private static final String LSAR_PLURAL = "localsubjectaccessreviews";

private boolean isNamespaced = false;

public SubjectAccessReviewDSLImpl(OperationContext context) {
super(context.withApiGroupName(AUTHORIZATION).withPlural(SAR_PLURAL));
}

private SubjectAccessReviewDSLImpl(OperationContext context, String namespace, String plural, boolean isNamespaced) {
super(context.withApiGroupName(AUTHORIZATION).withNamespace(namespace).withPlural(plural));
this.isNamespaced = isNamespaced;
}

public SubjectAccessReviewDSLImpl(OkHttpClient client, Config config) {
this(new OperationContext().withOkhttpClient(client).withConfig(config));
}

@Override
public boolean isResourceNamespaced() {
return isNamespaced;
}

@Override
public SubjectAccessReview create(SubjectAccessReview... resources) {
return new CreatableSubjectAccessReview().create(resources);
}

@Override
public DoneableSubjectAccessReview createNew() {
return new CreatableSubjectAccessReview().createNew();
}

@Override
public Createable<LocalSubjectAccessReview, LocalSubjectAccessReview, DoneableLocalSubjectAccessReview> inNamespace(String namespace) {
//Should we use this namespace to set the metadata namespace and the spec namespace of the LocalSubjectAccessReview object?
return new SubjectAccessReviewDSLImpl(this.context, namespace, LSAR_PLURAL, true).local(namespace);
}

private Createable<LocalSubjectAccessReview, LocalSubjectAccessReview, DoneableLocalSubjectAccessReview> local(String namespace) {
return new CreatableLocalSubjectAccessReview(namespace);
}

private class CreatableLocalSubjectAccessReview implements Createable<LocalSubjectAccessReview, LocalSubjectAccessReview, DoneableLocalSubjectAccessReview> {

private final String namespace;

CreatableLocalSubjectAccessReview(String namespace) {
this.namespace = namespace;
}

@Override
public LocalSubjectAccessReview create(LocalSubjectAccessReview... resources) {
try {
if (resources.length > 1) {
throw new IllegalArgumentException("Too many items to create.");
} else if (resources.length == 1) {
setNamespace(resources[0]);
return handleCreate(resources[0], LocalSubjectAccessReview.class);
} else {
throw new IllegalArgumentException("Nothing to create.");
}
} catch (InterruptedException | ExecutionException | IOException e) {
throw KubernetesClientException.launderThrowable(e);
}
}

private void setNamespace(LocalSubjectAccessReview resource) {
ObjectMeta meta = resource.getMetadata();

if(meta == null) {
meta = new ObjectMeta();
resource.setMetadata(meta);
}

if(Utils.isNullOrEmpty(meta.getNamespace())) {
meta.setNamespace(this.namespace);
}

SubjectAccessReviewSpec spec = resource.getSpec();
if(spec != null) {
if (spec.getResourceAttributes() != null
&& Utils.isNullOrEmpty(spec.getResourceAttributes().getNamespace())) {
spec.getResourceAttributes().setNamespace(this.namespace);
}
}
}

@Override
public DoneableLocalSubjectAccessReview createNew() {
return new DoneableLocalSubjectAccessReview(this::create);
}
}

private class CreatableSubjectAccessReview implements Createable<SubjectAccessReview, SubjectAccessReview, DoneableSubjectAccessReview> {

@Override
public SubjectAccessReview create(SubjectAccessReview... resources) {
try {
if (resources.length > 1) {
throw new IllegalArgumentException("Too many items to create.");
} else if (resources.length == 1) {
return handleCreate(resources[0], SubjectAccessReview.class);
} else {
throw new IllegalArgumentException("Nothing to create.");
}
} catch (InterruptedException | ExecutionException | IOException e) {
throw KubernetesClientException.launderThrowable(e);
}
}

@Override
public DoneableSubjectAccessReview createNew() {
return new DoneableSubjectAccessReview(this::create);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
import io.fabric8.kubernetes.client.dsl.ServiceResource;
import io.fabric8.kubernetes.client.dsl.SettingsAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.StorageAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.SubjectAccessReviewDSL;
import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
import io.fabric8.kubernetes.client.dsl.internal.RawCustomResourceOperationsImpl;
import org.apache.felix.scr.annotations.Activate;
Expand Down Expand Up @@ -307,6 +308,11 @@ public NonNamespaceOperation<Node, NodeList, DoneableNode, Resource<Node, Doneab
return delegate.nodes();
}

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

public MixedOperation<PersistentVolumeClaim, PersistentVolumeClaimList, DoneablePersistentVolumeClaim, Resource<PersistentVolumeClaim, DoneablePersistentVolumeClaim>> persistentVolumeClaims() {
return delegate.persistentVolumeClaims();
}
Expand Down
Loading

0 comments on commit d1f2e77

Please sign in to comment.