diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterDryRunEgressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterDryRunEgressPolicy.yaml new file mode 100644 index 000000000000..aadd137e0aff --- /dev/null +++ b/mmv1/products/accesscontextmanager/ServicePerimeterDryRunEgressPolicy.yaml @@ -0,0 +1,327 @@ +# Copyright 2024 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: 'ServicePerimeterDryRunEgressPolicy' +create_url: '{{perimeter}}' +base_url: '' +self_link: '{{perimeter}}' +create_verb: :PATCH +delete_verb: :PATCH +update_mask: true +immutable: true +identity: + - egressFrom + - egressTo +nested_query: !ruby/object:Api::Resource::NestedQuery + modify_by_patch: true + is_list_of_ids: false + keys: + - spec + - egressPolicies +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#egresspolicy' +description: | + Manage a single EgressPolicy in the spec (dry-run) configuration for a service perimeter. + 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). + + ~> **Note:** By default, updates to this resource will remove the EgressPolicy from the + from the perimeter and add it back in a non-atomic manner. To ensure that the new EgressPolicy + is added before the old one is removed, add a `lifecycle` block with `create_before_destroy = true` to this resource. +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'access_context_manager_service_perimeter_dry_run_egress_policy' + skip_test: true +autogen_async: true +exclude_tgc: true +# Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter +skip_sweeper: true +exclude_import: 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 + pre_update: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_create: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_delete: templates/terraform/pre_create/access_context_manager_dry_run_resource.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 + 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::Array + name: 'sources' + description: 'Sources that this EgressPolicy authorizes access from.' + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'accessLevel' + description: 'An AccessLevel resource name that allows resources outside the ServicePerimeter to be accessed from the inside.' + - !ruby/object:Api::Type::Enum + name: 'sourceRestriction' + description: 'Whether to enforce traffic restrictions based on `sources` field. If the `sources` field is non-empty, then this field must be set to `SOURCE_RESTRICTION_ENABLED`.' + values: + - :SOURCE_RESTRICTION_ENABLED + - :SOURCE_RESTRICTION_DISABLED + - !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`. +# 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: 'ServicePerimeterDryRunEgressPolicy' +create_url: '{{perimeter}}' +base_url: '' +self_link: '{{perimeter}}' +create_verb: :PATCH +delete_verb: :PATCH +update_mask: true +immutable: true +identity: + - egressFrom + - egressTo +nested_query: !ruby/object:Api::Resource::NestedQuery + modify_by_patch: true + is_list_of_ids: false + keys: + - spec + - egressPolicies +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#egresspolicy' +description: | + Manage a single EgressPolicy in the spec (dry-run) configuration for a service perimeter. + 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). + + ~> **Note:** By default, updates to this resource will remove the EgressPolicy from the + from the perimeter and add it back in a non-atomic manner. To ensure that the new EgressPolicy + is added before the old one is removed, add a `lifecycle` block with `create_before_destroy = true` to this resource. +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'access_context_manager_service_perimeter_dry_run_egress_policy' + skip_test: true +autogen_async: true +exclude_tgc: true +# Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter +skip_sweeper: true +exclude_import: 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 + pre_update: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_create: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_delete: templates/terraform/pre_create/access_context_manager_dry_run_resource.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 + 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::Array + name: 'sources' + description: 'Sources that this EgressPolicy authorizes access from.' + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'accessLevel' + description: 'An AccessLevel resource name that allows resources outside the ServicePerimeter to be accessed from the inside.' + - !ruby/object:Api::Type::Enum + name: 'sourceRestriction' + description: 'Whether to enforce traffic restrictions based on `sources` field. If the `sources` field is non-empty, then this field must be set to `SOURCE_RESTRICTION_ENABLED`.' + values: + - :SOURCE_RESTRICTION_UNSPECIFIED + - :SOURCE_RESTRICTION_ENABLED + - :SOURCE_RESTRICTION_DISABLED + - !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/ServicePerimeterDryRunIngressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterDryRunIngressPolicy.yaml new file mode 100644 index 000000000000..05dc07b8bf74 --- /dev/null +++ b/mmv1/products/accesscontextmanager/ServicePerimeterDryRunIngressPolicy.yaml @@ -0,0 +1,173 @@ +# Copyright 2024 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: 'ServicePerimeterDryRunIngressPolicy' +create_url: '{{perimeter}}' +base_url: '' +self_link: '{{perimeter}}' +create_verb: :PATCH +delete_verb: :PATCH +update_mask: true +immutable: true +identity: + - ingressFrom + - ingressTo +nested_query: !ruby/object:Api::Resource::NestedQuery + modify_by_patch: true + is_list_of_ids: false + keys: + - spec + - ingressPolicies +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters#ingresspolicy' +description: | + Manage a single IngressPolicy in the spec (dry-run) configuration for a service perimeter. + 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. + + ~> **Note:** By default, updates to this resource will remove the IngressPolicy from the + from the perimeter and add it back in a non-atomic manner. To ensure that the new IngressPolicy + is added before the old one is removed, add a `lifecycle` block with `create_before_destroy = true` to this resource. +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'access_context_manager_service_perimeter_dry_run_ingress_policy' + skip_test: true +autogen_async: true +exclude_tgc: true +# Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter +skip_sweeper: true +exclude_import: 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 + pre_update: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_create: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_delete: templates/terraform/pre_create/access_context_manager_dry_run_resource.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 + 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/products/accesscontextmanager/ServicePerimeterDryRunResource.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterDryRunResource.yaml index 9b39f873b779..a430d3c037e9 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeterDryRunResource.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeterDryRunResource.yaml @@ -65,9 +65,9 @@ examples: service_perimeter_name: 'restrict_all' custom_code: !ruby/object:Provider::Terraform::CustomCode custom_import: templates/terraform/custom_import/access_context_manager_service_perimeter_resource.go.erb - pre_update: templates/terraform/pre_create/access_context_manager_service_perimeter_dry_run_resource.go.erb - pre_create: templates/terraform/pre_create/access_context_manager_service_perimeter_dry_run_resource.go.erb - pre_delete: templates/terraform/pre_create/access_context_manager_service_perimeter_dry_run_resource.go.erb + pre_update: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_create: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb + pre_delete: templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb parameters: - !ruby/object:Api::Type::ResourceRef name: 'perimeterName' diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml index 2d2511ab8aec..6e27a59a5bcf 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml @@ -31,6 +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: | + Manage a single EgressPolicy in the status (enforced) configuration for a service perimeter. 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 @@ -50,6 +51,7 @@ autogen_async: true exclude_tgc: true # Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter skip_sweeper: true +exclude_import: true id_format: '{{perimeter}}' import_format: ['{{perimeter}}'] mutex: '{{perimeter}}' diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml index d0a3d0922b8a..2d2918be5579 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml @@ -31,6 +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: | + Manage a single IngressPolicy in the status (enforced) configuration for a service perimeter. 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. @@ -51,6 +52,7 @@ autogen_async: true exclude_tgc: true # Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter skip_sweeper: true +exclude_import: true id_format: '{{perimeter}}' import_format: ['{{perimeter}}'] mutex: '{{perimeter}}' diff --git a/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_dry_run_egress_policy.tf.erb b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_dry_run_egress_policy.tf.erb new file mode 100644 index 000000000000..17561629da0e --- /dev/null +++ b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_dry_run_egress_policy.tf.erb @@ -0,0 +1,36 @@ +resource "google_access_context_manager_service_perimeter" "storage-perimeter" { + parent = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}" + name = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}/serviceperimeters/storage-perimeter" + title = "Storage Perimeter" + spec { + restricted_services = ["storage.googleapis.com"] + } + lifecycle { + ignore_changes = [status[0].resources] + } +} + +resource "google_access_context_manager_service_perimeter_dry_run_egress_policy" "egress_policy" { + perimeter = "${google_access_context_manager_service_perimeter.storage-perimeter.name}" + egress_from { + identity_type = "ANY_IDENTITY" + } + egress_to { + resources = ["*"] + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + method = "*" + } + } + } + lifecycle { + create_before_destroy = true + } +} + + +resource "google_access_context_manager_access_policy" "access-policy" { + parent = "organizations/123456789" + title = "Storage Policy" +} diff --git a/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_dry_run_ingress_policy.tf.erb b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_dry_run_ingress_policy.tf.erb new file mode 100644 index 000000000000..df981c843515 --- /dev/null +++ b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_dry_run_ingress_policy.tf.erb @@ -0,0 +1,39 @@ +resource "google_access_context_manager_service_perimeter" "storage-perimeter" { + parent = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}" + name = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}/serviceperimeters/storage-perimeter" + title = "Storage Perimeter" + status { + restricted_services = ["storage.googleapis.com"] + } + lifecycle { + ignore_changes = [status[0].resources] + } +} + +resource "google_access_context_manager_service_perimeter_dry_run_ingress_policy" "ingress_policy" { + perimeter = "${google_access_context_manager_service_perimeter.storage-perimeter.name}" + ingress_from { + identity_type = "any_identity" + sources { + access_level = "*" + } + } + ingress_to { + resources = ["*"] + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + method = "*" + } + } + } + lifecycle { + create_before_destroy = true + } +} + + +resource "google_access_context_manager_access_policy" "access-policy" { + parent = "organizations/123456789" + title = "Storage Policy" +} diff --git a/mmv1/templates/terraform/pre_create/access_context_manager_service_perimeter_dry_run_resource.go.erb b/mmv1/templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb similarity index 100% rename from mmv1/templates/terraform/pre_create/access_context_manager_service_perimeter_dry_run_resource.go.erb rename to mmv1/templates/terraform/pre_create/access_context_manager_dry_run_resource.go.erb diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_access_policy_test.go.erb b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_access_policy_test.go.erb index c588f8d2d450..ac8d6de28d36 100644 --- a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_access_policy_test.go.erb +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_access_policy_test.go.erb @@ -29,7 +29,9 @@ func TestAccAccessContextManager(t *testing.T) { "access_levels": testAccAccessContextManagerAccessLevels_basicTest, "access_level_condition": testAccAccessContextManagerAccessLevelCondition_basicTest, "service_perimeter_egress_policy": testAccAccessContextManagerServicePerimeterEgressPolicy_basicTest, + "service_perimeter_dry_run_egress_policy": testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_basicTest, "service_perimeter_ingress_policy": testAccAccessContextManagerServicePerimeterIngressPolicy_basicTest, + "service_perimeter_dry_run_ingress_policy": testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_basicTest, "service_perimeters": testAccAccessContextManagerServicePerimeters_basicTest, "gcp_user_access_binding": testAccAccessContextManagerGcpUserAccessBinding_basicTest, "authorized_orgs_desc": testAccAccessContextManagerAuthorizedOrgsDesc_basicTest, diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_dry_run_egress_policy_test.go b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_dry_run_egress_policy_test.go new file mode 100644 index 000000000000..e41c2f333a67 --- /dev/null +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_dry_run_egress_policy_test.go @@ -0,0 +1,154 @@ +package accesscontextmanager_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +// 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 testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_basicTest(t *testing.T) { + org := envvar.GetTestOrgFromEnv(t) + //projects := acctest.BootstrapServicePerimeterProjects(t, 1) + policyTitle := acctest.RandString(t, 10) + perimeterTitle := "perimeter" + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_basic(org, policyTitle, perimeterTitle), + }, + { + Config: testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_destroy(org, policyTitle, perimeterTitle), + Check: testAccCheckAccessContextManagerServicePerimeterDryRunEgressPolicyDestroyProducer(t), + }, + }, + }) +} + +func testAccCheckAccessContextManagerServicePerimeterDryRunEgressPolicyDestroyProducer(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_service_perimeter_dry_run_egress_policy" { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{AccessContextManagerBasePath}}{{perimeter}}") + if err != nil { + return err + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + RawURL: url, + UserAgent: config.UserAgent, + }) + if err != nil { + return err + } + + v, ok := res["spec"] + if !ok || v == nil { + return nil + } + + res = v.(map[string]interface{}) + v, ok = res["egress_policies"] + if !ok || v == nil { + return nil + } + + resources := v.([]interface{}) + if len(resources) == 0 { + return nil + } + + return fmt.Errorf("expected 0 resources in perimeter, found %d: %v", len(resources), resources) + } + + return nil + } +} + +func testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_basic(org, policyTitle, perimeterTitleName string) string { + return fmt.Sprintf(` +%s + +resource "google_access_context_manager_access_level" "test-access" { + parent = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}" + name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/accessLevels/level" + title = "level" + description = "hello" + basic { + combining_function = "AND" + conditions { + ip_subnetworks = ["192.0.4.0/24"] + } + } +} + +resource "google_access_context_manager_service_perimeter_dry_run_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_dry_run_egress_policy" "test-access2" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + egress_from { + identity_type = "ANY_USER_ACCOUNT" + sources { + access_level = google_access_context_manager_access_level.test-access.name + } + source_restriction = "SOURCE_RESTRICTION_ENABLED" + } + depends_on = [google_access_context_manager_service_perimeter_dry_run_egress_policy.test-access1] +} + +`, testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_destroy(org, policyTitle, perimeterTitleName)) +} + +func testAccAccessContextManagerServicePerimeterDryRunEgressPolicy_destroy(org, policyTitle, perimeterTitleName string) string { + return fmt.Sprintf(` +resource "google_access_context_manager_access_policy" "test-access" { + parent = "organizations/%s" + title = "%s" +} + +resource "google_access_context_manager_service_perimeter" "test-access" { + parent = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}" + name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/servicePerimeters/%s" + title = "%s" + spec { + restricted_services = ["storage.googleapis.com"] + } + use_explicit_dry_run_spec = true + + lifecycle { + ignore_changes = [spec[0].egress_policies] + } +} +`, org, policyTitle, perimeterTitleName, perimeterTitleName) +} diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_dry_run_ingress_policy_test.go b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_dry_run_ingress_policy_test.go new file mode 100644 index 000000000000..b2b69231b1c3 --- /dev/null +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_dry_run_ingress_policy_test.go @@ -0,0 +1,156 @@ +package accesscontextmanager_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +// 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 testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_basicTest(t *testing.T) { + org := envvar.GetTestOrgFromEnv(t) + //projects := acctest.BootstrapServicePerimeterProjects(t, 1) + policyTitle := acctest.RandString(t, 10) + perimeterTitle := "perimeter" + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_basic(org, policyTitle, perimeterTitle), + }, + { + Config: testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_destroy(org, policyTitle, perimeterTitle), + Check: testAccCheckAccessContextManagerServicePerimeterDryRunIngressPolicyDestroyProducer(t), + }, + }, + }) +} + +func testAccCheckAccessContextManagerServicePerimeterDryRunIngressPolicyDestroyProducer(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_service_perimeter_dry_run_ingress_policy" { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{AccessContextManagerBasePath}}{{perimeter}}") + if err != nil { + return err + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + RawURL: url, + UserAgent: config.UserAgent, + }) + if err != nil { + return err + } + + v, ok := res["spec"] + if !ok || v == nil { + return nil + } + + res = v.(map[string]interface{}) + v, ok = res["ingress_policies"] + if !ok || v == nil { + return nil + } + + resources := v.([]interface{}) + if len(resources) == 0 { + return nil + } + + return fmt.Errorf("expected 0 resources in perimeter, found %d: %v", len(resources), resources) + } + + return nil + } +} + +func testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_basic(org, policyTitle, perimeterTitleName string) string { + return fmt.Sprintf(` +%s + +resource "google_access_context_manager_access_level" "test-access" { + parent = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}" + name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/accessLevels/level" + title = "level" + description = "hello" + basic { + combining_function = "AND" + conditions { + ip_subnetworks = ["192.0.4.0/24"] + } + } +} + +resource "google_access_context_manager_service_perimeter_dry_run_ingress_policy" "test-access1" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + ingress_from { + identity_type = "ANY_USER_ACCOUNT" + sources { + access_level = google_access_context_manager_access_level.test-access.name + } + } + ingress_to { + operations { + service_name = "storage.googleapis.com" + method_selectors { + method = "*" + } + } + } +} + +resource "google_access_context_manager_service_perimeter_dry_run_ingress_policy" "test-access2" { + perimeter = google_access_context_manager_service_perimeter.test-access.name + ingress_from { + identity_type = "ANY_USER_ACCOUNT" + sources { + access_level = google_access_context_manager_access_level.test-access.name + } + } + depends_on = [google_access_context_manager_service_perimeter_dry_run_ingress_policy.test-access1] +} + +`, testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_destroy(org, policyTitle, perimeterTitleName)) +} + +func testAccAccessContextManagerServicePerimeterDryRunIngressPolicy_destroy(org, policyTitle, perimeterTitleName string) string { + return fmt.Sprintf(` +resource "google_access_context_manager_access_policy" "test-access" { + parent = "organizations/%s" + title = "%s" +} + +resource "google_access_context_manager_service_perimeter" "test-access" { + parent = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}" + name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/servicePerimeters/%s" + title = "%s" + spec { + restricted_services = ["storage.googleapis.com"] + } + use_explicit_dry_run_spec = true + + lifecycle { + ignore_changes = [spec[0].ingress_policies] + } +} +`, org, policyTitle, perimeterTitleName, perimeterTitleName) +} diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_egress_policy_test.go b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_egress_policy_test.go index 4da90d018860..e04e313fc3ef 100644 --- a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_egress_policy_test.go +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_egress_policy_test.go @@ -30,11 +30,6 @@ func testAccAccessContextManagerServicePerimeterEgressPolicy_basicTest(t *testin { Config: testAccAccessContextManagerServicePerimeterEgressPolicy_basic(org, policyTitle, perimeterTitle), }, - { - ResourceName: "google_access_context_manager_service_perimeter.test-access", - ImportState: true, - ImportStateVerify: true, - }, { Config: testAccAccessContextManagerServicePerimeterEgressPolicy_destroy(org, policyTitle, perimeterTitle), Check: testAccCheckAccessContextManagerServicePerimeterEgressPolicyDestroyProducer(t), diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_ingress_policy_test.go b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_ingress_policy_test.go index 053a5b2c2829..cf8a4000ecbe 100644 --- a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_ingress_policy_test.go +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_ingress_policy_test.go @@ -30,11 +30,6 @@ func testAccAccessContextManagerServicePerimeterIngressPolicy_basicTest(t *testi { Config: testAccAccessContextManagerServicePerimeterIngressPolicy_basic(org, policyTitle, perimeterTitle), }, - { - ResourceName: "google_access_context_manager_service_perimeter.test-access", - ImportState: true, - ImportStateVerify: true, - }, { Config: testAccAccessContextManagerServicePerimeterIngressPolicy_destroy(org, policyTitle, perimeterTitle), Check: testAccCheckAccessContextManagerServicePerimeterIngressPolicyDestroyProducer(t),