Skip to content

Commit 63ea9b2

Browse files
Remove old quickstart (GoogleCloudPlatform#4706)
Remove old Quickstart The [new Quickstart](https://cloud.google.com/iam/docs/quickstart-client-libraries) is published , so we can remove the old Quickstart now. This PR also updates the test name for queryGrantableRoles to better reflect what the test is for. - [X] Please **merge** this PR for me once it is approved. * **Please coordinate with me though** because I need to publish a CL to update the documentation shortly after.
1 parent 31ee2bd commit 63ea9b2

File tree

5 files changed

+185
-257
lines changed

5 files changed

+185
-257
lines changed

iam/api-client/grantable_roles_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import grantable_roles
1818

1919

20-
def test_service_accounts(capsys):
20+
def test_grantable_roles(capsys):
2121
project = os.environ['GOOGLE_CLOUD_PROJECT']
2222
resource = '//cloudresourcemanager.googleapis.com/projects/' + project
2323
grantable_roles.view_grantable_roles(resource)

iam/api-client/quickstart.py

+100-27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
2-
3-
# Copyright 2018 Google Inc. All Rights Reserved.
2+
#
3+
# Copyright 2020 Google Inc. All Rights Reserved.
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
66
# you may not use this file except in compliance with the License.
@@ -14,38 +14,111 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
# [START iam_quickstart]
18+
import os
19+
20+
from google.oauth2 import service_account
21+
import googleapiclient.discovery
22+
23+
24+
def quickstart(project_id, member):
25+
"""Gets a policy, adds a member, prints their permissions, and removes the member."""
26+
27+
# Role to be granted.
28+
role = "roles/logging.logWriter"
1729

18-
def quickstart():
19-
# [START iam_quickstart]
20-
import os
30+
# Initializes service.
31+
crm_service = initialize_service()
2132

22-
from google.oauth2 import service_account
23-
import googleapiclient.discovery
33+
# Grants your member the 'Log Writer' role for the project.
34+
modify_policy_add_role(crm_service, project_id, role, member)
35+
36+
# Gets the project's policy and prints all members with the 'Log Writer' role.
37+
policy = get_policy(crm_service, project_id)
38+
binding = next(b for b in policy["bindings"] if b["role"] == role)
39+
print(f'Role: {(binding["role"])}')
40+
print("Members: ")
41+
for m in binding["members"]:
42+
print(f'[{m}]')
43+
44+
# Removes the member from the 'Log Writer' role.
45+
modify_policy_remove_member(crm_service, project_id, role, member)
46+
47+
48+
def initialize_service():
49+
"""Initializes a Cloud Resource Manager service."""
2450

25-
# Get credentials
2651
credentials = service_account.Credentials.from_service_account_file(
27-
filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'],
28-
scopes=['https://www.googleapis.com/auth/cloud-platform'])
52+
filename=os.environ["GOOGLE_APPLICATION_CREDENTIALS"],
53+
scopes=["https://www.googleapis.com/auth/cloud-platform"],
54+
)
55+
crm_service = googleapiclient.discovery.build(
56+
"cloudresourcemanager", "v1", credentials=credentials
57+
)
58+
return crm_service
59+
60+
61+
def modify_policy_add_role(crm_service, project_id, role, member):
62+
"""Adds a new role binding to a policy."""
2963

30-
# Create the Cloud IAM service object
31-
service = googleapiclient.discovery.build(
32-
'iam', 'v1', credentials=credentials)
64+
policy = get_policy(crm_service, project_id)
3365

34-
# Call the Cloud IAM Roles API
35-
# If using pylint, disable weak-typing warnings
36-
# pylint: disable=no-member
37-
response = service.roles().list().execute()
38-
roles = response['roles']
66+
binding = None
67+
for b in policy["bindings"]:
68+
if b["role"] == role:
69+
binding = b
70+
break
71+
if binding is not None:
72+
binding["members"].append(member)
73+
else:
74+
binding = {"role": role, "members": [member]}
75+
policy["bindings"].append(binding)
3976

40-
# Process the response
41-
for role in roles:
42-
print('Title: ' + role['title'])
43-
print('Name: ' + role['name'])
44-
if 'description' in role:
45-
print('Description: ' + role['description'])
46-
print('')
47-
# [END iam_quickstart]
77+
set_policy(crm_service, project_id, policy)
78+
79+
80+
def modify_policy_remove_member(crm_service, project_id, role, member):
81+
"""Removes a member from a role binding."""
82+
83+
policy = get_policy(crm_service, project_id)
84+
85+
binding = next(b for b in policy["bindings"] if b["role"] == role)
86+
if "members" in binding and member in binding["members"]:
87+
binding["members"].remove(member)
88+
89+
set_policy(crm_service, project_id, policy)
90+
91+
92+
def get_policy(crm_service, project_id, version=3):
93+
"""Gets IAM policy for a project."""
94+
95+
policy = (
96+
crm_service.projects()
97+
.getIamPolicy(
98+
resource=project_id,
99+
body={"options": {"requestedPolicyVersion": version}},
100+
)
101+
.execute()
102+
)
103+
return policy
104+
105+
106+
def set_policy(crm_service, project_id, policy):
107+
"""Sets IAM policy for a project."""
108+
109+
policy = (
110+
crm_service.projects()
111+
.setIamPolicy(resource=project_id, body={"policy": policy})
112+
.execute()
113+
)
114+
return policy
48115

49116

50117
if __name__ == '__main__':
51-
quickstart()
118+
119+
# TODO: replace with your project ID
120+
project_id = "your_project_id"
121+
# TODO: Replace with the ID of your member in the form 'user:[email protected].
122+
member = "your_member"
123+
quickstart(project_id, member)
124+
# [END iam_quickstart]

iam/api-client/quickstart_test.py

+84-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2018 Google Inc. All Rights Reserved.
1+
# Copyright 2020 Google Inc. All Rights Reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -12,10 +12,89 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
"""Tests for quickstart."""
16+
17+
import os
18+
import uuid
19+
20+
from google.oauth2 import service_account
21+
from googleapiclient import errors
22+
import googleapiclient.discovery
23+
import pytest
24+
from retrying import retry
25+
1526
import quickstart
1627

28+
# Setting up variables for testing
29+
GCLOUD_PROJECT = os.environ["GCLOUD_PROJECT"]
30+
31+
32+
def retry_if_conflict(exception):
33+
return (isinstance(exception, errors.HttpError)
34+
and 'There were concurrent policy changes' in str(exception))
35+
36+
37+
@pytest.fixture(scope="module")
38+
def test_member():
39+
# section to create service account to test policy updates.
40+
# we use the first portion of uuid4 because full version is too long.
41+
name = f'test-{uuid.uuid4().hex[:25]}'
42+
email = name + "@" + GCLOUD_PROJECT + ".iam.gserviceaccount.com"
43+
member = "serviceAccount:" + email
44+
create_service_account(
45+
GCLOUD_PROJECT, name, "Py Test Account"
46+
)
47+
48+
yield member
49+
50+
# deleting the service account created above
51+
delete_service_account(email)
52+
53+
54+
def create_service_account(project_id, name, display_name):
55+
"""Creates a service account."""
56+
57+
credentials = service_account.Credentials.from_service_account_file(
58+
filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'],
59+
scopes=['https://www.googleapis.com/auth/cloud-platform'])
60+
61+
service = googleapiclient.discovery.build(
62+
'iam', 'v1', credentials=credentials)
63+
64+
my_service_account = service.projects().serviceAccounts().create(
65+
name='projects/' + project_id,
66+
body={
67+
'accountId': name,
68+
'serviceAccount': {
69+
'displayName': display_name
70+
}
71+
}).execute()
72+
73+
print('Created service account: ' + my_service_account['email'])
74+
return my_service_account
75+
76+
77+
def delete_service_account(email):
78+
"""Deletes a service account."""
79+
80+
credentials = service_account.Credentials.from_service_account_file(
81+
filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'],
82+
scopes=['https://www.googleapis.com/auth/cloud-platform'])
83+
84+
service = googleapiclient.discovery.build(
85+
'iam', 'v1', credentials=credentials)
86+
87+
service.projects().serviceAccounts().delete(
88+
name='projects/-/serviceAccounts/' + email).execute()
89+
90+
print('Deleted service account: ' + email)
91+
1792

18-
def test_quickstart(capsys):
19-
quickstart.quickstart()
20-
out, _ = capsys.readouterr()
21-
assert 'Title' in out
93+
def test_quickstart(test_member, capsys):
94+
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000,
95+
stop_max_attempt_number=5, retry_on_exception=retry_if_conflict)
96+
def test_call():
97+
quickstart.quickstart(GCLOUD_PROJECT, test_member)
98+
out, _ = capsys.readouterr()
99+
assert test_member in out
100+
test_call()

iam/api-client/quickstartv2.py

-124
This file was deleted.

0 commit comments

Comments
 (0)