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