From 27b2e97f10ab5d3c10af22b88f1cd88b8cb2889c Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Mon, 5 Jun 2023 16:05:35 -0700 Subject: [PATCH] Add ACM policies fine grained resources (#8038) * Initial commit for ACM policies fine grained resources * Delete old test files * Fix tests failures * Fix tests * Make ingress_policy an array * Change the top level field to be ingressFrom and ingressTo * Support creation for multiple ingress/egress policies * Remove Wrong values in ingress_from/egress_from fields * Fix Lint * Change description for deprecated resources --- .../accesscontextmanager/EgressPolicy.yaml | 8 +- .../accesscontextmanager/IngressPolicy.yaml | 9 +- .../ServicePerimeterEgressPolicy.yaml | 136 +++++++++++++++ .../ServicePerimeterIngressPolicy.yaml | 160 ++++++++++++++++++ ...ger_service_perimeter_egress_policy.go.erb | 9 +- ...er_service_perimeter_ingress_policy.go.erb | 9 +- ..._context_manager_access_policy_test.go.erb | 30 ++-- ...r_service_perimeter_egress_policy_test.go} | 57 ++++--- ..._service_perimeter_ingress_policy_test.go} | 101 +++++------ 9 files changed, 406 insertions(+), 113 deletions(-) create mode 100644 mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml create mode 100644 mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml rename mmv1/third_party/terraform/tests/{resource_access_context_manager_egress_policy_test.go => resource_access_context_manager_service_perimeter_egress_policy_test.go} (57%) rename mmv1/third_party/terraform/tests/{resource_access_context_manager_ingress_policy_test.go => resource_access_context_manager_service_perimeter_ingress_policy_test.go} (54%) diff --git a/mmv1/products/accesscontextmanager/EgressPolicy.yaml b/mmv1/products/accesscontextmanager/EgressPolicy.yaml index b26535edbbde..2c5389d903db 100644 --- a/mmv1/products/accesscontextmanager/EgressPolicy.yaml +++ b/mmv1/products/accesscontextmanager/EgressPolicy.yaml @@ -31,13 +31,7 @@ nested_query: !ruby/object:Api::Resource::NestedQuery references: !ruby/object:Api::Resource::ReferenceLinks api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#egresspolicy' description: | - EgressPolicies match requests based on egressFrom and egressTo stanzas. - For an EgressPolicy to match, both egressFrom and egressTo stanzas must be matched. - If an EgressPolicy matches a request, the request is allowed to span the ServicePerimeter - boundary. For example, an EgressPolicy can be used to allow VMs on networks - within the ServicePerimeter to access a defined set of projects outside the - perimeter in certain contexts (e.g. to read data from a Cloud Storage bucket - or query against a BigQuery dataset). + This resource has been deprecated, please refer to ServicePerimeterEgressPolicy. autogen_async: true exclude_validator: true # Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter/IngressPolicy diff --git a/mmv1/products/accesscontextmanager/IngressPolicy.yaml b/mmv1/products/accesscontextmanager/IngressPolicy.yaml index a67a40ca30b8..901b11b4632f 100644 --- a/mmv1/products/accesscontextmanager/IngressPolicy.yaml +++ b/mmv1/products/accesscontextmanager/IngressPolicy.yaml @@ -31,14 +31,7 @@ nested_query: !ruby/object:Api::Resource::NestedQuery references: !ruby/object:Api::Resource::ReferenceLinks api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#ingresspolicy' description: | - IngressPolicies match requests based on ingressFrom and ingressTo stanzas. For an ingress policy to match, - both the ingressFrom and ingressTo stanzas must be matched. If an IngressPolicy matches a request, - the request is allowed through the perimeter boundary from outside the perimeter. - For example, access from the internet can be allowed either based on an AccessLevel or, - for traffic hosted on Google Cloud, the project of the source network. - For access from private networks, using the project of the hosting network is required. - Individual ingress policies can be limited by restricting which services and/ - or actions they match using the ingressTo field. + This resource has been deprecated, please refer to ServicePerimeterIngressPolicy. autogen_async: true exclude_validator: true # Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter/IngressPolicy diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml new file mode 100644 index 000000000000..337d6ca3932e --- /dev/null +++ b/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml @@ -0,0 +1,136 @@ +# Copyright 2018 Google Inc. +# 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. +--- !ruby/object:Api::Resource +name: 'ServicePerimeterEgressPolicy' +create_url: '{{perimeter}}' +base_url: '' +self_link: '{{perimeter}}' +create_verb: :PATCH +delete_verb: :PATCH +update_mask: true +identity: + - egressFrom + - egressTo +nested_query: !ruby/object:Api::Resource::NestedQuery + modify_by_patch: true + is_list_of_ids: false + keys: + - status + - egressPolicies +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#egresspolicy' +description: | + EgressPolicies match requests based on egressFrom and egressTo stanzas. + For an EgressPolicy to match, both egressFrom and egressTo stanzas must be matched. + If an EgressPolicy matches a request, the request is allowed to span the ServicePerimeter + boundary. For example, an EgressPolicy can be used to allow VMs on networks + within the ServicePerimeter to access a defined set of projects outside the + perimeter in certain contexts (e.g. to read data from a Cloud Storage bucket + or query against a BigQuery dataset). +autogen_async: true +exclude_validator: true +# Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter +skip_sweeper: true +id_format: '{{perimeter}}' +import_format: ['{{perimeter}}'] +mutex: '{{perimeter}}' +custom_code: !ruby/object:Provider::Terraform::CustomCode + custom_import: templates/terraform/custom_import/access_context_manager_service_perimeter_ingress_policy.go.erb +parameters: + - !ruby/object:Api::Type::ResourceRef + name: 'perimeter' + resource: 'ServicePerimeter' + imports: 'name' + description: | + The name of the Service Perimeter to add this resource to. + required: true + immutable: true + url_param_only: true +properties: + - !ruby/object:Api::Type::NestedObject + name: 'egressFrom' + description: | + Defines conditions on the source of a request causing this `EgressPolicy` to apply. + properties: + - !ruby/object:Api::Type::Enum + name: 'identityType' + description: | + Specifies the type of identities that are allowed access to outside the + perimeter. If left unspecified, then members of `identities` field will + be allowed access. + values: + - :ANY_IDENTITY + - :ANY_USER_ACCOUNT + - :ANY_SERVICE_ACCOUNT + - !ruby/object:Api::Type::Array + name: 'identities' + description: | + A list of identities that are allowed access through this `EgressPolicy`. + Should be in the format of email address. The email address should + represent individual user or service account only. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: 'egressTo' + description: | + Defines the conditions on the `ApiOperation` and destination resources that + cause this `EgressPolicy` to apply. + properties: + - !ruby/object:Api::Type::Array + name: 'resources' + item_type: Api::Type::String + description: | + A list of resources, currently only projects in the form + `projects/`, that match this to stanza. A request matches + if it contains a resource in this list. If * is specified for resources, + then this `EgressTo` rule will authorize access to all resources outside + the perimeter. + - !ruby/object:Api::Type::Array + name: 'externalResources' + item_type: Api::Type::String + description: | + A list of external resources that are allowed to be accessed. A request + matches if it contains an external resource in this list (Example: + s3://bucket/path). Currently '*' is not allowed. + - !ruby/object:Api::Type::Array + name: 'operations' + description: | + A list of `ApiOperations` that this egress rule applies to. A request matches + if it contains an operation/service in this list. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'serviceName' + description: | + The name of the API whose methods or permissions the `IngressPolicy` or + `EgressPolicy` want to allow. A single `ApiOperation` with serviceName + field set to `*` will allow all methods AND permissions for all services. + - !ruby/object:Api::Type::Array + name: 'methodSelectors' + description: | + API methods or permissions to allow. Method or permission must belong + to the service specified by `serviceName` field. A single MethodSelector + entry with `*` specified for the `method` field will allow all methods + AND permissions for the service specified in `serviceName`. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'method' + description: | + Value for `method` should be a valid method name for the corresponding + `serviceName` in `ApiOperation`. If `*` used as value for method, + then ALL methods and permissions are allowed. + - !ruby/object:Api::Type::String + name: 'permission' + description: | + Value for permission should be a valid Cloud IAM permission for the + corresponding `serviceName` in `ApiOperation`. diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml new file mode 100644 index 000000000000..f292102fbdf4 --- /dev/null +++ b/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml @@ -0,0 +1,160 @@ +# Copyright 2018 Google Inc. +# 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. +--- !ruby/object:Api::Resource +name: 'ServicePerimeterIngressPolicy' +create_url: '{{perimeter}}' +base_url: '' +self_link: '{{perimeter}}' +create_verb: :PATCH +delete_verb: :PATCH +update_mask: true +identity: + - ingressFrom + - ingressTo +nested_query: !ruby/object:Api::Resource::NestedQuery + modify_by_patch: true + is_list_of_ids: false + keys: + - status + - ingressPolicies +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#ingresspolicy' +description: | + IngressPolicies match requests based on ingressFrom and ingressTo stanzas. For an ingress policy to match, + both the ingressFrom and ingressTo stanzas must be matched. If an IngressPolicy matches a request, + the request is allowed through the perimeter boundary from outside the perimeter. + For example, access from the internet can be allowed either based on an AccessLevel or, + for traffic hosted on Google Cloud, the project of the source network. + For access from private networks, using the project of the hosting network is required. + Individual ingress policies can be limited by restricting which services and/ + or actions they match using the ingressTo field. +autogen_async: true +exclude_validator: true +# Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter +skip_sweeper: true +id_format: '{{perimeter}}' +import_format: ['{{perimeter}}'] +mutex: '{{perimeter}}' +custom_code: !ruby/object:Provider::Terraform::CustomCode + custom_import: templates/terraform/custom_import/access_context_manager_service_perimeter_ingress_policy.go.erb +parameters: + - !ruby/object:Api::Type::ResourceRef + name: 'perimeter' + resource: 'ServicePerimeter' + imports: 'name' + description: | + The name of the Service Perimeter to add this resource to. + required: true + immutable: true + url_param_only: true +properties: + - !ruby/object:Api::Type::NestedObject + name: 'ingressFrom' + description: | + Defines the conditions on the source of a request causing this `IngressPolicy` + to apply. + properties: + - !ruby/object:Api::Type::Enum + name: 'identityType' + description: | + Specifies the type of identities that are allowed access from outside the + perimeter. If left unspecified, then members of `identities` field will be + allowed access. + values: + - :ANY_IDENTITY + - :ANY_USER_ACCOUNT + - :ANY_SERVICE_ACCOUNT + - !ruby/object:Api::Type::Array + name: 'identities' + item_type: Api::Type::String + description: | + A list of identities that are allowed access through this ingress policy. + Should be in the format of email address. The email address should represent + individual user or service account only. + - !ruby/object:Api::Type::Array + name: 'sources' + description: | + Sources that this `IngressPolicy` authorizes access from. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'accessLevel' + description: | + An `AccessLevel` resource name that allow resources within the + `ServicePerimeters` to be accessed from the internet. `AccessLevels` listed + must be in the same policy as this `ServicePerimeter`. Referencing a nonexistent + `AccessLevel` will cause an error. If no `AccessLevel` names are listed, + resources within the perimeter can only be accessed via Google Cloud calls + with request origins within the perimeter. + Example `accessPolicies/MY_POLICY/accessLevels/MY_LEVEL.` + If * is specified, then all IngressSources will be allowed. + - !ruby/object:Api::Type::String + name: 'resource' + description: | + A Google Cloud resource that is allowed to ingress the perimeter. + Requests from these resources will be allowed to access perimeter data. + Currently only projects are allowed. Format `projects/{project_number}` + The project may be in any Google Cloud organization, not just the + organization that the perimeter is defined in. `*` is not allowed, the case + of allowing all Google Cloud resources only is not supported. + - !ruby/object:Api::Type::NestedObject + name: 'ingressTo' + description: | + Defines the conditions on the `ApiOperation` and request destination that cause + this `IngressPolicy` to apply. + properties: + - !ruby/object:Api::Type::Array + name: 'resources' + item_type: Api::Type::String + description: | + A list of resources, currently only projects in the form + `projects/`, protected by this `ServicePerimeter` + that are allowed to be accessed by sources defined in the + corresponding `IngressFrom`. A request matches if it contains + a resource in this list. If `*` is specified for resources, + then this `IngressTo` rule will authorize access to all + resources inside the perimeter, provided that the request + also matches the `operations` field. + - !ruby/object:Api::Type::Array + name: 'operations' + description: | + A list of `ApiOperations` the sources specified in corresponding `IngressFrom` + are allowed to perform in this `ServicePerimeter`. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'serviceName' + description: | + The name of the API whose methods or permissions the `IngressPolicy` or + `EgressPolicy` want to allow. A single `ApiOperation` with `serviceName` + field set to `*` will allow all methods AND permissions for all services. + - !ruby/object:Api::Type::Array + name: 'methodSelectors' + description: | + API methods or permissions to allow. Method or permission must belong to + the service specified by serviceName field. A single `MethodSelector` entry + with `*` specified for the method field will allow all methods AND + permissions for the service specified in `serviceName`. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'method' + description: | + Value for method should be a valid method name for the corresponding + serviceName in `ApiOperation`. If `*` used as value for `method`, then + ALL methods and permissions are allowed. + - !ruby/object:Api::Type::String + name: 'permission' + description: | + Value for permission should be a valid Cloud IAM permission for the + corresponding `serviceName` in `ApiOperation`. diff --git a/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_egress_policy.go.erb b/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_egress_policy.go.erb index b2b39af2a8b1..269d4812fbdd 100644 --- a/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_egress_policy.go.erb +++ b/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_egress_policy.go.erb @@ -15,15 +15,12 @@ config := meta.(*transport_tpg.Config) // current import_formats can't import fields with forward slashes in their value - parts, err := tpgresource.GetImportIdQualifiers([]string{"accessPolicies/(?P[^/]+)/servicePerimeters/(?P[^/]+)/(?P.+)"}, d, config, d.Id()) + parts, err := tpgresource.GetImportIdQualifiers([]string{"accessPolicies/(?P[^/]+)/servicePerimeters/(?P[^/]+)"}, d, config, d.Id()) if err != nil { return nil, err } - if err := d.Set("egress_policy_name", fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", parts["accessPolicy"], parts["perimeter"])); err != nil { - return nil, fmt.Errorf("Error setting egress_policy_name: %s", err) - } - if err := d.Set("resource", parts["resource"]); err != nil { - return nil, fmt.Errorf("Error setting resource: %s", err) + if err := d.Set("perimeter", fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", parts["accessPolicy"], parts["perimeter"])); err != nil { + return nil, fmt.Errorf("Error setting perimeter: %s", err) } return []*schema.ResourceData{d}, nil diff --git a/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_ingress_policy.go.erb b/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_ingress_policy.go.erb index e01799b4305a..269d4812fbdd 100644 --- a/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_ingress_policy.go.erb +++ b/mmv1/templates/terraform/custom_import/access_context_manager_service_perimeter_ingress_policy.go.erb @@ -15,15 +15,12 @@ config := meta.(*transport_tpg.Config) // current import_formats can't import fields with forward slashes in their value - parts, err := tpgresource.GetImportIdQualifiers([]string{"accessPolicies/(?P[^/]+)/servicePerimeters/(?P[^/]+)/(?P.+)"}, d, config, d.Id()) + parts, err := tpgresource.GetImportIdQualifiers([]string{"accessPolicies/(?P[^/]+)/servicePerimeters/(?P[^/]+)"}, d, config, d.Id()) if err != nil { return nil, err } - if err := d.Set("ingress_policy_name", fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", parts["accessPolicy"], parts["perimeter"])); err != nil { - return nil, fmt.Errorf("Error setting ingress_policy_name: %s", err) - } - if err := d.Set("resource", parts["resource"]); err != nil { - return nil, fmt.Errorf("Error setting resource: %s", err) + if err := d.Set("perimeter", fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", parts["accessPolicy"], parts["perimeter"])); err != nil { + return nil, fmt.Errorf("Error setting perimeter: %s", err) } return []*schema.ResourceData{d}, nil diff --git a/mmv1/third_party/terraform/tests/resource_access_context_manager_access_policy_test.go.erb b/mmv1/third_party/terraform/tests/resource_access_context_manager_access_policy_test.go.erb index dcda4cefc190..6f846e77042d 100644 --- a/mmv1/third_party/terraform/tests/resource_access_context_manager_access_policy_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_access_context_manager_access_policy_test.go.erb @@ -92,21 +92,21 @@ func testSweepAccessContextManagerPolicies(region string) error { // can exist, they need to be run serially func TestAccAccessContextManager(t *testing.T) { testCases := map[string]func(t *testing.T){ - "access_policy": testAccAccessContextManagerAccessPolicy_basicTest, - "access_policy_scoped": testAccAccessContextManagerAccessPolicy_scopedTest, - "service_perimeter": testAccAccessContextManagerServicePerimeter_basicTest, - "service_perimeter_update": testAccAccessContextManagerServicePerimeter_updateTest, - "service_perimeter_resource": testAccAccessContextManagerServicePerimeterResource_basicTest, - "access_level": testAccAccessContextManagerAccessLevel_basicTest, - "access_level_full": testAccAccessContextManagerAccessLevel_fullTest, - "access_level_custom": testAccAccessContextManagerAccessLevel_customTest, - "access_levels": testAccAccessContextManagerAccessLevels_basicTest, - "access_level_condition": testAccAccessContextManagerAccessLevelCondition_basicTest, - "egress_policy": testAccAccessContextManagerEgressPolicy_basicTest, - "ingress_policy": testAccAccessContextManagerIngressPolicy_basicTest, - "service_perimeters": testAccAccessContextManagerServicePerimeters_basicTest, - "gcp_user_access_binding": testAccAccessContextManagerGcpUserAccessBinding_basicTest, - "authorized_orgs_desc": testAccAccessContextManagerAuthorizedOrgsDesc_basicTest, + "access_policy": testAccAccessContextManagerAccessPolicy_basicTest, + "access_policy_scoped": testAccAccessContextManagerAccessPolicy_scopedTest, + "service_perimeter": testAccAccessContextManagerServicePerimeter_basicTest, + "service_perimeter_update": testAccAccessContextManagerServicePerimeter_updateTest, + "service_perimeter_resource": testAccAccessContextManagerServicePerimeterResource_basicTest, + "access_level": testAccAccessContextManagerAccessLevel_basicTest, + "access_level_full": testAccAccessContextManagerAccessLevel_fullTest, + "access_level_custom": testAccAccessContextManagerAccessLevel_customTest, + "access_levels": testAccAccessContextManagerAccessLevels_basicTest, + "access_level_condition": testAccAccessContextManagerAccessLevelCondition_basicTest, + "service_perimeter_egress_policy": testAccAccessContextManagerServicePerimeterEgressPolicy_basicTest, + "service_perimeter_ingress_policy": testAccAccessContextManagerServicePerimeterIngressPolicy_basicTest, + "service_perimeters": testAccAccessContextManagerServicePerimeters_basicTest, + "gcp_user_access_binding": testAccAccessContextManagerGcpUserAccessBinding_basicTest, + "authorized_orgs_desc": testAccAccessContextManagerAuthorizedOrgsDesc_basicTest, } for name, tc := range testCases { diff --git a/mmv1/third_party/terraform/tests/resource_access_context_manager_egress_policy_test.go b/mmv1/third_party/terraform/tests/resource_access_context_manager_service_perimeter_egress_policy_test.go similarity index 57% rename from mmv1/third_party/terraform/tests/resource_access_context_manager_egress_policy_test.go rename to mmv1/third_party/terraform/tests/resource_access_context_manager_service_perimeter_egress_policy_test.go index cdc11ad7f5ab..9611d4e4e09a 100644 --- a/mmv1/third_party/terraform/tests/resource_access_context_manager_egress_policy_test.go +++ b/mmv1/third_party/terraform/tests/resource_access_context_manager_service_perimeter_egress_policy_test.go @@ -14,11 +14,11 @@ import ( // Since each test here is acting on the same organization and only one AccessPolicy // can exist, they need to be run serially. See AccessPolicy for the test runner. -func testAccAccessContextManagerEgressPolicy_basicTest(t *testing.T) { +func testAccAccessContextManagerServicePerimeterEgressPolicy_basicTest(t *testing.T) { // Multiple fine-grained resources acctest.SkipIfVcr(t) org := acctest.GetTestOrgFromEnv(t) - projects := BootstrapServicePerimeterProjects(t, 1) + //projects := BootstrapServicePerimeterProjects(t, 1) policyTitle := RandString(t, 10) perimeterTitle := "perimeter" @@ -27,31 +27,31 @@ func testAccAccessContextManagerEgressPolicy_basicTest(t *testing.T) { ProtoV5ProviderFactories: ProtoV5ProviderFactories(t), Steps: []resource.TestStep{ { - Config: testAccAccessContextManagerEgressPolicy_basic(org, policyTitle, perimeterTitle, projects[0].ProjectNumber), + Config: testAccAccessContextManagerServicePerimeterEgressPolicy_basic(org, policyTitle, perimeterTitle), }, { - ResourceName: "google_access_context_manager_egress_policy.test-access1", + ResourceName: "google_access_context_manager_service_perimeter.test-access", ImportState: true, ImportStateVerify: true, }, { - Config: testAccAccessContextManagerEgressPolicy_destroy(org, policyTitle, perimeterTitle), - Check: testAccCheckAccessContextManagerEgressPolicyDestroyProducer(t), + Config: testAccAccessContextManagerServicePerimeterEgressPolicy_destroy(org, policyTitle, perimeterTitle), + Check: testAccCheckAccessContextManagerServicePerimeterEgressPolicyDestroyProducer(t), }, }, }) } -func testAccCheckAccessContextManagerEgressPolicyDestroyProducer(t *testing.T) func(s *terraform.State) error { +func testAccCheckAccessContextManagerServicePerimeterEgressPolicyDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { - if rs.Type != "google_access_context_manager_egress_policy" { + if rs.Type != "google_access_context_manager_service_perimeter_egress_policy" { continue } config := GoogleProviderConfig(t) - url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{AccessContextManagerBasePath}}{{egress_policy_name}}") + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{AccessContextManagerBasePath}}{{perimeter}}") if err != nil { return err } @@ -72,7 +72,7 @@ func testAccCheckAccessContextManagerEgressPolicyDestroyProducer(t *testing.T) f } res = v.(map[string]interface{}) - v, ok = res["resources"] + v, ok = res["egress_policies"] if !ok || v == nil { return nil } @@ -89,19 +89,37 @@ func testAccCheckAccessContextManagerEgressPolicyDestroyProducer(t *testing.T) f } } -func testAccAccessContextManagerEgressPolicy_basic(org, policyTitle, perimeterTitleName string, projectNumber1 int64) string { +func testAccAccessContextManagerServicePerimeterEgressPolicy_basic(org, policyTitle, perimeterTitleName string) string { return fmt.Sprintf(` %s -resource "google_access_context_manager_egress_policy" "test-access1" { - egress_policy_name = google_access_context_manager_service_perimeter.test-access.name - resource = "projects/%d" +resource "google_access_context_manager_service_perimeter_egress_policy" "test-access1" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + egress_from { + identity_type = "ANY_USER_ACCOUNT" + } + egress_to { + operations { + service_name = "storage.googleapis.com" + method_selectors { + method = "*" + } + } + } + +} + +resource "google_access_context_manager_service_perimeter_egress_policy" "test-access2" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + egress_from { + identity_type = "ANY_USER_ACCOUNT" + } } -`, testAccAccessContextManagerEgressPolicy_destroy(org, policyTitle, perimeterTitleName), projectNumber1) +`, testAccAccessContextManagerServicePerimeterEgressPolicy_destroy(org, policyTitle, perimeterTitleName)) } -func testAccAccessContextManagerEgressPolicy_destroy(org, policyTitle, perimeterTitleName string) string { +func testAccAccessContextManagerServicePerimeterEgressPolicy_destroy(org, policyTitle, perimeterTitleName string) string { return fmt.Sprintf(` resource "google_access_context_manager_access_policy" "test-access" { parent = "organizations/%s" @@ -114,15 +132,10 @@ resource "google_access_context_manager_service_perimeter" "test-access" { title = "%s" status { restricted_services = ["storage.googleapis.com"] - egress_policies { - egress_from { - identity_type = "ANY_USER_ACCOUNT" - } - } } lifecycle { - ignore_changes = [status[0].resources] + ignore_changes = [status[0].egress_policies] } } `, org, policyTitle, perimeterTitleName, perimeterTitleName) diff --git a/mmv1/third_party/terraform/tests/resource_access_context_manager_ingress_policy_test.go b/mmv1/third_party/terraform/tests/resource_access_context_manager_service_perimeter_ingress_policy_test.go similarity index 54% rename from mmv1/third_party/terraform/tests/resource_access_context_manager_ingress_policy_test.go rename to mmv1/third_party/terraform/tests/resource_access_context_manager_service_perimeter_ingress_policy_test.go index 0f14aa1bc3b4..411f640ac9c7 100644 --- a/mmv1/third_party/terraform/tests/resource_access_context_manager_ingress_policy_test.go +++ b/mmv1/third_party/terraform/tests/resource_access_context_manager_service_perimeter_ingress_policy_test.go @@ -14,11 +14,11 @@ import ( // Since each test here is acting on the same organization and only one AccessPolicy // can exist, they need to be run serially. See AccessPolicy for the test runner. -func testAccAccessContextManagerIngressPolicy_basicTest(t *testing.T) { +func testAccAccessContextManagerServicePerimeterIngressPolicy_basicTest(t *testing.T) { // Multiple fine-grained resources acctest.SkipIfVcr(t) org := acctest.GetTestOrgFromEnv(t) - projects := BootstrapServicePerimeterProjects(t, 1) + //projects := BootstrapServicePerimeterProjects(t, 1) policyTitle := RandString(t, 10) perimeterTitle := "perimeter" @@ -27,31 +27,31 @@ func testAccAccessContextManagerIngressPolicy_basicTest(t *testing.T) { ProtoV5ProviderFactories: ProtoV5ProviderFactories(t), Steps: []resource.TestStep{ { - Config: testAccAccessContextManagerIngressPolicy_basic(org, policyTitle, perimeterTitle, projects[0].ProjectNumber), + Config: testAccAccessContextManagerServicePerimeterIngressPolicy_basic(org, policyTitle, perimeterTitle), }, { - ResourceName: "google_access_context_manager_ingress_policy.test-access1", + ResourceName: "google_access_context_manager_service_perimeter.test-access", ImportState: true, ImportStateVerify: true, }, { - Config: testAccAccessContextManagerIngressPolicy_destroy(org, policyTitle, perimeterTitle), - Check: testAccCheckAccessContextManagerIngressPolicyDestroyProducer(t), + Config: testAccAccessContextManagerServicePerimeterIngressPolicy_destroy(org, policyTitle, perimeterTitle), + Check: testAccCheckAccessContextManagerServicePerimeterIngressPolicyDestroyProducer(t), }, }, }) } -func testAccCheckAccessContextManagerIngressPolicyDestroyProducer(t *testing.T) func(s *terraform.State) error { +func testAccCheckAccessContextManagerServicePerimeterIngressPolicyDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { - if rs.Type != "google_access_context_manager_ingress_policy" { + if rs.Type != "google_access_context_manager_service_perimeter_ingress_policy" { continue } config := GoogleProviderConfig(t) - url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{AccessContextManagerBasePath}}{{ingress_policy_name}}") + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{AccessContextManagerBasePath}}{{perimeter}}") if err != nil { return err } @@ -72,7 +72,7 @@ func testAccCheckAccessContextManagerIngressPolicyDestroyProducer(t *testing.T) } res = v.(map[string]interface{}) - v, ok = res["resources"] + v, ok = res["perimeter"] if !ok || v == nil { return nil } @@ -89,19 +89,54 @@ func testAccCheckAccessContextManagerIngressPolicyDestroyProducer(t *testing.T) } } -func testAccAccessContextManagerIngressPolicy_basic(org, policyTitle, perimeterTitleName string, projectNumber1 int64) string { +func testAccAccessContextManagerServicePerimeterIngressPolicy_basic(org, policyTitle, perimeterTitleName string) string { return fmt.Sprintf(` %s -resource "google_access_context_manager_ingress_policy" "test-access1" { - ingress_policy_name = google_access_context_manager_service_perimeter.test-access.name - resource = "projects/%d" +resource "google_access_context_manager_service_perimeter_ingress_policy" "test-access1" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + ingress_from { + identity_type = "ANY_IDENTITY" + } + ingress_to { + resources = [ "*" ] + operations { + service_name = "bigquery.googleapis.com" + + method_selectors { + method = "BigQueryStorage.ReadRows" + } + + method_selectors { + method = "TableService.ListTables" + } + + method_selectors { + permission = "bigquery.jobs.get" + } + } + + operations { + service_name = "storage.googleapis.com" + + method_selectors { + method = "google.storage.objects.create" + } + } + } } -`, testAccAccessContextManagerIngressPolicy_destroy(org, policyTitle, perimeterTitleName), projectNumber1) +resource "google_access_context_manager_service_perimeter_ingress_policy" "test-access2" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + ingress_from { + identity_type = "ANY_IDENTITY" + } } -func testAccAccessContextManagerIngressPolicy_destroy(org, policyTitle, perimeterTitleName string) string { +`, testAccAccessContextManagerServicePerimeterIngressPolicy_destroy(org, policyTitle, perimeterTitleName)) +} + +func testAccAccessContextManagerServicePerimeterIngressPolicy_destroy(org, policyTitle, perimeterTitleName string) string { return fmt.Sprintf(` resource "google_access_context_manager_access_policy" "test-access" { parent = "organizations/%s" @@ -114,42 +149,10 @@ resource "google_access_context_manager_service_perimeter" "test-access" { title = "%s" status { restricted_services = ["storage.googleapis.com"] - ingress_policies { - ingress_from { - identity_type = "ANY_IDENTITY" - } - - ingress_to { - resources = [ "*" ] - operations { - service_name = "bigquery.googleapis.com" - - method_selectors { - method = "BigQueryStorage.ReadRows" - } - - method_selectors { - method = "TableService.ListTables" - } - - method_selectors { - permission = "bigquery.jobs.get" - } - } - - operations { - service_name = "storage.googleapis.com" - - method_selectors { - method = "google.storage.objects.create" - } - } - } - } } lifecycle { - ignore_changes = [status[0].resources] + ignore_changes = [status[0].ingress_policies] } } `, org, policyTitle, perimeterTitleName, perimeterTitleName)