From 83b5d8c3053c7ab62667eab5a65c6406c0434fb7 Mon Sep 17 00:00:00 2001 From: Ty Larrabee Date: Thu, 19 Sep 2019 22:43:17 +0000 Subject: [PATCH] Add metadataFilters to GlobalForwardingRule Signed-off-by: Modular Magician --- ...resource_compute_global_forwarding_rule.go | 165 ++++++++++++++++++ ...mpute_global_forwarding_rule.html.markdown | 56 ++++++ 2 files changed, 221 insertions(+) diff --git a/google/resource_compute_global_forwarding_rule.go b/google/resource_compute_global_forwarding_rule.go index b8721248b85..ec4603097b2 100644 --- a/google/resource_compute_global_forwarding_rule.go +++ b/google/resource_compute_global_forwarding_rule.go @@ -85,6 +85,42 @@ func resourceComputeGlobalForwardingRule() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{"INTERNAL_SELF_MANAGED", "EXTERNAL", ""}, false), Default: "EXTERNAL", }, + "metadata_filters": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "filter_labels": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + MinItems: 1, + MaxItems: 64, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + "filter_match_criteria": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"MATCH_ANY", "MATCH_ALL"}, false), + }, + }, + }, + }, "port_range": { Type: schema.TypeString, Optional: true, @@ -139,6 +175,12 @@ func resourceComputeGlobalForwardingRuleCreate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("load_balancing_scheme"); !isEmptyValue(reflect.ValueOf(loadBalancingSchemeProp)) && (ok || !reflect.DeepEqual(v, loadBalancingSchemeProp)) { obj["loadBalancingScheme"] = loadBalancingSchemeProp } + metadataFiltersProp, err := expandComputeGlobalForwardingRuleMetadataFilters(d.Get("metadata_filters"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("metadata_filters"); !isEmptyValue(reflect.ValueOf(metadataFiltersProp)) && (ok || !reflect.DeepEqual(v, metadataFiltersProp)) { + obj["metadataFilters"] = metadataFiltersProp + } nameProp, err := expandComputeGlobalForwardingRuleName(d.Get("name"), d, config) if err != nil { return err @@ -237,6 +279,9 @@ func resourceComputeGlobalForwardingRuleRead(d *schema.ResourceData, meta interf if err := d.Set("load_balancing_scheme", flattenComputeGlobalForwardingRuleLoadBalancingScheme(res["loadBalancingScheme"], d)); err != nil { return fmt.Errorf("Error reading GlobalForwardingRule: %s", err) } + if err := d.Set("metadata_filters", flattenComputeGlobalForwardingRuleMetadataFilters(res["metadataFilters"], d)); err != nil { + return fmt.Errorf("Error reading GlobalForwardingRule: %s", err) + } if err := d.Set("name", flattenComputeGlobalForwardingRuleName(res["name"], d)); err != nil { return fmt.Errorf("Error reading GlobalForwardingRule: %s", err) } @@ -382,6 +427,56 @@ func flattenComputeGlobalForwardingRuleLoadBalancingScheme(v interface{}, d *sch return v } +func flattenComputeGlobalForwardingRuleMetadataFilters(v interface{}, d *schema.ResourceData) 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{}{ + "filter_match_criteria": flattenComputeGlobalForwardingRuleMetadataFiltersFilterMatchCriteria(original["filterMatchCriteria"], d), + "filter_labels": flattenComputeGlobalForwardingRuleMetadataFiltersFilterLabels(original["filterLabels"], d), + }) + } + return transformed +} +func flattenComputeGlobalForwardingRuleMetadataFiltersFilterMatchCriteria(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeGlobalForwardingRuleMetadataFiltersFilterLabels(v interface{}, d *schema.ResourceData) 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{}{ + "name": flattenComputeGlobalForwardingRuleMetadataFiltersFilterLabelsName(original["name"], d), + "value": flattenComputeGlobalForwardingRuleMetadataFiltersFilterLabelsValue(original["value"], d), + }) + } + return transformed +} +func flattenComputeGlobalForwardingRuleMetadataFiltersFilterLabelsName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeGlobalForwardingRuleMetadataFiltersFilterLabelsValue(v interface{}, d *schema.ResourceData) interface{} { + return v +} + func flattenComputeGlobalForwardingRuleName(v interface{}, d *schema.ResourceData) interface{} { return v } @@ -414,6 +509,76 @@ func expandComputeGlobalForwardingRuleLoadBalancingScheme(v interface{}, d Terra return v, nil } +func expandComputeGlobalForwardingRuleMetadataFilters(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{}) + + transformedFilterMatchCriteria, err := expandComputeGlobalForwardingRuleMetadataFiltersFilterMatchCriteria(original["filter_match_criteria"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFilterMatchCriteria); val.IsValid() && !isEmptyValue(val) { + transformed["filterMatchCriteria"] = transformedFilterMatchCriteria + } + + transformedFilterLabels, err := expandComputeGlobalForwardingRuleMetadataFiltersFilterLabels(original["filter_labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFilterLabels); val.IsValid() && !isEmptyValue(val) { + transformed["filterLabels"] = transformedFilterLabels + } + + req = append(req, transformed) + } + return req, nil +} + +func expandComputeGlobalForwardingRuleMetadataFiltersFilterMatchCriteria(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeGlobalForwardingRuleMetadataFiltersFilterLabels(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{}) + + transformedName, err := expandComputeGlobalForwardingRuleMetadataFiltersFilterLabelsName(original["name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedName); val.IsValid() && !isEmptyValue(val) { + transformed["name"] = transformedName + } + + transformedValue, err := expandComputeGlobalForwardingRuleMetadataFiltersFilterLabelsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !isEmptyValue(val) { + transformed["value"] = transformedValue + } + + req = append(req, transformed) + } + return req, nil +} + +func expandComputeGlobalForwardingRuleMetadataFiltersFilterLabelsName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeGlobalForwardingRuleMetadataFiltersFilterLabelsValue(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandComputeGlobalForwardingRuleName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } diff --git a/website/docs/r/compute_global_forwarding_rule.html.markdown b/website/docs/r/compute_global_forwarding_rule.html.markdown index 90e38f3d505..d9a6213e5ad 100644 --- a/website/docs/r/compute_global_forwarding_rule.html.markdown +++ b/website/docs/r/compute_global_forwarding_rule.html.markdown @@ -105,6 +105,13 @@ resource "google_compute_global_forwarding_rule" "default" { port_range = "80" load_balancing_scheme = "INTERNAL_SELF_MANAGED" ip_address = "0.0.0.0" + metadata_filters { + filter_match_criteria = "MATCH_ANY" + filter_labels { + name = "PLANET" + value = "MARS" + } + } } resource "google_compute_target_http_proxy" "default" { @@ -219,6 +226,8 @@ The following arguments are supported: (Required) The URL of the target resource to receive the matched traffic. The forwarded traffic must be of a type appropriate to the target object. + For INTERNAL_SELF_MANAGED load balancing, only HTTP and HTTPS targets + are valid. - - - @@ -276,6 +285,23 @@ The following arguments are supported: NOTE: Currently global forwarding rules cannot be used for INTERNAL load balancing. +* `metadata_filters` - + (Optional) + 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 overridden by those specified in + the UrlMap that this ForwardingRule references. + metadataFilters only applies to Loadbalancers that have their + loadBalancingScheme set to INTERNAL_SELF_MANAGED. Structure is documented below. + * `port_range` - (Optional) This field is used along with the target field for TargetHttpProxy, @@ -299,6 +325,36 @@ The following arguments are supported: If it is not provided, the provider project is used. +The `metadata_filters` block supports: + +* `filter_match_criteria` - + (Required) + Specifies how individual filterLabel matches within the list of + filterLabels contribute towards the overall metadataFilter match. + 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. + +* `filter_labels` - + (Required) + 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. Structure is documented below. + + +The `filter_labels` block supports: + +* `name` - + (Required) + Name of the metadata label. The length must be between + 1 and 1024 characters, inclusive. + +* `value` - + (Required) + The value that the label must match. The value has a maximum + length of 1024 characters. + ## Timeouts