Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for LoadBalancer Pool LoadShedding #1108

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions cloudflare/resource_cloudflare_load_balancer_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log"
"math"
"strings"

"time"
Expand Down Expand Up @@ -78,6 +79,12 @@ func resourceCloudflareLoadBalancerPool() *schema.Resource {
Optional: true,
},

"load_shedding": {
Type: schema.TypeSet,
Optional: true,
Elem: loadShedElem,
},

"created_on": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -143,6 +150,38 @@ var originsElem = &schema.Resource{
},
}

var loadShedElem = &schema.Resource{
Schema: map[string]*schema.Schema{
"default_percent": {
Type: schema.TypeFloat,
Default: 0,
Optional: true,
ValidateFunc: validation.FloatBetween(0, 100),
},

"default_policy": {
Type: schema.TypeString,
Default: "",
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"", "hash", "random"}, false),
},

"session_percent": {
Type: schema.TypeFloat,
Default: 0,
Optional: true,
ValidateFunc: validation.FloatBetween(0, 100),
},

"session_policy": {
Type: schema.TypeString,
Default: "",
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"", "hash"}, false),
},
},
}

func resourceCloudflareLoadBalancerPoolCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*cloudflare.API)

Expand All @@ -165,6 +204,10 @@ func resourceCloudflareLoadBalancerPoolCreate(d *schema.ResourceData, meta inter
loadBalancerPool.Monitor = monitor.(string)
}

if shed, ok := d.GetOk("load_shedding"); ok {
loadBalancerPool.LoadShedding = expandLoadBalancerLoadShedding(shed.(*schema.Set))
}

if notificationEmail, ok := d.GetOk("notification_email"); ok {
loadBalancerPool.NotificationEmail = notificationEmail.(string)
}
Expand Down Expand Up @@ -210,6 +253,10 @@ func resourceCloudflareLoadBalancerPoolUpdate(d *schema.ResourceData, meta inter
loadBalancerPool.Monitor = monitor.(string)
}

if shed, ok := d.GetOk("load_shedding"); ok {
loadBalancerPool.LoadShedding = expandLoadBalancerLoadShedding(shed.(*schema.Set))
}

if notificationEmail, ok := d.GetOk("notification_email"); ok {
loadBalancerPool.NotificationEmail = notificationEmail.(string)
}
Expand Down Expand Up @@ -246,6 +293,22 @@ func flattenLoadBalancerPoolHeader(header map[string][]string) *schema.Set {
return schema.NewSet(HashByMapKey("header"), flattened)
}

func expandLoadBalancerLoadShedding(s *schema.Set) *cloudflare.LoadBalancerLoadShedding {
if s == nil {
return nil
}
for _, iface := range s.List() {
o := iface.(map[string]interface{})
return &cloudflare.LoadBalancerLoadShedding{
DefaultPercent: float32(o["default_percent"].(float64)),
DefaultPolicy: o["default_policy"].(string),
SessionPercent: float32(o["session_percent"].(float64)),
SessionPolicy: o["session_policy"].(string),
}
}
return nil
}

func expandLoadBalancerOrigins(originSet *schema.Set) (origins []cloudflare.LoadBalancerOrigin) {
for _, iface := range originSet.List() {
o := iface.(map[string]interface{})
Expand Down Expand Up @@ -294,6 +357,10 @@ func resourceCloudflareLoadBalancerPoolRead(d *schema.ResourceData, meta interfa
log.Printf("[WARN] Error setting origins on load balancer pool %q: %s", d.Id(), err)
}

if err := d.Set("load_shedding", flattenLoadBalancerLoadShedding(loadBalancerPool.LoadShedding)); err != nil {
log.Printf("[WARN] Error setting load_shedding 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)
}
Expand All @@ -317,6 +384,18 @@ 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)

Expand Down
30 changes: 23 additions & 7 deletions cloudflare/resource_cloudflare_load_balancer_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package cloudflare
import (
"context"
"fmt"
"github.com/pkg/errors"
"os"
"regexp"
"testing"

"github.com/pkg/errors"

"time"

"github.com/cloudflare/cloudflare-go"
Expand Down Expand Up @@ -62,6 +63,11 @@ func TestAccCloudflareLoadBalancerPool_FullySpecified(t *testing.T) {
testAccCheckCloudflareLoadBalancerPoolExists(name, &loadBalancerPool),
// checking our overrides of default values worked
resource.TestCheckResourceAttr(name, "enabled", "false"),
resource.TestCheckResourceAttr(name, "load_shedding.#", "1"),
resource.TestCheckResourceAttr(name, "load_shedding.2749995019.default_percent", "55"),
resource.TestCheckResourceAttr(name, "load_shedding.2749995019.default_policy", "random"),
resource.TestCheckResourceAttr(name, "load_shedding.2749995019.session_percent", "12"),
resource.TestCheckResourceAttr(name, "load_shedding.2749995019.session_policy", "hash"),
resource.TestCheckResourceAttr(name, "description", "tfacc-fully-specified"),
resource.TestCheckResourceAttr(name, "check_regions.#", "1"),
resource.TestCheckResourceAttr(name, "minimum_origins", "2"),
Expand Down Expand Up @@ -220,25 +226,35 @@ func testAccCheckCloudflareLoadBalancerPoolConfigFullySpecified(id string, heade
return fmt.Sprintf(`
resource "cloudflare_load_balancer_pool" "%[1]s" {
name = "my-tf-pool-basic-%[1]s"

origins {
name = "example-1"
address = "192.0.2.1"
enabled = false
weight = 1.0
header {
header = "Host"
values = ["test1.%[2]s"]
}
header = "Host"
values = ["test1.%[2]s"]
}
}

origins {
name = "example-2"
address = "192.0.2.2"
weight = 0.5
header {
header = "Host"
values = ["test2.%[2]s"]
}
header = "Host"
values = ["test2.%[2]s"]
}
}

load_shedding {
default_percent = 55
default_policy = "random"
session_percent = 12
session_policy = "hash"
}

check_regions = ["WEU"]
description = "tfacc-fully-specified"
enabled = false
Expand Down
13 changes: 13 additions & 0 deletions website/docs/r/load_balancer_pool.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ resource "cloudflare_load_balancer_pool" "foo" {
enabled = false
minimum_origins = 1
notification_email = "someone@example.com"
load_shedding {
default_percent = 55
default_policy = "random"
session_percent = 12
session_policy = "hash"
}
}
```

Expand All @@ -48,6 +54,7 @@ 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).
* `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.
Expand All @@ -61,6 +68,12 @@ The **origins** block supports:
* `enabled` - (Optional) Whether to enable (the default) this origin within the Pool. Disabled origins will not receive traffic and are excluded from health checks. The origin will only be disabled for the current pool.
* `header` - (Optional) The HTTP request headers. For security reasons, this header also needs to be a subdomain of the overall zone. Fields documented below.

The **load_shedding** block supports:
* `default_percent` - (Optional) Percent of traffic to shed 0 - 100.
* `default_policy` - (Optional) Method of shedding traffic "", "hash" or "random".
* `session_percent` - (Optional) Percent of session traffic to shed 0 - 100.
* `session_policy` - (Optional) Method of shedding session traffic "" or "hash".

**header** requires the following:

* `header` - (Required) The header name.
Expand Down