From aff63007d2df663065ef838c18a7f647afa3d6fe Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Wed, 14 Oct 2015 13:17:44 -0500 Subject: [PATCH] provider/google: one more fix to GCE metadata In #3501 @lwander got us almost all the way there, but we still had tests failing. This seemed to be because GCE sets `metadata.startup-script` to a blank string on instance creation, and if a user specifies any `metadata` in their config this is seen as the desired full contents of metadata, so we get a diff trying to remove `startup-script`. Here, to address this, we just proactively remove the "startup-script" key from `Read`, and then we enforce that "metadata_startup_script" is the only way to configure startup scripts on instances. --- resource_compute_instance.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/resource_compute_instance.go b/resource_compute_instance.go index 229d1b05..68b8aed3 100644 --- a/resource_compute_instance.go +++ b/resource_compute_instance.go @@ -197,9 +197,10 @@ func resourceComputeInstance() *schema.Resource { }, "metadata": &schema.Schema{ - Type: schema.TypeMap, - Optional: true, - Elem: schema.TypeString, + Type: schema.TypeMap, + Optional: true, + Elem: schema.TypeString, + ValidateFunc: validateInstanceMetadata, }, "service_account": &schema.Schema{ @@ -516,16 +517,16 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error md := instance.Metadata _md := MetadataFormatSchema(md) + delete(_md, "startup-script") + if script, scriptExists := d.GetOk("metadata_startup_script"); scriptExists { d.Set("metadata_startup_script", script) - delete(_md, "startup-script") } if err = d.Set("metadata", _md); err != nil { return fmt.Errorf("Error setting metadata: %s", err) } - d.Set("can_ip_forward", instance.CanIpForward) // Set the service accounts @@ -671,7 +672,6 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err n.(map[string]interface{})["startup-script"] = script } - updateMD := func() error { // Reload the instance in the case of a fingerprint mismatch instance, err = getInstance(config, d) @@ -810,13 +810,8 @@ func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) err func resourceInstanceMetadata(d *schema.ResourceData) (*compute.Metadata, error) { m := &compute.Metadata{} mdMap := d.Get("metadata").(map[string]interface{}) - _, mapScriptExists := mdMap["startup-script"] - dScript, dScriptExists := d.GetOk("metadata_startup_script") - if mapScriptExists && dScriptExists { - return nil, fmt.Errorf("Not allowed to have both metadata_startup_script and metadata.startup-script") - } - if dScriptExists { - mdMap["startup-script"] = dScript + if v, ok := d.GetOk("metadata_startup_script"); ok && v.(string) != "" { + mdMap["startup-script"] = v } if len(mdMap) > 0 { m.Items = make([]*compute.MetadataItems, 0, len(mdMap)) @@ -852,3 +847,12 @@ func resourceInstanceTags(d *schema.ResourceData) *compute.Tags { return tags } + +func validateInstanceMetadata(v interface{}, k string) (ws []string, es []error) { + mdMap := v.(map[string]interface{}) + if _, ok := mdMap["startup-script"]; ok { + es = append(es, fmt.Errorf( + "Use metadata_startup_script instead of a startup-script key in %q.", k)) + } + return +}