185 lines
4.7 KiB
Go
185 lines
4.7 KiB
Go
package profitbricks
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
"github.com/profitbricks/profitbricks-sdk-go"
|
|
"log"
|
|
"regexp"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func resourceProfitBricksDatacenter() *schema.Resource {
|
|
return &schema.Resource{
|
|
Create: resourceProfitBricksDatacenterCreate,
|
|
Read: resourceProfitBricksDatacenterRead,
|
|
Update: resourceProfitBricksDatacenterUpdate,
|
|
Delete: resourceProfitBricksDatacenterDelete,
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
//Datacenter parameters
|
|
"name": {
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
},
|
|
|
|
"location": {
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
},
|
|
"description": {
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func resourceProfitBricksDatacenterCreate(d *schema.ResourceData, meta interface{}) error {
|
|
datacenter := profitbricks.Datacenter{
|
|
Properties: profitbricks.DatacenterProperties{
|
|
Name: d.Get("name").(string),
|
|
Location: d.Get("location").(string),
|
|
},
|
|
}
|
|
|
|
if attr, ok := d.GetOk("description"); ok {
|
|
datacenter.Properties.Description = attr.(string)
|
|
}
|
|
dc := profitbricks.CreateDatacenter(datacenter)
|
|
|
|
if dc.StatusCode > 299 {
|
|
return fmt.Errorf(
|
|
"Error creating data center (%s) (%s)", d.Id(), dc.Response)
|
|
}
|
|
d.SetId(dc.Id)
|
|
|
|
log.Printf("[INFO] DataCenter Id: %s", d.Id())
|
|
|
|
err := waitTillProvisioned(meta, dc.Headers.Get("Location"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return resourceProfitBricksDatacenterRead(d, meta)
|
|
}
|
|
|
|
func resourceProfitBricksDatacenterRead(d *schema.ResourceData, meta interface{}) error {
|
|
datacenter := profitbricks.GetDatacenter(d.Id())
|
|
if datacenter.StatusCode > 299 {
|
|
if datacenter.StatusCode == 404 {
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
return fmt.Errorf("Error while fetching a data center ID %s %s", d.Id(), datacenter.Response)
|
|
}
|
|
|
|
d.Set("name", datacenter.Properties.Name)
|
|
d.Set("location", datacenter.Properties.Location)
|
|
d.Set("description", datacenter.Properties.Description)
|
|
return nil
|
|
}
|
|
|
|
func resourceProfitBricksDatacenterUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
obj := profitbricks.DatacenterProperties{}
|
|
|
|
if d.HasChange("name") {
|
|
_, newName := d.GetChange("name")
|
|
|
|
obj.Name = newName.(string)
|
|
}
|
|
|
|
if d.HasChange("description") {
|
|
_, newDescription := d.GetChange("description")
|
|
obj.Description = newDescription.(string)
|
|
}
|
|
|
|
resp := profitbricks.PatchDatacenter(d.Id(), obj)
|
|
waitTillProvisioned(meta, resp.Headers.Get("Location"))
|
|
return resourceProfitBricksDatacenterRead(d, meta)
|
|
}
|
|
|
|
func resourceProfitBricksDatacenterDelete(d *schema.ResourceData, meta interface{}) error {
|
|
dcid := d.Id()
|
|
resp := profitbricks.DeleteDatacenter(dcid)
|
|
|
|
if resp.StatusCode > 299 {
|
|
return fmt.Errorf("An error occured while deleting the data center ID %s %s", d.Id(), string(resp.Body))
|
|
}
|
|
err := waitTillProvisioned(meta, resp.Headers.Get("Location"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
|
|
func waitTillProvisioned(meta interface{}, path string) error {
|
|
config := meta.(*Config)
|
|
waitCount := 50
|
|
|
|
if config.Retries != 0 {
|
|
waitCount = config.Retries
|
|
}
|
|
for i := 0; i < waitCount; i++ {
|
|
request := profitbricks.GetRequestStatus(path)
|
|
pc, _, _, ok := runtime.Caller(1)
|
|
details := runtime.FuncForPC(pc)
|
|
if ok && details != nil {
|
|
log.Printf("[DEBUG] Called from %s", details.Name())
|
|
}
|
|
log.Printf("[DEBUG] Request status: %s", request.Metadata.Status)
|
|
log.Printf("[DEBUG] Request status path: %s", path)
|
|
|
|
if request.Metadata.Status == "DONE" {
|
|
return nil
|
|
}
|
|
if request.Metadata.Status == "FAILED" {
|
|
|
|
return fmt.Errorf("Request failed with following error: %s", request.Metadata.Message)
|
|
}
|
|
time.Sleep(10 * time.Second)
|
|
i++
|
|
}
|
|
return fmt.Errorf("Timeout has expired")
|
|
}
|
|
|
|
func getImageId(dcId string, imageName string, imageType string) string {
|
|
if imageName == "" {
|
|
return ""
|
|
}
|
|
dc := profitbricks.GetDatacenter(dcId)
|
|
if dc.StatusCode > 299 {
|
|
log.Print(fmt.Errorf("Error while fetching a data center ID %s %s", dcId, dc.Response))
|
|
}
|
|
|
|
images := profitbricks.ListImages()
|
|
if images.StatusCode > 299 {
|
|
log.Print(fmt.Errorf("Error while fetching the list of images %s", images.Response))
|
|
}
|
|
|
|
if len(images.Items) > 0 {
|
|
for _, i := range images.Items {
|
|
imgName := ""
|
|
if i.Properties.Name != "" {
|
|
imgName = i.Properties.Name
|
|
}
|
|
|
|
if imageType == "SSD" {
|
|
imageType = "HDD"
|
|
}
|
|
if imgName != "" && strings.Contains(strings.ToLower(imgName), strings.ToLower(imageName)) && i.Properties.ImageType == imageType && i.Properties.Location == dc.Properties.Location && i.Properties.Public == true {
|
|
return i.Id
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func IsValidUUID(uuid string) bool {
|
|
r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$")
|
|
return r.MatchString(uuid)
|
|
}
|