Skip to content
This repository was archived by the owner on Aug 30, 2026. It is now read-only.

Commit 44932cb

Browse files
authored
feat: Backup Level IAM (#160)
1 parent ff3c577 commit 44932cb

2 files changed

Lines changed: 159 additions & 0 deletions

File tree

google/cloud/bigtable/backup.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
BigtableTableAdminClient,
2222
)
2323
from google.cloud.bigtable_admin_v2.types import table_pb2
24+
from google.cloud.bigtable.policy import Policy
2425
from google.cloud.exceptions import NotFound
2526
from google.protobuf import field_mask_pb2
2627

@@ -392,3 +393,54 @@ def restore(self, table_id):
392393
"""
393394
api = self._instance._client.table_admin_client
394395
return api.restore_table(self._instance.name, table_id, self.name)
396+
397+
def get_iam_policy(self):
398+
"""Gets the IAM access control policy for this backup.
399+
400+
:rtype: :class:`google.cloud.bigtable.policy.Policy`
401+
:returns: The current IAM policy of this backup.
402+
"""
403+
table_api = self._instance._client.table_admin_client
404+
args = {"resource": self.name}
405+
response = table_api.get_iam_policy(**args)
406+
return Policy.from_pb(response)
407+
408+
def set_iam_policy(self, policy):
409+
"""Sets the IAM access control policy for this backup. Replaces any
410+
existing policy.
411+
412+
For more information about policy, please see documentation of
413+
class `google.cloud.bigtable.policy.Policy`
414+
415+
:type policy: :class:`google.cloud.bigtable.policy.Policy`
416+
:param policy: A new IAM policy to replace the current IAM policy
417+
of this backup.
418+
419+
:rtype: :class:`google.cloud.bigtable.policy.Policy`
420+
:returns: The current IAM policy of this backup.
421+
"""
422+
table_api = self._instance._client.table_admin_client
423+
response = table_api.set_iam_policy(resource=self.name, policy=policy.to_pb())
424+
return Policy.from_pb(response)
425+
426+
def test_iam_permissions(self, permissions):
427+
"""Tests whether the caller has the given permissions for this backup.
428+
Returns the permissions that the caller has.
429+
430+
:type permissions: list
431+
:param permissions: The set of permissions to check for
432+
the ``resource``. Permissions with wildcards (such as '*'
433+
or 'storage.*') are not allowed. For more information see
434+
`IAM Overview
435+
<https://cloud.google.com/iam/docs/overview#permissions>`_.
436+
`Bigtable Permissions
437+
<https://cloud.google.com/bigtable/docs/access-control>`_.
438+
439+
:rtype: list
440+
:returns: A List(string) of permissions allowed on the backup.
441+
"""
442+
table_api = self._instance._client.table_admin_client
443+
response = table_api.test_iam_permissions(
444+
resource=self.name, permissions=permissions
445+
)
446+
return list(response.permissions)

tests/unit/test_backup.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,113 @@ def test_restore_success(self):
734734
backup=self.BACKUP_NAME,
735735
)
736736

737+
def test_get_iam_policy(self):
738+
from google.cloud.bigtable.client import Client
739+
from google.cloud.bigtable_admin_v2.gapic import bigtable_table_admin_client
740+
from google.iam.v1 import policy_pb2
741+
from google.cloud.bigtable.policy import BIGTABLE_ADMIN_ROLE
742+
743+
credentials = _make_credentials()
744+
client = Client(project=self.PROJECT_ID, credentials=credentials, admin=True)
745+
746+
instance = client.instance(instance_id=self.INSTANCE_ID)
747+
backup = self._make_one(self.BACKUP_ID, instance, cluster_id=self.CLUSTER_ID)
748+
749+
version = 1
750+
etag = b"etag_v1"
751+
members = ["serviceAccount:service_acc1@test.com", "user:user1@test.com"]
752+
bindings = [{"role": BIGTABLE_ADMIN_ROLE, "members": members}]
753+
iam_policy = policy_pb2.Policy(version=version, etag=etag, bindings=bindings)
754+
755+
table_api = mock.create_autospec(
756+
bigtable_table_admin_client.BigtableTableAdminClient
757+
)
758+
client._table_admin_client = table_api
759+
table_api.get_iam_policy.return_value = iam_policy
760+
761+
result = backup.get_iam_policy()
762+
763+
table_api.get_iam_policy.assert_called_once_with(resource=backup.name)
764+
self.assertEqual(result.version, version)
765+
self.assertEqual(result.etag, etag)
766+
767+
admins = result.bigtable_admins
768+
self.assertEqual(len(admins), len(members))
769+
for found, expected in zip(sorted(admins), sorted(members)):
770+
self.assertEqual(found, expected)
771+
772+
def test_set_iam_policy(self):
773+
from google.cloud.bigtable.client import Client
774+
from google.cloud.bigtable_admin_v2.gapic import bigtable_table_admin_client
775+
from google.iam.v1 import policy_pb2
776+
from google.cloud.bigtable.policy import Policy
777+
from google.cloud.bigtable.policy import BIGTABLE_ADMIN_ROLE
778+
779+
credentials = _make_credentials()
780+
client = Client(project=self.PROJECT_ID, credentials=credentials, admin=True)
781+
782+
instance = client.instance(instance_id=self.INSTANCE_ID)
783+
backup = self._make_one(self.BACKUP_ID, instance, cluster_id=self.CLUSTER_ID)
784+
785+
version = 1
786+
etag = b"etag_v1"
787+
members = ["serviceAccount:service_acc1@test.com", "user:user1@test.com"]
788+
bindings = [{"role": BIGTABLE_ADMIN_ROLE, "members": sorted(members)}]
789+
iam_policy_pb = policy_pb2.Policy(version=version, etag=etag, bindings=bindings)
790+
791+
table_api = mock.create_autospec(
792+
bigtable_table_admin_client.BigtableTableAdminClient
793+
)
794+
client._table_admin_client = table_api
795+
table_api.set_iam_policy.return_value = iam_policy_pb
796+
797+
iam_policy = Policy(etag=etag, version=version)
798+
iam_policy[BIGTABLE_ADMIN_ROLE] = [
799+
Policy.user("user1@test.com"),
800+
Policy.service_account("service_acc1@test.com"),
801+
]
802+
803+
result = backup.set_iam_policy(iam_policy)
804+
805+
table_api.set_iam_policy.assert_called_once_with(
806+
resource=backup.name, policy=iam_policy_pb
807+
)
808+
self.assertEqual(result.version, version)
809+
self.assertEqual(result.etag, etag)
810+
811+
admins = result.bigtable_admins
812+
self.assertEqual(len(admins), len(members))
813+
for found, expected in zip(sorted(admins), sorted(members)):
814+
self.assertEqual(found, expected)
815+
816+
def test_test_iam_permissions(self):
817+
from google.cloud.bigtable.client import Client
818+
from google.cloud.bigtable_admin_v2.gapic import bigtable_table_admin_client
819+
from google.iam.v1 import iam_policy_pb2
820+
821+
credentials = _make_credentials()
822+
client = Client(project=self.PROJECT_ID, credentials=credentials, admin=True)
823+
824+
instance = client.instance(instance_id=self.INSTANCE_ID)
825+
backup = self._make_one(self.BACKUP_ID, instance, cluster_id=self.CLUSTER_ID)
826+
827+
permissions = ["bigtable.backups.create", "bigtable.backups.list"]
828+
829+
response = iam_policy_pb2.TestIamPermissionsResponse(permissions=permissions)
830+
831+
table_api = mock.create_autospec(
832+
bigtable_table_admin_client.BigtableTableAdminClient
833+
)
834+
table_api.test_iam_permissions.return_value = response
835+
client._table_admin_client = table_api
836+
837+
result = backup.test_iam_permissions(permissions)
838+
839+
self.assertEqual(result, permissions)
840+
table_api.test_iam_permissions.assert_called_once_with(
841+
resource=backup.name, permissions=permissions
842+
)
843+
737844

738845
class _Client(object):
739846
def __init__(self, project=TestBackup.PROJECT_ID):

0 commit comments

Comments
 (0)