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