Skip to content

Commit 21cfae6

Browse files
committed
Add system tests for topic/subscription IAM policy get/set methods.
1 parent 4ccb7a1 commit 21cfae6

File tree

8 files changed

+84
-45
lines changed

8 files changed

+84
-45
lines changed

docs/pubsub-usage.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ Test permissions allowed by the current IAM policy on a topic:
9999
.. doctest::
100100

101101
>>> from gcloud import pubsub
102-
>>> from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
102+
>>> from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
103103
>>> client = pubsub.Client()
104104
>>> topic = client.topic('topic_name')
105105
>>> allowed = topic.check_iam_permissions(
106-
... [READER_ROLE, WRITER_ROLE, OWNER_ROLE]) # API request
107-
>>> allowed == [READER_ROLE, WRITER_ROLE]
106+
... [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE]) # API request
107+
>>> allowed == [VIEWER_ROLE, EDITOR_ROLE]
108108
True
109109

110110

@@ -349,11 +349,11 @@ Test permissions allowed by the current IAM policy on a subscription:
349349
.. doctest::
350350

351351
>>> from gcloud import pubsub
352-
>>> from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
352+
>>> from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
353353
>>> client = pubsub.Client()
354354
>>> topic = client.topic('topic_name')
355355
>>> subscription = topic.subscription('subscription_name')
356356
>>> allowed = subscription.check_iam_permissions(
357-
... [READER_ROLE, WRITER_ROLE, OWNER_ROLE]) # API request
358-
>>> allowed == [READER_ROLE, WRITER_ROLE]
357+
... [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE]) # API request
358+
>>> allowed == [VIEWER_ROLE, EDITOR_ROLE]
359359
True

gcloud/pubsub/iam.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
OWNER_ROLE = 'roles/owner'
1717
"""IAM permission implying all rights to an object."""
1818

19-
WRITER_ROLE = 'roles/writer'
19+
EDITOR_ROLE = 'roles/editor'
2020
"""IAM permission implying rights to modify an object."""
2121

22-
READER_ROLE = 'roles/reader'
22+
VIEWER_ROLE = 'roles/viewer'
2323
"""IAM permission implying rights to access an object without modifying it."""
2424

2525

@@ -127,9 +127,9 @@ def from_api_repr(cls, resource):
127127
members = set(binding['members'])
128128
if role == OWNER_ROLE:
129129
policy.owners = members
130-
elif role == WRITER_ROLE:
130+
elif role == EDITOR_ROLE:
131131
policy.writers = members
132-
elif role == READER_ROLE:
132+
elif role == VIEWER_ROLE:
133133
policy.readers = members
134134
else:
135135
raise ValueError('Unknown role: %s' % (role,))
@@ -157,11 +157,11 @@ def to_api_repr(self):
157157

158158
if self.writers:
159159
bindings.append(
160-
{'role': WRITER_ROLE, 'members': sorted(self.writers)})
160+
{'role': EDITOR_ROLE, 'members': sorted(self.writers)})
161161

162162
if self.readers:
163163
bindings.append(
164-
{'role': READER_ROLE, 'members': sorted(self.readers)})
164+
{'role': VIEWER_ROLE, 'members': sorted(self.readers)})
165165

166166
if bindings:
167167
resource['bindings'] = bindings

gcloud/pubsub/subscription.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,9 @@ def set_iam_policy(self, policy, client=None):
305305
client = self._require_client(client)
306306
path = '%s:setIamPolicy' % (self.path,)
307307
resource = policy.to_api_repr()
308+
wrapped = {'policy': resource}
308309
resp = client.connection.api_request(
309-
method='POST', path=path, data=resource)
310+
method='POST', path=path, data=wrapped)
310311
return Policy.from_api_repr(resp)
311312

312313
def check_iam_permissions(self, permissions, client=None):

gcloud/pubsub/test_iam.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def test_from_api_repr_only_etag(self):
8787
self.assertEqual(list(policy.readers), [])
8888

