From de90c84eecfde0034426e3c967a9307788cef09f Mon Sep 17 00:00:00 2001
From: Modular Magician <magic-modules@google.com>
Date: Wed, 13 Mar 2024 13:52:16 +0000
Subject: [PATCH] Add fields pathTemplateMatch and pathTemplateRewrite to
 resource google_compute_region_url_map (#10157)

[upstream:48d346d562b56f53668e2b34e1eab4a536ba097a]

Signed-off-by: Modular Magician <magic-modules@google.com>
---
 .changelog/10157.txt                          |   6 +
 .../resource_compute_region_url_map.go        |  64 +++++++++
 ...e_compute_region_url_map_generated_test.go | 118 +++++++++++++++++
 .../r/compute_region_url_map.html.markdown    | 123 ++++++++++++++++++
 4 files changed, 311 insertions(+)
 create mode 100644 .changelog/10157.txt

diff --git a/.changelog/10157.txt b/.changelog/10157.txt
new file mode 100644
index 00000000000..45be4891a39
--- /dev/null
+++ b/.changelog/10157.txt
@@ -0,0 +1,6 @@
+```release-note:enhancement
+compute: added field `path_template_match` to resource `google_compute_region_url_map`
+```
+```release-note:enhancement
+compute: added field `path_template_rewrite` to resource `google_compute_region_url_map`
+```
\ No newline at end of file
diff --git a/google/services/compute/resource_compute_region_url_map.go b/google/services/compute/resource_compute_region_url_map.go
index 048f6b7aa10..19628c63a7b 100644
--- a/google/services/compute/resource_compute_region_url_map.go
+++ b/google/services/compute/resource_compute_region_url_map.go
@@ -1514,6 +1514,19 @@ the provided metadata. Possible values: ["MATCH_ALL", "MATCH_ANY"]`,
 														},
 													},
 												},
+												"path_template_match": {
+													Type:     schema.TypeString,
+													Optional: true,
+													Description: `For satisfying the matchRule condition, the path of the request
+must match the wildcard pattern specified in pathTemplateMatch
+after removing any query parameters and anchor that may be part
+of the original URL.
+
+pathTemplateMatch must be between 1 and 255 characters
+(inclusive).  The pattern specified by pathTemplateMatch may
+have at most 5 wildcard operators and at most 5 variable
+captures in total.`,
+												},
 												"prefix_match": {
 													Type:     schema.TypeString,
 													Optional: true,
@@ -1874,6 +1887,24 @@ header is replaced with contents of hostRewrite. The value must be between 1 and
 portion of the request's path is replaced by pathPrefixRewrite. The value must
 be between 1 and 1024 characters.`,
 															},
+															"path_template_rewrite": {
+																Type:     schema.TypeString,
+																Optional: true,
+																Description: `Prior to forwarding the request to the selected origin, if the
+request matched a pathTemplateMatch, the matching portion of the
+request's path is replaced re-written using the pattern specified
+by pathTemplateRewrite.
+
+pathTemplateRewrite must be between 1 and 255 characters
+(inclusive), must start with a '/', and must only use variables
+captured by the route's pathTemplate matchers.
+
+pathTemplateRewrite may only be used when all of a route's
+MatchRules specify pathTemplate.
+
+Only one of pathPrefixRewrite and pathTemplateRewrite may be
+specified.`,
+															},
 														},
 													},
 												},
@@ -2857,6 +2888,7 @@ func flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRules(v interface{}, d
 			"prefix_match":            flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRulesPrefixMatch(original["prefixMatch"], d, config),
 			"query_parameter_matches": flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRulesQueryParameterMatches(original["queryParameterMatches"], d, config),
 			"regex_match":             flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRulesRegexMatch(original["regexMatch"], d, config),
+			"path_template_match":     flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRulesPathTemplateMatch(original["pathTemplateMatch"], d, config),
 		})
 	}
 	return transformed
@@ -3066,6 +3098,10 @@ func flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRulesRegexMatch(v inter
 	return v
 }
 
