github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/profitbricks/resource_profitbricks_datacenter.go (about)

     1  package profitbricks
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/hashicorp/terraform/helper/schema"
     6  	"github.com/profitbricks/profitbricks-sdk-go"
     7  	"log"
     8  	"regexp"
     9  	"runtime"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  func resourceProfitBricksDatacenter() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceProfitBricksDatacenterCreate,
    17  		Read:   resourceProfitBricksDatacenterRead,
    18  		Update: resourceProfitBricksDatacenterUpdate,
    19  		Delete: resourceProfitBricksDatacenterDelete,
    20  		Schema: map[string]*schema.Schema{
    21  
    22  			//Datacenter parameters
    23  			"name": {
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  			},
    27  
    28  			"location": {
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  			},
    32  			"description": {
    33  				Type:     schema.TypeString,
    34  				Optional: true,
    35  				Computed: true,
    36  			},
    37  		},
    38  	}
    39  }
    40  
    41  func resourceProfitBricksDatacenterCreate(d *schema.ResourceData, meta interface{}) error {
    42  	datacenter := profitbricks.Datacenter{
    43  		Properties: profitbricks.DatacenterProperties{
    44  			Name:     d.Get("name").(string),
    45  			Location: d.Get("location").(string),
    46  		},
    47  	}
    48  
    49  	if attr, ok := d.GetOk("description"); ok {
    50  		datacenter.Properties.Description = attr.(string)
    51  	}
    52  	dc := profitbricks.CreateDatacenter(datacenter)
    53  
    54  	if dc.StatusCode > 299 {
    55  		return fmt.Errorf(
    56  			"Error creating data center (%s) (%s)", d.Id(), dc.Response)
    57  	}
    58  	d.SetId(dc.Id)
    59  
    60  	log.Printf("[INFO] DataCenter Id: %s", d.Id())
    61  
    62  	err := waitTillProvisioned(meta, dc.Headers.Get("Location"))
    63  	if err != nil {
    64  		return err
    65  	}
    66  	return resourceProfitBricksDatacenterRead(d, meta)
    67  }
    68  
    69  func resourceProfitBricksDatacenterRead(d *schema.ResourceData, meta interface{}) error {
    70  	datacenter := profitbricks.GetDatacenter(d.Id())
    71  	if datacenter.StatusCode > 299 {
    72  		if datacenter.StatusCode == 404 {
    73  			d.SetId("")
    74  			return nil
    75  		}
    76  		return fmt.Errorf("Error while fetching a data center ID %s %s", d.Id(), datacenter.Response)
    77  	}
    78  
    79  	d.Set("name", datacenter.Properties.Name)
    80  	d.Set("location", datacenter.Properties.Location)
    81  	d.Set("description", datacenter.Properties.Description)
    82  	return nil
    83  }
    84  
    85  func resourceProfitBricksDatacenterUpdate(d *schema.ResourceData, meta interface{}) error {
    86  	obj := profitbricks.DatacenterProperties{}
    87  
    88  	if d.HasChange("name") {
    89  		_, newName := d.GetChange("name")
    90  
    91  		obj.Name = newName.(string)
    92  	}
    93  
    94  	if d.HasChange("description") {
    95  		_, newDescription := d.GetChange("description")
    96  		obj.Description = newDescription.(string)
    97  	}
    98  
    99  	resp := profitbricks.PatchDatacenter(d.Id(), obj)
   100  	waitTillProvisioned(meta, resp.Headers.Get("Location"))
   101  	return resourceProfitBricksDatacenterRead(d, meta)
   102  }
   103  
   104  func resourceProfitBricksDatacenterDelete(d *schema.ResourceData, meta interface{}) error {
   105  	dcid := d.Id()
   106  	resp := profitbricks.DeleteDatacenter(dcid)
   107  
   108  	if resp.StatusCode > 299 {
   109  		return fmt.Errorf("An error occured while deleting the data center ID %s %s", d.Id(), string(resp.Body))
   110  	}
   111  	err := waitTillProvisioned(meta, resp.Headers.Get("Location"))
   112  	if err != nil {
   113  		return err
   114  	}
   115  	d.SetId("")
   116  	return nil
   117  }
   118  
   119  func waitTillProvisioned(meta interface{}, path string) error {
   120  	config := meta.(*Config)
   121  	waitCount := 50
   122  
   123  	if config.Retries != 0 {
   124  		waitCount = config.Retries
   125  	}
   126  	for i := 0; i < waitCount; i++ {
   127  		request := profitbricks.GetRequestStatus(path)
   128  		pc, _, _, ok := runtime.Caller(1)
   129  		details := runtime.FuncForPC(pc)
   130  		if ok && details != nil {
   131  			log.Printf("[DEBUG] Called from %s", details.Name())
   132  		}
   133  		log.Printf("[DEBUG] Request status: %s", request.Metadata.Status)
   134  		log.Printf("[DEBUG] Request status path: %s", path)
   135  
   136  		if request.Metadata.Status == "DONE" {
   137  			return nil
   138  		}
   139  		if request.Metadata.Status == "FAILED" {
   140  
   141  			return fmt.Errorf("Request failed with following error: %s", request.Metadata.Message)
   142  		}
   143  		time.Sleep(10 * time.Second)
   144  		i++
   145  	}
   146  	return fmt.Errorf("Timeout has expired")
   147  }
   148  
   149  func getImageId(dcId string, imageName string, imageType string) string {
   150  	if imageName == "" {
   151  		return ""
   152  	}
   153  	dc := profitbricks.GetDatacenter(dcId)
   154  	if dc.StatusCode > 299 {
   155  		log.Print(fmt.Errorf("Error while fetching a data center ID %s %s", dcId, dc.Response))
   156  	}
   157  
   158  	images := profitbricks.ListImages()
   159  	if images.StatusCode > 299 {
   160  		log.Print(fmt.Errorf("Error while fetching the list of images %s", images.Response))
   161  	}
   162  
   163  	if len(images.Items) > 0 {
   164  		for _, i := range images.Items {
   165  			imgName := ""
   166  			if i.Properties.Name != "" {
   167  				imgName = i.Properties.Name
   168  			}
   169  
   170  			if imageType == "SSD" {
   171  				imageType = "HDD"
   172  			}
   173  			if imgName != "" && strings.Contains(strings.ToLower(imgName), strings.ToLower(imageName)) && i.Properties.ImageType == imageType && i.Properties.Location == dc.Properties.Location && i.Properties.Public == true {
   174  				return i.Id
   175  			}
   176  		}
   177  	}
   178  	return ""
   179  }
   180  
   181  func IsValidUUID(uuid string) bool {
   182  	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}$")
   183  	return r.MatchString(uuid)
   184  }