Skip to content

Commit

Permalink
added bootable and active fields to disk_attachment (#439)
Browse files Browse the repository at this point in the history
  • Loading branch information
engelmi authored Jun 14, 2022
1 parent 3e10e69 commit 953e7e3
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 147 deletions.
7 changes: 7 additions & 0 deletions docs/resources/disk_attachment.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ resource "ovirt_disk_attachment" "test" {
vm_id = ovirt_vm.test.id
disk_id = ovirt_disk.test.id
disk_interface = "virtio_scsi"
bootable = true
active = true
}
```

Expand All @@ -50,6 +52,11 @@ resource "ovirt_disk_attachment" "test" {
- `disk_interface` (String) Type of interface to use for attaching disk. One of: `ide`, `sata`, `spapr_vscsi`, `virtio`, `virtio_scsi`.
- `vm_id` (String) ID of the VM the disk should be attached to.

### Optional

- `active` (Boolean) Defines whether the disk is active in the virtual machine it is attached to.
- `bootable` (Boolean) Defines whether the disk is bootable.

### Read-Only

- `id` (String) The ID of this resource.
Expand Down
7 changes: 7 additions & 0 deletions docs/resources/disk_attachments.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ resource "ovirt_disk_attachments" "test" {
attachment {
disk_id = ovirt_disk.test.id
disk_interface = "virtio_scsi"
bootable = true
active = true
}
}
```
Expand Down Expand Up @@ -75,6 +77,11 @@ Required:
- `disk_id` (String) ID of the disk to attach. This disk must either be shared or not yet attached to a different VM.
- `disk_interface` (String) Type of interface to use for attaching disk. One of: `ide`, `sata`, `spapr_vscsi`, `virtio`, `virtio_scsi`.

Optional:

- `active` (Boolean) Defines whether the disk is active in the virtual machine it is attached to.
- `bootable` (Boolean) Defines whether the disk is bootable.

Read-Only:

- `id` (String) The ID of this resource.
Expand Down
2 changes: 2 additions & 0 deletions examples/resources/ovirt_disk_attachment/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ resource "ovirt_disk_attachment" "test" {
vm_id = ovirt_vm.test.id
disk_id = ovirt_disk.test.id
disk_interface = "virtio_scsi"
bootable = true
active = true
}
2 changes: 2 additions & 0 deletions examples/resources/ovirt_disk_attachments/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ resource "ovirt_disk_attachments" "test" {
attachment {
disk_id = ovirt_disk.test.id
disk_interface = "virtio_scsi"
bootable = true
active = true
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/ovirt/go-ovirt-client v1.0.0-beta2
github.com/ovirt/go-ovirt-client v1.0.0-beta4
github.com/ovirt/go-ovirt-client-log/v3 v3.0.0
github.com/vmihailenco/tagparser v0.1.2 // indirect
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/ovirt/go-ovirt v0.0.0-20220427092237-114c47f2835c h1:jXRFpl7+W0YZj/fghoYuE4vJWW/KeQGvdrhnRwRGtAY=
github.com/ovirt/go-ovirt v0.0.0-20220427092237-114c47f2835c/go.mod h1:Zkdj9/rW6eyuw0uOeEns6O3pP5G2ak+bI/tgkQ/tEZI=
github.com/ovirt/go-ovirt-client v1.0.0-beta2 h1:GszjqWO9he3h1Y4SUUAxz/5Wgev/p1A6MVIf7Z8eQXg=
github.com/ovirt/go-ovirt-client v1.0.0-beta2/go.mod h1:tv8E2pxUkggayDAgMLuQHzcNtzt8RFvnhO5V5b/5X4U=
github.com/ovirt/go-ovirt-client v1.0.0-beta4 h1:A8MFK4Y4ZZ3Ad7N6Q0obqJl8r2Pai1FmzD193WwBpoo=
github.com/ovirt/go-ovirt-client v1.0.0-beta4/go.mod h1:tv8E2pxUkggayDAgMLuQHzcNtzt8RFvnhO5V5b/5X4U=
github.com/ovirt/go-ovirt-client-log/v3 v3.0.0 h1:uvACVHYhYPMkNJrrgWiABcfELB6qoFfsDDUTbpb4Jv4=
github.com/ovirt/go-ovirt-client-log/v3 v3.0.0/go.mod h1:chKKxCv4lRjxezrTG+EIhkWXGhDAWByglPVXh/iYdnQ=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
45 changes: 44 additions & 1 deletion internal/ovirt/resource_ovirt_disk_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ var diskAttachmentSchema = map[string]*schema.Schema{
ForceNew: true,
ValidateDiagFunc: validateDiskInterface,
},
"bootable": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
Description: "Defines whether the disk is bootable.",
},
"active": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
Description: "Defines whether the disk is active in the virtual machine it is attached to.",
},
}

func (p *provider) diskAttachmentResource() *schema.Resource {
Expand Down Expand Up @@ -66,11 +80,34 @@ func (p *provider) diskAttachmentCreate(
diskID := data.Get("disk_id").(string)
diskInterface := data.Get("disk_interface").(string)

var err error
var diags diag.Diagnostics
params := ovirtclient.CreateDiskAttachmentParams()
params, err = params.WithBootable(data.Get("bootable").(bool))
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Failed to set bootable flag for disk attachment.",
Detail: err.Error(),
})
}
params, err = params.WithActive(data.Get("active").(bool))
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Failed to set active flag for disk attachment.",
Detail: err.Error(),
})
}
if diags.HasError() {
return diags
}

diskAttachment, err := client.CreateDiskAttachment(
ovirtclient.VMID(vmID),
ovirtclient.DiskID(diskID),
ovirtclient.DiskInterface(diskInterface),
ovirtclient.CreateDiskAttachmentParams(),
params,
)
if err != nil {
return diag.Diagnostics{
Expand Down Expand Up @@ -164,6 +201,12 @@ func (p *provider) diskAttachmentImport(
if err := data.Set("disk_interface", string(attachment.DiskInterface())); err != nil {
return nil, fmt.Errorf("failed to set disk_interface to %s", attachment.DiskInterface())
}
if err := data.Set("bootable", attachment.Bootable()); err != nil {
return nil, fmt.Errorf("failed to set bootable to %v", attachment.Bootable())
}
if err := data.Set("active", attachment.Active()); err != nil {
return nil, fmt.Errorf("failed to set active to %v", attachment.Active())
}
return []*schema.ResourceData{data}, nil
}

Expand Down
147 changes: 103 additions & 44 deletions internal/ovirt/resource_ovirt_disk_attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,111 @@ func TestDiskAttachmentResource(t *testing.T) {
clusterID := p.getTestHelper().GetClusterID()
templateID := p.getTestHelper().GetBlankTemplateID()

resource.UnitTest(
t, resource.TestCase{
ProviderFactories: p.getProviderFactories(),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(
`
provider "ovirt" {
mock = true
}
resource "ovirt_disk" "test" {
storage_domain_id = "%s"
format = "raw"
size = 1048576
alias = "test"
sparse = true
}
resource "ovirt_vm" "test" {
cluster_id = "%s"
template_id = "%s"
name = "test"
}
baseConfig := fmt.Sprintf(`
provider "ovirt" {
mock = true
}
resource "ovirt_disk" "test" {
storage_domain_id = "%s"
format = "raw"
size = 1048576
alias = "test"
sparse = true
}
resource "ovirt_vm" "test" {
cluster_id = "%s"
template_id = "%s"
name = "test"
}`,
storageDomainID,
clusterID,
templateID,
)

resource "ovirt_disk_attachment" "test" {
vm_id = ovirt_vm.test.id
disk_id = ovirt_disk.test.id
disk_interface = "virtio_scsi"
}
`,
storageDomainID,
clusterID,
templateID,
),
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
"ovirt_disk_attachment.test",
"id",
regexp.MustCompile("^.+$"),
),
),
},
},
testcases := []struct {
name string
inputBootable string
inputActive string
expectedBootable bool
expectedActive bool
}{
{
name: "all set to true",
inputBootable: "true",
inputActive: "true",
expectedBootable: true,
expectedActive: true,
},
)
{
name: "all set to false",
inputBootable: "false",
inputActive: "false",
expectedBootable: false,
expectedActive: false,
},
{
name: "using defaults",
inputBootable: "null",
inputActive: "null",
expectedBootable: false,
expectedActive: false,
},
}

