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