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 }