github.com/jsoriano/terraform@v0.6.7-0.20151026070445-8b70867fdd95/builtin/providers/google/resource_compute_project_metadata.go (about)

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