Skip to content

Commit

Permalink
Merge pull request #1644 from tseaver/pubsub-subscription-get_iam_policy
Browse files Browse the repository at this point in the history
Add 'Subscription.get_iam_policy' API wrapper.
  • Loading branch information
tseaver committed Mar 22, 2016
2 parents 6d7172a + 21af14c commit c2c9cff
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 0 deletions.
18 changes: 18 additions & 0 deletions docs/pubsub-usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,21 @@ Fetch messages for a pull subscription without blocking (none pending):
>>> messages = [recv[1] for recv in received]
>>> [message.message_id for message in messages]
[]

Fetch the IAM policy for a subscription

.. doctest::

>>> from gcloud import pubsub
>>> client = pubsub.Client()
>>> topic = client.topic('topic_name')
>>> subscription = topic.subscription('subscription_name')
>>> policy = subscription.get_iam_policy() # API request
>>> policy.etag
'DEADBEEF'
>>> policy.owners
['user:phred@example.com']
>>> policy.writers
['systemAccount:abc-1234@systemaccounts.example.com']
>>> policy.readers
['domain:example.com']
20 changes: 20 additions & 0 deletions gcloud/pubsub/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from gcloud.exceptions import NotFound
from gcloud.pubsub._helpers import topic_name_from_path
from gcloud.pubsub.iam import Policy
from gcloud.pubsub.message import Message


Expand Down Expand Up @@ -263,3 +264,22 @@ def delete(self, client=None):
"""
client = self._require_client(client)
client.connection.api_request(method='DELETE', path=self.path)

def get_iam_policy(self, client=None):
"""Fetch the IAM policy for the subscription.
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/getIamPolicy
:type client: :class:`gcloud.pubsub.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current subscription's topic.
:rtype: :class:`gcloud.pubsub.iam.Policy`
:returns: policy created from the resource returned by the
``getIamPolicy`` API request.
"""
client = self._require_client(client)
path = '%s:getIamPolicy' % (self.path,)
resp = client.connection.api_request(method='GET', path=path)
return Policy.from_api_repr(resp)
71 changes: 71 additions & 0 deletions gcloud/pubsub/test_subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,77 @@ def test_delete_w_alternate_client(self):
self.assertEqual(req['method'], 'DELETE')
self.assertEqual(req['path'], '/%s' % SUB_PATH)

def test_get_iam_policy_w_bound_client(self):
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'
POLICY = {
'etag': 'DEADBEEF',
'version': 17,
'bindings': [
{'role': 'roles/owner', 'members': [OWNER1, OWNER2]},
{'role': 'roles/writer', 'members': [WRITER1, WRITER2]},
{'role': 'roles/reader', 'members': [READER1, READER2]},
],
}
PROJECT = 'PROJECT'
TOPIC_NAME = 'topic_name'
SUB_NAME = 'sub_name'
PATH = 'projects/%s/subscriptions/%s:getIamPolicy' % (
PROJECT, SUB_NAME)

conn = _Connection(POLICY)
CLIENT = _Client(project=PROJECT, connection=conn)
topic = _Topic(TOPIC_NAME, client=CLIENT)
subscription = self._makeOne(SUB_NAME, topic)

policy = subscription.get_iam_policy()

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(len(conn._requested), 1)
req = conn._requested[0]
self.assertEqual(req['method'], 'GET')
self.assertEqual(req['path'], '/%s' % PATH)

def test_get_iam_policy_w_alternate_client(self):
POLICY = {
'etag': 'ACAB',
}
PROJECT = 'PROJECT'
TOPIC_NAME = 'topic_name'
SUB_NAME = 'sub_name'
PATH = 'projects/%s/subscriptions/%s:getIamPolicy' % (
PROJECT, SUB_NAME)

conn1 = _Connection()
conn2 = _Connection(POLICY)
CLIENT1 = _Client(project=PROJECT, connection=conn1)
CLIENT2 = _Client(project=PROJECT, connection=conn2)
topic = _Topic(TOPIC_NAME, client=CLIENT1)
subscription = self._makeOne(SUB_NAME, topic)

policy = subscription.get_iam_policy(client=CLIENT2)

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(len(conn1._requested), 0)
self.assertEqual(len(conn2._requested), 1)
req = conn2._requested[0]
self.assertEqual(req['method'], 'GET')
self.assertEqual(req['path'], '/%s' % PATH)


class _Connection(object):

Expand Down

0 comments on commit c2c9cff

Please sign in to comment.