From 732ba398bf31ac39ef6e17ebf27db570b178958b Mon Sep 17 00:00:00 2001 From: Ty Larrabee Date: Mon, 9 Dec 2019 17:34:45 -0800 Subject: [PATCH] Add route_rules to RegionUrlMap (#2807) Merged PR #2807. --- build/ansible | 2 +- build/inspec | 2 +- build/terraform | 2 +- build/terraform-beta | 2 +- build/terraform-mapper | 2 +- products/compute/api.yaml | 690 ++++++++++++++++++ products/compute/terraform.yaml | 14 + .../region_url_map_l7_ilb_route.tf.erb | 85 +++ ...region_url_map_l7_ilb_route_partial.tf.erb | 61 ++ ...esource_compute_region_url_map_test.go.erb | 209 ++++++ 10 files changed, 1064 insertions(+), 5 deletions(-) create mode 100644 templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb create mode 100644 templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb diff --git a/build/ansible b/build/ansible index 29001a3c6a48..6bc2d2006a6b 160000 --- a/build/ansible +++ b/build/ansible @@ -1 +1 @@ -Subproject commit 29001a3c6a480e4559d1b4a1e030d2ea63a8a5d7 +Subproject commit 6bc2d2006a6b0bf29dcabd4829cc65c61af7dda2 diff --git a/build/inspec b/build/inspec index 8b46d0a6905f..d71382723747 160000 --- a/build/inspec +++ b/build/inspec @@ -1 +1 @@ -Subproject commit 8b46d0a6905f22efe995e18973d06b9f4ec1a12f +Subproject commit d7138272374753efa90513d3849b37663c6edbe5 diff --git a/build/terraform b/build/terraform index df454bdc74a9..6c8ef61974fa 160000 --- a/build/terraform +++ b/build/terraform @@ -1 +1 @@ -Subproject commit df454bdc74a93cd960a393a213e0f8c238d08d5a +Subproject commit 6c8ef61974fa2011f8105e233915697929904c46 diff --git a/build/terraform-beta b/build/terraform-beta index a5a15b825743..7743e40d0852 160000 --- a/build/terraform-beta +++ b/build/terraform-beta @@ -1 +1 @@ -Subproject commit a5a15b8257433dd4197d475a936c80e2a3f05896 +Subproject commit 7743e40d08525ab2c5fef602150bdb1f847b9729 diff --git a/build/terraform-mapper b/build/terraform-mapper index faa52548d023..43d9f58687b3 160000 --- a/build/terraform-mapper +++ b/build/terraform-mapper @@ -1 +1 @@ -Subproject commit faa52548d02395d47daae1d7204dc78d07914a91 +Subproject commit 43d9f58687b33d0f8dbb5949075d8436e66261c0 diff --git a/products/compute/api.yaml b/products/compute/api.yaml index efc8f7b3a092..2285cda7d8e7 100644 --- a/products/compute/api.yaml +++ b/products/compute/api.yaml @@ -7887,6 +7887,683 @@ objects: required: true description: | The name to which this PathMatcher is referred by the HostRule. + - !ruby/object:Api::Type::Array + name: 'routeRules' + description: | + The list of ordered HTTP route rules. Use this list instead of pathRules when + advanced route matching and routing actions are desired. The order of specifying + routeRules matters: the first rule that matches will cause its specified routing + action to take effect. Within a given pathMatcher, only one of pathRules or + routeRules must be set. routeRules are not supported in UrlMaps intended for + External load balancers. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Integer + name: 'priority' + required: true + description: | + For routeRules within a given pathMatcher, priority determines the order + in which load balancer will interpret routeRules. RouteRules are evaluated + in order of priority, from the lowest to highest number. The priority of + a rule decreases as its number increases (1, 2, 3, N+1). The first rule + that matches the request is applied. + + You cannot configure two or more routeRules with the same priority. + Priority for each rule must be set to a number between 0 and + 2147483647 inclusive. + + Priority numbers can have gaps, which enable you to add or remove rules + in the future without affecting the rest of the rules. For example, + 1, 2, 3, 4, 5, 9, 12, 16 is a valid series of priority numbers to which + you could add rules numbered from 6 to 8, 10 to 11, and 13 to 15 in the + future without any impact on existing rules. + - !ruby/object:Api::Type::ResourceRef + name: 'service' + resource: 'RegionBackendService' + imports: 'selfLink' + description: | + The region backend service resource to which traffic is + directed if this rule is matched. If routeAction is additionally specified, + advanced routing actions like URL Rewrites, etc. take effect prior to sending + the request to the backend. However, if service is specified, routeAction cannot + contain any weightedBackendService s. Conversely, if routeAction specifies any + weightedBackendServices, service must not be specified. Only one of urlRedirect, + service or routeAction.weightedBackendService must be set. + - !ruby/object:Api::Type::NestedObject + name: 'headerAction' + description: | + Specifies changes to request and response headers that need to take effect for + the selected backendService. The headerAction specified here are applied before + the matching pathMatchers[].headerAction and after pathMatchers[].routeRules[].r + outeAction.weightedBackendService.backendServiceWeightAction[].headerAction + properties: + - !ruby/object:Api::Type::Array + name: 'requestHeadersToAdd' + description: | + Headers to add to a matching request prior to forwarding the request to the + backendService. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'headerName' + required: true + description: | + The name of the header. + - !ruby/object:Api::Type::String + name: 'headerValue' + required: true + description: | + The value of the header to add. + - !ruby/object:Api::Type::Boolean + name: 'replace' + required: true + description: | + If false, headerValue is appended to any values that already exist for the + header. If true, headerValue is set for the header, discarding any values that + were set for that header. + - !ruby/object:Api::Type::Array + name: 'requestHeadersToRemove' + item_type: Api::Type::String + description: | + A list of header names for headers that need to be removed from the request + prior to forwarding the request to the backendService. + - !ruby/object:Api::Type::Array + name: 'responseHeadersToAdd' + description: | + Headers to add the response prior to sending the response back to the client. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'headerName' + required: true + description: | + The name of the header. + - !ruby/object:Api::Type::String + name: 'headerValue' + required: true + description: | + The value of the header to add. + - !ruby/object:Api::Type::Boolean + name: 'replace' + required: true + description: | + If false, headerValue is appended to any values that already exist for the + header. If true, headerValue is set for the header, discarding any values that + were set for that header. + - !ruby/object:Api::Type::Array + name: 'responseHeadersToRemove' + item_type: Api::Type::String + description: | + A list of header names for headers that need to be removed from the response + prior to sending the response back to the client. + - !ruby/object:Api::Type::Array + name: 'matchRules' + description: | + The rules for determining a match. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'fullPathMatch' + description: | + For satifying the matchRule condition, the path of the request must exactly + match the value specified in fullPathMatch after removing any query parameters + and anchor that may be part of the original URL. FullPathMatch must be between 1 + and 1024 characters. Only one of prefixMatch, fullPathMatch or regexMatch must + be specified. + - !ruby/object:Api::Type::Array + name: 'headerMatches' + description: | + Specifies a list of header match criteria, all of which must match corresponding + headers in the request. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'exactMatch' + description: | + The value should exactly match contents of exactMatch. Only one of exactMatch, + prefixMatch, suffixMatch, regexMatch, presentMatch or rangeMatch must be set. + - !ruby/object:Api::Type::String + name: 'headerName' + required: true + description: | + The name of the HTTP header to match. For matching against the HTTP request's + authority, use a headerMatch with the header name ":authority". For matching a + request's method, use the headerName ":method". + - !ruby/object:Api::Type::Boolean + name: 'invertMatch' + default_value: false + description: | + If set to false, the headerMatch is considered a match if the match criteria + above are met. If set to true, the headerMatch is considered a match if the + match criteria above are NOT met. Defaults to false. + - !ruby/object:Api::Type::String + name: 'prefixMatch' + description: | + The value of the header must start with the contents of prefixMatch. Only one of + exactMatch, prefixMatch, suffixMatch, regexMatch, presentMatch or rangeMatch + must be set. + - !ruby/object:Api::Type::Boolean + name: 'presentMatch' + description: | + A header with the contents of headerName must exist. The match takes place + whether or not the request's header has a value or not. Only one of exactMatch, + prefixMatch, suffixMatch, regexMatch, presentMatch or rangeMatch must be set. + - !ruby/object:Api::Type::NestedObject + name: 'rangeMatch' + description: | + The header value must be an integer and its value must be in the range specified + in rangeMatch. If the header does not contain an integer, number or is empty, + the match fails. For example for a range [-5, 0] - -3 will match. - 0 will + not match. - 0.25 will not match. - -3someString will not match. Only one of + exactMatch, prefixMatch, suffixMatch, regexMatch, presentMatch or rangeMatch + must be set. + properties: + - !ruby/object:Api::Type::Integer + name: 'rangeEnd' + required: true + description: | + The end of the range (exclusive). + - !ruby/object:Api::Type::Integer + name: 'rangeStart' + required: true + description: | + The start of the range (inclusive). + - !ruby/object:Api::Type::String + name: 'regexMatch' + description: | + The value of the header must match the regualar expression specified in + regexMatch. For regular expression grammar, please see: + en.cppreference.com/w/cpp/regex/ecmascript For matching against a port + specified in the HTTP request, use a headerMatch with headerName set to PORT and + a regular expression that satisfies the RFC2616 Host header's port specifier. + Only one of exactMatch, prefixMatch, suffixMatch, regexMatch, presentMatch or + rangeMatch must be set. + - !ruby/object:Api::Type::String + name: 'suffixMatch' + description: | + The value of the header must end with the contents of suffixMatch. Only one of + exactMatch, prefixMatch, suffixMatch, regexMatch, presentMatch or rangeMatch + must be set. + - !ruby/object:Api::Type::Boolean + name: 'ignoreCase' + default_value: false + description: | + Specifies that prefixMatch and fullPathMatch matches are case sensitive. + Defaults to false. + - !ruby/object:Api::Type::Array + name: 'metadataFilters' + description: | + Opaque filter criteria used by Loadbalancer to restrict routing configuration to + a limited set xDS compliant clients. In their xDS requests to Loadbalancer, xDS + clients present node metadata. If a match takes place, the relevant routing + configuration is made available to those proxies. For each metadataFilter in + this list, if its filterMatchCriteria is set to MATCH_ANY, at least one of the + filterLabels must match the corresponding label provided in the metadata. If its + filterMatchCriteria is set to MATCH_ALL, then all of its filterLabels must match + with corresponding labels in the provided metadata. metadataFilters specified + here can be overrides those specified in ForwardingRule that refers to this + UrlMap. metadataFilters only applies to Loadbalancers that have their + loadBalancingScheme set to INTERNAL_SELF_MANAGED. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Array + name: 'filterLabels' + min_size: 1 + max_size: 64 + required: true + description: | + The list of label value pairs that must match labels in the provided metadata + based on filterMatchCriteria This list must not be empty and can have at the + most 64 entries. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'name' + required: true + description: | + Name of metadata label. The name can have a maximum length of 1024 characters + and must be at least 1 character long. + - !ruby/object:Api::Type::String + name: 'value' + required: true + description: | + The value of the label must match the specified value. value can have a maximum + length of 1024 characters. + - !ruby/object:Api::Type::Enum + name: 'filterMatchCriteria' + required: true + description: | + Specifies how individual filterLabel matches within the list of filterLabels + contribute towards the overall metadataFilter match. Supported values are: + - MATCH_ANY: At least one of the filterLabels must have a matching label in the + provided metadata. + - MATCH_ALL: All filterLabels must have matching labels in + the provided metadata. + values: + - :MATCH_ALL + - :MATCH_ANY + - !ruby/object:Api::Type::String + name: 'prefixMatch' + description: | + For satifying the matchRule condition, the request's path must begin with the + specified prefixMatch. prefixMatch must begin with a /. The value must be + between 1 and 1024 characters. Only one of prefixMatch, fullPathMatch or + regexMatch must be specified. + - !ruby/object:Api::Type::Array + name: 'queryParameterMatches' + description: | + Specifies a list of query parameter match criteria, all of which must match + corresponding query parameters in the request. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'exactMatch' + description: | + The queryParameterMatch matches if the value of the parameter exactly matches + the contents of exactMatch. Only one of presentMatch, exactMatch and regexMatch + must be set. + - !ruby/object:Api::Type::String + name: 'name' + required: true + description: | + The name of the query parameter to match. The query parameter must exist in the + request, in the absence of which the request match fails. + - !ruby/object:Api::Type::Boolean + name: 'presentMatch' + description: | + Specifies that the queryParameterMatch matches if the request contains the query + parameter, irrespective of whether the parameter has a value or not. Only one of + presentMatch, exactMatch and regexMatch must be set. + - !ruby/object:Api::Type::String + name: 'regexMatch' + description: | + The queryParameterMatch matches if the value of the parameter matches the + regular expression specified by regexMatch. For the regular expression grammar, + please see en.cppreference.com/w/cpp/regex/ecmascript Only one of presentMatch, + exactMatch and regexMatch must be set. + - !ruby/object:Api::Type::String + name: 'regexMatch' + description: | + For satifying the matchRule condition, the path of the request must satisfy the + regular expression specified in regexMatch after removing any query parameters + and anchor supplied with the original URL. For regular expression grammar please + see en.cppreference.com/w/cpp/regex/ecmascript Only one of prefixMatch, + fullPathMatch or regexMatch must be specified. + - !ruby/object:Api::Type::NestedObject + name: 'routeAction' + description: | + In response to a matching matchRule, the load balancer performs advanced routing + actions like URL rewrites, header transformations, etc. prior to forwarding the + request to the selected backend. If routeAction specifies any + weightedBackendServices, service must not be set. Conversely if service is set, + routeAction cannot contain any weightedBackendServices. Only one of routeAction + or urlRedirect must be set. + properties: + - !ruby/object:Api::Type::NestedObject + name: 'corsPolicy' + description: | + The specification for allowing client side cross-origin requests. Please see W3C + Recommendation for Cross Origin Resource Sharing + properties: + - !ruby/object:Api::Type::Boolean + name: 'allowCredentials' + default_value: false + description: | + In response to a preflight request, setting this to true indicates that the + actual request can include user credentials. This translates to the Access- + Control-Allow-Credentials header. Defaults to false. + - !ruby/object:Api::Type::Array + name: 'allowHeaders' + item_type: Api::Type::String + description: | + Specifies the content for the Access-Control-Allow-Headers header. + - !ruby/object:Api::Type::Array + name: 'allowMethods' + item_type: Api::Type::String + description: | + Specifies the content for the Access-Control-Allow-Methods header. + - !ruby/object:Api::Type::Array + name: 'allowOriginRegexes' + item_type: Api::Type::String + description: | + Specifies the regualar expression patterns that match allowed origins. For + regular expression grammar please see en.cppreference.com/w/cpp/regex/ecmascript + An origin is allowed if it matches either allow_origins or allow_origin_regex. + - !ruby/object:Api::Type::Array + name: 'allowOrigins' + item_type: Api::Type::String + description: | + Specifies the list of origins that will be allowed to do CORS requests. An + origin is allowed if it matches either allow_origins or allow_origin_regex. + - !ruby/object:Api::Type::Boolean + name: 'disabled' + default_value: false + description: | + If true, specifies the CORS policy is disabled. + which indicates that the CORS policy is in effect. Defaults to false. + - !ruby/object:Api::Type::Array + name: 'exposeHeaders' + item_type: Api::Type::String + description: | + Specifies the content for the Access-Control-Expose-Headers header. + - !ruby/object:Api::Type::Integer + name: 'maxAge' + description: | + Specifies how long the results of a preflight request can be cached. This + translates to the content for the Access-Control-Max-Age header. + - !ruby/object:Api::Type::NestedObject + name: 'faultInjectionPolicy' + description: | + The specification for fault injection introduced into traffic to test the + resiliency of clients to backend service failure. As part of fault injection, + when clients send requests to a backend service, delays can be introduced by + Loadbalancer on a percentage of requests before sending those request to the + backend service. Similarly requests from clients can be aborted by the + Loadbalancer for a percentage of requests. timeout and retry_policy will be + ignored by clients that are configured with a fault_injection_policy. + properties: + - !ruby/object:Api::Type::NestedObject + name: 'abort' + description: | + The specification for how client requests are aborted as part of fault + injection. + properties: + - !ruby/object:Api::Type::Integer + name: 'httpStatus' + description: | + The HTTP status code used to abort the request. The value must be between 200 + and 599 inclusive. + - !ruby/object:Api::Type::Double + name: 'percentage' + description: | + The percentage of traffic (connections/operations/requests) which will be + aborted as part of fault injection. The value must be between 0.0 and 100.0 + inclusive. + - !ruby/object:Api::Type::NestedObject + name: 'delay' + description: | + The specification for how client requests are delayed as part of fault + injection, before being sent to a backend service. + properties: + - !ruby/object:Api::Type::NestedObject + name: 'fixedDelay' + description: | + Specifies the value of the fixed delay interval. + properties: + - !ruby/object:Api::Type::Integer + name: 'nanos' + description: | + Span of time that's a fraction of a second at nanosecond resolution. Durations + less than one second are represented with a 0 `seconds` field and a positive + `nanos` field. Must be from 0 to 999,999,999 inclusive. + - !ruby/object:Api::Type::String + name: 'seconds' + required: true + description: | + Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 + inclusive. + - !ruby/object:Api::Type::Double + name: 'percentage' + description: | + The percentage of traffic (connections/operations/requests) on which delay will + be introduced as part of fault injection. The value must be between 0.0 and + 100.0 inclusive. + - !ruby/object:Api::Type::NestedObject + name: 'requestMirrorPolicy' + description: | + Specifies the policy on how requests intended for the route's backends are + shadowed to a separate mirrored backend service. Loadbalancer does not wait for + responses from the shadow service. Prior to sending traffic to the shadow + service, the host / authority header is suffixed with -shadow. + properties: + - !ruby/object:Api::Type::ResourceRef + name: 'backendService' + required: true + resource: 'RegionBackendService' + imports: 'selfLink' + description: | + The RegionBackendService resource being mirrored to. + - !ruby/object:Api::Type::NestedObject + name: 'retryPolicy' + description: | + Specifies the retry policy associated with this route. + properties: + - !ruby/object:Api::Type::Integer + name: 'numRetries' + required: true + description: | + Specifies the allowed number retries. This number must be > 0. + - !ruby/object:Api::Type::NestedObject + name: 'perTryTimeout' + description: | + Specifies a non-zero timeout per retry attempt. + properties: + - !ruby/object:Api::Type::Integer + name: 'nanos' + description: | + Span of time that's a fraction of a second at nanosecond resolution. Durations + less than one second are represented with a 0 `seconds` field and a positive + `nanos` field. Must be from 0 to 999,999,999 inclusive. + - !ruby/object:Api::Type::String + name: 'seconds' + required: true + description: | + Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 + inclusive. + - !ruby/object:Api::Type::Array + name: 'retryConditions' + item_type: Api::Type::String + description: | + Specfies one or more conditions when this retry rule applies. Valid values are: + - 5xx: Loadbalancer will attempt a retry if the backend service responds with + any 5xx response code, or if the backend service does not respond at all, + example: disconnects, reset, read timeout, connection failure, and refused + streams. + - gateway-error: Similar to 5xx, but only applies to response codes + 502, 503 or 504. + - connect-failure: Loadbalancer will retry on failures + connecting to backend services, for example due to connection timeouts. + - retriable-4xx: Loadbalancer will retry for retriable 4xx response codes. + Currently the only retriable error supported is 409. + - refused-stream: Loadbalancer will retry if the backend service resets the stream with a + REFUSED_STREAM error code. This reset type indicates that it is safe to retry. + - cancelled: Loadbalancer will retry if the gRPC status code in the response + header is set to cancelled + - deadline-exceeded: Loadbalancer will retry if the + gRPC status code in the response header is set to deadline-exceeded + - resource-exhausted: Loadbalancer will retry if the gRPC status code in the response + header is set to resource-exhausted + - unavailable: Loadbalancer will retry if the gRPC status code in + the response header is set to unavailable + - !ruby/object:Api::Type::NestedObject + name: 'timeout' + description: | + Specifies the timeout for the selected route. Timeout is computed from the time + the request is has been fully processed (i.e. end-of-stream) up until the + response has been completely processed. Timeout includes all retries. If not + specified, the default value is 15 seconds. + properties: + - !ruby/object:Api::Type::Integer + name: 'nanos' + description: | + Span of time that's a fraction of a second at nanosecond resolution. Durations + less than one second are represented with a 0 `seconds` field and a positive + `nanos` field. Must be from 0 to 999,999,999 inclusive. + - !ruby/object:Api::Type::String + name: 'seconds' + required: true + description: | + Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 + inclusive. + - !ruby/object:Api::Type::NestedObject + name: 'urlRewrite' + description: | + The spec to modify the URL of the request, prior to forwarding the request to + the matched service + properties: + - !ruby/object:Api::Type::String + name: 'hostRewrite' + description: | + Prior to forwarding the request to the selected service, the request's host + header is replaced with contents of hostRewrite. The value must be between 1 and + 255 characters. + - !ruby/object:Api::Type::String + name: 'pathPrefixRewrite' + description: | + Prior to forwarding the request to the selected backend service, the matching + portion of the request's path is replaced by pathPrefixRewrite. The value must + be between 1 and 1024 characters. + - !ruby/object:Api::Type::Array + name: 'weightedBackendServices' + description: | + A list of weighted backend services to send traffic to when a route match + occurs. The weights determine the fraction of traffic that flows to their + corresponding backend service. If all traffic needs to go to a single backend + service, there must be one weightedBackendService with weight set to a non 0 + number. Once a backendService is identified and before forwarding the request to + the backend service, advanced routing actions like Url rewrites and header + transformations are applied depending on additional settings specified in this + HttpRouteAction. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::ResourceRef + name: 'backendService' + required: true + resource: 'RegionBackendService' + imports: 'selfLink' + description: | + The default RegionBackendService resource. Before + forwarding the request to backendService, the loadbalancer applies any relevant + headerActions specified as part of this backendServiceWeight. + - !ruby/object:Api::Type::NestedObject + name: 'headerAction' + description: | + Specifies changes to request and response headers that need to take effect for + the selected backendService. headerAction specified here take effect before + headerAction in the enclosing HttpRouteRule, PathMatcher and UrlMap. + properties: + - !ruby/object:Api::Type::Array + name: 'requestHeadersToAdd' + description: | + Headers to add to a matching request prior to forwarding the request to the + backendService. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'headerName' + required: true + description: | + The name of the header. + - !ruby/object:Api::Type::String + name: 'headerValue' + required: true + description: | + The value of the header to add. + - !ruby/object:Api::Type::Boolean + name: 'replace' + required: true + description: | + If false, headerValue is appended to any values that already exist for the + header. If true, headerValue is set for the header, discarding any values that + were set for that header. + - !ruby/object:Api::Type::Array + name: 'requestHeadersToRemove' + item_type: Api::Type::String + description: | + A list of header names for headers that need to be removed from the request + prior to forwarding the request to the backendService. + - !ruby/object:Api::Type::Array + name: 'responseHeadersToAdd' + description: | + Headers to add the response prior to sending the response back to the client. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'headerName' + required: true + description: | + The name of the header. + - !ruby/object:Api::Type::String + name: 'headerValue' + required: true + description: | + The value of the header to add. + - !ruby/object:Api::Type::Boolean + name: 'replace' + required: true + description: | + If false, headerValue is appended to any values that already exist for the + header. If true, headerValue is set for the header, discarding any values that + were set for that header. + - !ruby/object:Api::Type::Array + name: 'responseHeadersToRemove' + item_type: Api::Type::String + description: | + A list of header names for headers that need to be removed from the response + prior to sending the response back to the client. + - !ruby/object:Api::Type::Integer + name: 'weight' + required: true + description: | + Specifies the fraction of traffic sent to backendService, computed as weight / + (sum of all weightedBackendService weights in routeAction) . The selection of a + backend service is determined only for new traffic. Once a user's request has + been directed to a backendService, subsequent requests will be sent to the same + backendService as determined by the BackendService's session affinity policy. + The value must be between 0 and 1000 + - !ruby/object:Api::Type::NestedObject + name: 'urlRedirect' + description: | + When this rule is matched, the request is redirected to a URL specified by + urlRedirect. If urlRedirect is specified, service or routeAction must not be + set. + properties: + - !ruby/object:Api::Type::String + name: 'hostRedirect' + description: | + The host that will be used in the redirect response instead of the one that was + supplied in the request. The value must be between 1 and 255 characters. + - !ruby/object:Api::Type::Boolean + name: 'httpsRedirect' + default_value: false + description: | + If set to true, the URL scheme in the redirected request is set to https. If set + to false, the URL scheme of the redirected request will remain the same as that + of the request. This must only be set for UrlMaps used in TargetHttpProxys. + Setting this true for TargetHttpsProxy is not permitted. Defaults to false. + - !ruby/object:Api::Type::String + name: 'pathRedirect' + description: | + The path that will be used in the redirect response instead of the one that was + supplied in the request. Only one of pathRedirect or prefixRedirect must be + specified. The value must be between 1 and 1024 characters. + - !ruby/object:Api::Type::String + name: 'prefixRedirect' + description: | + The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch, + retaining the remaining portion of the URL before redirecting the request. + - !ruby/object:Api::Type::Enum + name: 'redirectResponseCode' + description: | + The HTTP Status code to use for this RedirectAction. Supported values are: - + MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301. - + FOUND, which corresponds to 302. - SEE_OTHER which corresponds to 303. - + TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method + will be retained. - PERMANENT_REDIRECT, which corresponds to 308. In this case, + the request method will be retained. + values: + - :FOUND + - :MOVED_PERMANENTLY_DEFAULT + - :PERMANENT_REDIRECT + - :SEE_OTHER + - :TEMPORARY_REDIRECT + - !ruby/object:Api::Type::Boolean + name: 'stripQuery' + default_value: false + description: | + If set to true, any accompanying query portion of the original URL is removed + prior to redirecting the request. If set to false, the query portion of the + original URL is retained. Defaults to false. - !ruby/object:Api::Type::Array name: 'pathRules' description: | @@ -12614,6 +13291,18 @@ objects: 1, 2, 3, 4, 5, 9, 12, 16 is a valid series of priority numbers to which you could add rules numbered from 6 to 8, 10 to 11, and 13 to 15 in the future without any impact on existing rules. + - !ruby/object:Api::Type::ResourceRef + name: 'service' + resource: 'BackendService' + imports: 'selfLink' + description: | + The backend service resource to which traffic is + directed if this rule is matched. If routeAction is additionally specified, + advanced routing actions like URL Rewrites, etc. take effect prior to sending + the request to the backend. However, if service is specified, routeAction cannot + contain any weightedBackendService s. Conversely, if routeAction specifies any + weightedBackendServices, service must not be specified. Only one of urlRedirect, + service or routeAction.weightedBackendService must be set. - !ruby/object:Api::Type::NestedObject name: 'headerAction' description: | @@ -13190,6 +13879,7 @@ objects: prior to sending the response back to the client. - !ruby/object:Api::Type::Integer name: 'weight' + required: true description: | Specifies the fraction of traffic sent to backendService, computed as weight / (sum of all weightedBackendService weights in routeAction) . The selection of a diff --git a/products/compute/terraform.yaml b/products/compute/terraform.yaml index 82a228e293d4..34f344f14117 100644 --- a/products/compute/terraform.yaml +++ b/products/compute/terraform.yaml @@ -1261,6 +1261,20 @@ overrides: !ruby/object:Overrides::ResourceOverrides region_url_map_name: "regionurlmap" home_region_backend_service_name: "home" region_health_check_name: "health-check" + - !ruby/object:Provider::Terraform::Examples + name: "region_url_map_l7_ilb_route" + primary_resource_id: "regionurlmap" + vars: + region_url_map_name: "regionurlmap" + home_region_backend_service_name: "home" + region_health_check_name: "health-check" + - !ruby/object:Provider::Terraform::Examples + name: "region_url_map_l7_ilb_route_partial" + primary_resource_id: "regionurlmap" + vars: + region_url_map_name: "regionurlmap" + home_region_backend_service_name: "home" + region_health_check_name: "health-check" properties: region: !ruby/object:Overrides::Terraform::PropertyOverride default_from_api: true diff --git a/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb b/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb new file mode 100644 index 000000000000..e6f691367ebb --- /dev/null +++ b/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb @@ -0,0 +1,85 @@ +resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" { + provider = "google-beta" + name = "<%= ctx[:vars]['region_url_map_name'] %>" + description = "a description" + default_service = google_compute_region_backend_service.home.self_link + + host_rule { + hosts = ["mysite.com"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = google_compute_region_backend_service.home.self_link + + route_rules { + priority = 1 + header_action { + request_headers_to_remove = ["RemoveMe2"] + request_headers_to_add { + header_name = "AddSomethingElse" + header_value = "MyOtherValue" + replace = true + } + response_headers_to_remove = ["RemoveMe3"] + response_headers_to_add { + header_name = "AddMe" + header_value = "MyValue" + replace = false + } + } + match_rules { + full_path_match = "a full path" + header_matches { + header_name = "someheader" + exact_match = "match this exactly" + invert_match = true + } + ignore_case = true + metadata_filters { + filter_match_criteria = "MATCH_ANY" + filter_labels { + name = "PLANET" + value = "MARS" + } + } + query_parameter_matches { + name = "a query parameter" + present_match = true + } + } + url_redirect { + host_redirect = "A host" + https_redirect = false + path_redirect = "some/path" + redirect_response_code = "TEMPORARY_REDIRECT" + strip_query = true + } + } + } + + test { + service = google_compute_region_backend_service.home.self_link + host = "hi.com" + path = "/home" + } +} + +resource "google_compute_region_backend_service" "home" { + provider = "google-beta" + name = "<%= ctx[:vars]['home_region_backend_service_name'] %>" + protocol = "HTTP" + timeout_sec = 10 + + health_checks = [google_compute_region_health_check.default.self_link] + load_balancing_scheme = "INTERNAL_MANAGED" +} + +resource "google_compute_region_health_check" "default" { + provider = "google-beta" + name = "<%= ctx[:vars]['region_health_check_name'] %>" + http_health_check { + port = 80 + } +} diff --git a/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb b/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb new file mode 100644 index 000000000000..7060f3ed6937 --- /dev/null +++ b/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb @@ -0,0 +1,61 @@ +resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" { + provider = "google-beta" + name = "<%= ctx[:vars]['region_url_map_name'] %>" + description = "a description" + default_service = google_compute_region_backend_service.home.self_link + + host_rule { + hosts = ["mysite.com"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = google_compute_region_backend_service.home.self_link + + route_rules { + priority = 1 + service = google_compute_region_backend_service.home.self_link + header_action { + request_headers_to_remove = ["RemoveMe2"] + } + match_rules { + full_path_match = "a full path" + header_matches { + header_name = "someheader" + exact_match = "match this exactly" + invert_match = true + } + query_parameter_matches { + name = "a query parameter" + present_match = true + } + } + } + } + + test { + service = google_compute_region_backend_service.home.self_link + host = "hi.com" + path = "/home" + } +} + +resource "google_compute_region_backend_service" "home" { + provider = "google-beta" + name = "<%= ctx[:vars]['home_region_backend_service_name'] %>" + protocol = "HTTP" + timeout_sec = 10 + + health_checks = [google_compute_region_health_check.default.self_link] + load_balancing_scheme = "INTERNAL_MANAGED" +} + +resource "google_compute_region_health_check" "default" { + provider = "google-beta" + name = "<%= ctx[:vars]['region_health_check_name'] %>" + http_health_check { + port = 80 + } +} + diff --git a/third_party/terraform/tests/resource_compute_region_url_map_test.go.erb b/third_party/terraform/tests/resource_compute_region_url_map_test.go.erb index 42203fc4f7d0..7c63851083be 100644 --- a/third_party/terraform/tests/resource_compute_region_url_map_test.go.erb +++ b/third_party/terraform/tests/resource_compute_region_url_map_test.go.erb @@ -131,6 +131,36 @@ func TestAccComputeRegionUrlMap_ilbPathUpdate(t *testing.T) { }) } +func TestAccComputeRegionUrlMap_ilbRouteUpdate(t *testing.T) { + t.Parallel() + + randomSuffix := acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeUrlMapDestroy, + Steps: []resource.TestStep{ + { + Config: testAccComputeRegionUrlMap_ilbRoute(randomSuffix), + }, + { + ResourceName: "google_compute_region_url_map.foobar", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeRegionUrlMap_ilbRouteUpdate(randomSuffix), + }, + { + ResourceName: "google_compute_region_url_map.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccComputeRegionUrlMap_basic1(randomSuffix string) string { return fmt.Sprintf(` resource "google_compute_region_backend_service" "foobar" { @@ -606,6 +636,185 @@ resource "google_compute_region_backend_service" "home2" { load_balancing_scheme = "INTERNAL_MANAGED" } +resource "google_compute_region_health_check" "default" { + name = "regionurlmap-test-%s" + http_health_check { + port = 80 + } +} +`, randomSuffix, randomSuffix, randomSuffix, randomSuffix) +} + +func testAccComputeRegionUrlMap_ilbRoute(randomSuffix string) string { + return fmt.Sprintf(` +resource "google_compute_region_url_map" "foobar" { + name = "regionurlmap-test-%s" + description = "a description" + default_service = google_compute_region_backend_service.home.self_link + + host_rule { + hosts = ["mysite.com"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = google_compute_region_backend_service.home.self_link + + route_rules { + priority = 1 + header_action { + request_headers_to_remove = ["RemoveMe2"] + request_headers_to_add { + header_name = "AddSomethingElse" + header_value = "MyOtherValue" + replace = true + } + response_headers_to_remove = ["RemoveMe3"] + response_headers_to_add { + header_name = "AddMe" + header_value = "MyValue" + replace = false + } + } + match_rules { + full_path_match = "a full path" + header_matches { + header_name = "someheader" + exact_match = "match this exactly" + invert_match = true + } + ignore_case = true + metadata_filters { + filter_match_criteria = "MATCH_ANY" + filter_labels { + name = "PLANET" + value = "MARS" + } + } + query_parameter_matches { + name = "a query parameter" + present_match = true + } + } + url_redirect { + host_redirect = "A host" + https_redirect = false + path_redirect = "some/path" + redirect_response_code = "TEMPORARY_REDIRECT" + strip_query = true + } + } + } + + test { + service = google_compute_region_backend_service.home.self_link + host = "hi.com" + path = "/home" + } +} + +resource "google_compute_region_backend_service" "home" { + name = "regionurlmap-test-%s" + protocol = "HTTP" + timeout_sec = 10 + + health_checks = [google_compute_region_health_check.default.self_link] + load_balancing_scheme = "INTERNAL_MANAGED" +} + +resource "google_compute_region_health_check" "default" { + name = "regionurlmap-test-%s" + http_health_check { + port = 80 + } +} +`, randomSuffix, randomSuffix, randomSuffix) +} + +func testAccComputeRegionUrlMap_ilbRouteUpdate(randomSuffix string) string { + return fmt.Sprintf(` +resource "google_compute_region_url_map" "foobar" { + name = "regionurlmap-test-%s" + description = "a description" + default_service = google_compute_region_backend_service.home.self_link + + host_rule { + hosts = ["mysite.com"] + path_matcher = "allpaths2" + } + + path_matcher { + name = "allpaths2" + default_service = google_compute_region_backend_service.home2.self_link + + route_rules { + priority = 2 + header_action { + request_headers_to_remove = ["RemoveMe2Again"] + request_headers_to_add { + header_name = "AddSomethingElseAgain" + header_value = "MyOtherValueAgain" + replace = false + } + response_headers_to_remove = ["RemoveMe3Again"] + response_headers_to_add { + header_name = "AddMeAgain" + header_value = "MyValueAgain" + replace = true + } + } + match_rules { + full_path_match = "a full path again" + header_matches { + header_name = "someheaderagain" + exact_match = "match this exactly again" + invert_match = false + } + ignore_case = false + metadata_filters { + filter_match_criteria = "MATCH_ALL" + filter_labels { + name = "PLANET" + value = "JUPITER" + } + } + } + url_redirect { + host_redirect = "A hosti again" + https_redirect = true + path_redirect = "some/path/again" + redirect_response_code = "TEMPORARY_REDIRECT" + strip_query = false + } + } + } + + test { + service = google_compute_region_backend_service.home.self_link + host = "hi.com" + path = "/home" + } +} + +resource "google_compute_region_backend_service" "home" { + name = "regionurlmap-test-%s" + protocol = "HTTP" + timeout_sec = 10 + + health_checks = [google_compute_region_health_check.default.self_link] + load_balancing_scheme = "INTERNAL_MANAGED" +} + +resource "google_compute_region_backend_service" "home2" { + name = "regionurlmap-test-%s-2" + protocol = "HTTP" + timeout_sec = 10 + + health_checks = [google_compute_region_health_check.default.self_link] + load_balancing_scheme = "INTERNAL_MANAGED" +} + resource "google_compute_region_health_check" "default" { name = "regionurlmap-test-%s" http_health_check {