Adding disk keep_on_remove support on delete case (#7169)
This both fixes the keep_on_remove reference in the disk update case as well as adds logic to safely eject disks in the destroy case.
This commit is contained in:
parent
0e07a27768
commit
95c0a74df7
|
@ -509,8 +509,8 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{
|
|||
virtualDisk := devices.FindByKey(int32(disk["key"].(int)))
|
||||
|
||||
keep := false
|
||||
if v, ok := d.GetOk("keep_on_remove"); ok {
|
||||
keep = v.(bool)
|
||||
if v, ok := disk["keep_on_remove"].(bool); ok {
|
||||
keep = v
|
||||
}
|
||||
|
||||
err = vm.RemoveDevice(context.TODO(), keep, virtualDisk)
|
||||
|
@ -1093,6 +1093,11 @@ func resourceVSphereVirtualMachineDelete(d *schema.ResourceData, meta interface{
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
devices, err := vm.Device(context.TODO())
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG] resourceVSphereVirtualMachineDelete - Failed to get device list: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Deleting virtual machine: %s", d.Id())
|
||||
state, err := vm.PowerState(context.TODO())
|
||||
|
@ -1112,6 +1117,26 @@ func resourceVSphereVirtualMachineDelete(d *schema.ResourceData, meta interface{
|
|||
}
|
||||
}
|
||||
|
||||
// Safely eject any disks the user marked as keep_on_remove
|
||||
if vL, ok := d.GetOk("disk"); ok {
|
||||
if diskSet, ok := vL.(*schema.Set); ok {
|
||||
|
||||
for _, value := range diskSet.List() {
|
||||
disk := value.(map[string]interface{})
|
||||
|
||||
if v, ok := disk["keep_on_remove"].(bool); ok && v == true {
|
||||
log.Printf("[DEBUG] not destroying %v", disk["name"])
|
||||
virtualDisk := devices.FindByKey(int32(disk["key"].(int)))
|
||||
err = vm.RemoveDevice(context.TODO(), true, virtualDisk)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] Update Remove Disk - Error removing disk: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task, err := vm.Destroy(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1154,3 +1154,99 @@ func testAccCheckVSphereVirtualMachineExists(n string, vm *virtualMachine) resou
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccCheckVSphereVirtualMachineConfig_keepOnRemove = `
|
||||
resource "vsphere_virtual_machine" "keep_disk" {
|
||||
name = "terraform-test"
|
||||
` + testAccTemplateBasicBody + `
|
||||
disk {
|
||||
size = 1
|
||||
iops = 500
|
||||
controller_type = "scsi"
|
||||
name = "one"
|
||||
keep_on_remove = true
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
func TestAccVSphereVirtualMachine_keepOnRemove(t *testing.T) {
|
||||
var vm virtualMachine
|
||||
basic_vars := setupTemplateBasicBodyVars()
|
||||
config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_keepOnRemove)
|
||||
var datastore string
|
||||
if v := os.Getenv("VSPHERE_DATASTORE"); v != "" {
|
||||
datastore = v
|
||||
}
|
||||
var datacenter string
|
||||
if v := os.Getenv("VSPHERE_DATACENTER"); v != "" {
|
||||
datacenter = v
|
||||
}
|
||||
|
||||
vmName := "vsphere_virtual_machine.keep_disk"
|
||||
test_exists, test_name, test_cpu, test_mem, test_num_disk, test_num_of_nic, test_nic_label :=
|
||||
TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "2"}.testCheckFuncBasic()
|
||||
|
||||
log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_keepOnRemove)
|
||||
log.Printf("[DEBUG] template config= %s", config)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckVSphereVirtualMachineDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: config,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
test_exists, test_name, test_cpu, test_mem, test_num_disk, test_num_of_nic, test_nic_label,
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: " ",
|
||||
Check: checkForDisk(datacenter, datastore, "terraform-test", "one.vmdk"),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func checkForDisk(datacenter string, datastore string, vmName string, path string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
client := testAccProvider.Meta().(*govmomi.Client)
|
||||
finder := find.NewFinder(client.Client, true)
|
||||
|
||||
dc, err := getDatacenter(client, datacenter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
finder.SetDatacenter(dc)
|
||||
|
||||
ds, err := finder.Datastore(context.TODO(), datastore)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] checkForDisk - Couldn't find Datastore '%v': %v", datastore, err)
|
||||
return err
|
||||
}
|
||||
|
||||
diskPath := vmName + "/" + path
|
||||
|
||||
_, err = ds.Stat(context.TODO(), diskPath)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] checkForDisk - Couldn't stat file '%v': %v", diskPath, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
fileManager := object.NewFileManager(client.Client)
|
||||
task, err := fileManager.DeleteDatastoreFile(context.TODO(), ds.Path(vmName), dc)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] checkForDisk - Couldn't delete vm folder '%v': %v", vmName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = task.WaitForResult(context.TODO(), nil)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] checForDisk - Failed while deleting vm folder '%v': %v", vmName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue