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