+func flattenComputeRegionUrlMapPathMatcherRouteRulesMatchRulesPathTemplateMatch(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+	return v
+}
+
 func flattenComputeRegionUrlMapPathMatcherRouteRulesRouteAction(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
 	if v == nil {
 		return nil
@@ -3412,6 +3448,8 @@ func flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewrite(v inte
 		flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewriteHostRewrite(original["hostRewrite"], d, config)
 	transformed["path_prefix_rewrite"] =
 		flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathPrefixRewrite(original["pathPrefixRewrite"], d, config)
+	transformed["path_template_rewrite"] =
+		flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathTemplateRewrite(original["pathTemplateRewrite"], d, config)
 	return []interface{}{transformed}
 }
 func flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewriteHostRewrite(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
@@ -3422,6 +3460,10 @@ func flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathPre
 	return v
 }
 
+func flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathTemplateRewrite(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+	return v
+}
+
 func flattenComputeRegionUrlMapPathMatcherRouteRulesRouteActionWeightedBackendServices(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
 	if v == nil {
 		return v
@@ -5224,6 +5266,13 @@ func expandComputeRegionUrlMapPathMatcherRouteRulesMatchRules(v interface{}, d t
 			transformed["regexMatch"] = transformedRegexMatch
 		}
 
+		transformedPathTemplateMatch, err := expandComputeRegionUrlMapPathMatcherRouteRulesMatchRulesPathTemplateMatch(original["path_template_match"], d, config)
+		if err != nil {
+			return nil, err
+		} else if val := reflect.ValueOf(transformedPathTemplateMatch); val.IsValid() && !tpgresource.IsEmptyValue(val) {
+			transformed["pathTemplateMatch"] = transformedPathTemplateMatch
+		}
+
 		req = append(req, transformed)
 	}
 	return req, nil
@@ -5507,6 +5556,10 @@ func expandComputeRegionUrlMapPathMatcherRouteRulesMatchRulesRegexMatch(v interf
 	return v, nil
 }
 
+func expandComputeRegionUrlMapPathMatcherRouteRulesMatchRulesPathTemplateMatch(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+	return v, nil
+}
+
 func expandComputeRegionUrlMapPathMatcherRouteRulesRouteAction(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
 	l := v.([]interface{})
 	if len(l) == 0 || l[0] == nil {
@@ -5951,6 +6004,13 @@ func expandComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewrite(v inter
 		transformed["pathPrefixRewrite"] = transformedPathPrefixRewrite
 	}
 
+	transformedPathTemplateRewrite, err := expandComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathTemplateRewrite(original["path_template_rewrite"], d, config)
+	if err != nil {
+		return nil, err
+	} else if val := reflect.ValueOf(transformedPathTemplateRewrite); val.IsValid() && !tpgresource.IsEmptyValue(val) {
+		transformed["pathTemplateRewrite"] = transformedPathTemplateRewrite
+	}
+
 	return transformed, nil
 }
 
@@ -5962,6 +6022,10 @@ func expandComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathPref
 	return v, nil
 }
 
+func expandComputeRegionUrlMapPathMatcherRouteRulesRouteActionUrlRewritePathTemplateRewrite(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+	return v, nil
+}
+
 func expandComputeRegionUrlMapPathMatcherRouteRulesRouteActionWeightedBackendServices(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
 	l := v.([]interface{})
 	req := make([]interface{}, 0, len(l))
diff --git a/google/services/compute/resource_compute_region_url_map_generated_test.go b/google/services/compute/resource_compute_region_url_map_generated_test.go
index fe25e8aa53b..df5ad08d2e6 100644
--- a/google/services/compute/resource_compute_region_url_map_generated_test.go
+++ b/google/services/compute/resource_compute_region_url_map_generated_test.go
@@ -756,6 +756,124 @@ resource "google_compute_region_health_check" "default" {
 `, context)
 }
 
+func TestAccComputeRegionUrlMap_regionUrlMapPathTemplateMatchExample(t *testing.T) {
+	t.Parallel()
+
+	context := map[string]interface{}{
+		"random_suffix": acctest.RandString(t, 10),
+	}
+
+	acctest.VcrTest(t, resource.TestCase{
+		PreCheck:                 func() { acctest.AccTestPreCheck(t) },
+		ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
+		CheckDestroy:             testAccCheckComputeRegionUrlMapDestroyProducer(t),
+		Steps: []resource.TestStep{
+			{
+				Config: testAccComputeRegionUrlMap_regionUrlMapPathTemplateMatchExample(context),
+			},
+			{
+				ResourceName:            "google_compute_region_url_map.urlmap",
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"default_service", "region"},
+			},
+		},
+	})
+}
+
+func testAccComputeRegionUrlMap_regionUrlMapPathTemplateMatchExample(context map[string]interface{}) string {
+	return acctest.Nprintf(`
+resource "google_compute_region_url_map" "urlmap" {
+  region = "us-central1"
+
+  name        = "urlmap%{random_suffix}"
+  description = "a description"
+
+  default_service = google_compute_region_backend_service.home-backend.id
+
+  host_rule {
+    hosts        = ["mysite.com"]
+    path_matcher = "mysite"
+  }
+
+  path_matcher {
+    name            = "mysite"
+    default_service = google_compute_region_backend_service.home-backend.id
+
+    route_rules {
+      match_rules {
+        path_template_match = "/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}"
+      }
+      service = google_compute_region_backend_service.cart-backend.id
+      priority = 1
+      route_action {
+        url_rewrite {
+          path_template_rewrite = "/{username}-{cartid}/"
+        }
+      }
+    }
+
+    route_rules {
+      match_rules {
+        path_template_match = "/xyzwebservices/v2/xyz/users/*/accountinfo/*"
+      }
+      service = google_compute_region_backend_service.user-backend.id
+      priority = 2
+    }
+  }
+}
+
+resource "google_compute_region_backend_service" "home-backend" {
+  region = "us-central1"
+
+  name        = "tf-test-home-service%{random_suffix}"
+  port_name   = "http"
+  protocol    = "HTTP"
+  timeout_sec = 10
+  load_balancing_scheme = "EXTERNAL_MANAGED"
+
+  health_checks = [google_compute_region_health_check.default.id]
+}
+
+resource "google_compute_region_backend_service" "cart-backend" {
+  region = "us-central1"
+
+  name        = "tf-test-cart-service%{random_suffix}"
+  port_name   = "http"
+  protocol    = "HTTP"
+  timeout_sec = 10
+  load_balancing_scheme = "EXTERNAL_MANAGED"
+
+  health_checks = [google_compute_region_health_check.default.id]
+}
+
+resource "google_compute_region_backend_service" "user-backend" {
+  region = "us-central1"
+
+  name        = "tf-test-user-service%{random_suffix}"
+  port_name   = "http"
+  protocol    = "HTTP"
+  timeout_sec = 10
+  load_balancing_scheme = "EXTERNAL_MANAGED"
+
+  health_checks = [google_compute_region_health_check.default.id]
+}
+
+resource "google_compute_region_health_check" "default" {
+  region = "us-central1"
+
+  name               = "tf-test-health-check%{random_suffix}"
+  check_interval_sec = 1
+  timeout_sec        = 1
+  http_health_check {
+    port         = 80
+    request_path = "/"
+  }
+}
+
+`, context)
+}
+
 func testAccCheckComputeRegionUrlMapDestroyProducer(t *testing.T) func(s *terraform.State) error {
 	return func(s *terraform.State) error {
 		for name, rs := range s.RootModule().Resources {
diff --git a/website/docs/r/compute_region_url_map.html.markdown b/website/docs/r/compute_region_url_map.html.markdown
index ea4b7b5b485..9d7e0ca2384 100644
--- a/website/docs/r/compute_region_url_map.html.markdown
+++ b/website/docs/r/compute_region_url_map.html.markdown
@@ -919,6 +919,104 @@ resource "google_compute_region_url_map" "redirect" {
     }
   }
 }
+```
+<div class = "oics-button" style="float: right; margin: 0 0 -15px">
+  <a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=region_url_map_path_template_match&cloudshell_image=gcr.io%2Fcloudshell-images%2Fcloudshell%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
+    <img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
+  </a>
+</div>
+## Example Usage - Region Url Map Path Template Match
+
+
+```hcl
+resource "google_compute_region_url_map" "urlmap" {
+  region = "us-central1"
+
+  name        = "urlmap"
+  description = "a description"
+
+  default_service = google_compute_region_backend_service.home-backend.id
+
+  host_rule {
+    hosts        = ["mysite.com"]
+    path_matcher = "mysite"
+  }
+
+  path_matcher {
+    name            = "mysite"
+    default_service = google_compute_region_backend_service.home-backend.id
+
+    route_rules {
+      match_rules {
+        path_template_match = "/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}"
+      }
+      service = google_compute_region_backend_service.cart-backend.id
+      priority = 1
+      route_action {
+        url_rewrite {
+          path_template_rewrite = "/{username}-{cartid}/"
+        }
+      }
+    }
+
+    route_rules {
+      match_rules {
+        path_template_match = "/xyzwebservices/v2/xyz/users/*/accountinfo/*"
+      }
+      service = google_compute_region_backend_service.user-backend.id
+      priority = 2
+    }
+  }
+}
+
+resource "google_compute_region_backend_service" "home-backend" {
+  region = "us-central1"
+
+  name        = "home-service"
+  port_name   = "http"
+  protocol    = "HTTP"
+  timeout_sec = 10
+  load_balancing_scheme = "EXTERNAL_MANAGED"
+
+  health_checks = [google_compute_region_health_check.default.id]
+}
+
+resource "google_compute_region_backend_service" "cart-backend" {
+  region = "us-central1"
+
+  name        = "cart-service"
+  port_name   = "http"
+  protocol    = "HTTP"
+  timeout_sec = 10
+  load_balancing_scheme = "EXTERNAL_MANAGED"
+
+  health_checks = [google_compute_region_health_check.default.id]
+}
+
+resource "google_compute_region_backend_service" "user-backend" {
+  region = "us-central1"
+
+  name        = "user-service"
+  port_name   = "http"
+  protocol    = "HTTP"
+  timeout_sec = 10
+  load_balancing_scheme = "EXTERNAL_MANAGED"
+
+  health_checks = [google_compute_region_health_check.default.id]
+}
+
+resource "google_compute_region_health_check" "default" {
+  region = "us-central1"
+
+  name               = "health-check"
+  check_interval_sec = 1
+  timeout_sec        = 1
+  http_health_check {
+    port         = 80
+    request_path = "/"
+  }
+}
+
 ```
 
 ## Argument Reference
@@ -1230,6 +1328,17 @@ The following arguments are supported:
   see en.cppreference.com/w/cpp/regex/ecmascript  Only one of prefixMatch,
   fullPathMatch or regexMatch must be specified.
 
+* `path_template_match` -
+  (Optional)
+  For satisfying the matchRule condition, the path of the request
+  must match the wildcard pattern specified in pathTemplateMatch
+  after removing any query parameters and anchor that may be part
+  of the original URL.
+  pathTemplateMatch must be between 1 and 255 characters
+  (inclusive).  The pattern specified by pathTemplateMatch may
+  have at most 5 wildcard operators and at most 5 variable
+  captures in total.
+
 
 <a name="nested_header_matches"></a>The `header_matches` block supports:
 
@@ -1597,6 +1706,20 @@ The following arguments are supported:
   portion of the request's path is replaced by pathPrefixRewrite. The value must
   be between 1 and 1024 characters.
 
+* `path_template_rewrite` -
+  (Optional)
+  Prior to forwarding the request to the selected origin, if the
+  request matched a pathTemplateMatch, the matching portion of the
+  request's path is replaced re-written using the pattern specified
+  by pathTemplateRewrite.
+  pathTemplateRewrite must be between 1 and 255 characters
+  (inclusive), must start with a '/', and must only use variables
+  captured by the route's pathTemplate matchers.
+  pathTemplateRewrite may only be used when all of a route's
+  MatchRules specify pathTemplate.
+  Only one of pathPrefixRewrite and pathTemplateRewrite may be
+  specified.
+
 <a name="nested_weighted_backend_services"></a>The `weighted_backend_services` block supports:
 
 * `backend_service` -