diff --git a/docs/pubsub-usage.rst b/docs/pubsub-usage.rst index df58f7273ae6..2f74fd584120 100644 --- a/docs/pubsub-usage.rst +++ b/docs/pubsub-usage.rst @@ -99,12 +99,12 @@ Test permissions allowed by the current IAM policy on a topic: .. doctest:: >>> from gcloud import pubsub - >>> from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + >>> from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE >>> client = pubsub.Client() >>> topic = client.topic('topic_name') >>> allowed = topic.check_iam_permissions( - ... [READER_ROLE, WRITER_ROLE, OWNER_ROLE]) # API request - >>> allowed == [READER_ROLE, WRITER_ROLE] + ... [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE]) # API request + >>> allowed == [VIEWER_ROLE, EDITOR_ROLE] True @@ -349,11 +349,11 @@ Test permissions allowed by the current IAM policy on a subscription: .. doctest:: >>> from gcloud import pubsub - >>> from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + >>> from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE >>> client = pubsub.Client() >>> topic = client.topic('topic_name') >>> subscription = topic.subscription('subscription_name') >>> allowed = subscription.check_iam_permissions( - ... [READER_ROLE, WRITER_ROLE, OWNER_ROLE]) # API request - >>> allowed == [READER_ROLE, WRITER_ROLE] + ... [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE]) # API request + >>> allowed == [VIEWER_ROLE, EDITOR_ROLE] True diff --git a/gcloud/pubsub/iam.py b/gcloud/pubsub/iam.py index 1ead9d05ce92..5c9b2eeac603 100644 --- a/gcloud/pubsub/iam.py +++ b/gcloud/pubsub/iam.py @@ -16,10 +16,10 @@ OWNER_ROLE = 'roles/owner' """IAM permission implying all rights to an object.""" -WRITER_ROLE = 'roles/writer' +EDITOR_ROLE = 'roles/editor' """IAM permission implying rights to modify an object.""" -READER_ROLE = 'roles/reader' +VIEWER_ROLE = 'roles/viewer' """IAM permission implying rights to access an object without modifying it.""" @@ -40,8 +40,8 @@ def __init__(self, etag=None, version=None): self.etag = etag self.version = version self.owners = set() - self.writers = set() - self.readers = set() + self.editors = set() + self.viewers = set() @staticmethod def user(email): @@ -127,10 +127,10 @@ def from_api_repr(cls, resource): members = set(binding['members']) if role == OWNER_ROLE: policy.owners = members - elif role == WRITER_ROLE: - policy.writers = members - elif role == READER_ROLE: - policy.readers = members + elif role == EDITOR_ROLE: + policy.editors = members + elif role == VIEWER_ROLE: + policy.viewers = members else: raise ValueError('Unknown role: %s' % (role,)) return policy @@ -155,13 +155,13 @@ def to_api_repr(self): bindings.append( {'role': OWNER_ROLE, 'members': sorted(self.owners)}) - if self.writers: + if self.editors: bindings.append( - {'role': WRITER_ROLE, 'members': sorted(self.writers)}) + {'role': EDITOR_ROLE, 'members': sorted(self.editors)}) - if self.readers: + if self.viewers: bindings.append( - {'role': READER_ROLE, 'members': sorted(self.readers)}) + {'role': VIEWER_ROLE, 'members': sorted(self.viewers)}) if bindings: resource['bindings'] = bindings diff --git a/gcloud/pubsub/subscription.py b/gcloud/pubsub/subscription.py index b9e5ef30834b..fc058c948347 100644 --- a/gcloud/pubsub/subscription.py +++ b/gcloud/pubsub/subscription.py @@ -305,8 +305,9 @@ def set_iam_policy(self, policy, client=None): client = self._require_client(client) path = '%s:setIamPolicy' % (self.path,) resource = policy.to_api_repr() + wrapped = {'policy': resource} resp = client.connection.api_request( - method='POST', path=path, data=resource) + method='POST', path=path, data=wrapped) return Policy.from_api_repr(resp) def check_iam_permissions(self, permissions, client=None): diff --git a/gcloud/pubsub/test_iam.py b/gcloud/pubsub/test_iam.py index d6a6e165e715..4aec6ad14130 100644 --- a/gcloud/pubsub/test_iam.py +++ b/gcloud/pubsub/test_iam.py @@ -29,8 +29,8 @@ def test_ctor_defaults(self): self.assertEqual(policy.etag, None) self.assertEqual(policy.version, None) self.assertEqual(list(policy.owners), []) - self.assertEqual(list(policy.writers), []) - self.assertEqual(list(policy.readers), []) + self.assertEqual(list(policy.editors), []) + self.assertEqual(list(policy.viewers), []) def test_ctor_explicit(self): VERSION = 17 @@ -39,8 +39,8 @@ def test_ctor_explicit(self): self.assertEqual(policy.etag, ETAG) self.assertEqual(policy.version, VERSION) self.assertEqual(list(policy.owners), []) - self.assertEqual(list(policy.writers), []) - self.assertEqual(list(policy.readers), []) + self.assertEqual(list(policy.editors), []) + self.assertEqual(list(policy.viewers), []) def test_user(self): EMAIL = 'phred@example.com' @@ -83,24 +83,24 @@ def test_from_api_repr_only_etag(self): self.assertEqual(policy.etag, 'ACAB') self.assertEqual(policy.version, None) self.assertEqual(list(policy.owners), []) - self.assertEqual(list(policy.writers), []) - self.assertEqual(list(policy.readers), []) + self.assertEqual(list(policy.editors), []) + self.assertEqual(list(policy.viewers), []) def test_from_api_repr_complete(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE OWNER1 = 'user:phred@example.com' OWNER2 = 'group:cloud-logs@google.com' - WRITER1 = 'domain:google.com' - WRITER2 = 'user:phred@example.com' - READER1 = 'serviceAccount:1234-abcdef@service.example.com' - READER2 = 'user:phred@example.com' + EDITOR1 = 'domain:google.com' + EDITOR2 = 'user:phred@example.com' + VIEWER1 = 'serviceAccount:1234-abcdef@service.example.com' + VIEWER2 = 'user:phred@example.com' RESOURCE = { 'etag': 'DEADBEEF', 'version': 17, 'bindings': [ {'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]}, - {'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]}, - {'role': READER_ROLE, 'members': [READER1, READER2]}, + {'role': EDITOR_ROLE, 'members': [EDITOR1, EDITOR2]}, + {'role': VIEWER_ROLE, 'members': [VIEWER1, VIEWER2]}, ], } klass = self._getTargetClass() @@ -108,8 +108,8 @@ def test_from_api_repr_complete(self): self.assertEqual(policy.etag, 'DEADBEEF') self.assertEqual(policy.version, 17) self.assertEqual(sorted(policy.owners), [OWNER2, OWNER1]) - self.assertEqual(sorted(policy.writers), [WRITER1, WRITER2]) - self.assertEqual(sorted(policy.readers), [READER1, READER2]) + self.assertEqual(sorted(policy.editors), [EDITOR1, EDITOR2]) + self.assertEqual(sorted(policy.viewers), [VIEWER1, VIEWER2]) def test_from_api_repr_bad_role(self): BOGUS1 = 'user:phred@example.com' @@ -134,27 +134,27 @@ def test_to_api_repr_only_etag(self): self.assertEqual(policy.to_api_repr(), {'etag': 'DEADBEEF'}) def test_to_api_repr_full(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE OWNER1 = 'group:cloud-logs@google.com' OWNER2 = 'user:phred@example.com' - WRITER1 = 'domain:google.com' - WRITER2 = 'user:phred@example.com' - READER1 = 'serviceAccount:1234-abcdef@service.example.com' - READER2 = 'user:phred@example.com' + EDITOR1 = 'domain:google.com' + EDITOR2 = 'user:phred@example.com' + VIEWER1 = 'serviceAccount:1234-abcdef@service.example.com' + VIEWER2 = 'user:phred@example.com' EXPECTED = { 'etag': 'DEADBEEF', 'version': 17, 'bindings': [ {'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]}, - {'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]}, - {'role': READER_ROLE, 'members': [READER1, READER2]}, + {'role': EDITOR_ROLE, 'members': [EDITOR1, EDITOR2]}, + {'role': VIEWER_ROLE, 'members': [VIEWER1, VIEWER2]}, ], } policy = self._makeOne('DEADBEEF', 17) policy.owners.add(OWNER1) policy.owners.add(OWNER2) - policy.writers.add(WRITER1) - policy.writers.add(WRITER2) - policy.readers.add(READER1) - policy.readers.add(READER2) + policy.editors.add(EDITOR1) + policy.editors.add(EDITOR2) + policy.viewers.add(VIEWER1) + policy.viewers.add(VIEWER2) self.assertEqual(policy.to_api_repr(), EXPECTED) diff --git a/gcloud/pubsub/test_subscription.py b/gcloud/pubsub/test_subscription.py index d4d3b2746e89..1b8ea750643a 100644 --- a/gcloud/pubsub/test_subscription.py +++ b/gcloud/pubsub/test_subscription.py @@ -485,20 +485,20 @@ def test_delete_w_alternate_client(self): self.assertEqual(req['path'], '/%s' % SUB_PATH) def test_get_iam_policy_w_bound_client(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE OWNER1 = 'user:phred@example.com' OWNER2 = 'group:cloud-logs@google.com' - WRITER1 = 'domain:google.com' - WRITER2 = 'user:phred@example.com' - READER1 = 'serviceAccount:1234-abcdef@service.example.com' - READER2 = 'user:phred@example.com' + EDITOR1 = 'domain:google.com' + EDITOR2 = 'user:phred@example.com' + VIEWER1 = 'serviceAccount:1234-abcdef@service.example.com' + VIEWER2 = 'user:phred@example.com' POLICY = { 'etag': 'DEADBEEF', 'version': 17, 'bindings': [ {'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]}, - {'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]}, - {'role': READER_ROLE, 'members': [READER1, READER2]}, + {'role': EDITOR_ROLE, 'members': [EDITOR1, EDITOR2]}, + {'role': VIEWER_ROLE, 'members': [VIEWER1, VIEWER2]}, ], } PROJECT = 'PROJECT' @@ -517,8 +517,8 @@ def test_get_iam_policy_w_bound_client(self): self.assertEqual(policy.etag, 'DEADBEEF') self.assertEqual(policy.version, 17) self.assertEqual(sorted(policy.owners), [OWNER2, OWNER1]) - self.assertEqual(sorted(policy.writers), [WRITER1, WRITER2]) - self.assertEqual(sorted(policy.readers), [READER1, READER2]) + self.assertEqual(sorted(policy.editors), [EDITOR1, EDITOR2]) + self.assertEqual(sorted(policy.viewers), [VIEWER1, VIEWER2]) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] @@ -547,8 +547,8 @@ def test_get_iam_policy_w_alternate_client(self): self.assertEqual(policy.etag, 'ACAB') self.assertEqual(policy.version, None) self.assertEqual(sorted(policy.owners), []) - self.assertEqual(sorted(policy.writers), []) - self.assertEqual(sorted(policy.readers), []) + self.assertEqual(sorted(policy.editors), []) + self.assertEqual(sorted(policy.viewers), []) self.assertEqual(len(conn1._requested), 0) self.assertEqual(len(conn2._requested), 1) @@ -557,21 +557,21 @@ def test_get_iam_policy_w_alternate_client(self): self.assertEqual(req['path'], '/%s' % PATH) def test_set_iam_policy_w_bound_client(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE from gcloud.pubsub.iam import Policy OWNER1 = 'group:cloud-logs@google.com' OWNER2 = 'user:phred@example.com' - WRITER1 = 'domain:google.com' - WRITER2 = 'user:phred@example.com' - READER1 = 'serviceAccount:1234-abcdef@service.example.com' - READER2 = 'user:phred@example.com' + EDITOR1 = 'domain:google.com' + EDITOR2 = 'user:phred@example.com' + VIEWER1 = 'serviceAccount:1234-abcdef@service.example.com' + VIEWER2 = 'user:phred@example.com' POLICY = { 'etag': 'DEADBEEF', 'version': 17, 'bindings': [ {'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]}, - {'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]}, - {'role': READER_ROLE, 'members': [READER1, READER2]}, + {'role': EDITOR_ROLE, 'members': [EDITOR1, EDITOR2]}, + {'role': VIEWER_ROLE, 'members': [VIEWER1, VIEWER2]}, ], } RESPONSE = POLICY.copy() @@ -590,24 +590,24 @@ def test_set_iam_policy_w_bound_client(self): policy = Policy('DEADBEEF', 17) policy.owners.add(OWNER1) policy.owners.add(OWNER2) - policy.writers.add(WRITER1) - policy.writers.add(WRITER2) - policy.readers.add(READER1) - policy.readers.add(READER2) + policy.editors.add(EDITOR1) + policy.editors.add(EDITOR2) + policy.viewers.add(VIEWER1) + policy.viewers.add(VIEWER2) new_policy = subscription.set_iam_policy(policy) self.assertEqual(new_policy.etag, 'ABACABAF') self.assertEqual(new_policy.version, 18) self.assertEqual(sorted(new_policy.owners), [OWNER1, OWNER2]) - self.assertEqual(sorted(new_policy.writers), [WRITER1, WRITER2]) - self.assertEqual(sorted(new_policy.readers), [READER1, READER2]) + self.assertEqual(sorted(new_policy.editors), [EDITOR1, EDITOR2]) + self.assertEqual(sorted(new_policy.viewers), [VIEWER1, VIEWER2]) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] self.assertEqual(req['method'], 'POST') self.assertEqual(req['path'], '/%s' % PATH) - self.assertEqual(req['data'], POLICY) + self.assertEqual(req['data'], {'policy': POLICY}) def test_set_iam_policy_w_alternate_client(self): from gcloud.pubsub.iam import Policy @@ -631,23 +631,24 @@ def test_set_iam_policy_w_alternate_client(self): self.assertEqual(new_policy.etag, 'ACAB') self.assertEqual(new_policy.version, None) self.assertEqual(sorted(new_policy.owners), []) - self.assertEqual(sorted(new_policy.writers), []) - self.assertEqual(sorted(new_policy.readers), []) + self.assertEqual(sorted(new_policy.editors), []) + self.assertEqual(sorted(new_policy.viewers), []) self.assertEqual(len(conn1._requested), 0) self.assertEqual(len(conn2._requested), 1) req = conn2._requested[0] self.assertEqual(req['method'], 'POST') self.assertEqual(req['path'], '/%s' % PATH) - self.assertEqual(req['data'], {}) + self.assertEqual(req['data'], {'policy': {}}) def test_check_iam_permissions_w_bound_client(self): + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE PROJECT = 'PROJECT' TOPIC_NAME = 'topic_name' SUB_NAME = 'sub_name' PATH = 'projects/%s/subscriptions/%s:testIamPermissions' % ( PROJECT, SUB_NAME) - ROLES = ['roles/reader', 'roles/writer', 'roles/owner'] + ROLES = [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE] REQUESTED = { 'permissions': ROLES, } @@ -669,12 +670,13 @@ def test_check_iam_permissions_w_bound_client(self): self.assertEqual(req['data'], REQUESTED) def test_check_iam_permissions_w_alternate_client(self): + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE PROJECT = 'PROJECT' TOPIC_NAME = 'topic_name' SUB_NAME = 'sub_name' PATH = 'projects/%s/subscriptions/%s:testIamPermissions' % ( PROJECT, SUB_NAME) - ROLES = ['roles/reader', 'roles/writer', 'roles/owner'] + ROLES = [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE] REQUESTED = { 'permissions': ROLES, } diff --git a/gcloud/pubsub/test_topic.py b/gcloud/pubsub/test_topic.py index de52cddc1c7f..c6967bfe4b72 100644 --- a/gcloud/pubsub/test_topic.py +++ b/gcloud/pubsub/test_topic.py @@ -453,20 +453,20 @@ def test_list_subscriptions_missing_key(self): self.assertEqual(req['query_params'], {}) def test_get_iam_policy_w_bound_client(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE OWNER1 = 'user:phred@example.com' OWNER2 = 'group:cloud-logs@google.com' - WRITER1 = 'domain:google.com' - WRITER2 = 'user:phred@example.com' - READER1 = 'serviceAccount:1234-abcdef@service.example.com' - READER2 = 'user:phred@example.com' + EDITOR1 = 'domain:google.com' + EDITOR2 = 'user:phred@example.com' + VIEWER1 = 'serviceAccount:1234-abcdef@service.example.com' + VIEWER2 = 'user:phred@example.com' POLICY = { 'etag': 'DEADBEEF', 'version': 17, 'bindings': [ {'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]}, - {'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]}, - {'role': READER_ROLE, 'members': [READER1, READER2]}, + {'role': EDITOR_ROLE, 'members': [EDITOR1, EDITOR2]}, + {'role': VIEWER_ROLE, 'members': [VIEWER1, VIEWER2]}, ], } TOPIC_NAME = 'topic_name' @@ -483,8 +483,8 @@ def test_get_iam_policy_w_bound_client(self): self.assertEqual(policy.etag, 'DEADBEEF') self.assertEqual(policy.version, 17) self.assertEqual(sorted(policy.owners), [OWNER2, OWNER1]) - self.assertEqual(sorted(policy.writers), [WRITER1, WRITER2]) - self.assertEqual(sorted(policy.readers), [READER1, READER2]) + self.assertEqual(sorted(policy.editors), [EDITOR1, EDITOR2]) + self.assertEqual(sorted(policy.viewers), [VIEWER1, VIEWER2]) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] @@ -511,8 +511,8 @@ def test_get_iam_policy_w_alternate_client(self): self.assertEqual(policy.etag, 'ACAB') self.assertEqual(policy.version, None) self.assertEqual(sorted(policy.owners), []) - self.assertEqual(sorted(policy.writers), []) - self.assertEqual(sorted(policy.readers), []) + self.assertEqual(sorted(policy.editors), []) + self.assertEqual(sorted(policy.viewers), []) self.assertEqual(len(conn1._requested), 0) self.assertEqual(len(conn2._requested), 1) @@ -522,20 +522,20 @@ def test_get_iam_policy_w_alternate_client(self): def test_set_iam_policy_w_bound_client(self): from gcloud.pubsub.iam import Policy - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE OWNER1 = 'group:cloud-logs@google.com' OWNER2 = 'user:phred@example.com' - WRITER1 = 'domain:google.com' - WRITER2 = 'user:phred@example.com' - READER1 = 'serviceAccount:1234-abcdef@service.example.com' - READER2 = 'user:phred@example.com' + EDITOR1 = 'domain:google.com' + EDITOR2 = 'user:phred@example.com' + VIEWER1 = 'serviceAccount:1234-abcdef@service.example.com' + VIEWER2 = 'user:phred@example.com' POLICY = { 'etag': 'DEADBEEF', 'version': 17, 'bindings': [ {'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]}, - {'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]}, - {'role': READER_ROLE, 'members': [READER1, READER2]}, + {'role': EDITOR_ROLE, 'members': [EDITOR1, EDITOR2]}, + {'role': VIEWER_ROLE, 'members': [VIEWER1, VIEWER2]}, ], } RESPONSE = POLICY.copy() @@ -552,24 +552,24 @@ def test_set_iam_policy_w_bound_client(self): policy = Policy('DEADBEEF', 17) policy.owners.add(OWNER1) policy.owners.add(OWNER2) - policy.writers.add(WRITER1) - policy.writers.add(WRITER2) - policy.readers.add(READER1) - policy.readers.add(READER2) + policy.editors.add(EDITOR1) + policy.editors.add(EDITOR2) + policy.viewers.add(VIEWER1) + policy.viewers.add(VIEWER2) new_policy = topic.set_iam_policy(policy) self.assertEqual(new_policy.etag, 'ABACABAF') self.assertEqual(new_policy.version, 18) self.assertEqual(sorted(new_policy.owners), [OWNER1, OWNER2]) - self.assertEqual(sorted(new_policy.writers), [WRITER1, WRITER2]) - self.assertEqual(sorted(new_policy.readers), [READER1, READER2]) + self.assertEqual(sorted(new_policy.editors), [EDITOR1, EDITOR2]) + self.assertEqual(sorted(new_policy.viewers), [VIEWER1, VIEWER2]) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] self.assertEqual(req['method'], 'POST') self.assertEqual(req['path'], '/%s' % PATH) - self.assertEqual(req['data'], POLICY) + self.assertEqual(req['data'], {'policy': POLICY}) def test_set_iam_policy_w_alternate_client(self): from gcloud.pubsub.iam import Policy @@ -591,23 +591,23 @@ def test_set_iam_policy_w_alternate_client(self): self.assertEqual(new_policy.etag, 'ACAB') self.assertEqual(new_policy.version, None) self.assertEqual(sorted(new_policy.owners), []) - self.assertEqual(sorted(new_policy.writers), []) - self.assertEqual(sorted(new_policy.readers), []) + self.assertEqual(sorted(new_policy.editors), []) + self.assertEqual(sorted(new_policy.viewers), []) self.assertEqual(len(conn1._requested), 0) self.assertEqual(len(conn2._requested), 1) req = conn2._requested[0] self.assertEqual(req['method'], 'POST') self.assertEqual(req['path'], '/%s' % PATH) - self.assertEqual(req['data'], {}) + self.assertEqual(req['data'], {'policy': {}}) def test_check_iam_permissions_w_bound_client(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE TOPIC_NAME = 'topic_name' PROJECT = 'PROJECT' PATH = 'projects/%s/topics/%s:testIamPermissions' % ( PROJECT, TOPIC_NAME) - ROLES = [READER_ROLE, WRITER_ROLE, OWNER_ROLE] + ROLES = [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE] REQUESTED = { 'permissions': ROLES, } @@ -628,12 +628,12 @@ def test_check_iam_permissions_w_bound_client(self): self.assertEqual(req['data'], REQUESTED) def test_check_iam_permissions_w_alternate_client(self): - from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE + from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE TOPIC_NAME = 'topic_name' PROJECT = 'PROJECT' PATH = 'projects/%s/topics/%s:testIamPermissions' % ( PROJECT, TOPIC_NAME) - ROLES = [READER_ROLE, WRITER_ROLE, OWNER_ROLE] + ROLES = [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE] REQUESTED = { 'permissions': ROLES, } diff --git a/gcloud/pubsub/topic.py b/gcloud/pubsub/topic.py index 859a84c93d29..5e442afeeb59 100644 --- a/gcloud/pubsub/topic.py +++ b/gcloud/pubsub/topic.py @@ -299,8 +299,9 @@ def set_iam_policy(self, policy, client=None): client = self._require_client(client) path = '%s:setIamPolicy' % (self.path,) resource = policy.to_api_repr() + wrapped = {'policy': resource} resp = client.connection.api_request( - method='POST', path=path, data=resource) + method='POST', path=path, data=wrapped) return Policy.from_api_repr(resp) def check_iam_permissions(self, permissions, client=None): diff --git a/system_tests/pubsub.py b/system_tests/pubsub.py index 956a788c6d36..813be010dc78 100644 --- a/system_tests/pubsub.py +++ b/system_tests/pubsub.py @@ -89,7 +89,7 @@ def test_create_subscription_defaults(self): self.assertFalse(topic.exists()) topic.create() self.to_delete.append(topic) - SUBSCRIPTION_NAME = 'subscribing-now' + SUBSCRIPTION_NAME = 'subscribing-now-%d' % (1000 * time.time(),) subscription = topic.subscription(SUBSCRIPTION_NAME) self.assertFalse(subscription.exists()) subscription.create() @@ -103,7 +103,7 @@ def test_create_subscription_w_ack_deadline(self): self.assertFalse(topic.exists()) topic.create() self.to_delete.append(topic) - SUBSCRIPTION_NAME = 'subscribing-now' + SUBSCRIPTION_NAME = 'subscribing-now-%d' % (1000 * time.time(),) subscription = topic.subscription(SUBSCRIPTION_NAME, ack_deadline=120) self.assertFalse(subscription.exists()) subscription.create() @@ -142,7 +142,7 @@ def test_message_pull_mode_e2e(self): self.assertFalse(topic.exists()) topic.create() self.to_delete.append(topic) - SUBSCRIPTION_NAME = 'subscribing-now' + SUBSCRIPTION_NAME = 'subscribing-now-%d' % (1000 * time.time(),) subscription = topic.subscription(SUBSCRIPTION_NAME) self.assertFalse(subscription.exists()) subscription.create() @@ -168,3 +168,42 @@ def _by_timestamp(message): self.assertEqual(message1.attributes['extra'], EXTRA_1) self.assertEqual(message2.data, MESSAGE_2) self.assertEqual(message2.attributes['extra'], EXTRA_2) + + def test_topic_iam_policy(self): + topic_name = 'test-topic-iam-policy-topic-%d' % (1000 * time.time(),) + topic = Config.CLIENT.topic(topic_name) + topic.create() + count = 5 + while count > 0 and not topic.exists(): + time.sleep(1) + count -= 1 + self.assertTrue(topic.exists()) + self.to_delete.append(topic) + policy = topic.get_iam_policy() + policy.readers.add(policy.user('jjg@google.com')) + new_policy = topic.set_iam_policy(policy) + self.assertEqual(new_policy.readers, policy.readers) + + def test_subscription_iam_policy(self): + topic_name = 'test-sub-iam-policy-topic-%d' % (1000 * time.time(),) + topic = Config.CLIENT.topic(topic_name) + topic.create() + count = 5 + while count > 0 and not topic.exists(): + time.sleep(1) + count -= 1 + self.assertTrue(topic.exists()) + self.to_delete.append(topic) + SUB_NAME = 'test-sub-iam-policy-sub-%d' % (1000 * time.time(),) + subscription = topic.subscription(SUB_NAME) + subscription.create() + count = 5 + while count > 0 and not subscription.exists(): + time.sleep(1) + count -= 1 + self.assertTrue(subscription.exists()) + self.to_delete.insert(0, subscription) + policy = subscription.get_iam_policy() + policy.readers.add(policy.user('jjg@google.com')) + new_policy = subscription.set_iam_policy(policy) + self.assertEqual(new_policy.readers, policy.readers)