github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/heroku/resource_heroku_space.go (about) 1 package heroku 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "time" 8 9 heroku "github.com/cyberdelia/heroku-go/v3" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceHerokuSpace() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceHerokuSpaceCreate, 17 Read: resourceHerokuSpaceRead, 18 Update: resourceHerokuSpaceUpdate, 19 Delete: resourceHerokuSpaceDelete, 20 21 Importer: &schema.ResourceImporter{ 22 State: schema.ImportStatePassthrough, 23 }, 24 25 Schema: map[string]*schema.Schema{ 26 "name": { 27 Type: schema.TypeString, 28 Required: true, 29 }, 30 31 "organization": { 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 37 "region": { 38 Type: schema.TypeString, 39 Optional: true, 40 ForceNew: true, 41 }, 42 }, 43 } 44 } 45 46 func resourceHerokuSpaceCreate(d *schema.ResourceData, meta interface{}) error { 47 client := meta.(*heroku.Service) 48 49 opts := heroku.SpaceCreateOpts{} 50 opts.Name = d.Get("name").(string) 51 opts.Organization = d.Get("organization").(string) 52 53 if v, ok := d.GetOk("region"); ok { 54 vs := v.(string) 55 opts.Region = &vs 56 } 57 58 space, err := client.SpaceCreate(context.TODO(), opts) 59 if err != nil { 60 return err 61 } 62 63 d.SetId(space.ID) 64 log.Printf("[INFO] Space ID: %s", d.Id()) 65 66 // Wait for the Space to be allocated 67 log.Printf("[DEBUG] Waiting for Space (%s) to be allocated", d.Id()) 68 stateConf := &resource.StateChangeConf{ 69 Pending: []string{"allocating"}, 70 Target: []string{"allocated"}, 71 Refresh: SpaceStateRefreshFunc(client, d.Id()), 72 Timeout: 20 * time.Minute, 73 } 74 75 if _, err := stateConf.WaitForState(); err != nil { 76 return fmt.Errorf("Error waiting for Space (%s) to become available: %s", d.Id(), err) 77 } 78 79 return resourceHerokuSpaceRead(d, meta) 80 } 81 82 func resourceHerokuSpaceRead(d *schema.ResourceData, meta interface{}) error { 83 client := meta.(*heroku.Service) 84 85 spaceRaw, _, err := SpaceStateRefreshFunc(client, d.Id())() 86 if err != nil { 87 return err 88 } 89 space := spaceRaw.(*heroku.Space) 90 91 setSpaceAttributes(d, space) 92 return nil 93 } 94 95 func resourceHerokuSpaceUpdate(d *schema.ResourceData, meta interface{}) error { 96 client := meta.(*heroku.Service) 97 98 if !d.HasChange("name") { 99 return nil 100 } 101 102 name := d.Get("name").(string) 103 opts := heroku.SpaceUpdateOpts{Name: &name} 104 105 space, err := client.SpaceUpdate(context.TODO(), d.Id(), opts) 106 if err != nil { 107 return err 108 } 109 110 // The type conversion here can be dropped when the vendored version of 111 // heroku-go is updated. 112 setSpaceAttributes(d, (*heroku.Space)(space)) 113 return nil 114 } 115 116 func setSpaceAttributes(d *schema.ResourceData, space *heroku.Space) { 117 d.Set("name", space.Name) 118 d.Set("organization", space.Organization.Name) 119 d.Set("region", space.Region.Name) 120 } 121 122 func resourceHerokuSpaceDelete(d *schema.ResourceData, meta interface{}) error { 123 client := meta.(*heroku.Service) 124 125 log.Printf("[INFO] Deleting space: %s", d.Id()) 126 _, err := client.SpaceDelete(context.TODO(), d.Id()) 127 if err != nil { 128 return err 129 } 130 131 d.SetId("") 132 return nil 133 } 134 135 // SpaceStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 136 // a Space. 137 func SpaceStateRefreshFunc(client *heroku.Service, id string) resource.StateRefreshFunc { 138 return func() (interface{}, string, error) { 139 space, err := client.SpaceInfo(context.TODO(), id) 140 if err != nil { 141 return nil, "", err 142 } 143 144 // The type conversion here can be dropped when the vendored version of 145 // heroku-go is updated. 146 return (*heroku.Space)(space), space.State, nil 147 } 148 }