github.com/ezbercih/terraform@v0.1.1-0.20140729011846-3c33865e0839/builtin/providers/heroku/resource_heroku_addon.go (about) 1 package heroku 2 3 import ( 4 "fmt" 5 "log" 6 "sync" 7 8 "github.com/bgentry/heroku-go" 9 "github.com/hashicorp/terraform/flatmap" 10 "github.com/hashicorp/terraform/helper/config" 11 "github.com/hashicorp/terraform/helper/diff" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 // Global lock to prevent parallelism for heroku_addon since 16 // the Heroku API cannot handle a single application requesting 17 // multiple addons simultaneously. 18 var addonLock sync.Mutex 19 20 func resource_heroku_addon_create( 21 s *terraform.ResourceState, 22 d *terraform.ResourceDiff, 23 meta interface{}) (*terraform.ResourceState, error) { 24 addonLock.Lock() 25 defer addonLock.Unlock() 26 27 p := meta.(*ResourceProvider) 28 client := p.client 29 30 // Merge the diff into the state so that we have all the attributes 31 // properly. 32 rs := s.MergeDiff(d) 33 34 app := rs.Attributes["app"] 35 plan := rs.Attributes["plan"] 36 opts := heroku.AddonCreateOpts{} 37 38 if attr, ok := rs.Attributes["config.#"]; ok && attr == "1" { 39 vs := flatmap.Expand( 40 rs.Attributes, "config").([]interface{}) 41 42 config := make(map[string]string) 43 for k, v := range vs[0].(map[string]interface{}) { 44 config[k] = v.(string) 45 } 46 47 opts.Config = &config 48 } 49 50 log.Printf("[DEBUG] Addon create configuration: %#v, %#v, %#v", app, plan, opts) 51 52 a, err := client.AddonCreate(app, plan, &opts) 53 54 if err != nil { 55 return s, err 56 } 57 58 rs.ID = a.Id 59 log.Printf("[INFO] Addon ID: %s", rs.ID) 60 61 addon, err := resource_heroku_addon_retrieve(app, rs.ID, client) 62 if err != nil { 63 return rs, err 64 } 65 66 return resource_heroku_addon_update_state(rs, addon) 67 } 68 69 func resource_heroku_addon_update( 70 s *terraform.ResourceState, 71 d *terraform.ResourceDiff, 72 meta interface{}) (*terraform.ResourceState, error) { 73 p := meta.(*ResourceProvider) 74 client := p.client 75 rs := s.MergeDiff(d) 76 77 app := rs.Attributes["app"] 78 79 if attr, ok := d.Attributes["plan"]; ok { 80 ad, err := client.AddonUpdate( 81 app, rs.ID, 82 attr.New) 83 84 if err != nil { 85 return s, err 86 } 87 88 // Store the new ID 89 rs.ID = ad.Id 90 } 91 92 addon, err := resource_heroku_addon_retrieve(app, rs.ID, client) 93 94 if err != nil { 95 return rs, err 96 } 97 98 return resource_heroku_addon_update_state(rs, addon) 99 } 100 101 func resource_heroku_addon_destroy( 102 s *terraform.ResourceState, 103 meta interface{}) error { 104 p := meta.(*ResourceProvider) 105 client := p.client 106 107 log.Printf("[INFO] Deleting Addon: %s", s.ID) 108 109 // Destroy the app 110 err := client.AddonDelete(s.Attributes["app"], s.ID) 111 112 if err != nil { 113 return fmt.Errorf("Error deleting addon: %s", err) 114 } 115 116 return nil 117 } 118 119 func resource_heroku_addon_refresh( 120 s *terraform.ResourceState, 121 meta interface{}) (*terraform.ResourceState, error) { 122 p := meta.(*ResourceProvider) 123 client := p.client 124 125 app, err := resource_heroku_addon_retrieve(s.Attributes["app"], s.ID, client) 126 if err != nil { 127 return nil, err 128 } 129 130 return resource_heroku_addon_update_state(s, app) 131 } 132 133 func resource_heroku_addon_diff( 134 s *terraform.ResourceState, 135 c *terraform.ResourceConfig, 136 meta interface{}) (*terraform.ResourceDiff, error) { 137 138 b := &diff.ResourceBuilder{ 139 Attrs: map[string]diff.AttrType{ 140 "app": diff.AttrTypeCreate, 141 "plan": diff.AttrTypeUpdate, 142 "config": diff.AttrTypeCreate, 143 }, 144 145 ComputedAttrs: []string{ 146 "provider_id", 147 "config_vars", 148 }, 149 } 150 151 return b.Diff(s, c) 152 } 153 154 func resource_heroku_addon_update_state( 155 s *terraform.ResourceState, 156 addon *heroku.Addon) (*terraform.ResourceState, error) { 157 158 s.Attributes["name"] = addon.Name 159 s.Attributes["plan"] = addon.Plan.Name 160 s.Attributes["provider_id"] = addon.ProviderId 161 162 toFlatten := make(map[string]interface{}) 163 164 if len(addon.ConfigVars) > 0 { 165 toFlatten["config_vars"] = addon.ConfigVars 166 } 167 168 for k, v := range flatmap.Flatten(toFlatten) { 169 s.Attributes[k] = v 170 } 171 172 s.Dependencies = []terraform.ResourceDependency{ 173 terraform.ResourceDependency{ID: s.Attributes["app"]}, 174 } 175 176 return s, nil 177 } 178 179 func resource_heroku_addon_retrieve(app string, id string, client *heroku.Client) (*heroku.Addon, error) { 180 addon, err := client.AddonInfo(app, id) 181 182 if err != nil { 183 return nil, fmt.Errorf("Error retrieving addon: %s", err) 184 } 185 186 return addon, nil 187 } 188 189 func resource_heroku_addon_validation() *config.Validator { 190 return &config.Validator{ 191 Required: []string{ 192 "app", 193 "plan", 194 }, 195 Optional: []string{ 196 "config.*", 197 }, 198 } 199 }