diff --git a/mmv1/products/networkservices/Gateway.yaml b/mmv1/products/networkservices/Gateway.yaml index 99e3df6ad299..653d8d061e86 100644 --- a/mmv1/products/networkservices/Gateway.yaml +++ b/mmv1/products/networkservices/Gateway.yaml @@ -53,8 +53,9 @@ async: message: 'message' custom_code: constants: 'templates/terraform/constants/network_services_gateway.go.tmpl' + pre_create: 'templates/terraform/pre_create/network_services_gateway.go.tmpl' post_delete: 'templates/terraform/post_delete/network_services_gateway.go.tmpl' - pre_update: 'templates/terraform/pre_update/network_services_gateway.tmpl' + pre_update: 'templates/terraform/pre_update/network_services_gateway.go.tmpl' examples: - name: 'network_services_gateway_basic' primary_resource_id: 'default' @@ -206,3 +207,12 @@ properties: This feature only applies to gateways of type 'SECURE_WEB_GATEWAY'. item_type: type: String + - name: 'routingMode' + type: Enum + immutable: true + description: | + The routing mode of the Gateway. This field is configurable only for gateways of type SECURE_WEB_GATEWAY. This field is required for gateways of type SECURE_WEB_GATEWAY. + custom_flatten: 'templates/terraform/custom_flatten/network_services_gateway_routing_mode.go.tmpl' + enum_values: + - 'EXPLICIT_ROUTING_MODE' + - 'NEXT_HOP_ROUTING_MODE' diff --git a/mmv1/templates/terraform/custom_flatten/network_services_gateway_routing_mode.go.tmpl b/mmv1/templates/terraform/custom_flatten/network_services_gateway_routing_mode.go.tmpl new file mode 100644 index 000000000000..783c84a3b648 --- /dev/null +++ b/mmv1/templates/terraform/custom_flatten/network_services_gateway_routing_mode.go.tmpl @@ -0,0 +1,18 @@ +{{/* + The license inside this block applies to this file + 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. +*/ -}} +func flatten{{$.GetPrefix}}{{$.TitlelizeProperty}}(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if d.Get("type") == "SECURE_WEB_GATEWAY" && v == nil { + return "EXPLICIT_ROUTING_MODE" + } + return v +} diff --git a/mmv1/templates/terraform/examples/network_services_gateway_multiple_swp_same_network.tf.tmpl b/mmv1/templates/terraform/examples/network_services_gateway_multiple_swp_same_network.tf.tmpl index 200f38d39928..b5a4cf6911bc 100644 --- a/mmv1/templates/terraform/examples/network_services_gateway_multiple_swp_same_network.tf.tmpl +++ b/mmv1/templates/terraform/examples/network_services_gateway_multiple_swp_same_network.tf.tmpl @@ -51,6 +51,7 @@ resource "google_network_services_gateway" "{{$.PrimaryResourceId}}" { location = "us-south1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] scope = "{{index $.Vars "scope_1"}}" certificate_urls = [google_certificate_manager_certificate.default.id] @@ -66,6 +67,7 @@ resource "google_network_services_gateway" "gateway2" { location = "us-south1" addresses = ["10.128.0.98"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] scope = "{{index $.Vars "scope_2"}}" certificate_urls = [google_certificate_manager_certificate.default.id] diff --git a/mmv1/templates/terraform/examples/network_services_gateway_secure_web_proxy.tf.tmpl b/mmv1/templates/terraform/examples/network_services_gateway_secure_web_proxy.tf.tmpl index dd0446334b48..de03b6a79bba 100644 --- a/mmv1/templates/terraform/examples/network_services_gateway_secure_web_proxy.tf.tmpl +++ b/mmv1/templates/terraform/examples/network_services_gateway_secure_web_proxy.tf.tmpl @@ -51,6 +51,7 @@ resource "google_network_services_gateway" "{{$.PrimaryResourceId}}" { location = "us-central1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] scope = "{{index $.Vars "scope_1"}}" certificate_urls = [google_certificate_manager_certificate.default.id] diff --git a/mmv1/templates/terraform/pre_create/network_services_gateway.go.tmpl b/mmv1/templates/terraform/pre_create/network_services_gateway.go.tmpl new file mode 100644 index 000000000000..ac3d3391bb91 --- /dev/null +++ b/mmv1/templates/terraform/pre_create/network_services_gateway.go.tmpl @@ -0,0 +1,3 @@ +if obj["type"] == "SECURE_WEB_GATEWAY" && obj["routingMode"] == nil { + return fmt.Errorf("Field routing_mode is required for Gateway of type SECURE_WEB_GATEWAY") +} \ No newline at end of file diff --git a/mmv1/templates/terraform/pre_update/network_services_gateway.tmpl b/mmv1/templates/terraform/pre_update/network_services_gateway.go.tmpl similarity index 68% rename from mmv1/templates/terraform/pre_update/network_services_gateway.tmpl rename to mmv1/templates/terraform/pre_update/network_services_gateway.go.tmpl index feed1adcc26e..3f976f267b19 100644 --- a/mmv1/templates/terraform/pre_update/network_services_gateway.tmpl +++ b/mmv1/templates/terraform/pre_update/network_services_gateway.go.tmpl @@ -1,4 +1,5 @@ if d.Get("type") == "SECURE_WEB_GATEWAY" { obj["name"] = d.Get("name") obj["type"] = d.Get("type") + obj["routingMode"] = d.Get("routingMode") } \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_service_attachment_test.go.tmpl b/mmv1/third_party/terraform/services/compute/resource_compute_service_attachment_test.go.tmpl index b8dd4990c9d7..eec80a76d674 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_service_attachment_test.go.tmpl +++ b/mmv1/third_party/terraform/services/compute/resource_compute_service_attachment_test.go.tmpl @@ -491,6 +491,7 @@ resource "google_network_services_gateway" "foobar" { location = "us-east1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "my description" scope = "%s" diff --git a/mmv1/third_party/terraform/services/networkservices/resource_network_services_gateway_test.go b/mmv1/third_party/terraform/services/networkservices/resource_network_services_gateway_test.go index b889daba865e..352d6962e309 100644 --- a/mmv1/third_party/terraform/services/networkservices/resource_network_services_gateway_test.go +++ b/mmv1/third_party/terraform/services/networkservices/resource_network_services_gateway_test.go @@ -155,6 +155,7 @@ resource "google_network_services_gateway" "default" { config += acctest.Nprintf(` type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] scope = "tf-test-my-default-scope-%{random_suffix}" certificate_urls = [google_certificate_manager_certificate.default.id] @@ -265,6 +266,7 @@ resource "google_network_services_gateway" "foobar" { location = "us-east1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "my description" scope = "%s" @@ -358,6 +360,7 @@ resource "google_network_services_gateway" "foobar" { location = "us-east1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "updated description" scope = "%s" @@ -467,6 +470,7 @@ resource "google_network_services_gateway" "gateway1" { location = "us-west1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "gateway1_subnet1" scope = "%s" @@ -492,6 +496,7 @@ resource "google_network_services_gateway" "gateway2" { location = "us-west1" addresses = ["10.142.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "gateway2_subnet2" scope = "%s" @@ -561,6 +566,7 @@ resource "google_network_services_gateway" "gateway1" { location = "us-west1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "gateway1_subnet1" scope = "%s" @@ -683,6 +689,7 @@ resource "google_network_services_gateway" "gateway1" { location = "us-west2" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "gateway1_subnet1" scope = "%s" @@ -723,6 +730,7 @@ resource "google_network_services_gateway" "gateway2" { location = "us-west2" addresses = ["10.142.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "gateway2_subnet2" scope = "%s" @@ -792,6 +800,7 @@ resource "google_network_services_gateway" "gateway1" { location = "us-west2" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "gateway1_subnet1" scope = "%s" @@ -904,6 +913,7 @@ resource "google_network_services_gateway" "foobar" { location = "us-central1" addresses = ["10.128.0.99"] type = "SECURE_WEB_GATEWAY" + routing_mode = "EXPLICIT_ROUTING_MODE" ports = [443] description = "my description" gateway_security_policy = google_network_security_gateway_security_policy.default.id @@ -914,3 +924,218 @@ resource "google_network_services_gateway" "foobar" { } `, netName, subnetName, pSubnetName, policyName, ruleName, gatewayName) } + +func TestAccNetworkServicesGateway_swpAsNextHop(t *testing.T) { + context := map[string]interface{}{ + "region": "us-east1", + "random_suffix": fmt.Sprintf("-%s", acctest.RandString(t, 10)), + "name_prefix": "tf-test-gateway-", + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckNetworkServicesGatewayDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccNetworkServicesGateway_swpAsNextHop(context), + }, + { + ResourceName: "google_network_services_gateway.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "delete_swg_autogen_router_on_destroy"}, + }, + }, + }) +} + +func testAccNetworkServicesGateway_swpAsNextHop(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_compute_network" "default" { + name = "%{name_prefix}network%{random_suffix}" + routing_mode = "REGIONAL" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "proxyonlysubnet" { + name = "%{name_prefix}proxysubnet%{random_suffix}" + purpose = "REGIONAL_MANAGED_PROXY" + ip_cidr_range = "192.168.0.0/23" + region = "%{region}" + network = google_compute_network.default.id + role = "ACTIVE" +} + +resource "google_compute_subnetwork" "default" { + name = "%{name_prefix}subnet%{random_suffix}" + purpose = "PRIVATE" + ip_cidr_range = "10.128.0.0/20" + region = "%{region}" + network = google_compute_network.default.id + role = "ACTIVE" +} + +resource "google_privateca_ca_pool" "default" { + name = "%{name_prefix}ca-pool%{random_suffix}" + location = "%{region}" + tier = "DEVOPS" + + publishing_options { + publish_ca_cert = false + publish_crl = false + } + + issuance_policy { + maximum_lifetime = "1209600s" + baseline_values { + ca_options { + is_ca = false + } + key_usage { + base_key_usage {} + extended_key_usage { + server_auth = true + } + } + } + } +} + +resource "google_privateca_certificate_authority" "default" { + pool = google_privateca_ca_pool.default.name + certificate_authority_id = "%{name_prefix}certificate-authority%{random_suffix}" + location = "%{region}" + lifetime = "86400s" + type = "SELF_SIGNED" + deletion_protection = false + skip_grace_period = true + ignore_active_certificates_on_deletion = true + + config { + subject_config { + subject { + organization = "Test LLC" + common_name = "private-certificate-authority" + } + } + x509_config { + ca_options { + is_ca = true + } + key_usage { + base_key_usage { + cert_sign = true + crl_sign = true + } + extended_key_usage { + server_auth = false + } + } + } + } + + key_spec { + algorithm = "RSA_PKCS1_4096_SHA256" + } +} + +resource "google_certificate_manager_certificate" "default" { + name = "%{name_prefix}certificate%{random_suffix}" + location = "%{region}" + + self_managed { + pem_certificate = file("test-fixtures/cert.pem") + pem_private_key = file("test-fixtures/private-key.pem") + } +} + +resource "google_network_security_tls_inspection_policy" "default" { + name = "%{name_prefix}tls-insp-policy%{random_suffix}" + location = "%{region}" + ca_pool = google_privateca_ca_pool.default.id + + depends_on = [ + google_privateca_ca_pool.default, + google_privateca_certificate_authority.default + ] +} + +resource "google_network_security_gateway_security_policy" "default" { + name = "%{name_prefix}sec-policy%{random_suffix}" + location = "%{region}" + description = "my description" + tls_inspection_policy = google_network_security_tls_inspection_policy.default.id + + depends_on = [ + google_network_security_tls_inspection_policy.default + ] +} + +resource "google_network_security_gateway_security_policy_rule" "default" { + name = "%{name_prefix}sec-policy-rule%{random_suffix}" + location = "%{region}" + gateway_security_policy = google_network_security_gateway_security_policy.default.name + enabled = true + description = "my description" + priority = 0 + session_matcher = "host() == 'example.com'" + application_matcher = "request.method == 'POST'" + tls_inspection_enabled = true + basic_profile = "ALLOW" +} + +resource "google_network_services_gateway" "default" { + name = "%{name_prefix}swp%{random_suffix}" + location = "%{region}" + addresses = ["10.128.0.99"] + type = "SECURE_WEB_GATEWAY" + routing_mode = "NEXT_HOP_ROUTING_MODE" + ports = [443] + description = "my description" + scope = "%s" + certificate_urls = [google_certificate_manager_certificate.default.id] + gateway_security_policy = google_network_security_gateway_security_policy.default.id + network = google_compute_network.default.id + subnetwork = google_compute_subnetwork.default.id + delete_swg_autogen_router_on_destroy = true + depends_on = [google_compute_subnetwork.proxyonlysubnet] +} + +resource "google_compute_route" "default" { + name = "%{name_prefix}route%{random_suffix}" + dest_range = "15.0.0.0/24" + network = google_compute_network.default.name + next_hop_ip = google_network_services_gateway.default.addresses[0] + priority = 100 +} + +resource "google_network_connectivity_policy_based_route" "swproute" { + name = "%{name_prefix}policy-based-swp-route%{random_suffix}" + description = "My routing policy" + network = google_compute_network.default.id + next_hop_ilb_ip = google_network_services_gateway.default.addresses[0] + priority = 2 + + filter { + protocol_version = "IPV4" + src_range = "10.0.0.0/24" + dest_range = "15.0.0.0/24" + } +} + +resource "google_network_connectivity_policy_based_route" "default" { + name = "%{name_prefix}policy-based-route%{random_suffix}" + description = "My routing policy" + network = google_compute_network.default.id + next_hop_other_routes = "DEFAULT_ROUTING" + priority = 1 + + filter { + protocol_version = "IPV4" + src_range = "10.0.0.0/24" + dest_range = "15.0.0.0/24" + } +} + `, context) +}