diff --git a/cloudflare/resource_cloudflare_load_balancer.go b/cloudflare/resource_cloudflare_load_balancer.go index e7d963b7e5..858fc66473 100644 --- a/cloudflare/resource_cloudflare_load_balancer.go +++ b/cloudflare/resource_cloudflare_load_balancer.go @@ -57,6 +57,11 @@ func resourceCloudflareLoadBalancer() *schema.Resource { }, }, + "session_affinity": { + Type: schema.TypeString, + Optional: true, + }, + "proxied": { Type: schema.TypeBool, Optional: true, @@ -157,6 +162,7 @@ func resourceCloudflareLoadBalancerCreate(d *schema.ResourceData, meta interface DefaultPools: expandInterfaceToStringList(d.Get("default_pool_ids")), Proxied: d.Get("proxied").(bool), TTL: d.Get("ttl").(int), + Persistence: d.Get("session_affinity").(string), } if description, ok := d.GetOk("description"); ok { diff --git a/cloudflare/resource_cloudflare_load_balancer_pool.go b/cloudflare/resource_cloudflare_load_balancer_pool.go index 8e7fdf5267..c5a3b81788 100644 --- a/cloudflare/resource_cloudflare_load_balancer_pool.go +++ b/cloudflare/resource_cloudflare_load_balancer_pool.go @@ -106,6 +106,13 @@ var originsElem = &schema.Resource{ }, }, + "weight": { + Type: schema.TypeFloat, + Optional: true, + Default: 1.0, + ValidateFunc: floatBetween(0.0, 1.0), + }, + "enabled": { Type: schema.TypeBool, Optional: true, @@ -202,6 +209,7 @@ func expandLoadBalancerOrigins(originSet *schema.Set) (origins []cloudflare.Load Name: o["name"].(string), Address: o["address"].(string), Enabled: o["enabled"].(bool), + Weight: o["weight"].(float64), } origins = append(origins, origin) } @@ -251,6 +259,7 @@ func flattenLoadBalancerOrigins(origins []cloudflare.LoadBalancerOrigin) *schema "name": o.Name, "address": o.Address, "enabled": o.Enabled, + "weight": o.Weight, } flattened = append(flattened, cfg) } @@ -269,3 +278,21 @@ func resourceCloudflareLoadBalancerPoolDelete(d *schema.ResourceData, meta inter return nil } + +// floatBetween returns a validate function that can be used in schema definitions. +func floatBetween(min, max float64) schema.SchemaValidateFunc { + return func(i interface{}, k string) (s []string, es []error) { + v, ok := i.(float64) + if !ok { + es = append(es, fmt.Errorf("expected type of %s to be float64", k)) + return + } + + if v < min || v > max { + es = append(es, fmt.Errorf("expected %s to be within %v and %v", k, min, max)) + return + } + + return + } +} diff --git a/cloudflare/resource_cloudflare_load_balancer_pool_test.go b/cloudflare/resource_cloudflare_load_balancer_pool_test.go index 92f4b8ae56..2fe55fa209 100644 --- a/cloudflare/resource_cloudflare_load_balancer_pool_test.go +++ b/cloudflare/resource_cloudflare_load_balancer_pool_test.go @@ -204,10 +204,12 @@ resource "cloudflare_load_balancer_pool" "%[1]s" { name = "example-1" address = "192.0.2.1" enabled = false + weight = 1.0 } origins { name = "example-2" address = "192.0.2.2" + weight = 0.5 } check_regions = ["WEU"] description = "tfacc-fully-specified" diff --git a/cloudflare/resource_cloudflare_load_balancer_test.go b/cloudflare/resource_cloudflare_load_balancer_test.go index 3a549685b2..4afac585dd 100644 --- a/cloudflare/resource_cloudflare_load_balancer_test.go +++ b/cloudflare/resource_cloudflare_load_balancer_test.go @@ -9,11 +9,12 @@ import ( "os" + "regexp" + "github.com/cloudflare/cloudflare-go" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - "regexp" ) func TestAccCloudflareLoadBalancer_Basic(t *testing.T) { @@ -49,6 +50,35 @@ func TestAccCloudflareLoadBalancer_Basic(t *testing.T) { }) } +func TestAccCloudflareLoadBalancer_SessionAffinity(t *testing.T) { + t.Parallel() + var loadBalancer cloudflare.LoadBalancer + zone := os.Getenv("CLOUDFLARE_DOMAIN") + rnd := acctest.RandString(10) + name := "cloudflare_load_balancer." + rnd + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudflareLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckCloudflareLoadBalancerConfigSessionAffinity(zone, rnd), + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudflareLoadBalancerExists(name, &loadBalancer), + testAccCheckCloudflareLoadBalancerIDIsValid(name, zone), + // explicitly verify that our session_affinity has been set + resource.TestCheckResourceAttr(name, "session_affinity", "cookie"), + // dont check that other specified values are set, this will be evident by lack + // of plan diff some values will get empty values + resource.TestCheckResourceAttr(name, "pop_pools.#", "0"), + resource.TestCheckResourceAttr(name, "region_pools.#", "0"), + ), + }, + }, + }) +} + func TestAccCloudflareLoadBalancer_GeoBalanced(t *testing.T) { t.Parallel() var loadBalancer cloudflare.LoadBalancer @@ -299,6 +329,17 @@ resource "cloudflare_load_balancer" "%[2]s" { }`, zone, id) } +func testAccCheckCloudflareLoadBalancerConfigSessionAffinity(zone, id string) string { + return testAccCheckCloudflareLoadBalancerPoolConfigBasic(id) + fmt.Sprintf(` +resource "cloudflare_load_balancer" "%[2]s" { + zone = "%[1]s" + name = "tf-testacc-lb-session-affinity-%[2]s" + fallback_pool_id = "${cloudflare_load_balancer_pool.%[2]s.id}" + default_pool_ids = ["${cloudflare_load_balancer_pool.%[2]s.id}"] + session_affinity = "cookie" +}`, zone, id) +} + func testAccCheckCloudflareLoadBalancerConfigGeoBalanced(zone, id string) string { return testAccCheckCloudflareLoadBalancerPoolConfigBasic(id) + fmt.Sprintf(` resource "cloudflare_load_balancer" "%[2]s" {