From df73a57bb7f66666bb40f45df29931e054daf79d Mon Sep 17 00:00:00 2001 From: Paul BESRET Date: Thu, 14 Nov 2024 17:18:08 +0100 Subject: [PATCH] Added resource 'cloudtemple_compute_iaas_opensource_virtual_disk' --- .../compute_iaas_opensource_virtual_disk.md | 41 +++++ .../client/compute_openiaas_virtual_disk.go | 33 ++++ internal/provider/provider.go | 3 +- .../resource_compute_openiaas_virtual_disk.go | 151 ++++++++++++++++++ ...source_compute_openiaas_virtual_machine.go | 24 +-- 5 files changed, 228 insertions(+), 24 deletions(-) create mode 100644 docs/resources/compute_iaas_opensource_virtual_disk.md create mode 100644 internal/provider/resource_compute_openiaas_virtual_disk.go diff --git a/docs/resources/compute_iaas_opensource_virtual_disk.md b/docs/resources/compute_iaas_opensource_virtual_disk.md new file mode 100644 index 0000000..2bde044 --- /dev/null +++ b/docs/resources/compute_iaas_opensource_virtual_disk.md @@ -0,0 +1,41 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cloudtemple_compute_iaas_opensource_virtual_disk Resource - terraform-provider-cloudtemple" +subcategory: "Compute" +description: |- + To manage this resource you will need the following roles: + - compute_iaas_opensource_management + - compute_iaas_opensource_read + - activity_read +--- + +# cloudtemple_compute_iaas_opensource_virtual_disk (Resource) + +To manage this resource you will need the following roles: + - `compute_iaas_opensource_management` + - `compute_iaas_opensource_read` + - `activity_read` + + + + +## Schema + +### Required + +- `mode` (String) The mode of the virtual disk. +- `name` (String) The name of the virtual disk. +- `size` (Number) The size of the virtual disk in bytes. +- `storage_repository_id` (String) The ID of the storage repository where the virtual disk is stored. +- `virtual_machine_id` (String) The ID of the virtual machine to which the virtual disk is attached. + +### Optional + +- `bootable` (Boolean) Whether the virtual disk is bootable. + +### Read-Only + +- `id` (String) The ID of the virtual disk. +- `usage` (String) The usage of the virtual disk. + + diff --git a/internal/client/compute_openiaas_virtual_disk.go b/internal/client/compute_openiaas_virtual_disk.go index 10ee553..aec1a22 100644 --- a/internal/client/compute_openiaas_virtual_disk.go +++ b/internal/client/compute_openiaas_virtual_disk.go @@ -28,6 +28,21 @@ type OpenIaaSVirtualDisk struct { } `terraform:"virtual_machines"` } +type OpenIaaSVirtualDiskCreateRequest struct { + Name string `json:"name"` + Size int `json:"size"` + Mode string `json:"mode"` + StorageRepositoryID string `json:"storageRepositoryId"` + VirtualMachineID string `json:"virtualMachineId"` + Bootable bool `json:"bootable"` +} + +func (v *OpenIaaSVirtualDiskClient) Create(ctx context.Context, req *OpenIaaSVirtualDiskCreateRequest) (string, error) { + r := v.c.newRequest("POST", "/compute/v1/open_iaas/virtual_disks") + r.obj = req + return v.c.doRequestAndReturnActivity(ctx, r) +} + func (v *OpenIaaSVirtualDiskClient) Read(ctx context.Context, id string) (*OpenIaaSVirtualDisk, error) { r := v.c.newRequest("GET", "/compute/v1/open_iaas/virtual_disks/%s", id) resp, err := v.c.doRequest(ctx, r) @@ -68,3 +83,21 @@ func (v *OpenIaaSVirtualDiskClient) List(ctx context.Context, virtualMachineId s return out, nil } + +type OpenIaaSVirtualDiskAttachRequest struct { + VirtualMachineID string `json:"virtualMachineId"` + Bootable bool `json:"bootable,omitempty"` + Mode string `json:"mode"` + Position string `json:"position,omitempty"` +} + +func (v *OpenIaaSVirtualDiskClient) Attach(ctx context.Context, id string, req *OpenIaaSVirtualDiskAttachRequest) (string, error) { + r := v.c.newRequest("POST", "/compute/v1/open_iaas/virtual_disks/%s/attach", id) + r.obj = req + return v.c.doRequestAndReturnActivity(ctx, r) +} + +func (v *OpenIaaSVirtualDiskClient) Delete(ctx context.Context, id string) (string, error) { + r := v.c.newRequest("DELETE", "/compute/v1/open_iaas/virtual_disks/%s", id) + return v.c.doRequestAndReturnActivity(ctx, r) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 9402a96..191b83d 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -160,7 +160,8 @@ func New(version string) func() *schema.Provider { "cloudtemple_iam_personal_access_token": documentResource(resourcePersonalAccessToken(), "iam_offline_access"), // Compute - Open IaaS - "cloudtemple_compute_iaas_opensource_virtual_machine": documentResource(resourceOpenIaasVirtualMachine(), "compute_iaas_opensource_infrastructure_read", "compute_iaas_opensource_infrastructure_write", "compute_iaas_opensource_management", "compute_iaas_opensource_read", "compute_iaas_opensource_virtual_machine_power", "backup_iaas_opensource_read", "backup_iaas_opensource_write", "activity_read", "tag_read", "tag_write"), + "cloudtemple_compute_iaas_opensource_virtual_machine": documentResource(resourceOpenIaasVirtualMachine(), "compute_iaas_opensource_management", "compute_iaas_opensource_read", "compute_iaas_opensource_virtual_machine_power", "backup_iaas_opensource_read", "backup_iaas_opensource_write", "activity_read", "tag_read", "tag_write"), + "cloudtemple_compute_iaas_opensource_virtual_disk": documentResource(resourceOpenIaasVirtualDisk(), "compute_iaas_opensource_management", "compute_iaas_opensource_read", "activity_read"), }, } diff --git a/internal/provider/resource_compute_openiaas_virtual_disk.go b/internal/provider/resource_compute_openiaas_virtual_disk.go new file mode 100644 index 0000000..b1f2a99 --- /dev/null +++ b/internal/provider/resource_compute_openiaas_virtual_disk.go @@ -0,0 +1,151 @@ +package provider + +import ( + "context" + + "github.com/cloud-temple/terraform-provider-cloudtemple/internal/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceOpenIaasVirtualDisk() *schema.Resource { + return &schema.Resource{ + CreateContext: openIaasVirtualDiskCreate, + ReadContext: openIaasVirtualDiskRead, + UpdateContext: openIaasVirtualDiskUpdate, + DeleteContext: openIaasVirtualDiskDelete, + + Schema: map[string]*schema.Schema{ + // In + "name": { + Type: schema.TypeString, + Description: "The name of the virtual disk.", + Required: true, + ForceNew: true, + }, + "size": { + Type: schema.TypeInt, + Description: "The size of the virtual disk in bytes.", + Required: true, + ForceNew: true, + }, + "mode": { + Type: schema.TypeString, + Description: "The mode of the virtual disk.", + ValidateFunc: validation.StringInSlice([]string{"RW", "RO"}, false), + Required: true, + ForceNew: true, + }, + "storage_repository_id": { + Type: schema.TypeString, + Description: "The ID of the storage repository where the virtual disk is stored.", + Required: true, + ValidateFunc: validation.IsUUID, + ForceNew: true, + }, + "virtual_machine_id": { + Type: schema.TypeString, + Description: "The ID of the virtual machine to which the virtual disk is attached.", + Required: true, + ValidateFunc: validation.IsUUID, + ForceNew: true, + }, + "bootable": { + Type: schema.TypeBool, + Description: "Whether the virtual disk is bootable.", + Optional: true, + Default: false, + ForceNew: true, + }, + + // Out + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The ID of the virtual disk.", + }, + "usage": { + Type: schema.TypeString, + Computed: true, + Description: "The usage of the virtual disk.", + }, + }, + } +} + +func openIaasVirtualDiskCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c := getClient(meta) + + activityId, err := c.Compute().OpenIaaS().VirtualDisk().Create(ctx, &client.OpenIaaSVirtualDiskCreateRequest{ + Name: d.Get("name").(string), + Size: d.Get("size").(int), + Mode: d.Get("mode").(string), + StorageRepositoryID: d.Get("storage_repository_id").(string), + VirtualMachineID: d.Get("virtual_machine_id").(string), + Bootable: d.Get("bootable").(bool), + }) + if err != nil { + return diag.Errorf("the virtual disk could not be created: %s", err) + } + activity, err := c.Activity().WaitForCompletion(ctx, activityId, getWaiterOptions((ctx))) + setIdFromActivityState(d, activity) + if err != nil { + return diag.Errorf("the virtual disk could not be created: %s", err) + } + + return openIaasVirtualDiskUpdate(ctx, d, meta) +} + +func openIaasVirtualDiskRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c := getClient(meta) + virtualDisk, err := c.Compute().OpenIaaS().VirtualDisk().Read(ctx, d.Id()) + if err != nil { + return diag.Errorf("the virtual disk could not be read: %s", err) + } + if virtualDisk == nil { + return diag.Errorf("the virtual disk could not be found: %s", err) + } + + // Set the retrieved data to the schema + d.Set("name", virtualDisk.Name) + d.Set("size", virtualDisk.Size) + d.Set("usage", virtualDisk.Usage) + d.Set("storage_repository_id", virtualDisk.StorageRepository.ID) + + return nil +} + +func openIaasVirtualDiskUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + // TODO : Implement Detach on API to be able to change a virtual disk VM attachment + + // TODO : Implement this on Compute API + // // Update the virtual disk properties if they have changed + // if d.HasChange("name") || d.HasChange("size") || d.HasChange("mode") || d.HasChange("storage_repository_id") || d.HasChange("bootable") { + // _, err := c.Compute().OpenIaaS().VirtualDisk().Update(ctx, d.Id(), &client.OpenIaaSVirtualDiskUpdateRequest{ + // Name: d.Get("name").(string), + // Size: d.Get("size").(int), + // Mode: d.Get("mode").(string), + // StorageRepositoryID: d.Get("storage_repository_id").(string), + // Bootable: d.Get("bootable").(bool), + // }) + // if err != nil { + // return diag.Errorf("failed to update virtual disk: %s", err) + // } + // } + + return openIaasVirtualDiskRead(ctx, d, meta) +} + +func openIaasVirtualDiskDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c := getClient(meta) + + activityId, err := c.Compute().OpenIaaS().VirtualDisk().Delete(ctx, d.Id()) + if err != nil { + return diag.Errorf("failed to delete virtual disk: %s", err) + } + if _, err = c.Activity().WaitForCompletion(ctx, activityId, getWaiterOptions(ctx)); err != nil { + return diag.Errorf("failed to delete virtual disk, %s", err) + } + return nil +} diff --git a/internal/provider/resource_compute_openiaas_virtual_machine.go b/internal/provider/resource_compute_openiaas_virtual_machine.go index eefef92..4e864b6 100644 --- a/internal/provider/resource_compute_openiaas_virtual_machine.go +++ b/internal/provider/resource_compute_openiaas_virtual_machine.go @@ -306,28 +306,6 @@ func openIaasVirtualMachineUpdate(ctx context.Context, d *schema.ResourceData, m return diag.Errorf("failed to update virtual machine, %s", err) } - // TODO: Implement the mount/unmount methods and get files from the storage repository - - // if d.HasChange("mounted") { - // var activityId string - // var err error - // if d.Get("mounted").(bool) { - // activityId, err = c.Compute().OpenIaaS().VirtualMachine().Mount(ctx, &client.MountISORequest{ - // ID: d.Id(), - // IsoPath: d.Get("iso_path").(string), - // ContentLibraryItemId: d.Get("content_library_item_id").(string), - // }) - // } else { - // activityId, err = c.Compute().VirtualMachine().Unmount(ctx, d.Id()) - // } - // if err != nil { - // return diag.Errorf("the virtual machine could not be connected: %s", err) - // } - // _, err = c.Activity().WaitForCompletion(ctx, activityId, getWaiterOptions(ctx)) - // if err != nil { - // return diag.Errorf("failed to connect virtual machine, %s", err) - // } - // } if d.HasChange("boot_order") { bootOrder := d.Get("boot_order").([]interface{}) bootOrderStr := make([]string, len(bootOrder)) @@ -349,7 +327,7 @@ func openIaasVirtualMachineUpdate(ctx context.Context, d *schema.ResourceData, m activityId, err := c.Compute().OpenIaaS().VirtualMachine().Power(ctx, d.Id(), &client.UpdateOpenIaasVirtualMachinePowerRequest{ HostId: d.Get("host_id").(string), PowerState: powerState, - Force: true, + Force: false, BypassMacAddressesCheck: false, BypassBlockedOperation: false, ForceShutdownDelay: 0,