Skip to content

Commit fe773bf

Browse files
committed
Add 'Topic.get_iam_policy' API wrapper.
Toward googleapis#1073.
1 parent 8672837 commit fe773bf

3 files changed

Lines changed: 104 additions & 0 deletions

File tree

docs/pubsub-usage.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,23 @@ Delete a topic:
6666
>>> topic = client.topic('topic_name')
6767
>>> topic.delete() # API request
6868

69+
Fetch the IAM policy for a topic:
70+
71+
.. doctest::
72+
73+
>>> from gcloud import pubsub
74+
>>> client = pubsub.Client()
75+
>>> topic = client.topic('topic_name')
76+
>>> policy = topic.get_iam_policy() # API request
77+
>>> policy.etag
78+
'DEADBEEF'
79+
>>> policy.owners
80+
['user:phred@example.com']
81+
>>> policy.writers
82+
['systemAccount':abc-1234@systemaccounts.example.com']
83+
>>> policy.readers
84+
['doman':example.com']
85+
6986

7087
Publish messages to a topic
7188
---------------------------

gcloud/pubsub/test_topic.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,73 @@ def test_list_subscriptions_missing_key(self):
452452
% (PROJECT, TOPIC_NAME))
453453
self.assertEqual(req['query_params'], {})
454454

455+
def test_get_iam_policy_w_bound_client(self):
456+
OWNER1 = 'user:phred@example.com'
457+
OWNER2 = 'group:cloud-logs@google.com'
458+
WRITER1 = 'domain:google.com'
459+
WRITER2 = 'user:phred@example.com'
460+
READER1 = 'serviceAccount:1234-abcdef@service.example.com'
461+
READER2 = 'user:phred@example.com'
462+
POLICY = {
463+
'etag': 'DEADBEEF',
464+
'version': 17,
465+
'bindings': [
466+
{'role': 'roles/owner', 'members': [OWNER1, OWNER2]},
467+
{'role': 'roles/writer', 'members': [WRITER1, WRITER2]},
468+
{'role': 'roles/reader', 'members': [READER1, READER2]},
469+
],
470+
}
471+
TOPIC_NAME = 'topic_name'
472+
PROJECT = 'PROJECT'
473+
TOPIC_NAME = 'topic_name'
474+
PATH = 'projects/%s/topics/%s:getIamPolicy' % (PROJECT, TOPIC_NAME)
475+
476+
conn = _Connection(POLICY)
477+
CLIENT = _Client(project=PROJECT, connection=conn)
478+
topic = self._makeOne(TOPIC_NAME, client=CLIENT)
479+
480+
policy = topic.get_iam_policy()
481+
482+
self.assertEqual(policy.etag, 'DEADBEEF')
483+
self.assertEqual(policy.version, 17)
484+
self.assertEqual(sorted(policy.owners), [OWNER2, OWNER1])
485+
self.assertEqual(sorted(policy.writers), [WRITER1, WRITER2])
486+
self.assertEqual(sorted(policy.readers), [READER1, READER2])
487+
488+
self.assertEqual(len(conn._requested), 1)
489+
req = conn._requested[0]
490+
self.assertEqual(req['method'], 'GET')
491+
self.assertEqual(req['path'], '/%s' % PATH)
492+
493+
def test_get_iam_policy_w_alternate_client(self):
494+
POLICY = {
495+
'etag': 'ACAB',
496+
}
497+
TOPIC_NAME = 'topic_name'
498+
PROJECT = 'PROJECT'
499+
TOPIC_NAME = 'topic_name'
500+
PATH = 'projects/%s/topics/%s:getIamPolicy' % (PROJECT, TOPIC_NAME)
501+
502+
conn1 = _Connection()
503+
conn2 = _Connection(POLICY)
504+
CLIENT1 = _Client(project=PROJECT, connection=conn1)
505+
CLIENT2 = _Client(project=PROJECT, connection=conn2)
506+
topic = self._makeOne(TOPIC_NAME, client=CLIENT1)
507+
508+
policy = topic.get_iam_policy(client=CLIENT2)
509+
510+
self.assertEqual(policy.etag, 'ACAB')
511+
self.assertEqual(policy.version, None)
512+
self.assertEqual(sorted(policy.owners), [])
513+
self.assertEqual(sorted(policy.writers), [])
514+
self.assertEqual(sorted(policy.readers), [])
515+
516+
self.assertEqual(len(conn1._requested), 0)
517+
self.assertEqual(len(conn2._requested), 1)
518+
req = conn2._requested[0]
519+
self.assertEqual(req['method'], 'GET')
520+
self.assertEqual(req['path'], '/%s' % PATH)
521+
455522

456523
class TestBatch(unittest2.TestCase):
457524

gcloud/pubsub/topic.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from gcloud.exceptions import NotFound
2222
from gcloud.pubsub._helpers import subscription_name_from_path
2323
from gcloud.pubsub._helpers import topic_name_from_path
24+
from gcloud.pubsub.iam import Policy
2425
from gcloud.pubsub.subscription import Subscription
2526

2627

@@ -258,6 +259,25 @@ def list_subscriptions(self, page_size=None, page_token=None, client=None):
258259
subscriptions.append(Subscription(sub_name, self))
259260
return subscriptions, resp.get('nextPageToken')
260261

262+
def get_iam_policy(self, client=None):
263+
"""Fetch the IAM policy for the topic.
264+
265+
See:
266+
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/getIamPolicy
267+
268+
:type client: :class:`gcloud.pubsub.client.Client` or ``NoneType``
269+
:param client: the client to use. If not passed, falls back to the
270+
``client`` stored on the current batch.
271+
272+
:rtype: :class:`gcloud.pubsub.iam.Policy`
273+
:returns: policy created from the resource returned by the
274+
``getIamPolicy`` API request.
275+
"""
276+
client = self._require_client(client)
277+
path = '%s:getIamPolicy' % (self.path,)
278+
resp = client.connection.api_request(method='GET', path=path)
279+
return Policy.from_api_repr(resp)
280+
261281

262282
class Batch(object):
263283
"""Context manager: collect messages to publish via a single API call.

0 commit comments

Comments
 (0)