github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/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 }