github.com/acm1/terraform@v0.6.2-0.20150729164239-1f314444f45c/builtin/providers/google/resource_compute_instance_group_manager.go (about)

     1  package google
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"google.golang.org/api/googleapi"
     9  	"google.golang.org/api/compute/v1"
    10  
    11  	"github.com/hashicorp/terraform/helper/hashcode"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  func resourceComputeInstanceGroupManager() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceComputeInstanceGroupManagerCreate,
    18  		Read:   resourceComputeInstanceGroupManagerRead,
    19  		Update: resourceComputeInstanceGroupManagerUpdate,
    20  		Delete: resourceComputeInstanceGroupManagerDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  
    29  			"description": &schema.Schema{
    30  				Type:     schema.TypeString,
    31  				Optional: true,
    32  				ForceNew: true,
    33  			},
    34  
    35  			"base_instance_name": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Required: true,
    38  				ForceNew: true,
    39  			},
    40  
    41  			"fingerprint": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				Computed: true,
    44  			},
    45  
    46  			"instance_group": &schema.Schema{
    47  				Type:     schema.TypeString,
    48  				Computed: true,
    49  			},
    50  
    51  			"instance_template": &schema.Schema{
    52  				Type:     schema.TypeString,
    53  				Required: true,
    54  			},
    55  
    56  			"target_pools": &schema.Schema{
    57  				Type:     schema.TypeSet,
    58  				Required: true,
    59  				Elem:     &schema.Schema{Type: schema.TypeString},
    60  				Set: func(v interface{}) int {
    61  					return hashcode.String(v.(string))
    62  				},
    63  			},
    64  
    65  			"target_size": &schema.Schema{
    66  				Type:     schema.TypeInt,
    67  				Computed: true,
    68  				Optional: true,
    69  			},
    70  
    71  			"zone": &schema.Schema{
    72  				Type:     schema.TypeString,
    73  				Required: true,
    74  				ForceNew: true,
    75  			},
    76  
    77  			"self_link": &schema.Schema{
    78  				Type:     schema.TypeString,
    79  				Computed: true,
    80  			},
    81  		},
    82  	}
    83  }
    84  
    85  func waitOpZone(config *Config, op *compute.Operation, zone string,
    86  	resource string, action string) (*compute.Operation, error) {
    87  
    88  	w := &OperationWaiter{
    89  		Service: config.clientCompute,
    90  		Op:      op,
    91  		Project: config.Project,
    92  		Zone:    zone,
    93  		Type:    OperationWaitZone,
    94  	}
    95  	state := w.Conf()
    96  	state.Timeout = 8 * time.Minute
    97  	state.MinTimeout = 1 * time.Second
    98  	opRaw, err := state.WaitForState()
    99  	if err != nil {
   100  		return nil, fmt.Errorf("Error waiting for %s to %s: %s", resource, action, err)
   101  	}
   102  	return opRaw.(*compute.Operation), nil
   103  }
   104  
   105  func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta interface{}) error {
   106  	config := meta.(*Config)
   107  
   108  	// Get group size, default to 1 if not given
   109  	var target_size int64 = 1
   110  	if v, ok := d.GetOk("target_size"); ok {
   111  		target_size = int64(v.(int))
   112  	}
   113  
   114  	// Build the parameter
   115  	manager := &compute.InstanceGroupManager{
   116  		Name:             d.Get("name").(string),
   117  		BaseInstanceName: d.Get("base_instance_name").(string),
   118  		InstanceTemplate: d.Get("instance_template").(string),
   119  		TargetSize: target_size,
   120  	}
   121  
   122  	// Set optional fields
   123  	if v, ok := d.GetOk("description"); ok {
   124  		manager.Description = v.(string)
   125  	}
   126  
   127  	if attr := d.Get("target_pools").(*schema.Set); attr.Len() > 0 {
   128  		var s []string
   129  		for _, v := range attr.List() {
   130  			s = append(s, v.(string))
   131  		}
   132  		manager.TargetPools = s
   133  	}
   134  
   135  	log.Printf("[DEBUG] InstanceGroupManager insert request: %#v", manager)
   136  	op, err := config.clientCompute.InstanceGroupManagers.Insert(
   137  		config.Project, d.Get("zone").(string), manager).Do()
   138  	if err != nil {
   139  		return fmt.Errorf("Error creating InstanceGroupManager: %s", err)
   140  	}
   141  
   142  	// It probably maybe worked, so store the ID now
   143  	d.SetId(manager.Name)
   144  
   145  	// Wait for the operation to complete
   146  	op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "create")
   147  	if err != nil {
   148  		return err
   149  	}
   150  	if op.Error != nil {
   151  		// The resource didn't actually create
   152  		d.SetId("")
   153  		// Return the error
   154  		return OperationError(*op.Error)
   155  	}
   156  
   157  	return resourceComputeInstanceGroupManagerRead(d, meta)
   158  }
   159  
   160  func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error {
   161  	config := meta.(*Config)
   162  
   163  	manager, err := config.clientCompute.InstanceGroupManagers.Get(
   164  		config.Project, d.Get("zone").(string), d.Id()).Do()
   165  	if err != nil {
   166  		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
   167  			// The resource doesn't exist anymore
   168  			d.SetId("")
   169  
   170  			return nil
   171  		}
   172  
   173  		return fmt.Errorf("Error reading instance group manager: %s", err)
   174  	}
   175  
   176  	// Set computed fields
   177  	d.Set("fingerprint", manager.Fingerprint)
   178  	d.Set("instance_group", manager.InstanceGroup)
   179  	d.Set("target_size", manager.TargetSize)
   180  	d.Set("self_link", manager.SelfLink)
   181  
   182  	return nil
   183  }
   184  func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error {
   185  	config := meta.(*Config)
   186  
   187  	d.Partial(true)
   188  
   189  	// If target_pools changes then update
   190  	if d.HasChange("target_pools") {
   191  		var targetPools []string
   192  		if attr := d.Get("target_pools").(*schema.Set); attr.Len() > 0 {
   193  			for _, v := range attr.List() {
   194  				targetPools = append(targetPools, v.(string))
   195  			}
   196  		}
   197  
   198  		// Build the parameter
   199  		setTargetPools := &compute.InstanceGroupManagersSetTargetPoolsRequest{
   200  			Fingerprint: d.Get("fingerprint").(string),
   201  			TargetPools: targetPools,
   202  		}
   203  
   204  		op, err := config.clientCompute.InstanceGroupManagers.SetTargetPools(
   205  			config.Project, d.Get("zone").(string), d.Id(), setTargetPools).Do()
   206  		if err != nil {
   207  			return fmt.Errorf("Error updating InstanceGroupManager: %s", err)
   208  		}
   209  
   210  		// Wait for the operation to complete
   211  		op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update TargetPools")
   212  		if err != nil {
   213  			return err
   214  		}
   215  		if op.Error != nil {
   216  			return OperationError(*op.Error)
   217  		}
   218  
   219  		d.SetPartial("target_pools")
   220  	}
   221  
   222  	// If instance_template changes then update
   223  	if d.HasChange("instance_template") {
   224  		// Build the parameter
   225  		setInstanceTemplate := &compute.InstanceGroupManagersSetInstanceTemplateRequest{
   226  			InstanceTemplate: d.Get("instance_template").(string),
   227  		}
   228  
   229  		op, err := config.clientCompute.InstanceGroupManagers.SetInstanceTemplate(
   230  			config.Project, d.Get("zone").(string), d.Id(), setInstanceTemplate).Do()
   231  		if err != nil {
   232  			return fmt.Errorf("Error updating InstanceGroupManager: %s", err)
   233  		}
   234  
   235  		// Wait for the operation to complete
   236  		op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update instance template")
   237  		if err != nil {
   238  			return err
   239  		}
   240  		if op.Error != nil {
   241  			return OperationError(*op.Error)
   242  		}
   243  
   244  		d.SetPartial("instance_template")
   245  	}
   246  
   247  	// If size changes trigger a resize
   248  	if d.HasChange("target_size") {
   249  		if v, ok := d.GetOk("target_size"); ok {
   250  			// Only do anything if the new size is set
   251  			target_size := int64(v.(int))
   252  
   253  			op, err := config.clientCompute.InstanceGroupManagers.Resize(
   254  				config.Project, d.Get("zone").(string), d.Id(), target_size).Do()
   255  			if err != nil {
   256  				return fmt.Errorf("Error updating InstanceGroupManager: %s", err)
   257  			}
   258  
   259  			// Wait for the operation to complete
   260  			op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update target_size")
   261  			if err != nil {
   262  				return err
   263  			}
   264  			if op.Error != nil {
   265  				return OperationError(*op.Error)
   266  			}
   267  		}
   268  
   269  		d.SetPartial("target_size")
   270  	}
   271  
   272  	d.Partial(false)
   273  
   274  	return resourceComputeInstanceGroupManagerRead(d, meta)
   275  }
   276  
   277  func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error {
   278  	config := meta.(*Config)
   279  
   280  	zone := d.Get("zone").(string)
   281  	op, err := config.clientCompute.InstanceGroupManagers.Delete(config.Project, zone, d.Id()).Do()
   282  	if err != nil {
   283  		return fmt.Errorf("Error deleting instance group manager: %s", err)
   284  	}
   285  
   286  	// Wait for the operation to complete
   287  	op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "delete")
   288  	if err != nil {
   289  		return err
   290  	}
   291  	if op.Error != nil {
   292  		// The resource didn't actually create
   293  		d.SetId("")
   294  
   295  		// Return the error
   296  		return OperationError(*op.Error)
   297  	}
   298  
   299  	d.SetId("")
   300  	return nil
   301  }