Skip to content

Bigtable: add resource level IAM #3624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

}
},
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) {

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

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