From 52506c8f55d5b11dae81f54e9c2c7d1e1aff723d Mon Sep 17 00:00:00 2001 From: The Magician Date: Wed, 30 Nov 2022 16:42:16 -0800 Subject: [PATCH] Add new Enhanced Origin API fields. (#6846) (#13153) Resolves https://github.com/hashicorp/terraform-provider-google/issues/13073 Signed-off-by: Modular Magician Signed-off-by: Modular Magician --- .changelog/6846.txt | 3 + ...urce_network_services_edge_cache_origin.go | 370 ++++++++++++++++++ ...rvices_edge_cache_origin_generated_test.go | 24 +- ...k_services_edge_cache_origin.html.markdown | 96 ++++- 4 files changed, 489 insertions(+), 4 deletions(-) create mode 100644 .changelog/6846.txt diff --git a/.changelog/6846.txt b/.changelog/6846.txt new file mode 100644 index 0000000000..4048a35e49 --- /dev/null +++ b/.changelog/6846.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +`network_services`: added `origin_override_action` and `origin_redirect` to `google_network_services_edge_cache_origin` +``` diff --git a/google/resource_network_services_edge_cache_origin.go b/google/resource_network_services_edge_cache_origin.go index 48062cd95d..0ff6cee0cb 100644 --- a/google/resource_network_services_edge_cache_origin.go +++ b/google/resource_network_services_edge_cache_origin.go @@ -126,6 +126,105 @@ If no origin returns a valid response, an HTTP 502 will be returned to the clien Defaults to 1. Must be a value greater than 0 and less than 4.`, }, + "origin_override_action": { + Type: schema.TypeList, + Optional: true, + Description: `The override actions, including url rewrites and header +additions, for requests that use this origin.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_action": { + Type: schema.TypeList, + Optional: true, + Description: `The header actions, including adding and removing +headers, for request handled by this origin.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "request_headers_to_add": { + Type: schema.TypeList, + Optional: true, + Description: `Describes a header to add. + +You may add a maximum of 5 request headers.`, + MinItems: 1, + MaxItems: 5, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_name": { + Type: schema.TypeString, + Required: true, + Description: `The name of the header to add.`, + }, + "header_value": { + Type: schema.TypeString, + Required: true, + Description: `The value of the header to add.`, + }, + "replace": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether to replace all existing headers with the same name. + +By default, added header values are appended +to the response or request headers with the +same field names. The added values are +separated by commas. + +To overwrite existing values, set 'replace' to 'true'.`, + }, + }, + }, + }, + }, + }, + }, + "url_rewrite": { + Type: schema.TypeList, + Optional: true, + Description: `The URL rewrite configuration for request that are +handled by this origin.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host_rewrite": { + Type: schema.TypeString, + Optional: true, + Description: `Prior to forwarding the request to the selected +origin, the request's host header is replaced with +contents of the hostRewrite. + +This value must be between 1 and 255 characters.`, + }, + }, + }, + }, + }, + }, + }, + "origin_redirect": { + Type: schema.TypeList, + Optional: true, + Description: `Follow redirects from this origin.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "redirect_conditions": { + Type: schema.TypeList, + Optional: true, + Description: `The set of redirect response codes that the CDN +follows. Values of +[RedirectConditions](https://cloud.google.com/media-cdn/docs/reference/rest/v1/projects.locations.edgeCacheOrigins#redirectconditions) +are accepted.`, + MaxItems: 5, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, "port": { Type: schema.TypeInt, Computed: true, @@ -304,6 +403,18 @@ func resourceNetworkServicesEdgeCacheOriginCreate(d *schema.ResourceData, meta i } else if v, ok := d.GetOkExists("aws_v4_authentication"); !isEmptyValue(reflect.ValueOf(awsV4AuthenticationProp)) && (ok || !reflect.DeepEqual(v, awsV4AuthenticationProp)) { obj["awsV4Authentication"] = awsV4AuthenticationProp } + originOverrideActionProp, err := expandNetworkServicesEdgeCacheOriginOriginOverrideAction(d.Get("origin_override_action"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("origin_override_action"); !isEmptyValue(reflect.ValueOf(originOverrideActionProp)) && (ok || !reflect.DeepEqual(v, originOverrideActionProp)) { + obj["originOverrideAction"] = originOverrideActionProp + } + originRedirectProp, err := expandNetworkServicesEdgeCacheOriginOriginRedirect(d.Get("origin_redirect"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("origin_redirect"); !isEmptyValue(reflect.ValueOf(originRedirectProp)) && (ok || !reflect.DeepEqual(v, originRedirectProp)) { + obj["originRedirect"] = originRedirectProp + } url, err := replaceVars(d, config, "{{NetworkServicesBasePath}}projects/{{project}}/locations/global/edgeCacheOrigins?edgeCacheOriginId={{name}}") if err != nil { @@ -415,6 +526,12 @@ func resourceNetworkServicesEdgeCacheOriginRead(d *schema.ResourceData, meta int if err := d.Set("aws_v4_authentication", flattenNetworkServicesEdgeCacheOriginAwsV4Authentication(res["awsV4Authentication"], d, config)); err != nil { return fmt.Errorf("Error reading EdgeCacheOrigin: %s", err) } + if err := d.Set("origin_override_action", flattenNetworkServicesEdgeCacheOriginOriginOverrideAction(res["originOverrideAction"], d, config)); err != nil { + return fmt.Errorf("Error reading EdgeCacheOrigin: %s", err) + } + if err := d.Set("origin_redirect", flattenNetworkServicesEdgeCacheOriginOriginRedirect(res["originRedirect"], d, config)); err != nil { + return fmt.Errorf("Error reading EdgeCacheOrigin: %s", err) + } return nil } @@ -495,6 +612,18 @@ func resourceNetworkServicesEdgeCacheOriginUpdate(d *schema.ResourceData, meta i } else if v, ok := d.GetOkExists("aws_v4_authentication"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, awsV4AuthenticationProp)) { obj["awsV4Authentication"] = awsV4AuthenticationProp } + originOverrideActionProp, err := expandNetworkServicesEdgeCacheOriginOriginOverrideAction(d.Get("origin_override_action"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("origin_override_action"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, originOverrideActionProp)) { + obj["originOverrideAction"] = originOverrideActionProp + } + originRedirectProp, err := expandNetworkServicesEdgeCacheOriginOriginRedirect(d.Get("origin_redirect"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("origin_redirect"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, originRedirectProp)) { + obj["originRedirect"] = originRedirectProp + } url, err := replaceVars(d, config, "{{NetworkServicesBasePath}}projects/{{project}}/locations/global/edgeCacheOrigins/{{name}}") if err != nil { @@ -543,6 +672,14 @@ func resourceNetworkServicesEdgeCacheOriginUpdate(d *schema.ResourceData, meta i if d.HasChange("aws_v4_authentication") { updateMask = append(updateMask, "awsV4Authentication") } + + if d.HasChange("origin_override_action") { + updateMask = append(updateMask, "originOverrideAction") + } + + if d.HasChange("origin_redirect") { + updateMask = append(updateMask, "originRedirect") + } // updateMask is a URL parameter but not present in the schema, so replaceVars // won't set it url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -750,6 +887,100 @@ func flattenNetworkServicesEdgeCacheOriginAwsV4AuthenticationOriginRegion(v inte return v } +func flattenNetworkServicesEdgeCacheOriginOriginOverrideAction(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["url_rewrite"] = + flattenNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewrite(original["urlRewrite"], d, config) + transformed["header_action"] = + flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderAction(original["headerAction"], d, config) + return []interface{}{transformed} +} +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewrite(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["host_rewrite"] = + flattenNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewriteHostRewrite(original["hostRewrite"], d, config) + return []interface{}{transformed} +} +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewriteHostRewrite(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderAction(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["request_headers_to_add"] = + flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAdd(original["requestHeadersToAdd"], d, config) + return []interface{}{transformed} +} +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAdd(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "header_name": flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderName(original["headerName"], d, config), + "header_value": flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderValue(original["headerValue"], d, config), + "replace": flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddReplace(original["replace"], d, config), + }) + } + return transformed +} +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderValue(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddReplace(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenNetworkServicesEdgeCacheOriginOriginRedirect(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["redirect_conditions"] = + flattenNetworkServicesEdgeCacheOriginOriginRedirectRedirectConditions(original["redirectConditions"], d, config) + return []interface{}{transformed} +} +func flattenNetworkServicesEdgeCacheOriginOriginRedirectRedirectConditions(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + func expandNetworkServicesEdgeCacheOriginDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } @@ -889,3 +1120,142 @@ func expandNetworkServicesEdgeCacheOriginAwsV4AuthenticationSecretAccessKeyVersi func expandNetworkServicesEdgeCacheOriginAwsV4AuthenticationOriginRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } + +func expandNetworkServicesEdgeCacheOriginOriginOverrideAction(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedUrlRewrite, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewrite(original["url_rewrite"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUrlRewrite); val.IsValid() && !isEmptyValue(val) { + transformed["urlRewrite"] = transformedUrlRewrite + } + + transformedHeaderAction, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderAction(original["header_action"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHeaderAction); val.IsValid() && !isEmptyValue(val) { + transformed["headerAction"] = transformedHeaderAction + } + + return transformed, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewrite(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedHostRewrite, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewriteHostRewrite(original["host_rewrite"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHostRewrite); val.IsValid() && !isEmptyValue(val) { + transformed["hostRewrite"] = transformedHostRewrite + } + + return transformed, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionUrlRewriteHostRewrite(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderAction(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedRequestHeadersToAdd, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAdd(original["request_headers_to_add"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRequestHeadersToAdd); val.IsValid() && !isEmptyValue(val) { + transformed["requestHeadersToAdd"] = transformedRequestHeadersToAdd + } + + return transformed, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAdd(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedHeaderName, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderName(original["header_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHeaderName); val.IsValid() && !isEmptyValue(val) { + transformed["headerName"] = transformedHeaderName + } + + transformedHeaderValue, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderValue(original["header_value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHeaderValue); val.IsValid() && !isEmptyValue(val) { + transformed["headerValue"] = transformedHeaderValue + } + + transformedReplace, err := expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddReplace(original["replace"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedReplace); val.IsValid() && !isEmptyValue(val) { + transformed["replace"] = transformedReplace + } + + req = append(req, transformed) + } + return req, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddHeaderValue(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddReplace(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginRedirect(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedRedirectConditions, err := expandNetworkServicesEdgeCacheOriginOriginRedirectRedirectConditions(original["redirect_conditions"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRedirectConditions); val.IsValid() && !isEmptyValue(val) { + transformed["redirectConditions"] = transformedRedirectConditions + } + + return transformed, nil +} + +func expandNetworkServicesEdgeCacheOriginOriginRedirectRedirectConditions(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_network_services_edge_cache_origin_generated_test.go b/google/resource_network_services_edge_cache_origin_generated_test.go index 7410ca9c1a..418a577f26 100644 --- a/google/resource_network_services_edge_cache_origin_generated_test.go +++ b/google/resource_network_services_edge_cache_origin_generated_test.go @@ -85,10 +85,9 @@ func TestAccNetworkServicesEdgeCacheOrigin_networkServicesEdgeCacheOriginAdvance func testAccNetworkServicesEdgeCacheOrigin_networkServicesEdgeCacheOriginAdvancedExample(context map[string]interface{}) string { return Nprintf(` - resource "google_network_services_edge_cache_origin" "fallback" { name = "tf-test-my-fallback%{random_suffix}" - origin_address = "gs://media-edge-fallback" + origin_address = "fallback.example.com" description = "The default bucket for media edge test" max_attempts = 3 protocol = "HTTP" @@ -106,6 +105,27 @@ resource "google_network_services_edge_cache_origin" "fallback" { response_timeout = "60s" read_timeout = "5s" } + origin_override_action { + url_rewrite { + host_rewrite = "example.com" + } + header_action { + request_headers_to_add { + header_name = "x-header" + header_value = "value" + replace = true + } + } + } + origin_redirect { + redirect_conditions = [ + "MOVED_PERMANENTLY", + "FOUND", + "SEE_OTHER", + "TEMPORARY_REDIRECT", + "PERMANENT_REDIRECT", + ] + } } resource "google_network_services_edge_cache_origin" "default" { diff --git a/website/docs/r/network_services_edge_cache_origin.html.markdown b/website/docs/r/network_services_edge_cache_origin.html.markdown index 290e23573e..4a7bfaf7ff 100644 --- a/website/docs/r/network_services_edge_cache_origin.html.markdown +++ b/website/docs/r/network_services_edge_cache_origin.html.markdown @@ -48,10 +48,9 @@ resource "google_network_services_edge_cache_origin" "default" { ```hcl - resource "google_network_services_edge_cache_origin" "fallback" { name = "my-fallback" - origin_address = "gs://media-edge-fallback" + origin_address = "fallback.example.com" description = "The default bucket for media edge test" max_attempts = 3 protocol = "HTTP" @@ -69,6 +68,27 @@ resource "google_network_services_edge_cache_origin" "fallback" { response_timeout = "60s" read_timeout = "5s" } + origin_override_action { + url_rewrite { + host_rewrite = "example.com" + } + header_action { + request_headers_to_add { + header_name = "x-header" + header_value = "value" + replace = true + } + } + } + origin_redirect { + redirect_conditions = [ + "MOVED_PERMANENTLY", + "FOUND", + "SEE_OTHER", + "TEMPORARY_REDIRECT", + "PERMANENT_REDIRECT", + ] + } } resource "google_network_services_edge_cache_origin" "default" { @@ -207,6 +227,17 @@ The following arguments are supported: Enable AWS Signature Version 4 origin authentication. Structure is [documented below](#nested_aws_v4_authentication). +* `origin_override_action` - + (Optional) + The override actions, including url rewrites and header + additions, for requests that use this origin. + Structure is [documented below](#nested_origin_override_action). + +* `origin_redirect` - + (Optional) + Follow redirects from this origin. + Structure is [documented below](#nested_origin_redirect). + * `project` - (Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used. @@ -255,6 +286,67 @@ The following arguments are supported: (Required) The name of the AWS region that your origin is in. +The `origin_override_action` block supports: + +* `url_rewrite` - + (Optional) + The URL rewrite configuration for request that are + handled by this origin. + Structure is [documented below](#nested_url_rewrite). + +* `header_action` - + (Optional) + The header actions, including adding and removing + headers, for request handled by this origin. + Structure is [documented below](#nested_header_action). + + +The `url_rewrite` block supports: + +* `host_rewrite` - + (Optional) + Prior to forwarding the request to the selected + origin, the request's host header is replaced with + contents of the hostRewrite. + This value must be between 1 and 255 characters. + +The `header_action` block supports: + +* `request_headers_to_add` - + (Optional) + Describes a header to add. + You may add a maximum of 5 request headers. + Structure is [documented below](#nested_request_headers_to_add). + + +The `request_headers_to_add` block supports: + +* `header_name` - + (Required) + The name of the header to add. + +* `header_value` - + (Required) + The value of the header to add. + +* `replace` - + (Optional) + Whether to replace all existing headers with the same name. + By default, added header values are appended + to the response or request headers with the + same field names. The added values are + separated by commas. + To overwrite existing values, set `replace` to `true`. + +The `origin_redirect` block supports: + +* `redirect_conditions` - + (Optional) + The set of redirect response codes that the CDN + follows. Values of + [RedirectConditions](https://cloud.google.com/media-cdn/docs/reference/rest/v1/projects.locations.edgeCacheOrigins#redirectconditions) + are accepted. + ## Attributes Reference In addition to the arguments listed above, the following computed attributes are exported: