diff --git a/iam/api-client/access.py b/iam/api-client/access.py index 8f61b26fbaa..8d96aa82b43 100644 --- a/iam/api-client/access.py +++ b/iam/api-client/access.py @@ -21,12 +21,12 @@ import argparse import os -from google.oauth2 import service_account -import googleapiclient.discovery +from google.oauth2 import service_account # type: ignore +import googleapiclient.discovery # type: ignore # [START iam_get_policy] -def get_policy(project_id, version=1): +def get_policy(project_id: str, version: int = 1) -> dict: """Gets IAM policy for a project.""" credentials = service_account.Credentials.from_service_account_file( @@ -52,7 +52,7 @@ def get_policy(project_id, version=1): # [START iam_modify_policy_add_member] -def modify_policy_add_member(policy, role, member): +def modify_policy_add_member(policy: dict, role: str, member: str) -> dict: """Adds a new member to a role binding.""" binding = next(b for b in policy["bindings"] if b["role"] == role) @@ -65,7 +65,7 @@ def modify_policy_add_member(policy, role, member): # [START iam_modify_policy_add_role] -def modify_policy_add_role(policy, role, member): +def modify_policy_add_role(policy: dict, role: str, member: str) -> dict: """Adds a new role binding to a policy.""" binding = {"role": role, "members": [member]} @@ -78,7 +78,7 @@ def modify_policy_add_role(policy, role, member): # [START iam_modify_policy_remove_member] -def modify_policy_remove_member(policy, role, member): +def modify_policy_remove_member(policy: dict, role: str, member: str) -> dict: """Removes a member from a role binding.""" binding = next(b for b in policy["bindings"] if b["role"] == role) if "members" in binding and member in binding["members"]: @@ -91,7 +91,7 @@ def modify_policy_remove_member(policy, role, member): # [START iam_set_policy] -def set_policy(project_id, policy): +def set_policy(project_id: str, policy: dict) -> dict: """Sets IAM policy for a project.""" credentials = service_account.Credentials.from_service_account_file( @@ -115,7 +115,7 @@ def set_policy(project_id, policy): # [START iam_test_permissions] -def test_permissions(project_id): +def test_permissions(project_id: str) -> dict: """Tests IAM permissions of the caller""" credentials = service_account.Credentials.from_service_account_file( @@ -144,7 +144,7 @@ def test_permissions(project_id): # [END iam_test_permissions] -def main(): +def main() -> None: parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, diff --git a/iam/api-client/access_test.py b/iam/api-client/access_test.py index 7734703f4f4..633108d59c8 100644 --- a/iam/api-client/access_test.py +++ b/iam/api-client/access_test.py @@ -13,16 +13,16 @@ # limitations under the License. import os +from typing import Iterator import uuid -from googleapiclient import errors +from googleapiclient import errors # type: ignore import pytest -from retrying import retry +from retrying import retry # type: ignore import access import service_accounts - # Setting up variables for testing GCLOUD_PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] @@ -30,21 +30,20 @@ GCP_ROLE = "roles/owner" -def retry_if_conflict(exception): - return (isinstance(exception, errors.HttpError) - and 'There were concurrent policy changes' in str(exception)) +def retry_if_conflict(exception: Exception) -> bool: + return isinstance( + exception, errors.HttpError + ) and "There were concurrent policy changes" in str(exception) @pytest.fixture(scope="module") -def test_member(): +def test_member() -> Iterator[str]: # section to create service account to test policy updates. # we use the first portion of uuid4 because full version is too long. - name = "python-test-" + str(uuid.uuid4()).split('-')[0] + name = "python-test-" + str(uuid.uuid4()).split("-")[0] email = name + "@" + GCLOUD_PROJECT + ".iam.gserviceaccount.com" member = "serviceAccount:" + email - service_accounts.create_service_account( - GCLOUD_PROJECT, name, "Py Test Account" - ) + service_accounts.create_service_account(GCLOUD_PROJECT, name, "Py Test Account") yield member @@ -52,46 +51,63 @@ def test_member(): service_accounts.delete_service_account(email) -def test_get_policy(capsys): +def test_get_policy(capsys: pytest.LogCaptureFixture) -> None: access.get_policy(GCLOUD_PROJECT, version=3) out, _ = capsys.readouterr() assert "etag" in out -def test_modify_policy_add_role(test_member, capsys): - @retry(wait_exponential_multiplier=1000, wait_exponential_max=10000, - stop_max_attempt_number=5, retry_on_exception=retry_if_conflict) - def test_call(): +def test_modify_policy_add_role( + test_member: str, capsys: pytest.LogCaptureFixture +) -> None: + @retry( + wait_exponential_multiplier=1000, + wait_exponential_max=10000, + stop_max_attempt_number=5, + retry_on_exception=retry_if_conflict, + ) + def test_call() -> None: policy = access.get_policy(GCLOUD_PROJECT, version=3) access.modify_policy_add_role(policy, GCLOUD_PROJECT, test_member) out, _ = capsys.readouterr() assert "etag" in out + test_call() -def test_modify_policy_remove_member(test_member, capsys): - @retry(wait_exponential_multiplier=1000, wait_exponential_max=10000, - stop_max_attempt_number=5, retry_on_exception=retry_if_conflict) - def test_call(): +def test_modify_policy_remove_member(test_member: str, capsys: pytest.LogCaptureFixture) -> None: + @retry( + wait_exponential_multiplier=1000, + wait_exponential_max=10000, + stop_max_attempt_number=5, + retry_on_exception=retry_if_conflict, + ) + def test_call() -> None: policy = access.get_policy(GCLOUD_PROJECT, version=3) access.modify_policy_remove_member(policy, GCP_ROLE, test_member) out, _ = capsys.readouterr() assert "iam.gserviceaccount.com" in out + test_call() -def test_set_policy(capsys): - @retry(wait_exponential_multiplier=1000, wait_exponential_max=10000, - stop_max_attempt_number=5, retry_on_exception=retry_if_conflict) - def test_call(): +def test_set_policy(capsys: pytest.LogCaptureFixture) -> None: + @retry( + wait_exponential_multiplier=1000, + wait_exponential_max=10000, + stop_max_attempt_number=5, + retry_on_exception=retry_if_conflict, + ) + def test_call() -> None: policy = access.get_policy(GCLOUD_PROJECT, version=3) access.set_policy(GCLOUD_PROJECT, policy) out, _ = capsys.readouterr() assert "etag" in out + test_call() -def test_permissions(capsys): +def test_permissions(capsys: pytest.LogCaptureFixture) -> None: access.test_permissions(GCLOUD_PROJECT) out, _ = capsys.readouterr() assert "permissions" in out diff --git a/iam/api-client/custom_roles.py b/iam/api-client/custom_roles.py index c4eed710bf7..d3ba611dfa6 100644 --- a/iam/api-client/custom_roles.py +++ b/iam/api-client/custom_roles.py @@ -24,9 +24,8 @@ import argparse import os -from google.oauth2 import service_account -import googleapiclient.discovery - +from google.oauth2 import service_account # type: ignore +import googleapiclient.discovery # type: ignore credentials = service_account.Credentials.from_service_account_file( filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'], @@ -36,7 +35,7 @@ # [START iam_query_testable_permissions] -def query_testable_permissions(resource): +def query_testable_permissions(resource: str) -> None: """Lists valid permissions for a resource.""" # pylint: disable=no-member @@ -49,7 +48,7 @@ def query_testable_permissions(resource): # [START iam_get_role] -def get_role(name): +def get_role(name: str) -> None: """Gets a role.""" # pylint: disable=no-member @@ -61,7 +60,7 @@ def get_role(name): # [START iam_create_role] -def create_role(name, project, title, description, permissions, stage): +def create_role(name: str, project: str, title: str, description: str, permissions: str, stage: str) -> dict: """Creates a role.""" # pylint: disable=no-member @@ -83,7 +82,7 @@ def create_role(name, project, title, description, permissions, stage): # [START iam_edit_role] -def edit_role(name, project, title, description, permissions, stage): +def edit_role(name: str, project: str, title: str, description: str, permissions: str, stage: str) -> dict: """Creates a role.""" # pylint: disable=no-member @@ -102,7 +101,7 @@ def edit_role(name, project, title, description, permissions, stage): # [START iam_list_roles] -def list_roles(project_id): +def list_roles(project_id: str) -> None: """Lists roles.""" # pylint: disable=no-member @@ -114,7 +113,7 @@ def list_roles(project_id): # [START iam_disable_role] -def disable_role(name, project): +def disable_role(name: str, project: str) -> dict: """Disables a role.""" # pylint: disable=no-member @@ -130,7 +129,7 @@ def disable_role(name, project): # [START iam_delete_role] -def delete_role(name, project): +def delete_role(name: str, project: str) -> dict: """Deletes a role.""" # pylint: disable=no-member @@ -143,7 +142,7 @@ def delete_role(name, project): # [START iam_undelete_role] -def undelete_role(name, project): +def undelete_role(name: str, project: str) -> dict: """Undeletes a role.""" # pylint: disable=no-member @@ -158,7 +157,7 @@ def undelete_role(name, project): # [END iam_undelete_role] -def main(): +def main() -> None: parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/iam/api-client/custom_roles_test.py b/iam/api-client/custom_roles_test.py index fcdefd222c8..10b3c240bb3 100644 --- a/iam/api-client/custom_roles_test.py +++ b/iam/api-client/custom_roles_test.py @@ -13,13 +13,13 @@ # limitations under the License. import os +from typing import Iterator import uuid import pytest import custom_roles - GCLOUD_PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] @@ -31,7 +31,7 @@ # Since this fixture will throw an exception upon failing to create or delete # a custom role, there are no separatetests for those activities needed. @pytest.fixture(scope="module") -def custom_role(): +def custom_role() -> Iterator[str]: role_name = "pythonTestCustomRole" + str(uuid.uuid4().hex) custom_roles.create_role( role_name, @@ -47,7 +47,7 @@ def custom_role(): custom_roles.delete_role(role_name, GCLOUD_PROJECT) -def test_query_testable_permissions(capsys): +def test_query_testable_permissions(capsys: pytest.CaptureFixture) -> None: custom_roles.query_testable_permissions( "//cloudresourcemanager.googleapis.com/projects/" + GCLOUD_PROJECT ) @@ -56,19 +56,19 @@ def test_query_testable_permissions(capsys): assert "\n" in out -def test_list_roles(capsys): +def test_list_roles(capsys: pytest.CaptureFixture) -> None: custom_roles.list_roles(GCLOUD_PROJECT) out, _ = capsys.readouterr() assert "roles/" in out -def test_get_role(capsys): +def test_get_role(capsys: pytest.CaptureFixture) -> None: custom_roles.get_role("roles/appengine.appViewer") out, _ = capsys.readouterr() assert "roles/" in out -def test_edit_role(custom_role, capsys): +def test_edit_role(custom_role: dict, capsys: pytest.CaptureFixture) -> None: custom_roles.edit_role( custom_role, GCLOUD_PROJECT, @@ -81,7 +81,7 @@ def test_edit_role(custom_role, capsys): assert "Updated role:" in out -def test_disable_role(custom_role, capsys): +def test_disable_role(custom_role: dict, capsys: pytest.CaptureFixture) -> None: custom_roles.disable_role(custom_role, GCLOUD_PROJECT) out, _ = capsys.readouterr() assert "Disabled role:" in out diff --git a/iam/api-client/grantable_roles.py b/iam/api-client/grantable_roles.py index 354345157d6..974f103f40b 100644 --- a/iam/api-client/grantable_roles.py +++ b/iam/api-client/grantable_roles.py @@ -17,8 +17,8 @@ import argparse import os -from google.oauth2 import service_account -import googleapiclient.discovery +from google.oauth2 import service_account # type: ignore +import googleapiclient.discovery # type: ignore credentials = service_account.Credentials.from_service_account_file( filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'], @@ -28,7 +28,7 @@ # [START iam_view_grantable_roles] -def view_grantable_roles(full_resource_name): +def view_grantable_roles(full_resource_name: str) -> None: roles = service.roles().queryGrantableRoles(body={ 'fullResourceName': full_resource_name }).execute() diff --git a/iam/api-client/grantable_roles_test.py b/iam/api-client/grantable_roles_test.py index ba6a7918bf6..34daa894b70 100644 --- a/iam/api-client/grantable_roles_test.py +++ b/iam/api-client/grantable_roles_test.py @@ -14,10 +14,12 @@ import os +import pytest + import grantable_roles -def test_grantable_roles(capsys): +def test_grantable_roles(capsys: pytest.CaptureFixture) -> None: project = os.environ['GOOGLE_CLOUD_PROJECT'] resource = '//cloudresourcemanager.googleapis.com/projects/' + project grantable_roles.view_grantable_roles(resource) diff --git a/iam/api-client/quickstart.py b/iam/api-client/quickstart.py index 3fd26049095..444a7ced116 100644 --- a/iam/api-client/quickstart.py +++ b/iam/api-client/quickstart.py @@ -19,7 +19,7 @@ import googleapiclient.discovery -def quickstart(project_id, member): +def quickstart(project_id: str, member: str) -> None: """Gets a policy, adds a member, prints their permissions, and removes the member.""" # Role to be granted. @@ -43,7 +43,7 @@ def quickstart(project_id, member): modify_policy_remove_member(crm_service, project_id, role, member) -def initialize_service(): +def initialize_service() -> dict: """Initializes a Cloud Resource Manager service.""" credentials, _ = google.auth.default( @@ -55,7 +55,7 @@ def initialize_service(): return crm_service -def modify_policy_add_role(crm_service, project_id, role, member): +def modify_policy_add_role(crm_service: str, project_id: str, role: str, member: str) -> None: """Adds a new role binding to a policy.""" policy = get_policy(crm_service, project_id) @@ -74,7 +74,7 @@ def modify_policy_add_role(crm_service, project_id, role, member): set_policy(crm_service, project_id, policy) -def modify_policy_remove_member(crm_service, project_id, role, member): +def modify_policy_remove_member(crm_service: str, project_id: str, role: str, member: str) -> None: """Removes a member from a role binding.""" policy = get_policy(crm_service, project_id) @@ -86,7 +86,7 @@ def modify_policy_remove_member(crm_service, project_id, role, member): set_policy(crm_service, project_id, policy) -def get_policy(crm_service, project_id, version=3): +def get_policy(crm_service: str, project_id: str, version: int = 3) -> dict: """Gets IAM policy for a project.""" policy = ( @@ -100,7 +100,7 @@ def get_policy(crm_service, project_id, version=3): return policy -def set_policy(crm_service, project_id, policy): +def set_policy(crm_service: str, project_id: str, policy: str) -> dict: """Sets IAM policy for a project.""" policy = ( diff --git a/iam/api-client/quickstart_test.py b/iam/api-client/quickstart_test.py index c429f587f92..a76b4e8b80c 100644 --- a/iam/api-client/quickstart_test.py +++ b/iam/api-client/quickstart_test.py @@ -15,11 +15,12 @@ """Tests for quickstart.""" import os +from typing import Iterator import uuid import google.auth -from googleapiclient import errors -import googleapiclient.discovery +from googleapiclient import errors # type: ignore +import googleapiclient.discovery # type: ignore import pytest from retrying import retry @@ -29,14 +30,14 @@ GCLOUD_PROJECT = os.environ["GCLOUD_PROJECT"] -def retry_if_conflict(exception): +def retry_if_conflict(exception: Exception) -> bool: return isinstance( exception, errors.HttpError ) and "There were concurrent policy changes" in str(exception) @pytest.fixture(scope="module") -def test_member(): +def test_member() -> Iterator[str]: # section to create service account to test policy updates. # we use the first portion of uuid4 because full version is too long. name = f"test-{uuid.uuid4().hex[:25]}" @@ -50,7 +51,7 @@ def test_member(): delete_service_account(email) -def create_service_account(project_id, name, display_name): +def create_service_account(project_id: str, name: str, display_name: str) -> dict: """Creates a service account.""" credentials, _ = google.auth.default( @@ -73,7 +74,7 @@ def create_service_account(project_id, name, display_name): return my_service_account -def delete_service_account(email): +def delete_service_account(email: str) -> None: """Deletes a service account.""" credentials, _ = google.auth.default( @@ -89,14 +90,14 @@ def delete_service_account(email): print("Deleted service account: " + email) -def test_quickstart(test_member, capsys): +def test_quickstart(test_member: str, capsys: pytest.CaptureFixture) -> None: @retry( wait_exponential_multiplier=1000, wait_exponential_max=10000, stop_max_attempt_number=5, retry_on_exception=retry_if_conflict, ) - def test_call(): + def test_call() -> None: quickstart.quickstart(GCLOUD_PROJECT, test_member) out, _ = capsys.readouterr() assert test_member in out diff --git a/iam/api-client/service_account_keys.py b/iam/api-client/service_account_keys.py index 9d8c9c18742..f5854ead926 100644 --- a/iam/api-client/service_account_keys.py +++ b/iam/api-client/service_account_keys.py @@ -28,7 +28,7 @@ import os from google.oauth2 import service_account -import googleapiclient.discovery +import googleapiclient.discovery # type: ignore # [END iam_create_key] # [END iam_list_keys] @@ -36,7 +36,7 @@ # [START iam_create_key] -def create_key(service_account_email): +def create_key(service_account_email: str) -> None: """Creates a key for a service account.""" credentials = service_account.Credentials.from_service_account_file( @@ -63,7 +63,7 @@ def create_key(service_account_email): # [START iam_list_keys] -def list_keys(service_account_email): +def list_keys(service_account_email: str) -> None: """Lists all keys for a service account.""" credentials = service_account.Credentials.from_service_account_file( @@ -82,7 +82,7 @@ def list_keys(service_account_email): # [START iam_delete_key] -def delete_key(full_key_name): +def delete_key(full_key_name: str) -> None: """Deletes a service account key.""" credentials = service_account.Credentials.from_service_account_file( diff --git a/iam/api-client/service_accounts.py b/iam/api-client/service_accounts.py index 0dd53d0c29d..73346da1ffc 100644 --- a/iam/api-client/service_accounts.py +++ b/iam/api-client/service_accounts.py @@ -28,8 +28,8 @@ # [START iam_delete_service_account] import os -from google.oauth2 import service_account -import googleapiclient.discovery +from google.oauth2 import service_account # type: ignore +import googleapiclient.discovery # type: ignore # [END iam_create_service_account] # [END iam_list_service_accounts] @@ -40,7 +40,7 @@ # [START iam_create_service_account] -def create_service_account(project_id, name, display_name): +def create_service_account(project_id: str, name: str, display_name: str) -> dict: """Creates a service account.""" credentials = service_account.Credentials.from_service_account_file( @@ -65,7 +65,7 @@ def create_service_account(project_id, name, display_name): # [START iam_list_service_accounts] -def list_service_accounts(project_id): +def list_service_accounts(project_id: str) -> dict: """Lists all service accounts for the current project.""" credentials = service_account.Credentials.from_service_account_file( @@ -87,7 +87,7 @@ def list_service_accounts(project_id): # [START iam_rename_service_account] -def rename_service_account(email, new_display_name): +def rename_service_account(email: str, new_display_name: str) -> dict: """Changes a service account's display name.""" # First, get a service account using List() or Get() @@ -115,7 +115,7 @@ def rename_service_account(email, new_display_name): # [START iam_disable_service_account] -def disable_service_account(email): +def disable_service_account(email: str) -> None: """Disables a service account.""" credentials = service_account.Credentials.from_service_account_file( @@ -133,7 +133,7 @@ def disable_service_account(email): # [START iam_enable_service_account] -def enable_service_account(email): +def enable_service_account(email: str) -> None: """Enables a service account.""" credentials = service_account.Credentials.from_service_account_file( @@ -151,7 +151,7 @@ def enable_service_account(email): # [START iam_delete_service_account] -def delete_service_account(email): +def delete_service_account(email: str) -> None: """Deletes a service account.""" credentials = service_account.Credentials.from_service_account_file( @@ -168,7 +168,7 @@ def delete_service_account(email): # [END iam_delete_service_account] -def main(): +def main() -> None: parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/iam/api-client/service_accounts_test.py b/iam/api-client/service_accounts_test.py index 055a48010fa..78a0c4e1e69 100644 --- a/iam/api-client/service_accounts_test.py +++ b/iam/api-client/service_accounts_test.py @@ -16,11 +16,12 @@ import uuid from googleapiclient.errors import HttpError +import pytest import service_accounts -def test_service_accounts(capsys): +def test_service_accounts(capsys: pytest.CaptureFixture) -> None: project_id = os.environ['GOOGLE_CLOUD_PROJECT'] name = f'test-{uuid.uuid4().hex[:25]}' diff --git a/iam/api-client/workload_identity_federation.py b/iam/api-client/workload_identity_federation.py index e2c2ca700ce..b595c0495f8 100644 --- a/iam/api-client/workload_identity_federation.py +++ b/iam/api-client/workload_identity_federation.py @@ -52,7 +52,7 @@ def create_token_aws(project_number: str, pool_id: str, provider_id: str) -> Non print("URL encoded token:\n%s" % urllib.parse.quote(json.dumps(token))) -def main(): +def main() -> None: # TODO(Developer): Replace the below credentials. # project_number: Google Project number (not the project id) project_number = "my-project-number"