Skip to content

Commit

Permalink
Bigtable: add resource level IAM (googleapis#3624)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorbernstein2 authored Sep 4, 2018
1 parent c715fc6 commit c81ff3e
Show file tree
Hide file tree
Showing 2 changed files with 403 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.api.core.ApiFunction;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
import com.google.api.resourcenames.ResourceName;
import com.google.bigtable.admin.v2.AppProfileName;
import com.google.bigtable.admin.v2.ClusterName;
import com.google.bigtable.admin.v2.DeleteAppProfileRequest;
Expand All @@ -27,6 +28,8 @@
import com.google.bigtable.admin.v2.ListAppProfilesRequest;
import com.google.bigtable.admin.v2.LocationName;
import com.google.bigtable.admin.v2.ProjectName;
import com.google.cloud.Policy;
import com.google.cloud.Policy.DefaultMarshaller;
import com.google.cloud.bigtable.admin.v2.BaseBigtableInstanceAdminClient.ListAppProfilesPage;
import com.google.cloud.bigtable.admin.v2.BaseBigtableInstanceAdminClient.ListAppProfilesPagedResponse;
import com.google.cloud.bigtable.admin.v2.models.AppProfile;
Expand All @@ -46,8 +49,13 @@
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.iam.v1.GetIamPolicyRequest;
import com.google.iam.v1.SetIamPolicyRequest;
import com.google.iam.v1.TestIamPermissionsRequest;
import com.google.iam.v1.TestIamPermissionsResponse;
import com.google.protobuf.Empty;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nonnull;
Expand Down Expand Up @@ -992,6 +1000,284 @@ public Void apply(Empty input) {
);
}

/**
* Gets the IAM access control policy for the specified instance.
*
* <p>Sample code:
*
* <pre>{@code
* Policy policy = client.getIamPolicy("my-instance");
* for(Map.Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
* System.out.printf("Role: %s Identities: %s\n", entry.getKey(), entry.getValue());
* }
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#iam-management-instance">Instance-level
* IAM management</a>
*/
@SuppressWarnings("WeakerAccess")
public Policy getIamPolicy(String instanceId) {
return awaitFuture(getIamPolicyAsync(instanceId));
}

/**
* Asynchronously gets the IAM access control policy for the specified instance.
*
* <p>Sample code:
*
* <pre>{@code
* ApiFuture<Policy> policyFuture = client.getIamPolicyAsync("my-instance");
*
* ApiFutures.addCallback(policyFuture,
* new ApiFutureCallback<Policy>() {
* public void onSuccess(Policy policy) {
* for (Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
* System.out.printf("Role: %s Identities: %s\n", entry.getKey(), entry.getValue());
* }
* }
*
* public void onFailure(Throwable t) {
* t.printStackTrace();
* }
* },
* MoreExecutors.directExecutor());
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#iam-management-instance">Instance-level IAM management</a>
*/
@SuppressWarnings("WeakerAccess")
public ApiFuture<Policy> getIamPolicyAsync(String instanceId) {
InstanceName name = InstanceName.of(projectName.getProject(), instanceId);

GetIamPolicyRequest request = GetIamPolicyRequest.newBuilder()
.setResource(name.toString())
.build();

final IamPolicyMarshaller marshaller = new IamPolicyMarshaller();

return ApiFutures.transform(
stub.getIamPolicyCallable().futureCall(request),
new ApiFunction<com.google.iam.v1.Policy, Policy>() {
@Override
public Policy apply(com.google.iam.v1.Policy proto) {
return marshaller.fromPb(proto);
}
},
MoreExecutors.directExecutor()
);
}

/**
* Replaces the IAM policy associated with the specified instance.
*
* <p>Sample code:
*
* <pre>{@code
* Policy newPolicy = client.setIamPolicy("my-instance",
* Policy.newBuilder()
* .addIdentity(Role.of("bigtable.user"), Identity.user("[email protected]"))
* .addIdentity(Role.of("bigtable.admin"), Identity.group("[email protected]"))
* .build());
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#iam-management-instance">Instance-level IAM management</a>
*/
@SuppressWarnings("WeakerAccess")
public Policy setIamPolicy(String instanceId, Policy policy) {
return awaitFuture(setIamPolicyAsync(instanceId, policy));
}

/**
* Asynchronously replaces the IAM policy associated with the specified instance.
*
* <p>Sample code:
*
* <pre>{@code
* ApiFuture<Policy> newPolicyFuture = client.setIamPolicyAsync("my-instance",
* Policy.newBuilder()
* .addIdentity(Role.of("bigtable.user"), Identity.user("[email protected]"))
* .addIdentity(Role.of("bigtable.admin"), Identity.group("[email protected]"))
* .build());
*
* ApiFutures.addCallback(policyFuture,
* new ApiFutureCallback<Policy>() {
* public void onSuccess(Policy policy) {
* for (Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
* System.out.printf("Role: %s Identities: %s\n", entry.getKey(), entry.getValue());
* }
* }
*
* public void onFailure(Throwable t) {
* t.printStackTrace();
* }
* },
* MoreExecutors.directExecutor());
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#iam-management-instance">Instance-level IAM management</a>
*/
@SuppressWarnings("WeakerAccess")
public ApiFuture<Policy> setIamPolicyAsync(String instanceId, Policy policy) {
InstanceName name = InstanceName.of(projectName.getProject(), instanceId);
final IamPolicyMarshaller marshaller = new IamPolicyMarshaller();

SetIamPolicyRequest request = SetIamPolicyRequest.newBuilder()
.setResource(name.toString())
.setPolicy(marshaller.toPb(policy))
.build();

return ApiFutures.transform(
stub.setIamPolicyCallable().futureCall(request),
new ApiFunction<com.google.iam.v1.Policy, Policy>() {
@Override
public Policy apply(com.google.iam.v1.Policy proto) {
return marshaller.fromPb(proto);
}
},
MoreExecutors.directExecutor()
);
}