8989
def test_from_api_repr_complete(self):
90-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
90+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
9191
OWNER1 = 'user:phred@example.com'
9292
OWNER2 = 'group:cloud-logs@google.com'
9393
WRITER1 = 'domain:google.com'
@@ -99,8 +99,8 @@ def test_from_api_repr_complete(self):
9999
'version': 17,
100100
'bindings': [
101101
{'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]},
102-
{'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]},
103-
{'role': READER_ROLE, 'members': [READER1, READER2]},
102+
{'role': EDITOR_ROLE, 'members': [WRITER1, WRITER2]},
103+
{'role': VIEWER_ROLE, 'members': [READER1, READER2]},
104104
],
105105
}
106106
klass = self._getTargetClass()
@@ -134,7 +134,7 @@ def test_to_api_repr_only_etag(self):
134134
self.assertEqual(policy.to_api_repr(), {'etag': 'DEADBEEF'})
135135

136136
def test_to_api_repr_full(self):
137-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
137+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
138138
OWNER1 = 'group:cloud-logs@google.com'
139139
OWNER2 = 'user:phred@example.com'
140140
WRITER1 = 'domain:google.com'
@@ -146,8 +146,8 @@ def test_to_api_repr_full(self):
146146
'version': 17,
147147
'bindings': [
148148
{'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]},
149-
{'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]},
150-
{'role': READER_ROLE, 'members': [READER1, READER2]},
149+
{'role': EDITOR_ROLE, 'members': [WRITER1, WRITER2]},
150+
{'role': VIEWER_ROLE, 'members': [READER1, READER2]},
151151
],
152152
}
153153
policy = self._makeOne('DEADBEEF', 17)

gcloud/pubsub/test_subscription.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def test_delete_w_alternate_client(self):
485485
self.assertEqual(req['path'], '/%s' % SUB_PATH)
486486

487487
def test_get_iam_policy_w_bound_client(self):
488-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
488+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
489489
OWNER1 = 'user:phred@example.com'
490490
OWNER2 = 'group:cloud-logs@google.com'
491491
WRITER1 = 'domain:google.com'
@@ -497,8 +497,8 @@ def test_get_iam_policy_w_bound_client(self):
497497
'version': 17,
498498
'bindings': [
499499
{'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]},
500-
{'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]},
501-
{'role': READER_ROLE, 'members': [READER1, READER2]},
500+
{'role': EDITOR_ROLE, 'members': [WRITER1, WRITER2]},
501+
{'role': VIEWER_ROLE, 'members': [READER1, READER2]},
502502
],
503503
}
504504
PROJECT = 'PROJECT'
@@ -557,7 +557,7 @@ def test_get_iam_policy_w_alternate_client(self):
557557
self.assertEqual(req['path'], '/%s' % PATH)
558558

559559
def test_set_iam_policy_w_bound_client(self):
560-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
560+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
561561
from gcloud.pubsub.iam import Policy
562562
OWNER1 = 'group:cloud-logs@google.com'
563563
OWNER2 = 'user:phred@example.com'
@@ -570,8 +570,8 @@ def test_set_iam_policy_w_bound_client(self):
570570
'version': 17,
571571
'bindings': [
572572
{'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]},
573-
{'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]},
574-
{'role': READER_ROLE, 'members': [READER1, READER2]},
573+
{'role': EDITOR_ROLE, 'members': [WRITER1, WRITER2]},
574+
{'role': VIEWER_ROLE, 'members': [READER1, READER2]},
575575
],
576576
}
577577
RESPONSE = POLICY.copy()
@@ -607,7 +607,7 @@ def test_set_iam_policy_w_bound_client(self):
607607
req = conn._requested[0]
608608
self.assertEqual(req['method'], 'POST')
609609
self.assertEqual(req['path'], '/%s' % PATH)
610-
self.assertEqual(req['data'], POLICY)
610+
self.assertEqual(req['data'], {'policy': POLICY})
611611

612612
def test_set_iam_policy_w_alternate_client(self):
613613
from gcloud.pubsub.iam import Policy
@@ -639,15 +639,15 @@ def test_set_iam_policy_w_alternate_client(self):
639639
req = conn2._requested[0]
640640
self.assertEqual(req['method'], 'POST')
641641
self.assertEqual(req['path'], '/%s' % PATH)
642-
self.assertEqual(req['data'], {})
642+
self.assertEqual(req['data'], {'policy': {}})
643643

644644
def test_check_iam_permissions_w_bound_client(self):
645645
PROJECT = 'PROJECT'
646646
TOPIC_NAME = 'topic_name'
647647
SUB_NAME = 'sub_name'
648648
PATH = 'projects/%s/subscriptions/%s:testIamPermissions' % (
649649
PROJECT, SUB_NAME)
650-
ROLES = ['roles/reader', 'roles/writer', 'roles/owner']
650+
ROLES = ['roles/viewer', 'roles/editor', 'roles/owner']
651651
REQUESTED = {
652652
'permissions': ROLES,
653653
}
@@ -674,7 +674,7 @@ def test_check_iam_permissions_w_alternate_client(self):
674674
SUB_NAME = 'sub_name'
675675
PATH = 'projects/%s/subscriptions/%s:testIamPermissions' % (
676676
PROJECT, SUB_NAME)
677-
ROLES = ['roles/reader', 'roles/writer', 'roles/owner']
677+
ROLES = ['roles/viewer', 'roles/editor', 'roles/owner']
678678
REQUESTED = {
679679
'permissions': ROLES,
680680
}

gcloud/pubsub/test_topic.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ def test_list_subscriptions_missing_key(self):
453453
self.assertEqual(req['query_params'], {})
454454

455455
def test_get_iam_policy_w_bound_client(self):
456-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
456+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
457457
OWNER1 = 'user:phred@example.com'
458458
OWNER2 = 'group:cloud-logs@google.com'
459459
WRITER1 = 'domain:google.com'
@@ -465,8 +465,8 @@ def test_get_iam_policy_w_bound_client(self):
465465
'version': 17,
466466
'bindings': [
467467
{'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]},
468-
{'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]},
469-
{'role': READER_ROLE, 'members': [READER1, READER2]},
468+
{'role': EDITOR_ROLE, 'members': [WRITER1, WRITER2]},
469+
{'role': VIEWER_ROLE, 'members': [READER1, READER2]},
470470
],
471471
}
472472
TOPIC_NAME = 'topic_name'
@@ -522,7 +522,7 @@ def test_get_iam_policy_w_alternate_client(self):
522522

523523
def test_set_iam_policy_w_bound_client(self):
524524
from gcloud.pubsub.iam import Policy
525-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
525+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
526526
OWNER1 = 'group:cloud-logs@google.com'
527527
OWNER2 = 'user:phred@example.com'
528528
WRITER1 = 'domain:google.com'
@@ -534,8 +534,8 @@ def test_set_iam_policy_w_bound_client(self):
534534
'version': 17,
535535
'bindings': [
536536
{'role': OWNER_ROLE, 'members': [OWNER1, OWNER2]},
537-
{'role': WRITER_ROLE, 'members': [WRITER1, WRITER2]},
538-
{'role': READER_ROLE, 'members': [READER1, READER2]},
537+
{'role': EDITOR_ROLE, 'members': [WRITER1, WRITER2]},
538+
{'role': VIEWER_ROLE, 'members': [READER1, READER2]},
539539
],
540540
}
541541
RESPONSE = POLICY.copy()
@@ -569,7 +569,7 @@ def test_set_iam_policy_w_bound_client(self):
569569
req = conn._requested[0]
570570
self.assertEqual(req['method'], 'POST')
571571
self.assertEqual(req['path'], '/%s' % PATH)
572-
self.assertEqual(req['data'], POLICY)
572+
self.assertEqual(req['data'], {'policy': POLICY})
573573

574574
def test_set_iam_policy_w_alternate_client(self):
575575
from gcloud.pubsub.iam import Policy
@@ -599,15 +599,15 @@ def test_set_iam_policy_w_alternate_client(self):
599599
req = conn2._requested[0]
600600
self.assertEqual(req['method'], 'POST')
601601
self.assertEqual(req['path'], '/%s' % PATH)
602-
self.assertEqual(req['data'], {})
602+
self.assertEqual(req['data'], {'policy': {}})
603603

604604
def test_check_iam_permissions_w_bound_client(self):
605-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
605+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
606606
TOPIC_NAME = 'topic_name'
607607
PROJECT = 'PROJECT'
608608
PATH = 'projects/%s/topics/%s:testIamPermissions' % (
609609
PROJECT, TOPIC_NAME)
610-
ROLES = [READER_ROLE, WRITER_ROLE, OWNER_ROLE]
610+
ROLES = [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE]
611611
REQUESTED = {
612612
'permissions': ROLES,
613613
}
@@ -628,12 +628,12 @@ def test_check_iam_permissions_w_bound_client(self):
628628
self.assertEqual(req['data'], REQUESTED)
629629

630630
def test_check_iam_permissions_w_alternate_client(self):
631-
from gcloud.pubsub.iam import OWNER_ROLE, WRITER_ROLE, READER_ROLE
631+
from gcloud.pubsub.iam import OWNER_ROLE, EDITOR_ROLE, VIEWER_ROLE
632632
TOPIC_NAME = 'topic_name'
633633
PROJECT = 'PROJECT'
634634
PATH = 'projects/%s/topics/%s:testIamPermissions' % (
635635
PROJECT, TOPIC_NAME)
636-
ROLES = [READER_ROLE, WRITER_ROLE, OWNER_ROLE]
636+
ROLES = [VIEWER_ROLE, EDITOR_ROLE, OWNER_ROLE]
637637
REQUESTED = {
638638
'permissions': ROLES,
639639
}

gcloud/pubsub/topic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,9 @@ def set_iam_policy(self, policy, client=None):
299299
client = self._require_client(client)
300300
path = '%s:setIamPolicy' % (self.path,)
301301
resource = policy.to_api_repr()
302+
wrapped = {'policy': resource}
302303
resp = client.connection.api_request(
303-
method='POST', path=path, data=resource)
304+
method='POST', path=path, data=wrapped)
304305
return Policy.from_api_repr(resp)
305306

306307
def check_iam_permissions(self, permissions, client=None):

system_tests/pubsub.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test_create_subscription_defaults(self):
8989
self.assertFalse(topic.exists())
9090
topic.create()
9191
self.to_delete.append(topic)
92-
SUBSCRIPTION_NAME = 'subscribing-now'
92+
SUBSCRIPTION_NAME = 'subscribing-now-%d' % (1000 * time.time(),)
9393
subscription = topic.subscription(SUBSCRIPTION_NAME)
9494
self.assertFalse(subscription.exists())
9595
subscription.create()
@@ -103,7 +103,7 @@ def test_create_subscription_w_ack_deadline(self):
103103
self.assertFalse(topic.exists())
104104
topic.create()
105105
self.to_delete.append(topic)
106-
SUBSCRIPTION_NAME = 'subscribing-now'
106+
SUBSCRIPTION_NAME = 'subscribing-now-%d' % (1000 * time.time(),)
107107
subscription = topic.subscription(SUBSCRIPTION_NAME, ack_deadline=120)
108108
self.assertFalse(subscription.exists())
109109
subscription.create()
@@ -142,7 +142,7 @@ def test_message_pull_mode_e2e(self):
142142
self.assertFalse(topic.exists())
143143
topic.create()
144144
self.to_delete.append(topic)
145-
SUBSCRIPTION_NAME = 'subscribing-now'
145+
SUBSCRIPTION_NAME = 'subscribing-now-%d' % (1000 * time.time(),)
146146
subscription = topic.subscription(SUBSCRIPTION_NAME)
147147
self.assertFalse(subscription.exists())
148148
subscription.create()
@@ -168,3 +168,40 @@ def _by_timestamp(message):
168168
self.assertEqual(message1.attributes['extra'], EXTRA_1)
169169
self.assertEqual(message2.data, MESSAGE_2)
170170
self.assertEqual(message2.attributes['extra'], EXTRA_2)
171+
172+
def test_topic_iam_policy(self):
173+
topic_name = 'test-topic-iam-policy-topic-%d' % (1000 * time.time(),)
174+
topic = Config.CLIENT.topic(topic_name)
175+
topic.create()
176+
count = 5
177+
while count > 0 and not topic.exists():
178+
time.sleep(1)
179+
count -= 1
180+
self.to_delete.append(topic)
181+
policy = topic.get_iam_policy()
182+
policy.readers.add(policy.user('jjg@google.com'))
183+
new_policy = topic.set_iam_policy(policy)
184+
self.assertEqual(new_policy.readers, policy.readers)
185+
186+
def test_subscription_iam_policy(self):
187+
topic_name = 'test-sub-iam-policy-topic-%d' % (1000 * time.time(),)
188+
topic = Config.CLIENT.topic(topic_name)
189+
topic.create()
190+
count = 5
191+
while count > 0 and not topic.exists():
192+
time.sleep(1)
193+
count -= 1
194+
self.assertTrue(topic.exists())
195+
self.to_delete.append(topic)
196+
SUB_NAME = 'test-sub-iam-policy-sub-%d' % (1000 * time.time(),)
197+
subscription = topic.subscription(SUB_NAME)
198+
subscription.create()
199+
count = 5
200+
while count > 0 and not subscription.exists():
201+
time.sleep(1)
202+
count -= 1
203+
self.to_delete.insert(0, subscription)
204+
policy = subscription.get_iam_policy()
205+
policy.readers.add(policy.user('jjg@google.com'))
206+
new_policy = subscription.set_iam_policy(policy)
207+
self.assertEqual(new_policy.readers, policy.readers)

0 commit comments

Comments
 (0)