github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/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 }