-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added ovirt_disk_resize_all resource
- Loading branch information
Janos Bonic
committed
Jun 9, 2022
1 parent
29ed65e
commit ce54a35
Showing
4 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "ovirt_vm_disks_resize Resource - terraform-provider-ovirt" | ||
subcategory: "" | ||
description: |- | ||
The ovirtvmdisks_resize resource resizes all disks in an oVirt VM to the specified size. | ||
~> Only use this resource with disks created from templates. Otherwise, two terraform resources will handle the same disk resource. | ||
--- | ||
|
||
# ovirt_vm_disks_resize (Resource) | ||
|
||
The ovirt_vm_disks_resize resource resizes all disks in an oVirt VM to the specified size. | ||
|
||
~> Only use this resource with disks created from templates. Otherwise, two terraform resources will handle the same disk resource. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `size` (Number) Disk size in bytes to set all disks to. | ||
- `vm_id` (String) Resize all disks in this VM to the specified size. | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of this resource. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package ovirt | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
ovirtclient "github.com/ovirt/go-ovirt-client" | ||
) | ||
|
||
var vmDisksResizeSchema = map[string]*schema.Schema{ | ||
"vm_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "Resize all disks in this VM to the specified size.", | ||
ValidateDiagFunc: validateUUID, | ||
}, | ||
"size": { | ||
Type: schema.TypeInt, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "Disk size in bytes to set all disks to.", | ||
ValidateDiagFunc: validateDiskSize, | ||
}, | ||
} | ||
|
||
func (p *provider) vmDisksResizeResource() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: p.vmDisksResizeCreate, | ||
ReadContext: p.vmDisksResizeRead, | ||
DeleteContext: p.vmDisksResizeDelete, | ||
Schema: vmDisksResizeSchema, | ||
Description: `The ovirt_vm_disks_resize resource resizes all disks in an oVirt VM to the specified size. | ||
~> Only use this resource with disks created from templates. Otherwise, two terraform resources will handle the same disk resource. | ||
`, | ||
} | ||
} | ||
|
||
func (p *provider) vmDisksResizeCreate( | ||
ctx context.Context, | ||
data *schema.ResourceData, | ||
_ interface{}, | ||
) diag.Diagnostics { | ||
client := p.client.WithContext(ctx) | ||
return resizeAllDisks(client, data) | ||
} | ||
|
||
func (p *provider) vmDisksResizeRead(ctx context.Context, data *schema.ResourceData, _ interface{}) diag.Diagnostics { | ||
client := p.client.WithContext(ctx) | ||
|
||
desiredSize := uint64(data.Get("size").(int)) | ||
size := desiredSize | ||
|
||
vmID := ovirtclient.VMID(data.Get("vm_id").(string)) | ||
|
||
diskAttachments, err := client.ListDiskAttachments(vmID) | ||
if err != nil { | ||
return errorToDiags(fmt.Sprintf("list disk attachments of VM %s", vmID), err) | ||
} | ||
for _, diskAttachment := range diskAttachments { | ||
disk, err := diskAttachment.Disk() | ||
if err != nil { | ||
return errorToDiags(fmt.Sprintf("get disk %s", diskAttachment.DiskID()), err) | ||
} | ||
if disk.ProvisionedSize() != desiredSize { | ||
// Set the reported size to the size differing so the resource can be refreshed and the disks resized. | ||
size = disk.ProvisionedSize() | ||
} | ||
} | ||
|
||
data.SetId(string(vmID)) | ||
diags := diag.Diagnostics{} | ||
diags = setResourceField(data, "size", size, diags) | ||
|
||
return diags | ||
} | ||
|
||
func (p *provider) vmDisksResizeDelete(_ context.Context, data *schema.ResourceData, _ interface{}) diag.Diagnostics { | ||
data.SetId("") | ||
return nil | ||
} | ||
|
||
func resizeAllDisks(client ovirtclient.Client, data *schema.ResourceData) diag.Diagnostics { | ||
vmID := ovirtclient.VMID(data.Get("vm_id").(string)) | ||
desiredSize := uint64(data.Get("size").(int)) | ||
|
||
diskAttachments, err := client.ListDiskAttachments(vmID) | ||
if err != nil { | ||
return errorToDiags(fmt.Sprintf("list disk attachments of VM %s", vmID), err) | ||
} | ||
var diags diag.Diagnostics | ||
for _, diskAttachment := range diskAttachments { | ||
disk, err := diskAttachment.Disk() | ||
if err != nil { | ||
return errorToDiags(fmt.Sprintf("get disk %s", diskAttachment.DiskID()), err) | ||
} | ||
if disk.ProvisionedSize() == desiredSize { | ||
continue | ||
} | ||
params := ovirtclient.UpdateDiskParams() | ||
if _, err := params.WithProvisionedSize(desiredSize); err != nil { | ||
diags = append( | ||
diags, | ||
diag.Diagnostic{ | ||
Severity: diag.Error, | ||
Summary: fmt.Sprintf("Failed to set parameters for updating disk %s size.", disk.ID()), | ||
Detail: err.Error(), | ||
}, | ||
) | ||
continue | ||
} | ||
updateFailedDiag := diag.Diagnostic{ | ||
Severity: diag.Error, | ||
Summary: fmt.Sprintf("Failed to update disk %s size.", disk.ID()), | ||
} | ||
diskUpdate, err := client.StartUpdateDisk(disk.ID(), params) | ||
if err != nil { | ||
updateFailedDiag.Detail = err.Error() | ||
diags = append(diags, updateFailedDiag) | ||
continue | ||
} | ||
_, err = diskUpdate.Wait() | ||
if err != nil { | ||
updateFailedDiag.Detail = err.Error() | ||
diags = append(diags, updateFailedDiag) | ||
continue | ||
} | ||
} | ||
|
||
data.SetId(string(vmID)) | ||
if !diags.HasError() { | ||
diags = setResourceField(data, "size", desiredSize, diags) | ||
} | ||
return diags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package ovirt | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
ovirtclient "github.com/ovirt/go-ovirt-client" | ||
) | ||
|
||
func TestVMDisksResize(t *testing.T) { | ||
t.Parallel() | ||
|
||
testData := []struct { | ||
name string | ||
diskCount int | ||
startingDiskSize uint64 | ||
desiredDiskSize uint64 | ||
}{ | ||
{ | ||
"empty", | ||
0, | ||
uint64(1024 * 1024), | ||
2 * uint64(1024*1024), | ||
}, | ||
{ | ||
"single", | ||
1, | ||
uint64(1024 * 1024), | ||
2 * uint64(1024*1024), | ||
}, | ||
{ | ||
"double", | ||
2, | ||
uint64(1024 * 1024), | ||
2 * uint64(1024*1024), | ||
}, | ||
} | ||
|
||
for _, testCase := range testData { | ||
t.Run( | ||
testCase.name, func(t *testing.T) { | ||
p := newProvider(newTestLogger(t)) | ||
|
||
helper := p.getTestHelper() | ||
client := helper.GetClient().WithContext(context.Background()) | ||
vm, err := client.CreateVM( | ||
helper.GetClusterID(), | ||
helper.GetBlankTemplateID(), | ||
helper.GenerateTestResourceName(t), | ||
nil, | ||
) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
startingDiskSize := testCase.startingDiskSize | ||
desiredDiskSize := testCase.desiredDiskSize | ||
|
||
disks := make([]ovirtclient.Disk, testCase.diskCount) | ||
|
||
for i := 0; i < testCase.diskCount; i++ { | ||
disk, err := client.CreateDisk( | ||
helper.GetStorageDomainID(), | ||
ovirtclient.ImageFormatRaw, | ||
startingDiskSize, | ||
nil, | ||
) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
_, err = client.CreateDiskAttachment(vm.ID(), disk.ID(), ovirtclient.DiskInterfaceVirtIO, nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
disks[i] = disk | ||
} | ||
|
||
config := fmt.Sprintf( | ||
` | ||
provider "ovirt" { | ||
mock = true | ||
} | ||
resource "ovirt_vm_disks_resize" "resized" { | ||
vm_id = "%s" | ||
size = %d | ||
}`, | ||
vm.ID(), | ||
desiredDiskSize, | ||
) | ||
|
||
resource.UnitTest( | ||
t, resource.TestCase{ | ||
ProviderFactories: p.getProviderFactories(), | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: config, | ||
Check: func(state *terraform.State) error { | ||
for _, disk := range disks { | ||
disk, err := client.GetDisk(disk.ID()) | ||
if err != nil { | ||
return err | ||
} | ||
if disk.ProvisionedSize() != desiredDiskSize { | ||
return fmt.Errorf( | ||
"incorrect disk size after apply: %d", | ||
disk.ProvisionedSize(), | ||
) | ||
} | ||
} | ||
return nil | ||
}, | ||
}, | ||
{ | ||
Config: config, | ||
Destroy: true, | ||
}, | ||
}, | ||
}, | ||
) | ||
}, | ||
) | ||
} | ||
} |