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  }