josenk / terraform-provider-esxi

Terraform-provider-esxi plugin
GNU General Public License v3.0
540 stars 154 forks source link

[BUG/FEATURE] Fix for Virtual Disk Dir that Contains "/" #164

Closed simplerick0 closed 2 years ago

simplerick0 commented 2 years ago

Feature/Bug: Virtual disks can be created when directories include subdirectories. Using virtual_disk_dir = disks/my_disk would allow you to create a disk, but any susequent call would be unable to read the disk.

Here is a snippet of the initial plan output:

Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # esxi_virtual_disk.my_disk will be created
  + resource "esxi_virtual_disk" "my_disk" {
      + id                      = (known after apply)
      + virtual_disk_dir        = "disks/my_disk"
      + virtual_disk_disk_store = "vmstore2"
      + virtual_disk_name       = "my_disk.vmdk"
      + virtual_disk_size       = 128
      + virtual_disk_type       = "zeroedthick"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

And here is a snippet from the second plan output after the first was applied.

esxi_virtual_disk.my_disk: Refreshing state... [id=/vmfs/volumes/vmstore2/disks/my_disk/my_disk.vmdk]
2022-01-27T14:56:22.634-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0: pid-579431-virtual-disk_read.go:12: [resourceVIRTUALDISKRead]
2022-01-27T14:56:22.634-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0: pid-579431-virtual-disk_functions.go:136: [virtualDiskREAD] Begin
2022-01-27T14:56:22.634-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0: pid-579431-virtual-disk_functions.go:146: [virtualDiskREAD] len=7 cap=7 [ vmfs volumes vmstore2 disks my_disk my_disk.vmdk]
2022-01-27T14:56:22.634-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0: pid-579431-esxi_remote_cmds.go:61: [runRemoteSshCommand] :test if virtual disk exists
2022-01-27T14:56:22.798-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0: pid-579431-esxi_remote_cmds.go:83: [runRemoteSshCommand] cmd:/test -s "/vmfs/volumes/vmstore2/disks/my_disk/my_disk.vmdk"/
2022-01-27T14:56:22.798-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0:  stdout://
2022-01-27T14:56:22.798-0700 [DEBUG] provider.terraform-provider-esxi_v1.10.0: stderr:/%!s(<nil>)/
2022-01-27T14:56:22.800-0700 [WARN]  Provider "registry.terraform.io/josenk/esxi" produced an unexpected new value for esxi_virtual_disk.my_disk during refresh.
      - .virtual_disk_type: was cty.StringVal("zeroedthick"), but now cty.StringVal("")
      - .virtual_disk_dir: was cty.StringVal("disks/my_disk"), but now cty.StringVal("")
      - .virtual_disk_disk_store: was cty.StringVal("vmstore2"), but now cty.StringVal("")
      - .virtual_disk_name: was cty.StringVal("my_disk.vmdk"), but now cty.StringVal("")
      - .virtual_disk_size: was cty.NumberIntVal(128), but now cty.NumberIntVal(0)
2022-01-27T14:56:22.809-0700 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/josenk/esxi/1.10.0/linux_amd64/terraform-provider-esxi_v1.10.0 pid=579431
2022-01-27T14:56:22.809-0700 [DEBUG] provider: plugin exited
2022-01-27T14:56:22.809-0700 [INFO]  backend/local: plan operation completed
2022-01-27T14:56:22.809-0700 [INFO]  backend/local: writing plan output to: tf2.plan

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform
apply":

  # esxi_virtual_disk.my_disk has changed
  ~ resource "esxi_virtual_disk" "my_disk" {
        id                      = "/vmfs/volumes/vmstore2/disks/my_disk/my_disk.vmdk"
      - virtual_disk_dir        = "disks/my_disk" -> null
      - virtual_disk_disk_store = "vmstore2" -> null
      - virtual_disk_name       = "my_disk.vmdk" -> null
      ~ virtual_disk_size       = 128 -> 0
      - virtual_disk_type       = "zeroedthick" -> null
    }

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes
using ignore_changes, the following plan may include actions to undo or respond to these changes.

─────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # esxi_virtual_disk.my_disk must be replaced
-/+ resource "esxi_virtual_disk" "my_disk" {
      ~ id                      = "/vmfs/volumes/vmstore2/disks/my_disk/my_disk.vmdk" -> (known after apply)
      + virtual_disk_dir        = "disks/my_disk" # forces replacement
      + virtual_disk_disk_store = "vmstore2" # forces replacement
      + virtual_disk_name       = "my_disk.vmdk" # forces replacement
      ~ virtual_disk_size       = 0 -> 128
      + virtual_disk_type       = "zeroedthick" # forces replacement
    }

Plan: 1 to add, 0 to change, 1 to destroy.

This PR adds the ability to do just that, allowing for better organization of your datastore.

The algorithm is simple. If the length of virtdisk_id is greater than 6 then we assume the directory contains '/'. We slice the string array s and Join the strings back into the directory path.

Tested manually with a simple main.tf that includes an esxi provider and a single disk. I tested with terraform plan, terraform apply, changed disk size to 150G (from 128G) and terraform apply again. Then terraform destroy. Each command succeeded.

Output from initial apply:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with t[2/403]following symbols:                                                                                                            + create

Terraform will perform the following actions:

  # esxi_virtual_disk.my_disk will be created
  + resource "esxi_virtual_disk" "my_disk" {
      + id                      = (known after apply)
      + virtual_disk_dir        = "disks/my_disks"
      + virtual_disk_disk_store = "vmstore2"
      + virtual_disk_name       = "my_disk.vmdk"
      + virtual_disk_size       = 150
      + virtual_disk_type       = "zeroedthick"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

esxi_virtual_disk.my_disk: Creating...
esxi_virtual_disk.my_disk: Creation complete after 6s [id=/vmfs/volumes/vmstore2/disks/my_disks/my_disk.vmdk]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Successful output from the second plan. As should be the case, no change should be necessary.

esxi_virtual_disk.my_disk: Refreshing state... [id=/vmfs/volumes/vmstore2/disks/my_disks/my_disk.vmdk]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are
needed.

And for completeness, if I wanted to grow the disk:

esxi_virtual_disk.my_disk: Refreshing state... [id=/vmfs/volumes/vmstore2/disks/my_disks/my_disk.vmdk]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # esxi_virtual_disk.my_disk will be updated in-place
  ~ resource "esxi_virtual_disk" "my_disk" {
        id                      = "/vmfs/volumes/vmstore2/disks/my_disks/my_disk.vmdk"
      ~ virtual_disk_size       = 150 -> 256
        # (4 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

I can provide further logs if you need.

josenk commented 2 years ago

Cool, Thanks! I will test it out and put it through some tests...