github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/heroku/resource_heroku_addon.go (about) 1 package heroku 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "sync" 8 9 "github.com/cyberdelia/heroku-go/v3" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 // Global lock to prevent parallelism for heroku_addon since 14 // the Heroku API cannot handle a single application requesting 15 // multiple addons simultaneously. 16 var addonLock sync.Mutex 17 18 func resourceHerokuAddon() *schema.Resource { 19 return &schema.Resource{ 20 Create: resourceHerokuAddonCreate, 21 Read: resourceHerokuAddonRead, 22 Update: resourceHerokuAddonUpdate, 23 Delete: resourceHerokuAddonDelete, 24 25 Schema: map[string]*schema.Schema{ 26 "app": &schema.Schema{ 27 Type: schema.TypeString, 28 Required: true, 29 ForceNew: true, 30 }, 31 32 "plan": &schema.Schema{ 33 Type: schema.TypeString, 34 Required: true, 35 }, 36 37 "config": &schema.Schema{ 38 Type: schema.TypeList, 39 Optional: true, 40 ForceNew: true, 41 Elem: &schema.Schema{ 42 Type: schema.TypeMap, 43 }, 44 }, 45 46 "provider_id": &schema.Schema{ 47 Type: schema.TypeString, 48 Computed: true, 49 }, 50 51 "config_vars": &schema.Schema{ 52 Type: schema.TypeList, 53 Computed: true, 54 Elem: &schema.Schema{ 55 Type: schema.TypeString, 56 }, 57 }, 58 }, 59 } 60 } 61 62 func resourceHerokuAddonCreate(d *schema.ResourceData, meta interface{}) error { 63 addonLock.Lock() 64 defer addonLock.Unlock() 65 66 client := meta.(*heroku.Service) 67 68 app := d.Get("app").(string) 69 opts := heroku.AddonCreateOpts{Plan: d.Get("plan").(string)} 70 71 if v := d.Get("config"); v != nil { 72 config := make(map[string]string) 73 for _, v := range v.([]interface{}) { 74 for k, v := range v.(map[string]interface{}) { 75 config[k] = v.(string) 76 } 77 } 78 79 opts.Config = &config 80 } 81 82 log.Printf("[DEBUG] Addon create configuration: %#v, %#v", app, opts) 83 a, err := client.AddonCreate(app, opts) 84 if err != nil { 85 return err 86 } 87 88 d.SetId(a.ID) 89 log.Printf("[INFO] Addon ID: %s", d.Id()) 90 91 return resourceHerokuAddonRead(d, meta) 92 } 93 94 func resourceHerokuAddonRead(d *schema.ResourceData, meta interface{}) error { 95 client := meta.(*heroku.Service) 96 97 addon, err := resourceHerokuAddonRetrieve( 98 d.Get("app").(string), d.Id(), client) 99 if err != nil { 100 return err 101 } 102 103 // Determine the plan. If we were configured without a specific plan, 104 // then just avoid the plan altogether (accepting anything that 105 // Heroku sends down). 106 plan := addon.Plan.Name 107 if v := d.Get("plan").(string); v != "" { 108 if idx := strings.IndexRune(v, ':'); idx == -1 { 109 idx = strings.IndexRune(plan, ':') 110 if idx > -1 { 111 plan = plan[:idx] 112 } 113 } 114 } 115 116 d.Set("name", addon.Name) 117 d.Set("plan", plan) 118 d.Set("provider_id", addon.ProviderID) 119 if err := d.Set("config_vars", addon.ConfigVars); err != nil { 120 return err 121 } 122 123 return nil 124 } 125 126 func resourceHerokuAddonUpdate(d *schema.ResourceData, meta interface{}) error { 127 client := meta.(*heroku.Service) 128 129 app := d.Get("app").(string) 130 131 if d.HasChange("plan") { 132 ad, err := client.AddonUpdate( 133 app, d.Id(), heroku.AddonUpdateOpts{Plan: d.Get("plan").(string)}) 134 if err != nil { 135 return err 136 } 137 138 // Store the new ID 139 d.SetId(ad.ID) 140 } 141 142 return resourceHerokuAddonRead(d, meta) 143 } 144 145 func resourceHerokuAddonDelete(d *schema.ResourceData, meta interface{}) error { 146 client := meta.(*heroku.Service) 147 148 log.Printf("[INFO] Deleting Addon: %s", d.Id()) 149 150 // Destroy the app 151 err := client.AddonDelete(d.Get("app").(string), d.Id()) 152 if err != nil { 153 return fmt.Errorf("Error deleting addon: %s", err) 154 } 155 156 d.SetId("") 157 return nil 158 } 159 160 func resourceHerokuAddonRetrieve(app string, id string, client *heroku.Service) (*heroku.Addon, error) { 161 addon, err := client.AddonInfo(app, id) 162 163 if err != nil { 164 return nil, fmt.Errorf("Error retrieving addon: %s", err) 165 } 166 167 return addon, nil 168 }