160 lines
4.2 KiB
Go
160 lines
4.2 KiB
Go
|
package clc
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"time"
|
||
|
|
||
|
"github.com/CenturyLinkCloud/clc-sdk"
|
||
|
"github.com/CenturyLinkCloud/clc-sdk/api"
|
||
|
"github.com/CenturyLinkCloud/clc-sdk/group"
|
||
|
"github.com/hashicorp/terraform/helper/resource"
|
||
|
"github.com/hashicorp/terraform/helper/schema"
|
||
|
)
|
||
|
|
||
|
func resourceCLCGroup() *schema.Resource {
|
||
|
return &schema.Resource{
|
||
|
Create: resourceCLCGroupCreate,
|
||
|
Read: resourceCLCGroupRead,
|
||
|
Update: resourceCLCGroupUpdate,
|
||
|
Delete: resourceCLCGroupDelete,
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"name": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
"description": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Default: "",
|
||
|
},
|
||
|
"parent": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
"location_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
"parent_group_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Computed: true,
|
||
|
},
|
||
|
"custom_fields": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeMap},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func resourceCLCGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
||
|
client := meta.(*clc.Client)
|
||
|
name := d.Get("name").(string)
|
||
|
desc := d.Get("description").(string)
|
||
|
parent := d.Get("parent").(string)
|
||
|
dc := d.Get("location_id").(string)
|
||
|
|
||
|
// clc doesn't enforce uniqueness by name
|
||
|
// so skip the trad'l error we'd raise
|
||
|
e, err := resolveGroupByNameOrId(name, dc, client)
|
||
|
if e != "" {
|
||
|
log.Printf("[INFO] Resolved existing group: %v => %v", name, e)
|
||
|
d.SetId(e)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
var pgid string
|
||
|
p, err := resolveGroupByNameOrId(parent, dc, client)
|
||
|
if p != "" {
|
||
|
log.Printf("[INFO] Resolved parent group: %v => %v", parent, p)
|
||
|
pgid = p
|
||
|
} else {
|
||
|
return fmt.Errorf("Failed resolving parent group %s - %s err:%s", parent, p, err)
|
||
|
}
|
||
|
|
||
|
d.Set("parent_group_id", pgid)
|
||
|
spec := group.Group{
|
||
|
Name: name,
|
||
|
Description: desc,
|
||
|
ParentGroupID: pgid,
|
||
|
}
|
||
|
resp, err := client.Group.Create(spec)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Failed creating group: %s", err)
|
||
|
}
|
||
|
log.Println("[INFO] Group created")
|
||
|
d.SetId(resp.ID)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func resourceCLCGroupRead(d *schema.ResourceData, meta interface{}) error {
|
||
|
client := meta.(*clc.Client)
|
||
|
id := d.Id()
|
||
|
g, err := client.Group.Get(id)
|
||
|
if err != nil {
|
||
|
log.Printf("[INFO] Failed finding group: %s - %s. Marking destroyed", id, err)
|
||
|
d.SetId("")
|
||
|
return nil
|
||
|
}
|
||
|
d.Set("name", g.Name)
|
||
|
d.Set("description", g.Description)
|
||
|
d.Set("parent_group_id", g.ParentGroupID())
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func resourceCLCGroupUpdate(d *schema.ResourceData, meta interface{}) error {
|
||
|
client := meta.(*clc.Client)
|
||
|
id := d.Id()
|
||
|
var err error
|
||
|
var patches []api.Update
|
||
|
|
||
|
g, err := client.Group.Get(id)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Failed fetching group: %v - %v", id, err)
|
||
|
}
|
||
|
|
||
|
if delta, orig := d.Get("name").(string), g.Name; delta != orig {
|
||
|
patches = append(patches, group.UpdateName(delta))
|
||
|
}
|
||
|
if delta, orig := d.Get("description").(string), g.Description; delta != orig {
|
||
|
patches = append(patches, group.UpdateDescription(delta))
|
||
|
}
|
||
|
newParent := d.Get("parent").(string)
|
||
|
pgid, err := resolveGroupByNameOrId(newParent, g.Locationid, client)
|
||
|
log.Printf("[DEBUG] PARENT current:%v new:%v resolved:%v", g.ParentGroupID(), newParent, pgid)
|
||
|
if pgid == "" {
|
||
|
return fmt.Errorf("Unable to resolve parent group %v: %v", newParent, err)
|
||
|
} else if newParent != g.ParentGroupID() {
|
||
|
patches = append(patches, group.UpdateParentGroupID(pgid))
|
||
|
}
|
||
|
|
||
|
if len(patches) == 0 {
|
||
|
return nil
|
||
|
}
|
||
|
err = client.Group.Update(id, patches...)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Failed updating group %v: %v", id, err)
|
||
|
}
|
||
|
return resource.Retry(1*time.Minute, func() error {
|
||
|
_, err := client.Group.Get(id)
|
||
|
if err == nil {
|
||
|
return resourceCLCGroupRead(d, meta)
|
||
|
}
|
||
|
return &resource.RetryError{Err: err}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func resourceCLCGroupDelete(d *schema.ResourceData, meta interface{}) error {
|
||
|
client := meta.(*clc.Client)
|
||
|
id := d.Id()
|
||
|
log.Printf("[INFO] Deleting group %v", id)
|
||
|
st, err := client.Group.Delete(id)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Failed deleting group: %v with err: %v", id, err)
|
||
|
}
|
||
|
waitStatus(client, st.ID)
|
||
|
return nil
|
||
|
}
|