terraform/builtin/providers/clc/resource_clc_load_balancer_...

180 lines
4.5 KiB
Go

package clc
import (
"fmt"
"log"
"strconv"
clc "github.com/CenturyLinkCloud/clc-sdk"
"github.com/CenturyLinkCloud/clc-sdk/lb"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceCLCLoadBalancerPool() *schema.Resource {
return &schema.Resource{
Create: resourceCLCLoadBalancerPoolCreate,
Read: resourceCLCLoadBalancerPoolRead,
Update: resourceCLCLoadBalancerPoolUpdate,
Delete: resourceCLCLoadBalancerPoolDelete,
Schema: map[string]*schema.Schema{
// pool args
"port": &schema.Schema{
Type: schema.TypeInt,
Required: true,
},
"data_center": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"load_balancer": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"method": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "roundRobin",
},
"persistence": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "standard",
},
"nodes": &schema.Schema{
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{Type: schema.TypeMap},
},
},
}
}
func resourceCLCLoadBalancerPoolCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clc.Client)
dc := d.Get("data_center").(string)
lbid := d.Get("load_balancer").(string)
s1 := d.Get("method").(string)
m := lb.LeastConn
if s1 == string(lb.RoundRobin) {
m = lb.RoundRobin
}
s2 := d.Get("persistence").(string)
p := lb.Standard
if s2 == string(lb.Sticky) {
p = lb.Sticky
}
r2 := lb.Pool{
Port: d.Get("port").(int),
Method: m,
Persistence: p,
}
lbp, err := client.LB.CreatePool(dc, lbid, r2)
if err != nil {
return fmt.Errorf("Failed creating pool under %v/%v: %v", dc, lbid, err)
}
d.SetId(lbp.ID)
return resourceCLCLoadBalancerPoolUpdate(d, meta)
}
func resourceCLCLoadBalancerPoolRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clc.Client)
dc := d.Get("data_center").(string)
lbid := d.Get("load_balancer").(string)
id := d.Id()
pool, err := client.LB.GetPool(dc, lbid, id)
if err != nil {
log.Printf("[INFO] Failed fetching pool %v/%v. Marking destroyed", lbid, d.Id())
d.SetId("")
return nil
}
nodes, err := client.LB.GetAllNodes(dc, lbid, id)
nodes2 := make([]lb.Node, len(nodes))
for i, n := range nodes {
nodes2[i] = *n
}
pool.Nodes = nodes2
d.Set("port", pool.Port)
d.Set("method", pool.Method)
d.Set("persistence", pool.Persistence)
d.Set("nodes", pool.Nodes)
d.Set("links", pool.Links)
return nil
}
func resourceCLCLoadBalancerPoolUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clc.Client)
dc := d.Get("data_center").(string)
lbid := d.Get("load_balancer").(string)
id := d.Id()
pool, err := client.LB.GetPool(dc, lbid, d.Id())
pool.Port = 0 // triggers empty value => omission from POST
if d.HasChange("method") {
d.SetPartial("method")
pool.Method = lb.Method(d.Get("method").(string))
}
if d.HasChange("persistence") {
d.SetPartial("persistence")
pool.Persistence = lb.Persistence(d.Get("persistence").(string))
}
err = client.LB.UpdatePool(dc, lbid, id, *pool)
if err != nil {
return fmt.Errorf("Failed updating pool %v: %v", id, err)
}
if d.HasChange("nodes") {
d.SetPartial("nodes")
nodes, err := parseNodes(d)
if err != nil {
return err
}
err = client.LB.UpdateNodes(dc, lbid, id, nodes...)
if err != nil {
return fmt.Errorf("Failed updating pool nodes %v: %v", id, err)
}
}
return resourceCLCLoadBalancerPoolRead(d, meta)
}
func resourceCLCLoadBalancerPoolDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clc.Client)
dc := d.Get("data_center").(string)
lbid := d.Get("load_balancer").(string)
id := d.Id()
err := client.LB.DeletePool(dc, lbid, id)
if err != nil {
return fmt.Errorf("Failed deleting pool %v: %v", id, err)
}
return nil
}
func parseNodes(d *schema.ResourceData) ([]lb.Node, error) {
var nodes []lb.Node
raw := d.Get("nodes")
if raw == nil {
log.Println("WARNING: pool missing nodes")
return nil, nil
}
if arr, ok := raw.([]interface{}); ok {
for _, v := range arr {
m := v.(map[string]interface{})
p, err := strconv.Atoi(m["privatePort"].(string))
if err != nil {
log.Printf("[WARN] Failed parsing port '%v'. skipping", m["privatePort"])
continue
}
n := lb.Node{
Status: m["status"].(string),
IPaddress: m["ipAddress"].(string),
PrivatePort: p,
}
nodes = append(nodes, n)
}
} else {
return nil, fmt.Errorf("Failed parsing nodes from pool spec: %v", raw)
}
return nodes, nil
}