diff --git a/.kokoro/tests/run_tests.sh b/.kokoro/tests/run_tests.sh index 909f607598a..b2c09cd1034 100755 --- a/.kokoro/tests/run_tests.sh +++ b/.kokoro/tests/run_tests.sh @@ -75,6 +75,9 @@ if [[ "$SCRIPT_DEBUG" != "true" ]]; then "java-dlp-samples-secrets.txt" \ "java-functions-samples-secrets.txt" \ "java-firestore-samples-secrets.txt" \ + "java-cts-v4-samples-secrets.txt" \ + "java-cloud-sql-samples-secrets.txt" \ + "java-iam-samples-secrets.txt" \ "java-scc-samples-secrets.txt") # create secret dir @@ -96,7 +99,7 @@ if [[ "$SCRIPT_DEBUG" != "true" ]]; then export AZURE_STORAGE_ACCOUNT=`S="$STS_AZURE_SECRET" python3 -c 'import json,sys,os;obj=json.loads(os.getenv("S"));print (obj["StorageAccount"]);'` export AZURE_CONNECTION_STRING=`S="$STS_AZURE_SECRET" python3 -c 'import json,sys,os;obj=json.loads(os.getenv("S"));print (obj["ConnectionString"]);'` export AZURE_SAS_TOKEN=`S="$STS_AZURE_SECRET" python3 -c 'import json,sys,os;obj=json.loads(os.getenv("S"));print (obj["SAS"]);'` - + # Activate service account gcloud auth activate-service-account \ --key-file="$GOOGLE_APPLICATION_CREDENTIALS" \ diff --git a/iam/snippets/pom.xml b/iam/snippets/pom.xml new file mode 100644 index 00000000000..b5d479265a4 --- /dev/null +++ b/iam/snippets/pom.xml @@ -0,0 +1,98 @@ + + + + iam-deny-samples + 4.0.0 + 1.0-SNAPSHOT + + + + + com.google.apis + google-api-services-cloudresourcemanager + v3-rev20221016-2.0.0 + + + com.google.auth + google-auth-library-oauth2-http + 1.12.1 + + + com.google.http-client + google-http-client-jackson2 + 1.42.3 + + + com.google.cloud + google-iam-policy + 1.6.8 + compile + + + com.google.apis + google-api-services-iamcredentials + v1-rev20211203-2.0.0 + + + + + truth + com.google.truth + test + 1.1.3 + + + junit + junit + test + 4.13.2 + + + + + + + + libraries-bom + com.google.cloud + import + pom + 26.1.4 + + + + + + + shared-configuration + com.google.cloud.samples + 1.2.0 + + + + 11 + 11 + + + gce-diregapic + + diff --git a/iam/snippets/src/main/java/CreateDenyPolicy.java b/iam/snippets/src/main/java/CreateDenyPolicy.java new file mode 100644 index 00000000000..f49634e47bb --- /dev/null +++ b/iam/snippets/src/main/java/CreateDenyPolicy.java @@ -0,0 +1,166 @@ +/* + * 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. + */ + +// [START iam_create_deny_policy] + +import com.google.iam.v2.CreatePolicyRequest; +import com.google.iam.v2.DenyRule; +import com.google.iam.v2.PoliciesClient; +import com.google.iam.v2.Policy; +import com.google.iam.v2.PolicyRule; +import com.google.longrunning.Operation; +import com.google.type.Expr; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class CreateDenyPolicy { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + // ID or number of the Google Cloud project you want to use. + String projectId = "your-google-cloud-project-id"; + + // Specify the id of the Deny policy you want to create. + String policyId = "deny-policy-id"; + + createDenyPolicy(projectId, policyId); + } + + // 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. + public static void createDenyPolicy(String projectId, String policyId) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + + try (PoliciesClient policiesClient = PoliciesClient.create()) { + // 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. + String urlEncodedResource = + URLEncoder.encode( + "cloudresourcemanager.googleapis.com/projects/", StandardCharsets.UTF_8); + String attachmentPoint = String.format("%s%s", urlEncodedResource, projectId); + + // Construct the full path of the resource to which the policy is attached. + // Its format is: "policies/{attachmentPoint}/denypolicies/{policyId}" + String policyParent = String.format("policies/%s/denypolicies", attachmentPoint); + + DenyRule denyRule = + DenyRule.newBuilder() + // 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/docs/principal-identifiers + .addDeniedPrincipals("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. + // .addExceptionPrincipals( + // "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 + .addDeniedPermissions("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. + // .addExceptionPermissions("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. + .setDenialCondition( + Expr.newBuilder() + // The expression uses Common Expression Language syntax (CEL). + // Here we block access based on tags. + // + // A tag is a key-value pair that can be attached to an organization, folder, + // or project. You can use deny policies to deny permissions based on tags + // without adding an IAM Condition to every role grant. + // For example, imagine that you tag all of your projects as dev, test, or + // prod. You want only members of project-admins@example.com to be able to + // perform operations on projects that are tagged prod. + // To solve this problem, you 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. + .setExpression("!resource.matchTag('12345678/env', 'test')") + .setTitle("Only for test projects") + .build()) + .build(); + + // Add the deny rule and a description for it. + Policy policy = + Policy.newBuilder() + // Set the deny rule. + .addRules( + PolicyRule.newBuilder() + // Set a description for the rule. + .setDescription( + "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") + .setDenyRule(denyRule) + .build()) + .build(); + + // Set the policy resource path, policy rules and a unique ID for the policy. + CreatePolicyRequest createPolicyRequest = + CreatePolicyRequest.newBuilder() + .setParent(policyParent) + .setPolicy(policy) + .setPolicyId(policyId) + .build(); + + // Build the create policy request. + Operation operation = + policiesClient + .createPolicyCallable() + .futureCall(createPolicyRequest) + .get(3, TimeUnit.MINUTES); + + // Wait for the operation to complete. + if (operation.hasError()) { + System.out.println("Error in creating the policy " + operation.getError()); + return; + } + + // Retrieve the policy name. + Policy response = policiesClient.getPolicy(String.format("%s/%s", policyParent, policyId)); + String policyName = response.getName(); + System.out.println( + "Created the deny policy: " + policyName.substring(policyName.lastIndexOf("/") + 1)); + } + } +} +// [END iam_create_deny_policy] diff --git a/iam/snippets/src/main/java/DeleteDenyPolicy.java b/iam/snippets/src/main/java/DeleteDenyPolicy.java new file mode 100644 index 00000000000..8b500faf61c --- /dev/null +++ b/iam/snippets/src/main/java/DeleteDenyPolicy.java @@ -0,0 +1,87 @@ +/* + * 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. + */ + +// [START iam_delete_deny_policy] + +import com.google.iam.v2.DeletePolicyRequest; +import com.google.iam.v2.PoliciesClient; +import com.google.longrunning.Operation; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class DeleteDenyPolicy { + + public static void main(String[] args) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + + // ID or number of the Google Cloud project you want to use. + String projectId = "your-google-cloud-project-id"; + + // Specify the ID of the deny policy you want to retrieve. + String policyId = "deny-policy-id"; + + deleteDenyPolicy(projectId, policyId); + } + + // Delete the policy if you no longer want to enforce the rules in a deny policy. + public static void deleteDenyPolicy(String projectId, String policyId) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + try (PoliciesClient policiesClient = PoliciesClient.create()) { + + // 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. + String urlEncodedResource = + URLEncoder.encode( + "cloudresourcemanager.googleapis.com/projects/", StandardCharsets.UTF_8); + String attachmentPoint = String.format("%s%s", urlEncodedResource, projectId); + + // Construct the full path of the resource to which the policy is attached. + // Its format is: "policies/{attachmentPoint}/denypolicies/{policyId}" + String policyParent = String.format("policies/%s/denypolicies/%s", attachmentPoint, policyId); + + // Create the DeletePolicy request. + DeletePolicyRequest deletePolicyRequest = + DeletePolicyRequest.newBuilder().setName(policyParent).build(); + + // Delete the policy and wait for the operation to complete. + Operation operation = + policiesClient + .deletePolicyCallable() + .futureCall(deletePolicyRequest) + .get(3, TimeUnit.MINUTES); + + if (operation.hasError()) { + System.out.println("Error in deleting the policy " + operation.getError()); + return; + } + + System.out.println("Deleted the deny policy: " + policyId); + } + } +} +// [END iam_delete_deny_policy] diff --git a/iam/snippets/src/main/java/GetDenyPolicy.java b/iam/snippets/src/main/java/GetDenyPolicy.java new file mode 100644 index 00000000000..0cf4e96c8a4 --- /dev/null +++ b/iam/snippets/src/main/java/GetDenyPolicy.java @@ -0,0 +1,72 @@ +/* + * 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. + */ + +// [START iam_get_deny_policy] + +import com.google.iam.v2.GetPolicyRequest; +import com.google.iam.v2.PoliciesClient; +import com.google.iam.v2.Policy; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +public class GetDenyPolicy { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // ID or number of the Google Cloud project you want to use. + String projectId = "your-google-cloud-project-id"; + + // Specify the ID of the deny policy you want to retrieve. + String policyId = "deny-policy-id"; + + getDenyPolicy(projectId, policyId); + } + + // Retrieve the deny policy given the project ID and policy ID. + public static void getDenyPolicy(String projectId, String policyId) throws IOException { + // Create the IAM Policies client. + try (PoliciesClient policiesClient = PoliciesClient.create()) { + + // 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. + String urlEncodedResource = + URLEncoder.encode( + "cloudresourcemanager.googleapis.com/projects/", StandardCharsets.UTF_8); + String attachmentPoint = String.format("%s%s", urlEncodedResource, projectId); + + // Construct the full path of the resource to which the policy is attached. + // Its format is: "policies/{attachmentPoint}/denypolicies/{policyId}" + String policyParent = String.format("policies/%s/denypolicies/%s", attachmentPoint, policyId); + + // Specify the policyParent and execute the GetPolicy request. + GetPolicyRequest getPolicyRequest = + GetPolicyRequest.newBuilder().setName(policyParent).build(); + + Policy policy = policiesClient.getPolicy(getPolicyRequest); + System.out.printf("Retrieved the deny policy: %s : %s%n", policyId, policy); + } + } +} +// [END iam_get_deny_policy] diff --git a/iam/snippets/src/main/java/ListDenyPolicies.java b/iam/snippets/src/main/java/ListDenyPolicies.java new file mode 100644 index 00000000000..566a5946df1 --- /dev/null +++ b/iam/snippets/src/main/java/ListDenyPolicies.java @@ -0,0 +1,67 @@ +/* + * 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. + */ + +// [START iam_list_deny_policy] + +import com.google.iam.v2.PoliciesClient; +import com.google.iam.v2.Policy; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +public class ListDenyPolicies { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + // ID or number of the Google Cloud project you want to use. + String projectId = "your-google-cloud-project-id"; + + listDenyPolicies(projectId); + } + + // List all the deny policies that are attached to a resource. + // A resource can have up to 5 deny policies. + public static void listDenyPolicies(String projectId) throws IOException { + // Initialize the Policies client. + try (PoliciesClient policiesClient = PoliciesClient.create()) { + + // 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. + String urlEncodedResource = + URLEncoder.encode( + "cloudresourcemanager.googleapis.com/projects/", StandardCharsets.UTF_8); + String attachmentPoint = String.format("%s%s", urlEncodedResource, projectId); + + // Construct the full path of the resource to which the policy is attached. + // Its format is: "policies/{attachmentPoint}/denypolicies" + String policyParent = String.format("policies/%s/denypolicies", attachmentPoint); + + // Create a list request and iterate over the returned policies. + for (Policy policy : policiesClient.listPolicies(policyParent).iterateAll()) { + System.out.println(policy.getName()); + } + System.out.println("Listed all deny policies"); + } + } +} +// [END iam_list_deny_policy] diff --git a/iam/snippets/src/main/java/UpdateDenyPolicy.java b/iam/snippets/src/main/java/UpdateDenyPolicy.java new file mode 100644 index 00000000000..a1885a01f54 --- /dev/null +++ b/iam/snippets/src/main/java/UpdateDenyPolicy.java @@ -0,0 +1,160 @@ +/* + * 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. + */ + +// [START iam_update_deny_policy] + +import com.google.iam.v2.DenyRule; +import com.google.iam.v2.PoliciesClient; +import com.google.iam.v2.Policy; +import com.google.iam.v2.PolicyRule; +import com.google.iam.v2.UpdatePolicyRequest; +import com.google.longrunning.Operation; +import com.google.type.Expr; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class UpdateDenyPolicy { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + + // ID or number of the Google Cloud project you want to use. + String projectId = "your-google-cloud-project-id"; + + // Specify the ID of the Deny policy you want to retrieve. + String policyId = "deny-policy-id"; + + // Etag field that identifies the policy version. The etag changes each time + // you update the policy. Get the etag of an existing policy by performing a GetPolicy request. + String etag = "policy_etag"; + + updateDenyPolicy(projectId, policyId, etag); + } + + // Update the deny rules and/ or its display name after policy creation. + public static void updateDenyPolicy(String projectId, String policyId, String etag) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + + try (PoliciesClient policiesClient = PoliciesClient.create()) { + + // 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. + String urlEncodedResource = + URLEncoder.encode( + "cloudresourcemanager.googleapis.com/projects/", StandardCharsets.UTF_8); + String attachmentPoint = String.format("%s%s", urlEncodedResource, projectId); + + // Construct the full path of the resource to which the policy is attached to. + // Its format is: "policies/{attachmentPoint}/denypolicies/{policyId}" + String policyParent = String.format("policies/%s/denypolicies/%s", attachmentPoint, policyId); + + DenyRule denyRule = + DenyRule.newBuilder() + // 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/docs/principal-identifiers + .addDeniedPrincipals("principalSet://goog/public:all") + + // Optionally, set the principals who should be exempted from the list of principals + // added in "DeniedPrincipals". + // Example, if you want to deny certain permissions to a group but exempt a few + // principals, then add those here. + // .addExceptionPrincipals( + // "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 + .addDeniedPermissions("cloudresourcemanager.googleapis.com/projects.delete") + + // Add the permissions to be exempted from this rule. + // Meaning, the deny rule will not be applicable to these permissions. + // .addExceptionPermissions("cloudresourcemanager.googleapis.com/projects.get") + + // 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. + .setDenialCondition( + Expr.newBuilder() + // The expression uses Common Expression Language syntax (CEL). Here we block + // access based on tags. + // + // A tag is a key-value pair that can be attached to an organization, folder, + // or project. You can use deny policies to deny permissions based on tags + // without adding an IAM Condition to every role grant. + // For example, imagine that you tag all of your projects as dev, test, or + // prod. You want only members of project-admins@example.com to be able to + // perform operations on projects that are tagged prod. + // To solve this problem, you 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 prod. + .setExpression("!resource.matchTag('12345678/env', 'prod')") + .setTitle("Only for prod projects") + .build()) + .build(); + + // Set the policy resource path, version (etag) and the updated deny rules. + Policy policy = + Policy.newBuilder() + .setName(policyParent) + .setEtag(etag) + .addRules( + PolicyRule.newBuilder() + // Set the rule description to update. + .setDescription( + "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 prod") + // Set the deny rule to update. + .setDenyRule(denyRule) + .build()) + .build(); + + // Create the update policy request. + UpdatePolicyRequest updatePolicyRequest = + UpdatePolicyRequest.newBuilder().setPolicy(policy).build(); + + // Wait for the operation to complete. + Operation operation = + policiesClient + .updatePolicyCallable() + .futureCall(updatePolicyRequest) + .get(3, TimeUnit.MINUTES); + + if (operation.hasError()) { + System.out.println("Error in updating the policy " + operation.getError()); + return; + } + + System.out.println("Updated the deny policy: " + policyId); + } + } +} +// [END iam_update_deny_policy] diff --git a/iam/snippets/src/test/java/DenyIT.java b/iam/snippets/src/test/java/DenyIT.java new file mode 100644 index 00000000000..3cb346588c2 --- /dev/null +++ b/iam/snippets/src/test/java/DenyIT.java @@ -0,0 +1,130 @@ +/* + * 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 static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.iam.v2.PoliciesClient; +import com.google.iam.v2.Policy; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class DenyIT { + + private static final String PROJECT_ID = System.getenv("IAM_PROJECT_ID"); + private static final String GOOGLE_APPLICATION_CREDENTIALS = + System.getenv("IAM_CREDENTIALS"); + private static String POLICY_ID; + + private ByteArrayOutputStream stdOut; + + // Check if the required environment variables are set. + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)) + .isNotEmpty(); + } + + @BeforeClass + public static void setUp() + throws IOException, InterruptedException, ExecutionException, TimeoutException { + final PrintStream out = System.out; + ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + requireEnvVar("IAM_CREDENTIALS"); + requireEnvVar("IAM_PROJECT_ID"); + + POLICY_ID = "limit-project-deletion" + UUID.randomUUID(); + + CreateDenyPolicy.createDenyPolicy(PROJECT_ID, POLICY_ID); + assertThat(stdOut.toString()).contains(String.format("Created the deny policy: %s", POLICY_ID)); + + stdOut.close(); + System.setOut(out); + } + + @AfterClass + public static void cleanup() + throws IOException, InterruptedException, ExecutionException, TimeoutException { + final PrintStream out = System.out; + ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + + DeleteDenyPolicy.deleteDenyPolicy(PROJECT_ID, POLICY_ID); + assertThat(stdOut.toString()).contains(String.format("Deleted the deny policy: %s", POLICY_ID)); + + stdOut.close(); + System.setOut(out); + } + + @Before + public void beforeEach() { + stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + } + + @After + public void afterEach() { + stdOut = null; + System.setOut(null); + } + + @Test + public void testListDenyPolicies() throws IOException { + ListDenyPolicies.listDenyPolicies(PROJECT_ID); + assertThat(stdOut.toString()).contains("Listed all deny policies"); + } + + @Test + public void testGetDenyPolicy() throws IOException { + GetDenyPolicy.getDenyPolicy(PROJECT_ID, POLICY_ID); + assertThat(stdOut.toString()) + .contains(String.format("Retrieved the deny policy: %s", POLICY_ID)); + assertThat(stdOut.toString()).contains(POLICY_ID); + } + + @Test + public void testUpdateDenyPolicy() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + + try (PoliciesClient policiesClient = PoliciesClient.create()) { + // Get the etag from the Deny policy. + String attachmentPoint = + String.format("cloudresourcemanager.googleapis.com/projects/%s", PROJECT_ID) + .replaceAll("/", "%2F"); + String policyParent = + String.format("policies/%s/denypolicies/%s", attachmentPoint, POLICY_ID); + Policy policy = policiesClient.getPolicy(policyParent); + + // Test policy update. + UpdateDenyPolicy.updateDenyPolicy(PROJECT_ID, POLICY_ID, policy.getEtag()); + assertThat(stdOut.toString()) + .contains(String.format("Updated the deny policy: %s", POLICY_ID)); + } + } +}