diff --git a/cloudflare/resource_cloudflare_load_balancer_pool.go b/cloudflare/resource_cloudflare_load_balancer_pool.go index 1c1eed105a3..9e8cf06f3aa 100644 --- a/cloudflare/resource_cloudflare_load_balancer_pool.go +++ b/cloudflare/resource_cloudflare_load_balancer_pool.go @@ -97,6 +97,12 @@ func resourceCloudflareLoadBalancerPool() *schema.Resource { Elem: loadShedElem, }, + "origin_steering": { + Type: schema.TypeSet, + Optional: true, + Elem: originSteeringElem, + }, + "created_on": { Type: schema.TypeString, Computed: true, @@ -194,6 +200,17 @@ var loadShedElem = &schema.Resource{ }, } +var originSteeringElem = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "policy": { + Type: schema.TypeString, + Default: "", + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"", "hash", "random"}, false), + }, + }, +} + func resourceCloudflareLoadBalancerPoolCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*cloudflare.API) @@ -229,6 +246,10 @@ func resourceCloudflareLoadBalancerPoolCreate(d *schema.ResourceData, meta inter loadBalancerPool.LoadShedding = expandLoadBalancerLoadShedding(shed.(*schema.Set)) } + if steering, ok := d.GetOk("origin_steering"); ok { + loadBalancerPool.OriginSteering = expandLoadBalancerOriginSteering(steering.(*schema.Set)) + } + if notificationEmail, ok := d.GetOk("notification_email"); ok { loadBalancerPool.NotificationEmail = notificationEmail.(string) } @@ -287,6 +308,10 @@ func resourceCloudflareLoadBalancerPoolUpdate(d *schema.ResourceData, meta inter loadBalancerPool.LoadShedding = expandLoadBalancerLoadShedding(shed.(*schema.Set)) } + if steering, ok := d.GetOk("origin_steering"); ok { + loadBalancerPool.OriginSteering = expandLoadBalancerOriginSteering(steering.(*schema.Set)) + } + if notificationEmail, ok := d.GetOk("notification_email"); ok { loadBalancerPool.NotificationEmail = notificationEmail.(string) } @@ -339,6 +364,19 @@ func expandLoadBalancerLoadShedding(s *schema.Set) *cloudflare.LoadBalancerLoadS return nil } +func expandLoadBalancerOriginSteering(s *schema.Set) *cloudflare.LoadBalancerOriginSteering { + if s == nil { + return nil + } + for _, iface := range s.List() { + o := iface.(map[string]interface{}) + return &cloudflare.LoadBalancerOriginSteering{ + Policy: o["policy"].(string), + } + } + return nil +} + func expandLoadBalancerOrigins(originSet *schema.Set) (origins []cloudflare.LoadBalancerOrigin) { for _, iface := range originSet.List() { o := iface.(map[string]interface{}) @@ -400,6 +438,10 @@ func resourceCloudflareLoadBalancerPoolRead(d *schema.ResourceData, meta interfa log.Printf("[WARN] Error setting load_shedding on load balancer pool %q: %s", d.Id(), err) } + if err := d.Set("origin_steering", flattenLoadBalancerOriginSteering(loadBalancerPool.OriginSteering)); err != nil { + log.Printf("[WARN] Error setting origin_steering on load balancer pool %q: %s", d.Id(), err) + } + if err := d.Set("check_regions", schema.NewSet(schema.HashString, flattenStringList(loadBalancerPool.CheckRegions))); err != nil { log.Printf("[WARN] Error setting check_regions on load balancer pool %q: %s", d.Id(), err) } @@ -407,6 +449,27 @@ func resourceCloudflareLoadBalancerPoolRead(d *schema.ResourceData, meta interfa return nil } +func flattenLoadBalancerLoadShedding(ls *cloudflare.LoadBalancerLoadShedding) *schema.Set { + if ls == nil { + return nil + } + return schema.NewSet(schema.HashResource(loadShedElem), []interface{}{map[string]interface{}{ + "default_percent": math.Round(float64(ls.DefaultPercent)*1000) / 1000, + "default_policy": ls.DefaultPolicy, + "session_percent": math.Round(float64(ls.SessionPercent)*1000) / 1000, + "session_policy": ls.SessionPolicy, + }}) +} + +func flattenLoadBalancerOriginSteering(os *cloudflare.LoadBalancerOriginSteering) *schema.Set { + if os == nil { + return nil + } + return schema.NewSet(schema.HashResource(originSteeringElem), []interface{}{map[string]interface{}{ + "policy": os.Policy, + }}) +} + func flattenLoadBalancerOrigins(d *schema.ResourceData, origins []cloudflare.LoadBalancerOrigin) *schema.Set { flattened := make([]interface{}, 0) for _, o := range origins { @@ -423,18 +486,6 @@ func flattenLoadBalancerOrigins(d *schema.ResourceData, origins []cloudflare.Loa return schema.NewSet(schema.HashResource(originsElem), flattened) } -func flattenLoadBalancerLoadShedding(ls *cloudflare.LoadBalancerLoadShedding) *schema.Set { - if ls == nil { - return nil - } - return schema.NewSet(schema.HashResource(loadShedElem), []interface{}{map[string]interface{}{ - "default_percent": math.Round(float64(ls.DefaultPercent)*1000) / 1000, - "default_policy": ls.DefaultPolicy, - "session_percent": math.Round(float64(ls.SessionPercent)*1000) / 1000, - "session_policy": ls.SessionPolicy, - }}) -} - func resourceCloudflareLoadBalancerPoolDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*cloudflare.API) diff --git a/cloudflare/resource_cloudflare_load_balancer_pool_test.go b/cloudflare/resource_cloudflare_load_balancer_pool_test.go index 54759fdc4d0..d15e0b6aea5 100644 --- a/cloudflare/resource_cloudflare_load_balancer_pool_test.go +++ b/cloudflare/resource_cloudflare_load_balancer_pool_test.go @@ -73,6 +73,10 @@ func TestAccCloudflareLoadBalancerPool_FullySpecified(t *testing.T) { resource.TestCheckResourceAttr(name, "minimum_origins", "2"), resource.TestCheckResourceAttr(name, "latitude", "12.3"), resource.TestCheckResourceAttr(name, "longitude", "55"), + resource.TestCheckResourceAttr(name, "origin_steering.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(name, "origin_steering.*", map[string]string{ + "policy": "random", + }), func(state *terraform.State) error { for _, rs := range state.RootModule().Resources { for k, v := range rs.Primary.Attributes { @@ -258,6 +262,10 @@ resource "cloudflare_load_balancer_pool" "%[1]s" { latitude = 12.3 longitude = 55 + origin_steering { + policy = "random" + } + check_regions = ["WEU"] description = "tfacc-fully-specified" enabled = false diff --git a/website/docs/r/load_balancer_pool.html.markdown b/website/docs/r/load_balancer_pool.html.markdown index 0d3e61cedaf..2c4bc473069 100644 --- a/website/docs/r/load_balancer_pool.html.markdown +++ b/website/docs/r/load_balancer_pool.html.markdown @@ -45,6 +45,9 @@ resource "cloudflare_load_balancer_pool" "foo" { session_percent = 12 session_policy = "hash" } + origin_steering { + policy = "random" + } } ``` @@ -56,13 +59,14 @@ The following arguments are supported: * `origins` - (Required) The list of origins within this pool. Traffic directed at this pool is balanced across all currently healthy origins, provided the pool itself is healthy. It's a complex value. See description below. * `check_regions` - (Optional) A list of regions (specified by region code) from which to run health checks. Empty means every Cloudflare data center (the default), but requires an Enterprise plan. Region codes can be found [here](https://support.cloudflare.com/hc/en-us/articles/115000540888-Load-Balancing-Geographic-Regions). * `description` - (Optional) Free text description. -* `load_shedding` - (Optional) Setting for controlling load shedding for this pool. * `enabled` - (Optional) Whether to enable (the default) this pool. Disabled pools will not receive traffic and are excluded from health checks. Disabling a pool will cause any load balancers using it to failover to the next pool (if any). +* `latitude` - (Optional) The latitude this pool is physically located at; used for proximity steering. Values should be between -90 and 90. +* `longitude` - (Optional) The longitude this pool is physically located at; used for proximity steering. Values should be between -180 and 180. +* `load_shedding` - (Optional) Setting for controlling load shedding for this pool. * `minimum_origins` - (Optional) The minimum number of origins that must be healthy for this pool to serve traffic. If the number of healthy origins falls below this number, the pool will be marked unhealthy and we will failover to the next available pool. Default: 1. * `monitor` - (Optional) The ID of the Monitor to use for health checking origins within this pool. * `notification_email` - (Optional) The email address to send health status notifications to. This can be an individual mailbox or a mailing list. Multiple emails can be supplied as a comma delimited list. -* `latitude` - (Optional) The latitude this pool is physically located at; used for proximity steering. Values should be between -90 and 90. -* `longitude` - (Optional) The longitude this pool is physically located at; used for proximity steering. Values should be between -180 and 180. +* `origin_steering` - (Optional) Set an origin steering policy to control origin selection within a pool. The **origins** block supports: @@ -78,6 +82,9 @@ The **load_shedding** block supports: * `session_percent` - (Optional) Percent of session traffic to shed 0 - 100. * `session_policy` - (Optional) Method of shedding session traffic "" or "hash". +The **origin_steering** block supports: +* `policy` - (Optional) Either "random" (default) or "hash". + **header** requires the following: * `header` - (Required) The header name.