From 4b15e959c1e5185e239b3c99b26b94b5617f1471 Mon Sep 17 00:00:00 2001 From: Tianzi Cai Date: Fri, 10 Jul 2020 15:44:26 -0700 Subject: [PATCH 1/3] samples: add subscription detachment sample --- samples/snippets/README.rst | 13 +++--- samples/snippets/iam.py | 84 +++++++++++++++++++++++++----------- samples/snippets/iam_test.py | 30 ++++++++----- 3 files changed, 86 insertions(+), 41 deletions(-) diff --git a/samples/snippets/README.rst b/samples/snippets/README.rst index 40b2e21fc..8034f330a 100644 --- a/samples/snippets/README.rst +++ b/samples/snippets/README.rst @@ -225,8 +225,8 @@ To run this sample: $ python iam.py usage: iam.py [-h] - project - {get-topic-policy,get-subscription-policy,set-topic-policy,set-subscription-policy,check-topic-permissions,check-subscription-permissions} + project_id + {get-topic-policy,get-subscription-policy,set-topic-policy,set-subscription-policy,check-topic-permissions,check-subscription-permissions,detach-subscription} ... This application demonstrates how to perform basic operations on IAM @@ -236,8 +236,8 @@ To run this sample: at https://cloud.google.com/pubsub/docs. positional arguments: - project Your Google Cloud project ID - {get-topic-policy,get-subscription-policy,set-topic-policy,set-subscription-policy,check-topic-permissions,check-subscription-permissions} + project_id Your Google Cloud project ID + {get-topic-policy,get-subscription-policy,set-topic-policy,set-subscription-policy,check-topic-permissions,check-subscription-permissions,detach-subscription} get-topic-policy Prints the IAM policy for the given topic. get-subscription-policy Prints the IAM policy for the given subscription. @@ -250,6 +250,9 @@ To run this sample: check-subscription-permissions Checks to which permissions are available on the given subscription. + detach-subscription + Detaches a subscription from a topic and drop all + messages retained in it. optional arguments: -h, --help show this help message and exit @@ -273,4 +276,4 @@ to `browse the source`_ and `report issues`_. https://github.com/GoogleCloudPlatform/google-cloud-python/issues -.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file +.. _Google Cloud SDK: https://cloud.google.com/sdk/ diff --git a/samples/snippets/iam.py b/samples/snippets/iam.py index 71c55d764..029cf2594 100644 --- a/samples/snippets/iam.py +++ b/samples/snippets/iam.py @@ -24,17 +24,17 @@ import argparse -def get_topic_policy(project, topic_id): +def get_topic_policy(project_id, topic_id): """Prints the IAM policy for the given topic.""" # [START pubsub_get_topic_policy] from google.cloud import pubsub_v1 - # TODO(developer) + # TODO(developer): Choose an existing topic. # project_id = "your-project-id" # topic_id = "your-topic-id" client = pubsub_v1.PublisherClient() - topic_path = client.topic_path(project, topic_id) + topic_path = client.topic_path(project_id, topic_id) policy = client.get_iam_policy(topic_path) @@ -44,17 +44,17 @@ def get_topic_policy(project, topic_id): # [END pubsub_get_topic_policy] -def get_subscription_policy(project, subscription_id): +def get_subscription_policy(project_id, subscription_id): """Prints the IAM policy for the given subscription.""" # [START pubsub_get_subscription_policy] from google.cloud import pubsub_v1 - # TODO(developer) + # TODO(developer): Choose an existing subscription. # project_id = "your-project-id" # subscription_id = "your-subscription-id" client = pubsub_v1.SubscriberClient() - subscription_path = client.subscription_path(project, subscription_id) + subscription_path = client.subscription_path(project_id, subscription_id) policy = client.get_iam_policy(subscription_path) @@ -66,17 +66,17 @@ def get_subscription_policy(project, subscription_id): # [END pubsub_get_subscription_policy] -def set_topic_policy(project, topic_id): +def set_topic_policy(project_id, topic_id): """Sets the IAM policy for a topic.""" # [START pubsub_set_topic_policy] from google.cloud import pubsub_v1 - # TODO(developer) + # TODO(developer): Choose an existing topic. # project_id = "your-project-id" # topic_id = "your-topic-id" client = pubsub_v1.PublisherClient() - topic_path = client.topic_path(project, topic_id) + topic_path = client.topic_path(project_id, topic_id) policy = client.get_iam_policy(topic_path) @@ -95,17 +95,17 @@ def set_topic_policy(project, topic_id): # [END pubsub_set_topic_policy] -def set_subscription_policy(project, subscription_id): +def set_subscription_policy(project_id, subscription_id): """Sets the IAM policy for a topic.""" # [START pubsub_set_subscription_policy] from google.cloud import pubsub_v1 - # TODO(developer) + # TODO(developer): Choose an existing subscription. # project_id = "your-project-id" # subscription_id = "your-subscription-id" client = pubsub_v1.SubscriberClient() - subscription_path = client.subscription_path(project, subscription_id) + subscription_path = client.subscription_path(project_id, subscription_id) policy = client.get_iam_policy(subscription_path) @@ -124,17 +124,17 @@ def set_subscription_policy(project, subscription_id): # [END pubsub_set_subscription_policy] -def check_topic_permissions(project, topic_id): +def check_topic_permissions(project_id, topic_id): """Checks to which permissions are available on the given topic.""" # [START pubsub_test_topic_permissions] from google.cloud import pubsub_v1 - # TODO(developer) + # TODO(developer): Choose an existing topic. # project_id = "your-project-id" # topic_id = "your-topic-id" client = pubsub_v1.PublisherClient() - topic_path = client.topic_path(project, topic_id) + topic_path = client.topic_path(project_id, topic_id) permissions_to_check = ["pubsub.topics.publish", "pubsub.topics.update"] @@ -146,17 +146,17 @@ def check_topic_permissions(project, topic_id): # [END pubsub_test_topic_permissions] -def check_subscription_permissions(project, subscription_id): +def check_subscription_permissions(project_id, subscription_id): """Checks to which permissions are available on the given subscription.""" # [START pubsub_test_subscription_permissions] from google.cloud import pubsub_v1 - # TODO(developer) + # TODO(developer): Choose an existing subscription. # project_id = "your-project-id" # subscription_id = "your-subscription-id" client = pubsub_v1.SubscriberClient() - subscription_path = client.subscription_path(project, subscription_id) + subscription_path = client.subscription_path(project_id, subscription_id) permissions_to_check = [ "pubsub.subscriptions.consume", @@ -177,11 +177,38 @@ def check_subscription_permissions(project, subscription_id): # [END pubsub_test_subscription_permissions] +def detach_subscription(project_id, subscription_id): + """Detaches a subscription from a topic and drop all messages retained in it.""" + # [START pubsub_detach_subscription] + from google.api_core.exceptions import GoogleAPICallError, RetryError + from google.cloud import pubsub_v1 + + # TODO(developer): Choose an existing subscription. + # project_id = "your-project-id" + # subscription_id = "your-subscription-id" + + publisher_client = pubsub_v1.PublisherClient() + subscriber_client = pubsub_v1.SubscriberClient() + subscription_path = subscriber_client.subscription_path(project_id, subscription_id) + + try: + publisher_client.detach_subscription(subscription_path) + except (GoogleAPICallError, RetryError, ValueError, Exception) as err: + print(err) + + subscription = subscriber_client.get_subscription(subscription_path) + if subscription.detached: + print("Subscription is detached.") + else: + print("Subscription is NOT detached.") + # [END pubsub_detach_subscription] + + if __name__ == "__main__": parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, ) - parser.add_argument("project", help="Your Google Cloud project ID") + parser.add_argument("project_id", help="Your Google Cloud project ID") subparsers = parser.add_subparsers(dest="command") @@ -215,17 +242,24 @@ def check_subscription_permissions(project, subscription_id): ) check_subscription_permissions_parser.add_argument("subscription_id") + detach_subscription_parser = subparsers.add_parser( + "detach-subscription", help=detach_subscription.__doc__, + ) + detach_subscription_parser.add_argument("subscription_id") + args = parser.parse_args() if args.command == "get-topic-policy": - get_topic_policy(args.project, args.topic_id) + get_topic_policy(args.project_id, args.topic_id) elif args.command == "get-subscription-policy": - get_subscription_policy(args.project, args.subscription_id) + get_subscription_policy(args.project_id, args.subscription_id) elif args.command == "set-topic-policy": - set_topic_policy(args.project, args.topic_id) + set_topic_policy(args.project_id, args.topic_id) elif args.command == "set-subscription-policy": - set_subscription_policy(args.project, args.subscription_id) + set_subscription_policy(args.project_id, args.subscription_id) elif args.command == "check-topic-permissions": - check_topic_permissions(args.project, args.topic_id) + check_topic_permissions(args.project_id, args.topic_id) elif args.command == "check-subscription-permissions": - check_subscription_permissions(args.project, args.subscription_id) + check_subscription_permissions(args.project_id, args.subscription_id) + elif args.command == "detach-subscription": + detach_subscription(args.project_id, args.subscription_id) diff --git a/samples/snippets/iam_test.py b/samples/snippets/iam_test.py index d196953f6..e42bc2b4f 100644 --- a/samples/snippets/iam_test.py +++ b/samples/snippets/iam_test.py @@ -21,9 +21,9 @@ import iam UUID = uuid.uuid4().hex -PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] -TOPIC = "iam-test-topic-" + UUID -SUBSCRIPTION = "iam-test-subscription-" + UUID +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] +TOPIC_ID = "iam-test-topic-" + UUID +SUBSCRIPTION_ID = "iam-test-subscription-" + UUID @pytest.fixture(scope="module") @@ -33,7 +33,7 @@ def publisher_client(): @pytest.fixture(scope="module") def topic(publisher_client): - topic_path = publisher_client.topic_path(PROJECT, TOPIC) + topic_path = publisher_client.topic_path(PROJECT_ID, TOPIC_ID) try: publisher_client.delete_topic(topic_path) @@ -56,7 +56,7 @@ def subscriber_client(): @pytest.fixture def subscription(subscriber_client, topic): - subscription_path = subscriber_client.subscription_path(PROJECT, SUBSCRIPTION) + subscription_path = subscriber_client.subscription_path(PROJECT_ID, SUBSCRIPTION_ID) try: subscriber_client.delete_subscription(subscription_path) @@ -71,21 +71,21 @@ def subscription(subscriber_client, topic): def test_get_topic_policy(topic, capsys): - iam.get_topic_policy(PROJECT, TOPIC) + iam.get_topic_policy(PROJECT_ID, TOPIC_ID) out, _ = capsys.readouterr() assert topic in out def test_get_subscription_policy(subscription, capsys): - iam.get_subscription_policy(PROJECT, SUBSCRIPTION) + iam.get_subscription_policy(PROJECT_ID, SUBSCRIPTION_ID) out, _ = capsys.readouterr() assert subscription in out def test_set_topic_policy(publisher_client, topic): - iam.set_topic_policy(PROJECT, TOPIC) + iam.set_topic_policy(PROJECT_ID, TOPIC_ID) policy = publisher_client.get_iam_policy(topic) assert "roles/pubsub.publisher" in str(policy) @@ -93,7 +93,7 @@ def test_set_topic_policy(publisher_client, topic): def test_set_subscription_policy(subscriber_client, subscription): - iam.set_subscription_policy(PROJECT, SUBSCRIPTION) + iam.set_subscription_policy(PROJECT_ID, SUBSCRIPTION_ID) policy = subscriber_client.get_iam_policy(subscription) assert "roles/pubsub.viewer" in str(policy) @@ -101,7 +101,7 @@ def test_set_subscription_policy(subscriber_client, subscription): def test_check_topic_permissions(topic, capsys): - iam.check_topic_permissions(PROJECT, TOPIC) + iam.check_topic_permissions(PROJECT_ID, TOPIC_ID) out, _ = capsys.readouterr() @@ -110,9 +110,17 @@ def test_check_topic_permissions(topic, capsys): def test_check_subscription_permissions(subscription, capsys): - iam.check_subscription_permissions(PROJECT, SUBSCRIPTION) + iam.check_subscription_permissions(PROJECT_ID, SUBSCRIPTION_ID) out, _ = capsys.readouterr() assert subscription in out assert "pubsub.subscriptions.consume" in out + + +def test_detach_subscription(subscription, capsys): + iam.check_subscription_permissions(PROJECT_ID, SUBSCRIPTION_ID) + + out, _ = capsys.readouterr() + + assert "Subscription is detached" in out From 2351d7b739c9cadaae169d071ded9fcefb7cae25 Mon Sep 17 00:00:00 2001 From: Tianzi Cai Date: Fri, 10 Jul 2020 16:16:36 -0700 Subject: [PATCH 2/3] address prad's comments --- samples/snippets/README.rst | 2 +- samples/snippets/iam.py | 2 +- samples/snippets/iam_test.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/snippets/README.rst b/samples/snippets/README.rst index 8034f330a..aac808428 100644 --- a/samples/snippets/README.rst +++ b/samples/snippets/README.rst @@ -251,7 +251,7 @@ To run this sample: Checks to which permissions are available on the given subscription. detach-subscription - Detaches a subscription from a topic and drop all + Detaches a subscription from a topic and drops all messages retained in it. optional arguments: diff --git a/samples/snippets/iam.py b/samples/snippets/iam.py index 029cf2594..6bcc56250 100644 --- a/samples/snippets/iam.py +++ b/samples/snippets/iam.py @@ -178,7 +178,7 @@ def check_subscription_permissions(project_id, subscription_id): def detach_subscription(project_id, subscription_id): - """Detaches a subscription from a topic and drop all messages retained in it.""" + """Detaches a subscription from a topic and drops all messages retained in it.""" # [START pubsub_detach_subscription] from google.api_core.exceptions import GoogleAPICallError, RetryError from google.cloud import pubsub_v1 diff --git a/samples/snippets/iam_test.py b/samples/snippets/iam_test.py index e42bc2b4f..d81a8dcef 100644 --- a/samples/snippets/iam_test.py +++ b/samples/snippets/iam_test.py @@ -119,7 +119,7 @@ def test_check_subscription_permissions(subscription, capsys): def test_detach_subscription(subscription, capsys): - iam.check_subscription_permissions(PROJECT_ID, SUBSCRIPTION_ID) + iam.detach_subscription(PROJECT_ID, SUBSCRIPTION_ID) out, _ = capsys.readouterr() From 1f5fcd8446a18b9dec7c2c5fb0c90e45c14b47ae Mon Sep 17 00:00:00 2001 From: Tianzi Cai Date: Mon, 14 Sep 2020 11:47:17 -0700 Subject: [PATCH 3/3] construct request --- samples/snippets/iam.py | 8 ++++++-- samples/snippets/iam_test.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/samples/snippets/iam.py b/samples/snippets/iam.py index 610453d51..ce443403f 100644 --- a/samples/snippets/iam.py +++ b/samples/snippets/iam.py @@ -196,11 +196,15 @@ def detach_subscription(project_id, subscription_id): subscription_path = subscriber_client.subscription_path(project_id, subscription_id) try: - publisher_client.detach_subscription(subscription_path) + publisher_client.detach_subscription( + request={"subscription": subscription_path} + ) except (GoogleAPICallError, RetryError, ValueError, Exception) as err: print(err) - subscription = subscriber_client.get_subscription(subscription_path) + subscription = subscriber_client.get_subscription( + request={"subscription": subscription_path} + ) if subscription.detached: print("Subscription is detached.") else: diff --git a/samples/snippets/iam_test.py b/samples/snippets/iam_test.py index 2322edd77..033b6ccc7 100644 --- a/samples/snippets/iam_test.py +++ b/samples/snippets/iam_test.py @@ -127,4 +127,4 @@ def test_detach_subscription(subscription, capsys): out, _ = capsys.readouterr() - assert "Subscription is detached" in out + assert "Subscription is detached." in out