github.com/atsaki/terraform@v0.4.3-0.20150919165407-25bba5967654/builtin/providers/google/resource_compute_project_metadata.go (about)

     1  package google
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	//	"github.com/hashicorp/terraform/helper/hashcode"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"google.golang.org/api/compute/v1"
    11  	//	"google.golang.org/api/googleapi"
    12  )
    13  
    14  func resourceComputeProjectMetadata() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceComputeProjectMetadataCreate,
    17  		Read:   resourceComputeProjectMetadataRead,
    18  		Update: resourceComputeProjectMetadataUpdate,
    19  		Delete: resourceComputeProjectMetadataDelete,
    20  
    21  		SchemaVersion: 0,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"metadata": &schema.Schema{
    25  				Elem:     schema.TypeString,
    26  				Type:     schema.TypeMap,
    27  				Required: true,
    28  			},
    29  		},
    30  	}
    31  }
    32  
    33  func resourceOperationWaitGlobal(config *Config, op *compute.Operation, activity string) error {
    34  	w := &OperationWaiter{
    35  		Service: config.clientCompute,
    36  		Op:      op,
    37  		Project: config.Project,
    38  		Type:    OperationWaitGlobal,
    39  	}
    40  
    41  	state := w.Conf()
    42  	state.Timeout = 2 * time.Minute
    43  	state.MinTimeout = 1 * time.Second
    44  	opRaw, err := state.WaitForState()
    45  	if err != nil {
    46  		return fmt.Errorf("Error waiting for %s: %s", activity, err)
    47  	}
    48  
    49  	op = opRaw.(*compute.Operation)
    50  	if op.Error != nil {
    51  		return OperationError(*op.Error)
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  func resourceComputeProjectMetadataCreate(d *schema.ResourceData, meta interface{}) error {
    58  	config := meta.(*Config)
    59  
    60  	createMD := func() error {
    61  		// Load project service
    62  		log.Printf("[DEBUG] Loading project service: %s", config.Project)
    63  		project, err := config.clientCompute.Projects.Get(config.Project).Do()
    64  		if err != nil {
    65  			return fmt.Errorf("Error loading project '%s': %s", config.Project, err)
    66  		}
    67  
    68  		md := project.CommonInstanceMetadata
    69  
    70  		newMDMap := d.Get("metadata").(map[string]interface{})
    71  		// Ensure that we aren't overwriting entries that already exist
    72  		for _, kv := range md.Items {
    73  			if _, ok := newMDMap[kv.Key]; ok {
    74  				return fmt.Errorf("Error, key '%s' already exists in project '%s'", kv.Key, config.Project)
    75  			}
    76  		}
    77  
    78  		// Append new metadata to existing metadata
    79  		for key, val := range newMDMap {
    80  			v := val.(string)
    81  			md.Items = append(md.Items, &compute.MetadataItems{
    82  				Key:   key,
    83  				Value: &v,
    84  			})
    85  		}
    86  
    87  		op, err := config.clientCompute.Projects.SetCommonInstanceMetadata(config.Project, md).Do()
    88  
    89  		if err != nil {
    90  			return fmt.Errorf("SetCommonInstanceMetadata failed: %s", err)
    91  		}
    92  
    93  		log.Printf("[DEBUG] SetCommonMetadata: %d (%s)", op.Id, op.SelfLink)
    94  
    95  		return resourceOperationWaitGlobal(config, op, "SetCommonMetadata")
    96  	}
    97  
    98  	err := MetadataRetryWrapper(createMD)
    99  	if err != nil {
   100  		return err;
   101  	}
   102  
   103  	return resourceComputeProjectMetadataRead(d, meta);
   104  }
   105  
   106  func resourceComputeProjectMetadataRead(d *schema.ResourceData, meta interface{}) error {
   107  	config := meta.(*Config)
   108  
   109  	// Load project service
   110  	log.Printf("[DEBUG] Loading project service: %s", config.Project)
   111  	project, err := config.clientCompute.Projects.Get(config.Project).Do()
   112  	if err != nil {
   113  		return fmt.Errorf("Error loading project '%s': %s", config.Project, err)
   114  	}
   115  
   116  	md := project.CommonInstanceMetadata
   117  
   118  	if err = d.Set("metadata", MetadataFormatSchema(md)); err != nil {
   119  		return fmt.Errorf("Error setting metadata: %s", err)
   120  	}
   121  
   122  	d.SetId("common_metadata")
   123  
   124  	return nil
   125  }
   126  
   127  func resourceComputeProjectMetadataUpdate(d *schema.ResourceData, meta interface{}) error {
   128  	config := meta.(*Config)
   129  
   130  	if d.HasChange("metadata") {
   131  		o, n := d.GetChange("metadata")
   132  
   133  		updateMD := func() error {
   134  			// Load project service
   135  			log.Printf("[DEBUG] Loading project service: %s", config.Project)
   136  			project, err := config.clientCompute.Projects.Get(config.Project).Do()
   137  			if err != nil {
   138  				return fmt.Errorf("Error loading project '%s': %s", config.Project, err)
   139  			}
   140  
   141  			md := project.CommonInstanceMetadata
   142  
   143  		    MetadataUpdate(o.(map[string]interface{}), n.(map[string]interface{}), md)
   144  
   145  			op, err := config.clientCompute.Projects.SetCommonInstanceMetadata(config.Project, md).Do()
   146  
   147  			if err != nil {
   148  				return fmt.Errorf("SetCommonInstanceMetadata failed: %s", err)
   149  			}
   150  
   151  			log.Printf("[DEBUG] SetCommonMetadata: %d (%s)", op.Id, op.SelfLink)
   152  
   153  			// Optimistic locking requires the fingerprint received to match
   154  			// the fingerprint we send the server, if there is a mismatch then we
   155  			// are working on old data, and must retry
   156  			return resourceOperationWaitGlobal(config, op, "SetCommonMetadata")
   157  		}
   158  
   159  		err := MetadataRetryWrapper(updateMD)
   160  		if err != nil {
   161  			return err;
   162  		}
   163  
   164  		return resourceComputeProjectMetadataRead(d, meta);
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  func resourceComputeProjectMetadataDelete(d *schema.ResourceData, meta interface{}) error {
   171  	config := meta.(*Config)
   172  
   173  	// Load project service
   174  	log.Printf("[DEBUG] Loading project service: %s", config.Project)
   175  	project, err := config.clientCompute.Projects.Get(config.Project).Do()
   176  	if err != nil {
   177  		return fmt.Errorf("Error loading project '%s': %s", config.Project, err)
   178  	}
   179  
   180  	md := project.CommonInstanceMetadata
   181  
   182  	// Remove all items
   183  	md.Items = nil
   184  
   185  	op, err := config.clientCompute.Projects.SetCommonInstanceMetadata(config.Project, md).Do()
   186  
   187  	log.Printf("[DEBUG] SetCommonMetadata: %d (%s)", op.Id, op.SelfLink)
   188  
   189  	err = resourceOperationWaitGlobal(config, op, "SetCommonMetadata")
   190  	if err != nil {
   191  		return err
   192  	}
   193  
   194  	return resourceComputeProjectMetadataRead(d, meta)
   195  }