180 lines
4.5 KiB
Go
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
|
||
|
}
|