PageRenderTime 58ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/builtin/providers/cloudstack/resources.go

https://gitlab.com/biopandemic/terraform
Go | 147 lines | 116 code | 22 blank | 9 comment | 24 complexity | 853b018daf8249e111f4c9ad0ad1d37f MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. package cloudstack
  2. import (
  3. "fmt"
  4. "log"
  5. "regexp"
  6. "time"
  7. "github.com/hashicorp/terraform/helper/schema"
  8. "github.com/xanzy/go-cloudstack/cloudstack"
  9. )
  10. // CloudStack uses a "special" ID of -1 to define an unlimited resource
  11. const UnlimitedResourceID = "-1"
  12. type retrieveError struct {
  13. name string
  14. value string
  15. err error
  16. }
  17. func (e *retrieveError) Error() error {
  18. return fmt.Errorf("Error retrieving ID of %s %s: %s", e.name, e.value, e.err)
  19. }
  20. func setValueOrID(d *schema.ResourceData, key string, value string, id string) {
  21. if isID(d.Get(key).(string)) {
  22. // If the given id is an empty string, check if the configured value matches
  23. // the UnlimitedResourceID in which case we set id to UnlimitedResourceID
  24. if id == "" && d.Get(key).(string) == UnlimitedResourceID {
  25. id = UnlimitedResourceID
  26. }
  27. d.Set(key, id)
  28. } else {
  29. d.Set(key, value)
  30. }
  31. }
  32. func retrieveID(cs *cloudstack.CloudStackClient, name, value string) (id string, e *retrieveError) {
  33. // If the supplied value isn't a ID, try to retrieve the ID ourselves
  34. if isID(value) {
  35. return value, nil
  36. }
  37. log.Printf("[DEBUG] Retrieving ID of %s: %s", name, value)
  38. var err error
  39. switch name {
  40. case "disk_offering":
  41. id, err = cs.DiskOffering.GetDiskOfferingID(value)
  42. case "virtual_machine":
  43. id, err = cs.VirtualMachine.GetVirtualMachineID(value)
  44. case "service_offering":
  45. id, err = cs.ServiceOffering.GetServiceOfferingID(value)
  46. case "network_offering":
  47. id, err = cs.NetworkOffering.GetNetworkOfferingID(value)
  48. case "project":
  49. id, err = cs.Project.GetProjectID(value)
  50. case "vpc_offering":
  51. id, err = cs.VPC.GetVPCOfferingID(value)
  52. case "vpc":
  53. id, err = cs.VPC.GetVPCID(value)
  54. case "network":
  55. id, err = cs.Network.GetNetworkID(value)
  56. case "zone":
  57. id, err = cs.Zone.GetZoneID(value)
  58. case "ipaddress":
  59. p := cs.Address.NewListPublicIpAddressesParams()
  60. p.SetIpaddress(value)
  61. l, e := cs.Address.ListPublicIpAddresses(p)
  62. if e != nil {
  63. err = e
  64. break
  65. }
  66. if l.Count == 1 {
  67. id = l.PublicIpAddresses[0].Id
  68. break
  69. }
  70. err = fmt.Errorf("Could not find ID of IP address: %s", value)
  71. case "os_type":
  72. p := cs.GuestOS.NewListOsTypesParams()
  73. p.SetDescription(value)
  74. l, e := cs.GuestOS.ListOsTypes(p)
  75. if e != nil {
  76. err = e
  77. break
  78. }
  79. if l.Count == 1 {
  80. id = l.OsTypes[0].Id
  81. break
  82. }
  83. err = fmt.Errorf("Could not find ID of OS Type: %s", value)
  84. default:
  85. return id, &retrieveError{name: name, value: value,
  86. err: fmt.Errorf("Unknown request: %s", name)}
  87. }
  88. if err != nil {
  89. return id, &retrieveError{name: name, value: value, err: err}
  90. }
  91. return id, nil
  92. }
  93. func retrieveTemplateID(cs *cloudstack.CloudStackClient, zoneid, value string) (id string, e *retrieveError) {
  94. // If the supplied value isn't a ID, try to retrieve the ID ourselves
  95. if isID(value) {
  96. return value, nil
  97. }
  98. log.Printf("[DEBUG] Retrieving ID of template: %s", value)
  99. id, err := cs.Template.GetTemplateID(value, "executable", zoneid)
  100. if err != nil {
  101. return id, &retrieveError{name: "template", value: value, err: err}
  102. }
  103. return id, nil
  104. }
  105. // ID can be either a UUID or a UnlimitedResourceID
  106. func isID(id string) bool {
  107. re := regexp.MustCompile(`^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|-1)$`)
  108. return re.MatchString(id)
  109. }
  110. // RetryFunc is the function retried n times
  111. type RetryFunc func() (interface{}, error)
  112. // Retry is a wrapper around a RetryFunc that will retry a function
  113. // n times or until it succeeds.
  114. func Retry(n int, f RetryFunc) (interface{}, error) {
  115. var lastErr error
  116. for i := 0; i < n; i++ {
  117. r, err := f()
  118. if err == nil {
  119. return r, nil
  120. }
  121. lastErr = err
  122. time.Sleep(30 * time.Second)
  123. }
  124. return nil, lastErr
  125. }