forked from googleapis/google-cloud-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bigtable: add resource level IAM (googleapis#3624)
- Loading branch information
1 parent
c715fc6
commit c81ff3e
Showing
2 changed files
with
403 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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 | ||
|
Oops, something went wrong.