provider/openstack: Fix Instance Metadata Deletion (#11252)

This commit fixes a bug where instance metadata removed from the
configuration was not removed from the actual instance.
This commit is contained in:
Joe Topjian 2017-01-18 04:50:59 -07:00 committed by Paul Stack
parent da48ac2d05
commit e31269d721
2 changed files with 96 additions and 4 deletions

View File

@ -594,10 +594,34 @@ func resourceComputeInstanceV2Update(d *schema.ResourceData, meta interface{}) e
} }
if d.HasChange("metadata") { if d.HasChange("metadata") {
var metadataOpts servers.MetadataOpts oldMetadata, newMetadata := d.GetChange("metadata")
metadataOpts = make(servers.MetadataOpts) var metadataToDelete []string
newMetadata := d.Get("metadata").(map[string]interface{})
for k, v := range newMetadata { // Determine if any metadata keys were removed from the configuration.
// Then request those keys to be deleted.
for oldKey, _ := range oldMetadata.(map[string]interface{}) {
var found bool
for newKey, _ := range newMetadata.(map[string]interface{}) {
if oldKey == newKey {
found = true
}
}
if !found {
metadataToDelete = append(metadataToDelete, oldKey)
}
}
for _, key := range metadataToDelete {
err := servers.DeleteMetadatum(computeClient, d.Id(), key).ExtractErr()
if err != nil {
return fmt.Errorf("Error deleting metadata (%s) from server (%s): %s", key, d.Id(), err)
}
}
// Update existing metadata and add any new metadata.
metadataOpts := make(servers.MetadataOpts)
for k, v := range newMetadata.(map[string]interface{}) {
metadataOpts[k] = v.(string) metadataOpts[k] = v.(string)
} }

View File

@ -591,6 +591,35 @@ func TestAccComputeV2Instance_stopBeforeDestroy(t *testing.T) {
}) })
} }
func TestAccComputeV2Instance_metadataRemove(t *testing.T) {
var instance servers.Server
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeV2InstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeV2Instance_metadataRemove_1,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance),
testAccCheckComputeV2InstanceMetadata(&instance, "foo", "bar"),
testAccCheckComputeV2InstanceMetadata(&instance, "abc", "def"),
),
},
resource.TestStep{
Config: testAccComputeV2Instance_metadataRemove_2,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance),
testAccCheckComputeV2InstanceMetadata(&instance, "foo", "bar"),
testAccCheckComputeV2InstanceMetadata(&instance, "ghi", "jkl"),
testAccCheckComputeV2InstanceNoMetadataKey(&instance, "abc"),
),
},
},
})
}
func testAccCheckComputeV2InstanceDestroy(s *terraform.State) error { func testAccCheckComputeV2InstanceDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config) config := testAccProvider.Meta().(*Config)
computeClient, err := config.computeV2Client(OS_REGION_NAME) computeClient, err := config.computeV2Client(OS_REGION_NAME)
@ -687,6 +716,23 @@ func testAccCheckComputeV2InstanceMetadata(
} }
} }
func testAccCheckComputeV2InstanceNoMetadataKey(
instance *servers.Server, k string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if instance.Metadata == nil {
return nil
}
for key, _ := range instance.Metadata {
if k == key {
return fmt.Errorf("Metadata found: %s", k)
}
}
return nil
}
}
func testAccCheckComputeV2InstanceVolumeAttachment( func testAccCheckComputeV2InstanceVolumeAttachment(
instance *servers.Server, volume *volumes.Volume) resource.TestCheckFunc { instance *servers.Server, volume *volumes.Volume) resource.TestCheckFunc {
return func(s *terraform.State) error { return func(s *terraform.State) error {
@ -1445,3 +1491,25 @@ resource "openstack_compute_instance_v2" "instance_1" {
stop_before_destroy = true stop_before_destroy = true
} }
` `
const testAccComputeV2Instance_metadataRemove_1 = `
resource "openstack_compute_instance_v2" "instance_1" {
name = "instance_1"
security_groups = ["default"]
metadata {
foo = "bar"
abc = "def"
}
}
`
const testAccComputeV2Instance_metadataRemove_2 = `
resource "openstack_compute_instance_v2" "instance_1" {
name = "instance_1"
security_groups = ["default"]
metadata {
foo = "bar"
ghi = "jkl"
}
}
`