github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/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  // CloudStack uses a "special" ID of -1 to define an unlimited resource
    14  const UnlimitedResourceID = "-1"
    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 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) == UnlimitedResourceID {
    31  			id = 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, value string) (id string, e *retrieveError) {
    41  	// If the supplied value isn't a ID, try to retrieve the ID ourselves
    42  	if 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 "virtual_machine":
    53  		id, err = cs.VirtualMachine.GetVirtualMachineID(value)
    54  	case "service_offering":
    55  		id, err = cs.ServiceOffering.GetServiceOfferingID(value)
    56  	case "network_offering":
    57  		id, err = cs.NetworkOffering.GetNetworkOfferingID(value)
    58  	case "project":
    59  		id, err = cs.Project.GetProjectID(value)
    60  	case "vpc_offering":
    61  		id, err = cs.VPC.GetVPCOfferingID(value)
    62  	case "vpc":
    63  		id, err = cs.VPC.GetVPCID(value)
    64  	case "network":
    65  		id, err = cs.Network.GetNetworkID(value)
    66  	case "zone":
    67  		id, err = cs.Zone.GetZoneID(value)
    68  	case "ipaddress":
    69  		p := cs.Address.NewListPublicIpAddressesParams()
    70  		p.SetIpaddress(value)
    71  		l, e := cs.Address.ListPublicIpAddresses(p)
    72  		if e != nil {
    73  			err = e
    74  			break
    75  		}
    76  		if l.Count == 1 {
    77  			id = l.PublicIpAddresses[0].Id
    78  			break
    79  		}
    80  		err = fmt.Errorf("Could not find ID of IP address: %s", value)
    81  	case "os_type":
    82  		p := cs.GuestOS.NewListOsTypesParams()
    83  		p.SetDescription(value)
    84  		l, e := cs.GuestOS.ListOsTypes(p)
    85  		if e != nil {
    86  			err = e
    87  			break
    88  		}
    89  		if l.Count == 1 {
    90  			id = l.OsTypes[0].Id
    91  			break
    92  		}
    93  		err = fmt.Errorf("Could not find ID of OS Type: %s", value)
    94  	default:
    95  		return id, &retrieveError{name: name, value: value,
    96  			err: fmt.Errorf("Unknown request: %s", name)}
    97  	}
    98  
    99  	if err != nil {
   100  		return id, &retrieveError{name: name, value: value, err: err}
   101  	}
   102  
   103  	return id, nil
   104  }
   105  
   106  func retrieveTemplateID(cs *cloudstack.CloudStackClient, zoneid, value string) (id string, e *retrieveError) {
   107  	// If the supplied value isn't a ID, try to retrieve the ID ourselves
   108  	if isID(value) {
   109  		return value, nil
   110  	}
   111  
   112  	log.Printf("[DEBUG] Retrieving ID of template: %s", value)
   113  
   114  	id, err := cs.Template.GetTemplateID(value, "executable", zoneid)
   115  	if err != nil {
   116  		return id, &retrieveError{name: "template", value: value, err: err}
   117  	}
   118  
   119  	return id, nil
   120  }
   121  
   122  // ID can be either a UUID or a UnlimitedResourceID
   123  func isID(id string) bool {
   124  	re := regexp.MustCompile(`^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|-1)$`)
   125  	return re.MatchString(id)
   126  }
   127  
   128  // RetryFunc is the function retried n times
   129  type RetryFunc func() (interface{}, error)
   130  
   131  // Retry is a wrapper around a RetryFunc that will retry a function
   132  // n times or until it succeeds.
   133  func Retry(n int, f RetryFunc) (interface{}, error) {
   134  	var lastErr error
   135  
   136  	for i := 0; i < n; i++ {
   137  		r, err := f()
   138  		if err == nil {
   139  			return r, nil
   140  		}
   141  
   142  		lastErr = err
   143  		time.Sleep(30 * time.Second)
   144  	}
   145  
   146  	return nil, lastErr
   147  }