github.com/ezbercih/terraform@v0.1.1-0.20140729011846-3c33865e0839/builtin/providers/heroku/resource_heroku_addon.go (about)

     1  package heroku
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"sync"
     7  
     8  	"github.com/bgentry/heroku-go"
     9  	"github.com/hashicorp/terraform/flatmap"
    10  	"github.com/hashicorp/terraform/helper/config"
    11  	"github.com/hashicorp/terraform/helper/diff"
    12  	"github.com/hashicorp/terraform/terraform"
    13  )
    14  
    15  // Global lock to prevent parallelism for heroku_addon since
    16  // the Heroku API cannot handle a single application requesting
    17  // multiple addons simultaneously.
    18  var addonLock sync.Mutex
    19  
    20  func resource_heroku_addon_create(
    21  	s *terraform.ResourceState,
    22  	d *terraform.ResourceDiff,
    23  	meta interface{}) (*terraform.ResourceState, error) {
    24  	addonLock.Lock()
    25  	defer addonLock.Unlock()
    26  
    27  	p := meta.(*ResourceProvider)
    28  	client := p.client
    29  
    30  	// Merge the diff into the state so that we have all the attributes
    31  	// properly.
    32  	rs := s.MergeDiff(d)
    33  
    34  	app := rs.Attributes["app"]
    35  	plan := rs.Attributes["plan"]
    36  	opts := heroku.AddonCreateOpts{}
    37  
    38  	if attr, ok := rs.Attributes["config.#"]; ok && attr == "1" {
    39  		vs := flatmap.Expand(
    40  			rs.Attributes, "config").([]interface{})
    41  
    42  		config := make(map[string]string)
    43  		for k, v := range vs[0].(map[string]interface{}) {
    44  			config[k] = v.(string)
    45  		}
    46  
    47  		opts.Config = &config
    48  	}
    49  
    50  	log.Printf("[DEBUG] Addon create configuration: %#v, %#v, %#v", app, plan, opts)
    51  
    52  	a, err := client.AddonCreate(app, plan, &opts)
    53  
    54  	if err != nil {
    55  		return s, err
    56  	}
    57  
    58  	rs.ID = a.Id
    59  	log.Printf("[INFO] Addon ID: %s", rs.ID)
    60  
    61  	addon, err := resource_heroku_addon_retrieve(app, rs.ID, client)
    62  	if err != nil {
    63  		return rs, err
    64  	}
    65  
    66  	return resource_heroku_addon_update_state(rs, addon)
    67  }
    68  
    69  func resource_heroku_addon_update(
    70  	s *terraform.ResourceState,
    71  	d *terraform.ResourceDiff,
    72  	meta interface{}) (*terraform.ResourceState, error) {
    73  	p := meta.(*ResourceProvider)
    74  	client := p.client
    75  	rs := s.MergeDiff(d)
    76  
    77  	app := rs.Attributes["app"]
    78  
    79  	if attr, ok := d.Attributes["plan"]; ok {
    80  		ad, err := client.AddonUpdate(
    81  			app, rs.ID,
    82  			attr.New)
    83  
    84  		if err != nil {
    85  			return s, err
    86  		}
    87  
    88  		// Store the new ID
    89  		rs.ID = ad.Id
    90  	}
    91  
    92  	addon, err := resource_heroku_addon_retrieve(app, rs.ID, client)
    93  
    94  	if err != nil {
    95  		return rs, err
    96  	}
    97  
    98  	return resource_heroku_addon_update_state(rs, addon)
    99  }
   100  
   101  func resource_heroku_addon_destroy(
   102  	s *terraform.ResourceState,
   103  	meta interface{}) error {
   104  	p := meta.(*ResourceProvider)
   105  	client := p.client
   106  
   107  	log.Printf("[INFO] Deleting Addon: %s", s.ID)
   108  
   109  	// Destroy the app
   110  	err := client.AddonDelete(s.Attributes["app"], s.ID)
   111  
   112  	if err != nil {
   113  		return fmt.Errorf("Error deleting addon: %s", err)
   114  	}
   115  
   116  	return nil
   117  }
   118  
   119  func resource_heroku_addon_refresh(
   120  	s *terraform.ResourceState,
   121  	meta interface{}) (*terraform.ResourceState, error) {
   122  	p := meta.(*ResourceProvider)
   123  	client := p.client
   124  
   125  	app, err := resource_heroku_addon_retrieve(s.Attributes["app"], s.ID, client)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  
   130  	return resource_heroku_addon_update_state(s, app)
   131  }
   132  
   133  func resource_heroku_addon_diff(
   134  	s *terraform.ResourceState,
   135  	c *terraform.ResourceConfig,
   136  	meta interface{}) (*terraform.ResourceDiff, error) {
   137  
   138  	b := &diff.ResourceBuilder{
   139  		Attrs: map[string]diff.AttrType{
   140  			"app":    diff.AttrTypeCreate,
   141  			"plan":   diff.AttrTypeUpdate,
   142  			"config": diff.AttrTypeCreate,
   143  		},
   144  
   145  		ComputedAttrs: []string{
   146  			"provider_id",
   147  			"config_vars",
   148  		},
   149  	}
   150  
   151  	return b.Diff(s, c)
   152  }
   153  
   154  func resource_heroku_addon_update_state(
   155  	s *terraform.ResourceState,
   156  	addon *heroku.Addon) (*terraform.ResourceState, error) {
   157  
   158  	s.Attributes["name"] = addon.Name
   159  	s.Attributes["plan"] = addon.Plan.Name
   160  	s.Attributes["provider_id"] = addon.ProviderId
   161  
   162  	toFlatten := make(map[string]interface{})
   163  
   164  	if len(addon.ConfigVars) > 0 {
   165  		toFlatten["config_vars"] = addon.ConfigVars
   166  	}
   167  
   168  	for k, v := range flatmap.Flatten(toFlatten) {
   169  		s.Attributes[k] = v
   170  	}
   171  
   172  	s.Dependencies = []terraform.ResourceDependency{
   173  		terraform.ResourceDependency{ID: s.Attributes["app"]},
   174  	}
   175  
   176  	return s, nil
   177  }
   178  
   179  func resource_heroku_addon_retrieve(app string, id string, client *heroku.Client) (*heroku.Addon, error) {
   180  	addon, err := client.AddonInfo(app, id)
   181  
   182  	if err != nil {
   183  		return nil, fmt.Errorf("Error retrieving addon: %s", err)
   184  	}
   185  
   186  	return addon, nil
   187  }
   188  
   189  func resource_heroku_addon_validation() *config.Validator {
   190  	return &config.Validator{
   191  		Required: []string{
   192  			"app",
   193  			"plan",
   194  		},
   195  		Optional: []string{
   196  			"config.*",
   197  		},
   198  	}
   199  }