Skip to content

Commit

Permalink
IBM-Cloud#985 Support configure geo routes in cis_glb
Browse files Browse the repository at this point in the history
  • Loading branch information
kavya498 committed Jul 22, 2020
1 parent ee18561 commit cc6cdee
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 19 deletions.
120 changes: 107 additions & 13 deletions ibm/resource_ibm_cis_global_load_balancer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ibm

import (
"fmt"
"log"
"reflect"
"strings"
Expand Down Expand Up @@ -76,18 +77,47 @@ func resourceIBMCISGlb() *schema.Resource {
Default: true,
Description: "set to true of LB needs to enabled",
},
// "region_pools": &schema.Schema{
// Type: schema.TypeMap,
// Optional: true,
// Computed: true,
// Elem: &schema.Schema{Type: schema.TypeString},
// },
// "pop_pools": &schema.Schema{
// Type: schema.TypeMap,
// Optional: true,
// Computed: true,
// Elem: &schema.Schema{Type: schema.TypeString},
// },
"pop_pools": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"pop": {
Type: schema.TypeString,
Required: true,
},

"pool_ids": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},

"region_pools": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Required: true,
},

"pool_ids": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
"created_on": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -144,6 +174,22 @@ func resourceCISGlbCreate(d *schema.ResourceData, meta interface{}) error {
if ttl, ok := d.GetOk("ttl"); ok {
glbNew.Ttl = ttl.(int)
}
if regionPools, ok := d.GetOk("region_pools"); ok {
expandedRegionPools, err := expandGeoPools(regionPools, "region")
if err != nil {
return err
}
glbNew.RegionPools = expandedRegionPools
}

if popPools, ok := d.GetOk("pop_pools"); ok {
expandedPopPools, err := expandGeoPools(popPools, "pop")
if err != nil {
return err
}
glbNew.PopPools = expandedPopPools
}

glb, err = cisClient.Glbs().CreateGlb(cisId, zoneId, glbNew)
if err != nil {
log.Printf("CreateGlbs Failed %s\n", err)
Expand All @@ -154,6 +200,21 @@ func resourceCISGlbCreate(d *schema.ResourceData, meta interface{}) error {

return resourceCISGlbUpdate(d, meta)
}
func expandGeoPools(pool interface{}, geoType string) (map[string][]string, error) {
pools := pool.(*schema.Set).List()
expandPool := make(map[string][]string)
for _, v := range pools {
locationConfig := v.(map[string]interface{})
location := locationConfig[geoType].(string)
if _, p := expandPool[location]; !p {
geoPools := expandStringList(locationConfig["pool_ids"].([]interface{}))
expandPool[location], _, _ = convertTfToCisTwoVarSlice(geoPools)
} else {
return nil, fmt.Errorf("duplicate entry specified for %s pool in location %q. each location must only be specified once", geoType, location)
}
}
return expandPool, nil
}

func resourceCISGlbRead(d *schema.ResourceData, meta interface{}) error {
cisClient, err := meta.(ClientSession).CisAPI()
Expand Down Expand Up @@ -187,9 +248,27 @@ func resourceCISGlbRead(d *schema.ResourceData, meta interface{}) error {
d.Set("proxied", glbObj.Proxied)
d.Set("enabled", glbObj.Enabled)
d.Set("session_affinity", glbObj.SessionAffinity)
if err := d.Set("pop_pools", flattenPools(glbObj.PopPools, "pop", cisId)); err != nil {
log.Printf("[WARN] Error setting pop_pools on cis load balancer %q: %s", d.Id(), err)
}

if err := d.Set("region_pools", flattenPools(glbObj.RegionPools, "region", cisId)); err != nil {
log.Printf("[WARN] Error setting region_pools on cis load balancer %q: %s", d.Id(), err)
}

return nil
}
func flattenPools(pools map[string][]string, geoType string, cisId string) []interface{} {
result := make([]interface{}, 0)
for k, v := range pools {
pool := map[string]interface{}{
geoType: k,
"pool_ids": convertCisToTfTwoVarSlice(v, cisId),
}
result = append(result, pool)
}
return result
}

func resourceCISGlbUpdate(d *schema.ResourceData, meta interface{}) error {
cisClient, err := meta.(ClientSession).CisAPI()
Expand All @@ -203,7 +282,7 @@ func resourceCISGlbUpdate(d *schema.ResourceData, meta interface{}) error {
}
glbUpdate := v1.GlbBody{}

if d.HasChange("name") || d.HasChange("default_pool_ids") || d.HasChange("fallback_pool_id") || d.HasChange("proxied") || d.HasChange("session_affinity") || d.HasChange("description") || d.HasChange("ttl") || d.HasChange("enabled") {
if d.HasChange("name") || d.HasChange("default_pool_ids") || d.HasChange("fallback_pool_id") || d.HasChange("proxied") || d.HasChange("session_affinity") || d.HasChange("description") || d.HasChange("ttl") || d.HasChange("enabled") || d.HasChange("pop_pools") || d.HasChange("region_pools") {

name := d.Get("name").(string)
glbUpdate.Name = name
Expand All @@ -224,6 +303,21 @@ func resourceCISGlbUpdate(d *schema.ResourceData, meta interface{}) error {
if enabled, ok := d.GetOk("enabled"); ok {
glbUpdate.Enabled = enabled.(bool)
}
if regionPools, ok := d.GetOk("region_pools"); ok {
expandedRegionPools, err := expandGeoPools(regionPools, "region")
if err != nil {
return err
}
glbUpdate.RegionPools = expandedRegionPools
}

if popPools, ok := d.GetOk("pop_pools"); ok {
expandedPopPools, err := expandGeoPools(popPools, "pop")
if err != nil {
return err
}
glbUpdate.PopPools = expandedPopPools
}
_, err = cisClient.Glbs().UpdateGlb(cisId, zoneId, glbId, glbUpdate)
if err != nil {
log.Printf("[WARN] Error getting zone during GlbUpdate %v\n", err)
Expand Down
40 changes: 36 additions & 4 deletions ibm/resource_ibm_cis_global_load_balancer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"log"
"testing"

//"regexp"

//"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
Expand All @@ -26,13 +25,26 @@ func TestAccIBMCisGlb_Basic(t *testing.T) {
CheckDestroy: testAccCheckCisGlbDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckCisGlbConfigCisDS_Basic("test", cisDomainStatic),
Config: testAccCheckCisGlbConfigCisDS_Basic("test", cisDomainStatic),
ExpectNonEmptyPlan: true,
Check: resource.ComposeTestCheckFunc(
testAccCheckCisGlbExists(name, &glb),
// dont check that 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"),
resource.TestCheckResourceAttr(name, "pop_pools.#", "0"),
resource.TestCheckResourceAttr(name, "region_pools.#", "0"),
resource.TestCheckResourceAttr(name, "proxied", "false"), // default value
),
},
{
Config: testAccCheckCisGlbConfigCisDS_Update("test", cisDomainStatic),
ExpectNonEmptyPlan: true,
Check: resource.ComposeTestCheckFunc(
testAccCheckCisGlbExists(name, &glb),
// dont check that specified values are set, this will be evident by lack of plan diff
// some values will get empty values
resource.TestCheckResourceAttr(name, "pop_pools.#", "1"),
resource.TestCheckResourceAttr(name, "region_pools.#", "1"),
resource.TestCheckResourceAttr(name, "proxied", "false"), // default value
),
},
Expand Down Expand Up @@ -253,6 +265,26 @@ func testAccCheckCisGlbConfigCisDS_Basic(id string, cisDomain string) string {
`, id, cisDomainStatic, cisInstance)
}

func testAccCheckCisGlbConfigCisDS_Update(id string, cisDomain string) string {
return testAccCheckCisPoolConfigFullySpecified(id, cisDomain) + fmt.Sprintf(`
resource "ibm_cis_global_load_balancer" "%[1]s" {
cis_id = data.ibm_cis.cis.id
domain_id = data.ibm_cis_domain.cis_domain.id
name = "%[2]s"
fallback_pool_id = ibm_cis_origin_pool.origin_pool.id
default_pool_ids = [ibm_cis_origin_pool.origin_pool.id]
region_pools{
region="WEU"
pool_ids = [ibm_cis_origin_pool.origin_pool.id]
}
pop_pools{
pop="LAX"
pool_ids = [ibm_cis_origin_pool.origin_pool.id]
}
}
`, id, cisDomainStatic, cisInstance)
}

func testAccCheckCisGlbConfigCisRI_Basic(id string, cisDomain string) string {
return testAccCheckCisPoolConfigCisRI_Basic(id, cisDomain) + fmt.Sprintf(`
resource "ibm_cis_global_load_balancer" "%[1]s" {
Expand Down
4 changes: 2 additions & 2 deletions ibm/resource_ibm_cis_origin_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,12 @@ func testAccCheckCisPoolConfigFullySpecified(resourceId string, cisDomainStatic
notification_email = "admin@outlook.com"
origins {
name = "example-1"
address = "192.0.2.1"
address = "150.0.0.1"
enabled = true
}
origins {
name = "example-2"
address = "192.0.2.2"
address = "150.0.0.2"
enabled = true
}
check_regions = ["WEU"]
Expand Down
14 changes: 14 additions & 0 deletions website/docs/r/cis_global_load_balancer.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ resource "ibm_cis_global_load_balancer" "example" {
default_pool_ids = [ibm_cis_origin_pool.example.id]
description = "example load balancer using geo-balancing"
proxied = true
region_pools{
region="WEU"
pool_ids = [ibm_cis_origin_pool.example.id]
}
pop_pools{
pop="LAX"
pool_ids = [ibm_cis_origin_pool.example.id]
}
}
resource "ibm_cis_origin_pool" "example" {
Expand Down Expand Up @@ -53,6 +61,12 @@ The following arguments are supported:
* `ttl` - (Optional,int) Time to live (TTL) of the DNS entry for the IP address returned by this load balancer.
* `enabled` - (Optional,bool) Indicates if the load balancer is enabled or not.
Region and pop pools are not currently implemented in this version of the provider.
* `region_pools` - (Optional,set) A set containing mappings of region/country codes to a list of pool IDs (ordered by their failover priority) for the given region.
* `region` - (Required,string) A region code. Multiple entries should not be specified with the same region.
* `pool_ids` - (Required,string) A list of pool IDs in failover priority to use in the given region.
* `pop_pools` - (Optional,set) A set containing mappings of IBM Point-of-Presence (PoP) identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). This feature is only available to enterprise customers.
* `pop` - (Required,string) A 3-letter code for the Point-of-Presence.Multiple entries should not be specified with the same PoP.
* `pool_ids` - (Required,string) A list of pool IDs in failover priority to use for traffic reaching the given PoP.

## Attributes Reference

Expand Down

0 comments on commit cc6cdee

Please sign in to comment.