generated from hashicorp/terraform-provider-scaffolding
-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add resource to manage virtual disks (#558)
* feat(netbox_virtual_machine): make disk_size_gb computed Since the addition of virtual disks, this field represents the aggregate size of all disks. When adding virtual disks, netbox automatically updates this field, so it must be a `computed` field to let terraform know that there can be changes from outside of terraform. * chore(go.mod): upgrade github.com/fbreckle/go-netbox to v0.0.0-20240229093931-1ddc00b277c1 * feat(netbox_virtual_disk): add new resource Add support to manage [virtual disks][0], which were added in netbox 3.7.0. [0]:https://docs.netbox.dev/en/stable/models/virtualization/virtualdisk/
- Loading branch information
Showing
9 changed files
with
368 additions
and
2 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,56 @@ | ||
--- | ||
# generated by https://github.com/fbreckle/terraform-plugin-docs | ||
page_title: "netbox_virtual_disk Resource - terraform-provider-netbox" | ||
subcategory: "Virtualization" | ||
description: |- | ||
From the official documentation https://docs.netbox.dev/en/stable/models/virtualization/virtualdisk/: | ||
> A virtual disk is used to model discrete virtual hard disks assigned to virtual machines. | ||
--- | ||
|
||
# netbox_virtual_disk (Resource) | ||
|
||
From the [official documentation](https://docs.netbox.dev/en/stable/models/virtualization/virtualdisk/): | ||
|
||
> A virtual disk is used to model discrete virtual hard disks assigned to virtual machines. | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
// Assumes vmw-cluster-01 exists in Netbox | ||
data "netbox_cluster" "vmw_cluster_01" { | ||
name = "vmw-cluster-01" | ||
} | ||
resource "netbox_virtual_machine" "base_vm" { | ||
cluster_id = data.netbox_cluster.vmw_cluster_01.id | ||
name = "myvm-1" | ||
} | ||
resource "netbox_virtual_disk" "example" { | ||
name = "disk-01" | ||
description = "Main disk" | ||
size = 50 | ||
virtual_machine_id = netbox_virtual_machine.base_vm.id | ||
} | ||
``` | ||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `name` (String) | ||
- `size` (Number) | ||
- `virtual_machine_id` (Number) | ||
|
||
### Optional | ||
|
||
- `custom_fields` (Map of String) | ||
- `description` (String) | ||
- `tags` (Set of String) | ||
|
||
### 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Assumes vmw-cluster-01 exists in Netbox | ||
data "netbox_cluster" "vmw_cluster_01" { | ||
name = "vmw-cluster-01" | ||
} | ||
|
||
resource "netbox_virtual_machine" "base_vm" { | ||
cluster_id = data.netbox_cluster.vmw_cluster_01.id | ||
name = "myvm-1" | ||
} | ||
|
||
resource "netbox_virtual_disk" "example" { | ||
name = "disk-01" | ||
description = "Main disk" | ||
size = 50 | ||
virtual_machine_id = netbox_virtual_machine.base_vm.id | ||
} |
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
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,186 @@ | ||
package netbox | ||
|
||
import ( | ||
"context" | ||
"strconv" | ||
|
||
"github.com/fbreckle/go-netbox/netbox/client" | ||
"github.com/fbreckle/go-netbox/netbox/client/virtualization" | ||
"github.com/fbreckle/go-netbox/netbox/models" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func resourceNetboxVirtualDisks() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceNetboxVirtualDisksCreate, | ||
ReadContext: resourceNetboxVirtualDisksRead, | ||
UpdateContext: resourceNetboxVirtualDisksUpdate, | ||
DeleteContext: resourceNetboxVirtualDisksDelete, | ||
Description: `:meta:subcategory:Virtualization:From the [official documentation](https://docs.netbox.dev/en/stable/models/virtualization/virtualdisk/): | ||
> A virtual disk is used to model discrete virtual hard disks assigned to virtual machines.`, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"description": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"size": { | ||
Type: schema.TypeInt, | ||
Required: true, | ||
}, | ||
"virtual_machine_id": { | ||
Type: schema.TypeInt, | ||
Required: true, | ||
}, | ||
tagsKey: tagsSchema, | ||
customFieldsKey: customFieldsSchema, | ||
}, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: schema.ImportStatePassthroughContext, | ||
}, | ||
} | ||
} | ||
|
||
func resourceNetboxVirtualDisksCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
api := m.(*client.NetBoxAPI) | ||
|
||
name := d.Get("name").(string) | ||
size := d.Get("size").(int) | ||
virtualMachineID := d.Get("virtual_machine_id").(int) | ||
|
||
data := models.WritableVirtualDisk{ | ||
Name: &name, | ||
Size: int64ToPtr(int64(size)), | ||
VirtualMachine: int64ToPtr(int64(virtualMachineID)), | ||
} | ||
|
||
descriptionValue, ok := d.GetOk("description") | ||
if ok { | ||
description := descriptionValue.(string) | ||
data.Description = description | ||
} | ||
|
||
ct, ok := d.GetOk(customFieldsKey) | ||
if ok { | ||
data.CustomFields = ct | ||
} | ||
|
||
data.Tags, _ = getNestedTagListFromResourceDataSet(api, d.Get(tagsKey)) | ||
|
||
params := virtualization.NewVirtualizationVirtualDisksCreateParams().WithData(&data) | ||
|
||
res, err := api.Virtualization.VirtualizationVirtualDisksCreate(params, nil) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.SetId(strconv.FormatInt(res.GetPayload().ID, 10)) | ||
|
||
return resourceNetboxVirtualDisksRead(ctx, d, m) | ||
} | ||
|
||
func resourceNetboxVirtualDisksRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
api := m.(*client.NetBoxAPI) | ||
|
||
id, _ := strconv.ParseInt(d.Id(), 10, 64) | ||
|
||
params := virtualization.NewVirtualizationVirtualDisksReadParams().WithID(id) | ||
|
||
res, err := api.Virtualization.VirtualizationVirtualDisksRead(params, nil) | ||
if err != nil { | ||
if errresp, ok := err.(*virtualization.VirtualizationVirtualDisksReadDefault); ok { | ||
errorcode := errresp.Code() | ||
if errorcode == 404 { | ||
d.SetId("") | ||
return nil | ||
} | ||
} | ||
return diag.FromErr(err) | ||
} | ||
|
||
VirtualDisks := res.GetPayload() | ||
|
||
d.Set("name", VirtualDisks.Name) | ||
d.Set("description", VirtualDisks.Description) | ||
|
||
if VirtualDisks.Size != nil { | ||
d.Set("size", *VirtualDisks.Size) | ||
} | ||
if VirtualDisks.VirtualMachine != nil { | ||
d.Set("virtual_machine_id", VirtualDisks.VirtualMachine.ID) | ||
} | ||
|
||
cf := getCustomFields(res.GetPayload().CustomFields) | ||
if cf != nil { | ||
d.Set(customFieldsKey, cf) | ||
} | ||
|
||
d.Set(tagsKey, getTagListFromNestedTagList(VirtualDisks.Tags)) | ||
return nil | ||
} | ||
|
||
func resourceNetboxVirtualDisksUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
api := m.(*client.NetBoxAPI) | ||
|
||
id, _ := strconv.ParseInt(d.Id(), 10, 64) | ||
data := models.WritableVirtualDisk{} | ||
|
||
name := d.Get("name").(string) | ||
size := int64(d.Get("size").(int)) | ||
virtualMachineID := int64(d.Get("virtual_machine_id").(int)) | ||
|
||
data.Name = &name | ||
data.Size = &size | ||
data.VirtualMachine = &virtualMachineID | ||
|
||
ct, ok := d.GetOk(customFieldsKey) | ||
if ok { | ||
data.CustomFields = ct | ||
} | ||
|
||
data.Tags, _ = getNestedTagListFromResourceDataSet(api, d.Get(tagsKey)) | ||
|
||
if d.HasChanges("description") { | ||
// check if description is set | ||
if descriptionValue, ok := d.GetOk("description"); ok { | ||
data.Description = descriptionValue.(string) | ||
} else { | ||
data.Description = " " | ||
} | ||
} | ||
|
||
params := virtualization.NewVirtualizationVirtualDisksUpdateParams().WithID(id).WithData(&data) | ||
|
||
_, err := api.Virtualization.VirtualizationVirtualDisksUpdate(params, nil) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return resourceNetboxVirtualDisksRead(ctx, d, m) | ||
} | ||
|
||
func resourceNetboxVirtualDisksDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
api := m.(*client.NetBoxAPI) | ||
|
||
id, _ := strconv.ParseInt(d.Id(), 10, 64) | ||
params := virtualization.NewVirtualizationVirtualDisksDeleteParams().WithID(id) | ||
|
||
_, err := api.Virtualization.VirtualizationVirtualDisksDelete(params, nil) | ||
if err != nil { | ||
if errresp, ok := err.(*virtualization.VirtualizationVirtualDisksDeleteDefault); ok { | ||
if errresp.Code() == 404 { | ||
d.SetId("") | ||
return nil | ||
} | ||
} | ||
return diag.FromErr(err) | ||
} | ||
|
||
return nil | ||
} |
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,105 @@ | ||
package netbox | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"testing" | ||
|
||
"github.com/fbreckle/go-netbox/netbox/client" | ||
"github.com/fbreckle/go-netbox/netbox/client/virtualization" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
func TestAccNetboxVirtualDisk_basic(t *testing.T) { | ||
testSlug := "virtual_disk" | ||
testName := testAccGetTestName(testSlug) | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckVirtualDiskDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: fmt.Sprintf(` | ||
resource "netbox_tag" "tag_a" { | ||
name = "[%[1]s_a]" | ||
color_hex = "123456" | ||
} | ||
resource "netbox_site" "test" { | ||
name = "%[1]s" | ||
status = "active" | ||
} | ||
resource "netbox_virtual_machine" "test" { | ||
name = "%[1]s" | ||
site_id = netbox_site.test.id | ||
} | ||
resource "netbox_virtual_disk" "test" { | ||
name = "%[1]s" | ||
description = "description" | ||
size = 30 | ||
virtual_machine_id = netbox_virtual_machine.test.id | ||
tags = [netbox_tag.tag_a.name] | ||
} | ||
`, testName), | ||
}, | ||
{ | ||
Config: fmt.Sprintf(` | ||
resource "netbox_tag" "tag_a" { | ||
name = "[%[1]s_a]" | ||
color_hex = "123456" | ||
} | ||
resource "netbox_site" "test" { | ||
name = "%[1]s" | ||
status = "active" | ||
} | ||
resource "netbox_virtual_machine" "test" { | ||
name = "%[1]s" | ||
site_id = netbox_site.test.id | ||
} | ||
resource "netbox_virtual_disk" "test" { | ||
name = "%[1]s_updated" | ||
description = "description updated" | ||
size = 60 | ||
virtual_machine_id = netbox_virtual_machine.test.id | ||
tags = [netbox_tag.tag_a.name] | ||
} | ||
`, testName), | ||
}, | ||
{ | ||
ResourceName: "netbox_virtual_disk.test", | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckVirtualDiskDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*client.NetBoxAPI) | ||
|
||
// loop through the resources in state, verifying each virtual machine | ||
// is destroyed | ||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "netbox_virtual_disk" { | ||
continue | ||
} | ||
|
||
stateID, _ := strconv.ParseInt(rs.Primary.ID, 10, 64) | ||
params := virtualization.NewVirtualizationVirtualDisksReadParams().WithID(stateID) | ||
_, err := conn.Virtualization.VirtualizationVirtualDisksRead(params, nil) | ||
|
||
if err == nil { | ||
return fmt.Errorf("virtual disk (%s) still exists", rs.Primary.ID) | ||
} | ||
|
||
if errresp, ok := err.(*virtualization.VirtualizationVirtualDisksReadDefault); ok { | ||
errorcode := errresp.Code() | ||
if errorcode == 404 { | ||
return nil | ||
} | ||
} | ||
return err | ||
} | ||
return nil | ||
} |
Oops, something went wrong.