Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions cloudstack/resource_cloudstack_nic.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func resourceCloudStackNIC() *schema.Resource {
Create: resourceCloudStackNICCreate,
Read: resourceCloudStackNICRead,
Delete: resourceCloudStackNICDelete,
Importer: &schema.ResourceImporter{
State: importStateNIC,
},

Schema: map[string]*schema.Schema{
"network_id": {
Expand All @@ -59,6 +62,12 @@ func resourceCloudStackNIC() *schema.Resource {
Computed: true,
ForceNew: true,
},

"project": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
}
}
Expand Down Expand Up @@ -107,8 +116,13 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error
func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)

// Get the virtual machine details
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(d.Get("virtual_machine_id").(string))
// Get the virtual machine details. Instances that belong to a project are
// not returned by listVirtualMachines unless the project is passed along,
// so scope the lookup the same way the instance resource does.
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(
d.Get("virtual_machine_id").(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if err != nil {
if count == 0 {
log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine_id").(string))
Expand Down Expand Up @@ -165,6 +179,30 @@ func resourceCloudStackNICDelete(d *schema.ResourceData, meta interface{}) error
return nil
}

// importStateNIC imports a NIC using "<virtual_machine_id>/<nic_id>", or
// "<project>/<virtual_machine_id>/<nic_id>" when the instance belongs to a
// project. The parent instance cannot be derived from the NIC ID alone, so the
// generic passthrough importer is not usable here.
func importStateNIC(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
s := strings.Split(d.Id(), "/")

switch len(s) {
case 2:
d.Set("virtual_machine_id", s[0])
d.SetId(s[1])
case 3:
d.Set("project", s[0])
d.Set("virtual_machine_id", s[1])
d.SetId(s[2])
default:
return nil, fmt.Errorf(
"invalid import ID %q, expected <virtual_machine_id>/<nic_id> or "+
"<project>/<virtual_machine_id>/<nic_id>", d.Id())
}

return []*schema.ResourceData{d}, nil
}

func retryableAddNicFunc(cs *cloudstack.CloudStackClient, p *cloudstack.AddNicToVirtualMachineParams) func() (interface{}, error) {
return func() (interface{}, error) {
r, err := cs.VirtualMachine.AddNicToVirtualMachine(p)
Expand Down
19 changes: 19 additions & 0 deletions website/docs/r/nic.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,29 @@ The following arguments are supported:
* `virtual_machine_id` - (Required) The ID of the virtual machine to which to
attach the NIC. Changing this forces a new resource to be created.

* `project` - (Optional) The name or ID of the project the virtual machine
belongs to. Required when the virtual machine belongs to a project,
otherwise the NIC cannot be read back. Changing this forces a new resource
to be created.

## Attributes Reference

The following attributes are exported:

* `id` - The ID of the NIC.
* `ip_address` - The assigned IP address.
* `mac_address` - The assigned MAC address.

## Import

NICs can be imported using `<virtual_machine_id>/<nic_id>`, e.g.

```shell
$ terraform import cloudstack_nic.test f8141e2f-4e7e-4c63-9362-986c908b7ea7/2b1a4b3c-5d6e-4f70-8192-a3b4c5d6e7f8
```

When the virtual machine belongs to a project, prefix the project:

```shell
$ terraform import cloudstack_nic.test my-project/f8141e2f-4e7e-4c63-9362-986c908b7ea7/2b1a4b3c-5d6e-4f70-8192-a3b4c5d6e7f8
```