Skip to content
This repository has been archived by the owner on Oct 16, 2023. It is now read-only.

Commit

Permalink
docs(samples): add deny samples and tests (#209)
Browse files Browse the repository at this point in the history
* docs(samples): init add deny samples and tests

* docs(samples): added requirements.txt

* docs(samples): minor update and refactoring

* added nox files

* added comments and minor refactoring

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* added region tags

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* added region tags

* modified comments acc to review

* modified comments acc to review

* updated env var

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* modified acc to review comments

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* modified acc to review comments

* added init.py

* updated acc to review comments

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Co-authored-by: nicain <nicholascain@google.com>
Co-authored-by: Anthonios Partheniou <partheniou@google.com>
  • Loading branch information
4 people committed Jul 15, 2022
1 parent 26abc8b commit 35cc484
Show file tree
Hide file tree
Showing 11 changed files with 859 additions and 0 deletions.
Empty file added samples/snippets/__init__.py
Empty file.
41 changes: 41 additions & 0 deletions samples/snippets/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import re
import uuid

from _pytest.capture import CaptureFixture
import pytest

from create_deny_policy import create_deny_policy
from delete_deny_policy import delete_deny_policy

PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"]
GOOGLE_APPLICATION_CREDENTIALS = os.environ["GOOGLE_APPLICATION_CREDENTIALS"]


@pytest.fixture
def deny_policy(capsys: CaptureFixture) -> None:
policy_id = f"limit-project-deletion-{uuid.uuid4()}"

# Create the Deny policy.
create_deny_policy(PROJECT_ID, policy_id)

yield policy_id

# Delete the Deny policy and assert if deleted.
delete_deny_policy(PROJECT_ID, policy_id)
out, _ = capsys.readouterr()
assert re.search(f"Deleted the deny policy: {policy_id}", out)
119 changes: 119 additions & 0 deletions samples/snippets/create_deny_policy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file contains code samples that demonstrate how to create IAM deny policies.

# [START iam_create_deny_policy]


def create_deny_policy(project_id: str, policy_id: str) -> None:
from google.cloud import iam_v2beta
from google.cloud.iam_v2beta import types
from google.type import expr_pb2

"""
Create a deny policy.
You can add deny policies to organizations, folders, and projects.
Each of these resources can have up to 5 deny policies.
Deny policies contain deny rules, which specify the following:
1. The permissions to deny and/or exempt.
2. The principals that are denied, or exempted from denial.
3. An optional condition on when to enforce the deny rules.
Params:
project_id: ID or number of the Google Cloud project you want to use.
policy_id: Specify the ID of the deny policy you want to create.
"""
policies_client = iam_v2beta.PoliciesClient()

# Each deny policy is attached to an organization, folder, or project.
# To work with deny policies, specify the attachment point.
#
# Its format can be one of the following:
# 1. cloudresourcemanager.googleapis.com/organizations/ORG_ID
# 2. cloudresourcemanager.googleapis.com/folders/FOLDER_ID
# 3. cloudresourcemanager.googleapis.com/projects/PROJECT_ID
#
# The attachment point is identified by its URL-encoded resource name. Hence, replace
# the "/" with "%2F".
attachment_point = f"cloudresourcemanager.googleapis.com%2Fprojects%2F{project_id}"

deny_rule = types.DenyRule()
# Add one or more principals who should be denied the permissions specified in this rule.
# For more information on allowed values, see: https://cloud.google.com/iam/help/deny/principal-identifiers
deny_rule.denied_principals = ["principalSet://goog/public:all"]

# Optionally, set the principals who should be exempted from the
# list of denied principals. For example, if you want to deny certain permissions
# to a group but exempt a few principals, then add those here.
# deny_rule.exception_principals = ["principalSet://goog/group/project-admins@example.com"]

# Set the permissions to deny.
# The permission value is of the format: service_fqdn/resource.action
# For the list of supported permissions, see: https://cloud.google.com/iam/help/deny/supported-permissions
deny_rule.denied_permissions = [
"cloudresourcemanager.googleapis.com/projects.delete"
]

# Optionally, add the permissions to be exempted from this rule.
# Meaning, the deny rule will not be applicable to these permissions.
# deny_rule.exception_permissions = ["cloudresourcemanager.googleapis.com/projects.create"]

# Set the condition which will enforce the deny rule.
# If this condition is true, the deny rule will be applicable. Else, the rule will not be enforced.
# The expression uses Common Expression Language syntax (CEL).
# Here we block access based on tags.
#
# Here, we create a deny rule that denies the cloudresourcemanager.googleapis.com/projects.delete permission to everyone except project-admins@example.com for resources that are tagged test.
# A tag is a key-value pair that can be attached to an organization, folder, or project.
# For more info, see: https://cloud.google.com/iam/docs/deny-access#create-deny-policy
deny_rule.denial_condition = {
"expression": "!resource.matchTag('12345678/env', 'test')"
}

# Add the deny rule and a description for it.
policy_rule = types.PolicyRule()
policy_rule.description = "block all principals from deleting projects, unless the principal is a member of project-admins@example.com and the project being deleted has a tag with the value test"
policy_rule.deny_rule = deny_rule

policy = types.Policy()
policy.display_name = "Restrict project deletion access"
policy.rules = [policy_rule]

# Set the policy resource path, policy rules and a unique ID for the policy.
request = types.CreatePolicyRequest()
# Construct the full path of the resource's deny policies.
# Its format is: "policies/{attachmentPoint}/denypolicies"
request.parent = f"policies/{attachment_point}/denypolicies"
request.policy = policy
request.policy_id = policy_id

# Build the create policy request.
policies_client.create_policy(request=request)
print(f"Created the deny policy: {policy_id}")


if __name__ == "__main__":
import uuid

# Your Google Cloud project ID.
project_id = "your-google-cloud-project-id"
# Any unique ID (0 to 63 chars) starting with a lowercase letter.
policy_id = f"deny-{uuid.uuid4()}"

# Test the policy lifecycle.
create_deny_policy(project_id, policy_id)

# [END iam_create_deny_policy]
62 changes: 62 additions & 0 deletions samples/snippets/delete_deny_policy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file contains code samples that demonstrate how to delete IAM deny policies.

# [START iam_delete_deny_policy]
def delete_deny_policy(project_id: str, policy_id: str) -> None:
from google.cloud import iam_v2beta
from google.cloud.iam_v2beta import types

"""
Delete the policy if you no longer want to enforce the rules in a deny policy.
project_id: ID or number of the Google Cloud project you want to use.
policy_id: The ID of the deny policy you want to retrieve.
"""
policies_client = iam_v2beta.PoliciesClient()

# Each deny policy is attached to an organization, folder, or project.
# To work with deny policies, specify the attachment point.
#
# Its format can be one of the following:
# 1. cloudresourcemanager.googleapis.com/organizations/ORG_ID
# 2. cloudresourcemanager.googleapis.com/folders/FOLDER_ID
# 3. cloudresourcemanager.googleapis.com/projects/PROJECT_ID
#
# The attachment point is identified by its URL-encoded resource name. Hence, replace
# the "/" with "%2F".
attachment_point = f"cloudresourcemanager.googleapis.com%2Fprojects%2F{project_id}"

request = types.DeletePolicyRequest()
# Construct the full path of the policy.
# Its format is: "policies/{attachmentPoint}/denypolicies/{policyId}"
request.name = f"policies/{attachment_point}/denypolicies/{policy_id}"

# Create the DeletePolicy request.
policies_client.delete_policy(request=request)
print(f"Deleted the deny policy: {policy_id}")


if __name__ == "__main__":
import uuid

# Your Google Cloud project ID.
project_id = "your-google-cloud-project-id"
# Any unique ID (0 to 63 chars) starting with a lowercase letter.
policy_id = f"deny-{uuid.uuid4()}"

delete_deny_policy(project_id, policy_id)

# [END iam_delete_deny_policy]
63 changes: 63 additions & 0 deletions samples/snippets/get_deny_policy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file contains code samples that demonstrate how to get IAM deny policies.

# [START iam_get_deny_policy]
def get_deny_policy(project_id: str, policy_id: str):
from google.cloud import iam_v2beta
from google.cloud.iam_v2beta import Policy, types

"""
Retrieve the deny policy given the project ID and policy ID.
project_id: ID or number of the Google Cloud project you want to use.
policy_id: The ID of the deny policy you want to retrieve.
"""
policies_client = iam_v2beta.PoliciesClient()

# Each deny policy is attached to an organization, folder, or project.
# To work with deny policies, specify the attachment point.
#
# Its format can be one of the following:
# 1. cloudresourcemanager.googleapis.com/organizations/ORG_ID
# 2. cloudresourcemanager.googleapis.com/folders/FOLDER_ID
# 3. cloudresourcemanager.googleapis.com/projects/PROJECT_ID
#
# The attachment point is identified by its URL-encoded resource name. Hence, replace
# the "/" with "%2F".
attachment_point = f"cloudresourcemanager.googleapis.com%2Fprojects%2F{project_id}"

request = types.GetPolicyRequest()
# Construct the full path of the policy.
# Its format is: "policies/{attachmentPoint}/denypolicies/{policyId}"
request.name = f"policies/{attachment_point}/denypolicies/{policy_id}"

# Execute the GetPolicy request.
policy = policies_client.get_policy(request=request)
print(f"Retrieved the deny policy: {policy_id} : {policy}")
return policy


if __name__ == "__main__":
import uuid

# Your Google Cloud project ID.
project_id = "your-google-cloud-project-id"
# Any unique ID (0 to 63 chars) starting with a lowercase letter.
policy_id = f"deny-{uuid.uuid4()}"

policy = get_deny_policy(project_id, policy_id)

# [END iam_get_deny_policy]
65 changes: 65 additions & 0 deletions samples/snippets/list_deny_policies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file contains code samples that demonstrate how to list IAM deny policies.

# [START iam_list_deny_policy]
def list_deny_policy(project_id: str) -> None:
from google.cloud import iam_v2beta
from google.cloud.iam_v2beta import types

"""
List all the deny policies that are attached to a resource.
A resource can have up to 5 deny policies.
project_id: ID or number of the Google Cloud project you want to use.
"""
policies_client = iam_v2beta.PoliciesClient()

# Each deny policy is attached to an organization, folder, or project.
# To work with deny policies, specify the attachment point.
#
# Its format can be one of the following:
# 1. cloudresourcemanager.googleapis.com/organizations/ORG_ID
# 2. cloudresourcemanager.googleapis.com/folders/FOLDER_ID
# 3. cloudresourcemanager.googleapis.com/projects/PROJECT_ID
#
# The attachment point is identified by its URL-encoded resource name. Hence, replace
# the "/" with "%2F".
attachment_point = f"cloudresourcemanager.googleapis.com%2Fprojects%2F{project_id}"

request = types.ListPoliciesRequest()
# Construct the full path of the resource's deny policies.
# Its format is: "policies/{attachmentPoint}/denypolicies"
request.parent = f"policies/{attachment_point}/denypolicies"

# Create a list request and iterate over the returned policies.
policies = policies_client.list_policies(request=request)

for policy in policies:
print(policy.name)
print("Listed all deny policies")


if __name__ == "__main__":
import uuid

# Your Google Cloud project ID.
project_id = "your-google-cloud-project-id"
# Any unique ID (0 to 63 chars) starting with a lowercase letter.
policy_id = f"deny-{uuid.uuid4()}"

list_deny_policy(project_id)

# [END iam_list_deny_policy]
Loading

0 comments on commit 35cc484

Please sign in to comment.