/**
* Tests whether the caller has the given permissions for the specified instance.
* Returns a subset of the specified permissions that the caller has.
*
* <p>Sample code:
*
* <pre>{@code
* List<String> grantedPermissions = client.testIamPermission("my-instance",
* "bigtable.tables.readRows", "bigtable.tables.mutateRows");
* }</pre>
*
* System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
* System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#permissions">Cloud Bigtable permissions</a>
*/
@SuppressWarnings("WeakerAccess")
public List<String> testIamPermission(String instanceId, String... permissions) {
return testIamPermission(InstanceName.of(projectName.getProject(), instanceId), permissions);
}

/**
* Asynchronously tests whether the caller has the given permissions for the specified instance.
* Returns a subset of the specified permissions that the caller has.
*
* <p>Sample code:
*
* <pre>{@code
* ApiFuture<List<String>> grantedPermissionsFuture = client.testIamPermission("my-instance",
* "bigtable.tables.readRows", "bigtable.tables.mutateRows");
*
* ApiFutures.addCallback(grantedPermissionsFuture,
* new ApiFutureCallback<List<String>>() {
* public void onSuccess(List<String> grantedPermissions) {
* System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
* System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
* }
*
* public void onFailure(Throwable t) {
* t.printStackTrace();
* }
* },
* MoreExecutors.directExecutor());
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#permissions">Cloud Bigtable permissions</a>
*/
@SuppressWarnings("WeakerAccess")
public ApiFuture<List<String>> testIamPermissionAsync(String instanceId, String... permissions) {
return testIamPermissionAsync(InstanceName.of(projectName.getProject(), instanceId), permissions);
}

/**
* Tests whether the caller has the given permissions for the specified absolute resource name
* (note that the current project of the client is ignored).
*
* Returns a subset of the specified permissions that the caller has.
*
* <p>Sample code:
*
* <pre>{@code
* List<String> grantedPermissions = client.testIamPermission(
* TableName.of("my-project", "my-instance", "my-table"),
* "bigtable.tables.readRows", "bigtable.tables.mutateRows");
*
* System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
* System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#permissions">Cloud Bigtable permissions</a>
*/
@SuppressWarnings("WeakerAccess")
public List<String> testIamPermission(ResourceName resourceName, String... permissions) {
return awaitFuture(testIamPermissionAsync(resourceName, permissions));
}


/**
* Asynchronously tests whether the caller has the given permissions for the the specified
* absolute resource name (note that the current project of the client is ignored).
* Returns a subset of the specified permissions that the caller has.
*
* <p>Sample code:
*
* <pre>{@code
* ApiFuture<List<String>> grantedPermissionsFuture = client.testIamPermission(
* TableName.of("my-project", "my-instance", "my-table"),
* "bigtable.tables.readRows", "bigtable.tables.mutateRows");
*
* ApiFutures.addCallback(grantedPermissionsFuture,
* new ApiFutureCallback<List<String>>() {
* public void onSuccess(List<String> grantedPermissions) {
* System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
* System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
* }
*
* public void onFailure(Throwable t) {
* t.printStackTrace();
* }
* },
* MoreExecutors.directExecutor());
* }</pre>
*
* @see <a href="https://cloud.google.com/bigtable/docs/access-control#permissions">Cloud Bigtable permissions</a>
*/
@SuppressWarnings("WeakerAccess")
public ApiFuture<List<String>> testIamPermissionAsync(ResourceName resourceName, String... permissions) {
TestIamPermissionsRequest request = TestIamPermissionsRequest.newBuilder()
.setResource(resourceName.toString())
.addAllPermissions(Arrays.asList(permissions))
.build();

return ApiFutures.transform(
stub.testIamPermissionsCallable().futureCall(request),
new ApiFunction<TestIamPermissionsResponse, List<String>>() {
@Override
public List<String> apply(TestIamPermissionsResponse input) {
return input.getPermissionsList();
}
},
MoreExecutors.directExecutor()
);
}

/**
* Simple adapter to expose {@link DefaultMarshaller} to this class. It enables this client to
* convert to/from IAM wrappers and protobufs.
*/
private static class IamPolicyMarshaller extends DefaultMarshaller {
@Override
public Policy fromPb(com.google.iam.v1.Policy policyPb) {
return super.fromPb(policyPb);
}

@Override
public com.google.iam.v1.Policy toPb(Policy policy) {
return super.toPb(policy);
}
}

/**
* Awaits the result of a future, taking care to propagate errors while maintaining the call site
* in a suppressed exception. This allows semantic errors to be caught across threads, while
Expand Down
Loading

0 comments on commit c81ff3e

Please sign in to comment.