github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/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{Type: schema.TypeMap}, 55 }, 56 }, 57 } 58 } 59 60 func resourceHerokuAddonCreate(d *schema.ResourceData, meta interface{}) error { 61 addonLock.Lock() 62 defer addonLock.Unlock() 63 64 client := meta.(*heroku.Service) 65 66 app := d.Get("app").(string) 67 opts := heroku.AddonCreateOpts{Plan: d.Get("plan").(string)} 68 69 if v := d.Get("config"); v != nil { 70 config := make(map[string]string) 71 for _, v := range v.([]interface{}) { 72 for k, v := range v.(map[string]interface{}) { 73 config[k] = v.(string) 74 } 75 } 76 77 opts.Config = &config 78 } 79 80 log.Printf("[DEBUG] Addon create configuration: %#v, %#v", app, opts) 81 a, err := client.AddonCreate(app, opts) 82 if err != nil { 83 return err 84 } 85 86 d.SetId(a.ID) 87 log.Printf("[INFO] Addon ID: %s", d.Id()) 88 89 return resourceHerokuAddonRead(d, meta) 90 } 91 92 func resourceHerokuAddonRead(d *schema.ResourceData, meta interface{}) error { 93 client := meta.(*heroku.Service) 94 95 addon, err := resourceHerokuAddonRetrieve( 96 d.Get("app").(string), d.Id(), client) 97 if err != nil { 98 return err 99 } 100 101 // Determine the plan. If we were configured without a specific plan, 102 // then just avoid the plan altogether (accepting anything that 103 // Heroku sends down). 104 plan := addon.Plan.Name 105 if v := d.Get("plan").(string); v != "" { 106 if idx := strings.IndexRune(v, ':'); idx == -1 { 107 idx = strings.IndexRune(plan, ':') 108 if idx > -1 { 109 plan = plan[:idx] 110 } 111 } 112 } 113 114 d.Set("name", addon.Name) 115 d.Set("plan", plan) 116 d.Set("provider_id", addon.ProviderID) 117 d.Set("config_vars", []interface{}{addon.ConfigVars}) 118 119 return nil 120 } 121 122 func resourceHerokuAddonUpdate(d *schema.ResourceData, meta interface{}) error { 123 client := meta.(*heroku.Service) 124 125 app := d.Get("app").(string) 126 127 if d.HasChange("plan") { 128 ad, err := client.AddonUpdate( 129 app, d.Id(), heroku.AddonUpdateOpts{Plan: d.Get("plan").(string)}) 130 if err != nil { 131 return err 132 } 133 134 // Store the new ID 135 d.SetId(ad.ID) 136 } 137 138 return resourceHerokuAddonRead(d, meta) 139 } 140 141 func resourceHerokuAddonDelete(d *schema.ResourceData, meta interface{}) error { 142 client := meta.(*heroku.Service) 143 144 log.Printf("[INFO] Deleting Addon: %s", d.Id()) 145 146 // Destroy the app 147 err := client.AddonDelete(d.Get("app").(string), d.Id()) 148 if err != nil { 149 return fmt.Errorf("Error deleting addon: %s", err) 150 } 151 152 d.SetId("") 153 return nil 154 } 155 156 func resourceHerokuAddonRetrieve(app string, id string, client *heroku.Service) (*heroku.Addon, error) { 157 addon, err := client.AddonInfo(app, id) 158 159 if err != nil { 160 return nil, fmt.Errorf("Error retrieving addon: %s", err) 161 } 162 163 return addon, nil 164 }