2017-07-28 17:49:02 +00:00
|
|
|
package google
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
2018-11-08 21:47:28 +00:00
|
|
|
"time"
|
2017-07-28 17:49:02 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
"google.golang.org/api/compute/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
func resourceComputeProjectMetadataItem() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Create: resourceComputeProjectMetadataItemCreate,
|
|
|
|
Read: resourceComputeProjectMetadataItemRead,
|
|
|
|
Update: resourceComputeProjectMetadataItemUpdate,
|
|
|
|
Delete: resourceComputeProjectMetadataItemDelete,
|
|
|
|
Importer: &schema.ResourceImporter{
|
|
|
|
State: schema.ImportStatePassthrough,
|
|
|
|
},
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"key": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
"value": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
"project": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
2017-11-28 00:32:20 +00:00
|
|
|
Computed: true,
|
2017-07-28 17:49:02 +00:00
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
},
|
2018-11-08 21:47:28 +00:00
|
|
|
|
|
|
|
Timeouts: &schema.ResourceTimeout{
|
|
|
|
Create: schema.DefaultTimeout(5 * time.Minute),
|
|
|
|
Update: schema.DefaultTimeout(5 * time.Minute),
|
|
|
|
Delete: schema.DefaultTimeout(5 * time.Minute),
|
|
|
|
},
|
2017-07-28 17:49:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceComputeProjectMetadataItemCreate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
config := meta.(*Config)
|
|
|
|
|
|
|
|
projectID, err := getProject(d, config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
key := d.Get("key").(string)
|
|
|
|
val := d.Get("value").(string)
|
|
|
|
|
2018-11-08 21:47:28 +00:00
|
|
|
err = updateComputeCommonInstanceMetadata(config, projectID, key, &val, int(d.Timeout(schema.TimeoutCreate).Minutes()))
|
2017-07-28 17:49:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(key)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceComputeProjectMetadataItemRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
config := meta.(*Config)
|
|
|
|
|
|
|
|
projectID, err := getProject(d, config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] Loading project metadata: %s", projectID)
|
|
|
|
project, err := config.clientCompute.Projects.Get(projectID).Do()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error loading project '%s': %s", projectID, err)
|
|
|
|
}
|
|
|
|
|
2017-11-29 17:47:42 +00:00
|
|
|
md := flattenMetadata(project.CommonInstanceMetadata)
|
2017-07-28 17:49:02 +00:00
|
|
|
val, ok := md[d.Id()]
|
|
|
|
if !ok {
|
|
|
|
// Resource no longer exists
|
|
|
|
d.SetId("")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-11-28 00:32:20 +00:00
|
|
|
d.Set("project", projectID)
|
2017-07-28 17:49:02 +00:00
|
|
|
d.Set("key", d.Id())
|
|
|
|
d.Set("value", val)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceComputeProjectMetadataItemUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
config := meta.(*Config)
|
|
|
|
|
|
|
|
projectID, err := getProject(d, config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if d.HasChange("value") {
|
|
|
|
key := d.Get("key").(string)
|
|
|
|
_, n := d.GetChange("value")
|
|
|
|
new := n.(string)
|
|
|
|
|
2018-11-08 21:47:28 +00:00
|
|
|
err = updateComputeCommonInstanceMetadata(config, projectID, key, &new, int(d.Timeout(schema.TimeoutUpdate).Minutes()))
|
2017-07-28 17:49:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceComputeProjectMetadataItemDelete(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
config := meta.(*Config)
|
|
|
|
|
|
|
|
projectID, err := getProject(d, config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
key := d.Get("key").(string)
|
|
|
|
|
2018-11-08 21:47:28 +00:00
|
|
|
err = updateComputeCommonInstanceMetadata(config, projectID, key, nil, int(d.Timeout(schema.TimeoutDelete).Minutes()))
|
2017-07-28 17:49:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId("")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-11-08 21:47:28 +00:00
|
|
|
func updateComputeCommonInstanceMetadata(config *Config, projectID string, key string, afterVal *string, timeout int) error {
|
2017-07-28 17:49:02 +00:00
|
|
|
updateMD := func() error {
|
|
|
|
log.Printf("[DEBUG] Loading project metadata: %s", projectID)
|
|
|
|
project, err := config.clientCompute.Projects.Get(projectID).Do()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error loading project '%s': %s", projectID, err)
|
|
|
|
}
|
|
|
|
|
2017-11-29 17:47:42 +00:00
|
|
|
md := flattenMetadata(project.CommonInstanceMetadata)
|
2017-07-28 17:49:02 +00:00
|
|
|
|
|
|
|
val, ok := md[key]
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
if afterVal == nil {
|
|
|
|
// Asked to set no value and we didn't find one - we're done
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if afterVal != nil && *afterVal == val {
|
|
|
|
// Asked to set a value and it's already set - we're done.
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if afterVal == nil {
|
|
|
|
delete(md, key)
|
|
|
|
} else {
|
|
|
|
md[key] = *afterVal
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attempt to write the new value now
|
|
|
|
op, err := config.clientCompute.Projects.SetCommonInstanceMetadata(
|
|
|
|
projectID,
|
|
|
|
&compute.Metadata{
|
|
|
|
Fingerprint: project.CommonInstanceMetadata.Fingerprint,
|
|
|
|
Items: expandComputeMetadata(md),
|
|
|
|
},
|
|
|
|
).Do()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] SetCommonInstanceMetadata: %d (%s)", op.Id, op.SelfLink)
|
|
|
|
|
2018-11-08 21:47:28 +00:00
|
|
|
return computeOperationWaitTime(config.clientCompute, op, project.Name, "SetCommonInstanceMetadata", timeout)
|
2017-07-28 17:49:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return MetadataRetryWrapper(updateMD)
|
|
|
|
}
|