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.
This commit is contained in:
Paul Hinze 2015-10-14 13:17:44 -05:00
parent 4f4c572aa4
commit 4f400a1944
1 changed files with 17 additions and 13 deletions

View File

@ -197,9 +197,10 @@ func resourceComputeInstance() *schema.Resource {
}, },
"metadata": &schema.Schema{ "metadata": &schema.Schema{
Type: schema.TypeMap, Type: schema.TypeMap,
Optional: true, Optional: true,
Elem: schema.TypeString, Elem: schema.TypeString,
ValidateFunc: validateInstanceMetadata,
}, },
"service_account": &schema.Schema{ "service_account": &schema.Schema{
@ -516,16 +517,16 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
md := instance.Metadata md := instance.Metadata
_md := MetadataFormatSchema(md) _md := MetadataFormatSchema(md)
delete(_md, "startup-script")
if script, scriptExists := d.GetOk("metadata_startup_script"); scriptExists { if script, scriptExists := d.GetOk("metadata_startup_script"); scriptExists {
d.Set("metadata_startup_script", script) d.Set("metadata_startup_script", script)
delete(_md, "startup-script")
} }
if err = d.Set("metadata", _md); err != nil { if err = d.Set("metadata", _md); err != nil {
return fmt.Errorf("Error setting metadata: %s", err) return fmt.Errorf("Error setting metadata: %s", err)
} }
d.Set("can_ip_forward", instance.CanIpForward) d.Set("can_ip_forward", instance.CanIpForward)
// Set the service accounts // Set the service accounts
@ -671,7 +672,6 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
n.(map[string]interface{})["startup-script"] = script n.(map[string]interface{})["startup-script"] = script
} }
updateMD := func() error { updateMD := func() error {
// Reload the instance in the case of a fingerprint mismatch // Reload the instance in the case of a fingerprint mismatch
instance, err = getInstance(config, d) 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) { func resourceInstanceMetadata(d *schema.ResourceData) (*compute.Metadata, error) {
m := &compute.Metadata{} m := &compute.Metadata{}
mdMap := d.Get("metadata").(map[string]interface{}) mdMap := d.Get("metadata").(map[string]interface{})
_, mapScriptExists := mdMap["startup-script"] if v, ok := d.GetOk("metadata_startup_script"); ok && v.(string) != "" {
dScript, dScriptExists := d.GetOk("metadata_startup_script") mdMap["startup-script"] = v
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 len(mdMap) > 0 { if len(mdMap) > 0 {
m.Items = make([]*compute.MetadataItems, 0, len(mdMap)) m.Items = make([]*compute.MetadataItems, 0, len(mdMap))
@ -852,3 +847,12 @@ func resourceInstanceTags(d *schema.ResourceData) *compute.Tags {
return 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
}