for _, testcase := range testcases {
t.Run(testcase.name, func(t *testing.T) {
resource.UnitTest(
t, resource.TestCase{
ProviderFactories: p.getProviderFactories(),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
%s
resource "ovirt_disk_attachment" "test" {
vm_id = ovirt_vm.test.id
disk_id = ovirt_disk.test.id
disk_interface = "virtio_scsi"
bootable = %s
active = %s
}`,
baseConfig,
testcase.inputBootable,
testcase.inputActive,
),
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
"ovirt_disk_attachment.test",
"id",
regexp.MustCompile("^.+$"),
),
func(s *terraform.State) error {
VMID := s.RootModule().Resources["ovirt_vm.test"].Primary.ID
diskAttachmentID := s.RootModule().Resources["ovirt_disk_attachment.test"].Primary.ID
diskAttachment, err := p.getTestHelper().GetClient().GetDiskAttachment(ovirtclient.VMID(VMID), ovirtclient.DiskAttachmentID(diskAttachmentID))
if err != nil {
return err
}
if diskAttachment.DiskInterface() != "virtio_scsi" {
return fmt.Errorf("Expected disk_interface 'virtio_scsi', but got '%s'", diskAttachment.DiskInterface())
}
if diskAttachment.Bootable() != testcase.expectedActive {
return fmt.Errorf("Expected bootable to be %t, but got %t", testcase.expectedBootable, diskAttachment.Bootable())
}
if diskAttachment.Active() != testcase.expectedActive {
return fmt.Errorf("Expected active to be %t, but got %t", testcase.expectedActive, diskAttachment.Active())
}
return nil
},
),
},
},
},
)
})
}
}

func TestDiskAttachmentResourceImport(t *testing.T) {
Expand Down
39 changes: 37 additions & 2 deletions internal/ovirt/resource_ovirt_disk_attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ var diskAttachmentsSchema = map[string]*schema.Schema{
ForceNew: false,
ValidateDiagFunc: validateDiskInterface,
},
"bootable": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
Description: "Defines whether the disk is bootable.",
},
"active": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
Description: "Defines whether the disk is active in the virtual machine it is attached to.",
},
},
},
},
Expand Down Expand Up @@ -180,6 +194,8 @@ func (p *provider) createOrUpdateDiskAttachment(
id := desiredAttachment["id"].(string)
diskID := desiredAttachment["disk_id"].(string)
diskInterfaceName := desiredAttachment["disk_interface"].(string)
bootable := desiredAttachment["bootable"].(bool)
active := desiredAttachment["active"].(bool)

var foundExisting ovirtclient.DiskAttachment
if id != "" {
Expand All @@ -194,7 +210,10 @@ func (p *provider) createOrUpdateDiskAttachment(
if foundExisting != nil {
// If we found an existing attachment, check if all parameters match. Otherwise, remove the attachment
// and let it be re-created below.
if foundExisting.DiskID() == ovirtclient.DiskID(diskID) && string(foundExisting.DiskInterface()) == diskInterfaceName {
if string(foundExisting.DiskID()) == diskID &&
string(foundExisting.DiskInterface()) == diskInterfaceName &&
foundExisting.Bootable() == bootable &&
foundExisting.Active() == active {
return nil
}
if err := foundExisting.Remove(); err != nil && !isNotFound(err) {
Expand All @@ -208,14 +227,27 @@ func (p *provider) createOrUpdateDiskAttachment(
desiredAttachment["id"] = ""
desiredAttachment["disk_id"] = ""
desiredAttachment["disk_interface"] = ""
desiredAttachment["bootable"] = false
desiredAttachment["active"] = false
}

var err error
params := ovirtclient.CreateDiskAttachmentParams()
params, err = params.WithBootable(bootable)
if err != nil {
return errorToDiags("set bootable flag for disk attachment.", err)
}
params, err = params.WithActive(active)
if err != nil {
return errorToDiags("set active flag for disk attachment.", err)
}

// Create or re-create disk attachment, then set it in the Terraform state.
attachment, err := client.CreateDiskAttachment(
ovirtclient.VMID(vmID),
ovirtclient.DiskID(diskID),
ovirtclient.DiskInterface(diskInterfaceName),
nil,
params,
)
if err != nil {
return errorToDiags(
Expand All @@ -226,6 +258,9 @@ func (p *provider) createOrUpdateDiskAttachment(
desiredAttachment["id"] = attachment.ID()
desiredAttachment["disk_id"] = attachment.DiskID()
desiredAttachment["disk_interface"] = string(attachment.DiskInterface())
desiredAttachment["bootable"] = attachment.Bootable()
desiredAttachment["active"] = attachment.Active()

return nil
}

Expand Down
Loading

0 comments on commit 953e7e3

Please sign in to comment.