github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/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  type retrieveError struct {
    14  	name  string
    15  	value string
    16  	err   error
    17  }
    18  
    19  func (e *retrieveError) Error() error {
    20  	return fmt.Errorf("Error retrieving UUID of %s %s: %s", e.name, e.value, e.err)
    21  }
    22  
    23  func setValueOrUUID(d *schema.ResourceData, key string, value string, uuid string) {
    24  	if isUUID(d.Get(key).(string)) {
    25  		d.Set(key, uuid)
    26  	} else {
    27  		d.Set(key, value)
    28  	}
    29  }
    30  
    31  func retrieveUUID(cs *cloudstack.CloudStackClient, name, value string) (uuid string, e *retrieveError) {
    32  	// If the supplied value isn't a UUID, try to retrieve the UUID ourselves
    33  	if isUUID(value) {
    34  		return value, nil
    35  	}
    36  
    37  	log.Printf("[DEBUG] Retrieving UUID of %s: %s", name, value)
    38  
    39  	var err error
    40  	switch name {
    41  	case "disk_offering":
    42  		uuid, err = cs.DiskOffering.GetDiskOfferingID(value)
    43  	case "virtual_machine":
    44  		uuid, err = cs.VirtualMachine.GetVirtualMachineID(value)
    45  	case "service_offering":
    46  		uuid, err = cs.ServiceOffering.GetServiceOfferingID(value)
    47  	case "network_offering":
    48  		uuid, err = cs.NetworkOffering.GetNetworkOfferingID(value)
    49  	case "vpc_offering":
    50  		uuid, err = cs.VPC.GetVPCOfferingID(value)
    51  	case "vpc":
    52  		uuid, err = cs.VPC.GetVPCID(value)
    53  	case "network":
    54  		uuid, err = cs.Network.GetNetworkID(value)
    55  	case "zone":
    56  		uuid, err = cs.Zone.GetZoneID(value)
    57  	case "ipaddress":
    58  		p := cs.Address.NewListPublicIpAddressesParams()
    59  		p.SetIpaddress(value)
    60  		l, e := cs.Address.ListPublicIpAddresses(p)
    61  		if e != nil {
    62  			err = e
    63  			break
    64  		}
    65  		if l.Count == 1 {
    66  			uuid = l.PublicIpAddresses[0].Id
    67  			break
    68  		}
    69  		err = fmt.Errorf("Could not find UUID of IP address: %s", value)
    70  	case "os_type":
    71  		p := cs.GuestOS.NewListOsTypesParams()
    72  		p.SetDescription(value)
    73  		l, e := cs.GuestOS.ListOsTypes(p)
    74  		if e != nil {
    75  			err = e
    76  			break
    77  		}
    78  		if l.Count == 1 {
    79  			uuid = l.OsTypes[0].Id
    80  			break
    81  		}
    82  		err = fmt.Errorf("Could not find UUID of OS Type: %s", value)
    83  	case "project":
    84  		uuid, err = cs.Project.GetProjectID(value)
    85  	default:
    86  		return uuid, &retrieveError{name: name, value: value,
    87  			err: fmt.Errorf("Unknown request: %s", name)}
    88  	}
    89  
    90  	if err != nil {
    91  		return uuid, &retrieveError{name: name, value: value, err: err}
    92  	}
    93  
    94  	return uuid, nil
    95  }
    96  
    97  func retrieveTemplateUUID(cs *cloudstack.CloudStackClient, zoneid, value string) (uuid string, e *retrieveError) {
    98  	// If the supplied value isn't a UUID, try to retrieve the UUID ourselves
    99  	if isUUID(value) {
   100  		return value, nil
   101  	}
   102  
   103  	log.Printf("[DEBUG] Retrieving UUID of template: %s", value)
   104  
   105  	uuid, err := cs.Template.GetTemplateID(value, "executable", zoneid)
   106  	if err != nil {
   107  		return uuid, &retrieveError{name: "template", value: value, err: err}
   108  	}
   109  
   110  	return uuid, nil
   111  }
   112  
   113  func isUUID(s string) bool {
   114  	re := regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
   115  	return re.MatchString(s)
   116  }
   117  
   118  // RetryFunc is the function retried n times
   119  type RetryFunc func() (interface{}, error)
   120  
   121  // Retry is a wrapper around a RetryFunc that will retry a function
   122  // n times or until it succeeds.
   123  func Retry(n int, f RetryFunc) (interface{}, error) {
   124  	var lastErr error
   125  
   126  	for i := 0; i < n; i++ {
   127  		r, err := f()
   128  		if err == nil {
   129  			return r, nil
   130  		}
   131  
   132  		lastErr = err
   133  		time.Sleep(30 * time.Second)
   134  	}
   135  
   136  	return nil, lastErr
   137  }