github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/builtin/providers/cloudstack/resources.go (about)

     1  package cloudstack
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"regexp"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"github.com/xanzy/go-cloudstack/cloudstack"
    11  )
    12  
    13  // Define a regexp for parsing the port
    14  var splitPorts = regexp.MustCompile(`^(\d+)(?:-(\d+))?$`)
    15  
    16  type retrieveError struct {
    17  	name  string
    18  	value string
    19  	err   error
    20  }
    21  
    22  func (e *retrieveError) Error() error {
    23  	return fmt.Errorf("Error retrieving ID of %s %s: %s", e.name, e.value, e.err)
    24  }
    25  
    26  func setValueOrID(d *schema.ResourceData, key string, value string, id string) {
    27  	if cloudstack.IsID(d.Get(key).(string)) {
    28  		// If the given id is an empty string, check if the configured value matches
    29  		// the UnlimitedResourceID in which case we set id to UnlimitedResourceID
    30  		if id == "" && d.Get(key).(string) == cloudstack.UnlimitedResourceID {
    31  			id = cloudstack.UnlimitedResourceID
    32  		}
    33  
    34  		d.Set(key, id)
    35  	} else {
    36  		d.Set(key, value)
    37  	}
    38  }
    39  
    40  func retrieveID(cs *cloudstack.CloudStackClient, name string, value string, opts ...cloudstack.OptionFunc) (id string, e *retrieveError) {
    41  	// If the supplied value isn't a ID, try to retrieve the ID ourselves
    42  	if cloudstack.IsID(value) {
    43  		return value, nil
    44  	}
    45  
    46  	log.Printf("[DEBUG] Retrieving ID of %s: %s", name, value)
    47  
    48  	var err error
    49  	switch name {
    50  	case "disk_offering":
    51  		id, err = cs.DiskOffering.GetDiskOfferingID(value)
    52  	case "service_offering":
    53  		id, err = cs.ServiceOffering.GetServiceOfferingID(value)
    54  	case "network_offering":
    55  		id, err = cs.NetworkOffering.GetNetworkOfferingID(value)
    56  	case "project":
    57  		id, err = cs.Project.GetProjectID(value)
    58  	case "vpc_offering":
    59  		id, err = cs.VPC.GetVPCOfferingID(value)
    60  	case "zone":
    61  		id, err = cs.Zone.GetZoneID(value)
    62  	case "os_type":
    63  		p := cs.GuestOS.NewListOsTypesParams()
    64  		p.SetDescription(value)
    65  		l, e := cs.GuestOS.ListOsTypes(p)
    66  		if e != nil {
    67  			err = e
    68  			break
    69  		}
    70  		if l.Count == 1 {
    71  			id = l.OsTypes[0].Id
    72  			break
    73  		}
    74  		err = fmt.Errorf("Could not find ID of OS Type: %s", value)
    75  	default:
    76  		return id, &retrieveError{name: name, value: value,
    77  			err: fmt.Errorf("Unknown request: %s", name)}
    78  	}
    79  
    80  	if err != nil {
    81  		return id, &retrieveError{name: name, value: value, err: err}
    82  	}
    83  
    84  	return id, nil
    85  }
    86  
    87  func retrieveTemplateID(cs *cloudstack.CloudStackClient, zoneid, value string) (id string, e *retrieveError) {
    88  	// If the supplied value isn't a ID, try to retrieve the ID ourselves
    89  	if cloudstack.IsID(value) {
    90  		return value, nil
    91  	}
    92  
    93  	log.Printf("[DEBUG] Retrieving ID of template: %s", value)
    94  
    95  	id, err := cs.Template.GetTemplateID(value, "executable", zoneid)
    96  	if err != nil {
    97  		return id, &retrieveError{name: "template", value: value, err: err}
    98  	}
    99  
   100  	return id, nil
   101  }
   102  
   103  // RetryFunc is the function retried n times
   104  type RetryFunc func() (interface{}, error)
   105  
   106  // Retry is a wrapper around a RetryFunc that will retry a function
   107  // n times or until it succeeds.
   108  func Retry(n int, f RetryFunc) (interface{}, error) {
   109  	var lastErr error
   110  
   111  	for i := 0; i < n; i++ {
   112  		r, err := f()
   113  		if err == nil || err == cloudstack.AsyncTimeoutErr {
   114  			return r, err
   115  		}
   116  
   117  		lastErr = err
   118  		time.Sleep(30 * time.Second)
   119  	}
   120  
   121  	return nil, lastErr
   122  }
   123  
   124  // If there is a project supplied, we retrieve and set the project id
   125  func setProjectid(p cloudstack.ProjectIDSetter, cs *cloudstack.CloudStackClient, d *schema.ResourceData) error {
   126  	if project, ok := d.GetOk("project"); ok {
   127  		projectid, e := retrieveID(cs, "project", project.(string))
   128  		if e != nil {
   129  			return e.Error()
   130  		}
   131  		p.SetProjectid(projectid)
   132  	}
   133  
   134  	return nil
   135  }