Skip to content

Commit

Permalink
F #477: add nic attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
treywelsh authored and frousselet committed Jan 16, 2024
1 parent 1d1d50d commit a7ed71b
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 30 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ FEATURES:
* **New Data Source**: `opennebula_marketplace_appliance` (#476)
* resources/opennebula_virtual_router_nic: add floating IP allocation (#510)

ENHANCEMENTS:

* resources/opennebula_virtual_machine: add `nic` scheduling attributes: `network_mode_auto`, `sched_requirements`, `sched_rank`. (#477)
* resources/opennebula_template: add `nic` scheduling attributes: `network_mode_auto`, `sched_requirements`, `sched_rank`. (#477)

BUG FIXES:

* resources/opennebula_virtual_machine: fix `cpumodel` update (#463)
Expand Down
35 changes: 27 additions & 8 deletions opennebula/helpers_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,19 @@ func vmDiskResize(ctx context.Context, vmc *goca.VMController, timeout time.Dura
// vmNICAttach is an helper that synchronously attach a nic
func vmNICAttach(ctx context.Context, vmc *goca.VMController, timeout time.Duration, nicTpl *shared.NIC) (int, error) {

networkID, err := nicTpl.GetI(shared.NetworkID)
if err != nil {
return -1, fmt.Errorf("NIC template doesn't have a network ID")
isNetworkMode := false
networkMode, netModeErr := nicTpl.Get(shared.NetworkMode)
networkID, netIDErr := nicTpl.GetI(shared.NetworkID)
if netIDErr == nil {
log.Printf("[DEBUG] Attach NIC to network (ID:%d)", networkID)
} else {
if netModeErr != nil {
return -1, fmt.Errorf("NIC template neither have a network ID or a network mode")
}
log.Printf("[DEBUG] Attach NIC with network mode %s", networkMode)
isNetworkMode = true
}

log.Printf("[DEBUG] Attach NIC to network (ID:%d)", networkID)

// Retrieve NIC list
vm, err := vmc.Info(false)
if err != nil {
Expand All @@ -237,7 +243,11 @@ func vmNICAttach(ctx context.Context, vmc *goca.VMController, timeout time.Durat

err = vmc.AttachNIC(nicTpl.String())
if err != nil {
return -1, fmt.Errorf("can't attach network with ID:%d: %s\n", networkID, err)
if isNetworkMode {
return -1, fmt.Errorf("can't attach NIC (mode:%s): %s\n", networkMode, err)
} else {
return -1, fmt.Errorf("can't attach network (ID:%d): %s\n", networkID, err)
}
}

// wait before checking NIC list
Expand Down Expand Up @@ -277,7 +287,11 @@ func vmNICAttach(ctx context.Context, vmc *goca.VMController, timeout time.Durat

vmerr, _ := vm.UserTemplate.Get(vmk.Error)

return -1, fmt.Errorf("network %d: %s", networkID, vmerr)
if isNetworkMode {
return -1, fmt.Errorf("network (mode:%s): %s\n", networkMode, vmerr)
} else {
return -1, fmt.Errorf("network (ID:%d): %s", networkID, vmerr)
}

} else {

Expand Down Expand Up @@ -314,7 +328,12 @@ func vmNICAttach(ctx context.Context, vmc *goca.VMController, timeout time.Durat
break
}
if attachedNIC == nil {
return -1, fmt.Errorf("network %d: can't find the nic", networkID)

if isNetworkMode {
return -1, fmt.Errorf("network (mode %s): can't find the NIC\n", networkMode)
} else {
return -1, fmt.Errorf("network (ID:%d): can't find the NIC", networkID)
}
}
}

Expand Down
39 changes: 35 additions & 4 deletions opennebula/resource_opennebula_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,21 @@ func flattenVMNICComputed(NICConfig map[string]interface{}, NIC shared.NIC) map[
NICMap["security_groups"] = NICMap["computed_security_groups"]
}

networkMode, err := NIC.Get(shared.NetworkMode)
if err == nil && networkMode == "auto" {
NICMap["network_mode_auto"] = true
}

schedReqs, err := NIC.Get(shared.SchedRequirements)
if err == nil {
NICMap["sched_requirements"] = schedReqs
}

schedRank, err := NIC.Get(shared.SchedRank)
if err == nil {
NICMap["sched_rank"] = schedRank
}

return NICMap
}

Expand Down Expand Up @@ -940,6 +955,10 @@ func matchNIC(NICConfig map[string]interface{}, NIC shared.NIC) bool {

model, _ := NIC.Get(shared.Model)
virtioQueues, _ := NIC.GetStr("VIRTIO_QUEUES")
schedRequirements, _ := NIC.Get(shared.SchedRequirements)
schedRank, _ := NIC.Get(shared.SchedRank)
networkMode, _ := NIC.Get(shared.NetworkMode)

securityGroupsArray, _ := NIC.Get(shared.SecurityGroups)

if NICConfig["security_groups"] != nil && len(NICConfig["security_groups"].([]interface{})) > 0 {
Expand Down Expand Up @@ -976,7 +995,10 @@ func matchNIC(NICConfig map[string]interface{}, NIC shared.NIC) bool {
emptyOrEqual(NICConfig["mac"], mac) &&
emptyOrEqual(NICConfig["physical_device"], physicalDevice) &&
emptyOrEqual(NICConfig["model"], model) &&
emptyOrEqual(NICConfig["virtio_queues"], virtioQueues)
emptyOrEqual(NICConfig["virtio_queues"], virtioQueues) &&
emptyOrEqual(NICConfig["sched_requirements"], schedRequirements) &&
emptyOrEqual(NICConfig["sched_rank"], schedRank) &&
(NICConfig["network_mode_auto"].(bool) == false || networkMode == "auto")
}

func matchNICComputed(NICConfig map[string]interface{}, NIC shared.NIC) bool {
Expand Down Expand Up @@ -1051,8 +1073,13 @@ NICLoop:
match = true
nicMap = flattenVMNICComputed(nicConfig, nic)

networkID, _ := nic.GetI(shared.NetworkID)
nicMap["network_id"] = networkID
networkIDCfg := nicConfig["network_id"].(int)
if networkIDCfg == -1 {
nicMap["network_id"] = -1
} else {
networkID, _ := nic.GetI(shared.NetworkID)
nicMap["network_id"] = networkID
}

nicList = append(nicList, nicMap)

Expand Down Expand Up @@ -1863,7 +1890,11 @@ func updateNIC(ctx context.Context, d *schema.ResourceData, meta interface{}) er
"security_groups",
"model",
"virtio_queues",
"physical_device")
"physical_device",
"network_mode_auto",
"sched_requirements",
"sched_rank",
)

// in case of NICs updated in the middle of the NIC list
// they would be reattached at the end of the list (we don't have in place XML-RPC update method).
Expand Down
23 changes: 16 additions & 7 deletions opennebula/resource_opennebula_virtual_machine_nic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,23 @@ func TestAccVirtualMachineNICUpdate(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "keep_nic_order", "false"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.#", "4"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.#", "5"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_ip", "172.16.100.112"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.1.computed_ip", "172.16.100.132"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.2.computed_ip", "172.16.100.113"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.3.computed_ip", "172.16.100.133"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.4.computed_ip", "172.16.100.133"),
),
},
{
Config: testAccVirtualMachineTemplateConfigMultipleNICsOrderedUpdate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "keep_nic_order", "true"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.#", "4"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.#", "5"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_ip", "172.16.100.112"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.1.computed_ip", "172.16.100.134"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.2.computed_ip", "172.16.100.113"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.3.computed_ip", "172.16.100.133"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.4.computed_ip", "172.16.100.133"),
),
},
{
Expand Down Expand Up @@ -105,7 +105,7 @@ func TestAccVirtualMachineTemplateNIC(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccSetDSdummy(),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.#", "2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_ip", "172.16.100.131"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_model", "virtio"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_virtio_queues", "2"),
Expand All @@ -116,7 +116,7 @@ func TestAccVirtualMachineTemplateNIC(t *testing.T) {
Config: testAccVirtualMachineTemplateNICAdd,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.#", "2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_ip", "172.16.100.131"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_model", "virtio"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_virtio_queues", "2"),
Expand All @@ -130,7 +130,7 @@ func TestAccVirtualMachineTemplateNIC(t *testing.T) {
Config: testAccVirtualMachineTemplateNIC,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.#", "2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_ip", "172.16.100.131"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_model", "virtio"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "template_nic.0.computed_virtio_queues", "2"),
Expand Down Expand Up @@ -445,6 +445,9 @@ var testAccVirtualMachineTemplateConfigMultipleNICs = testNICVNetResources + `
network_id = opennebula_virtual_network.network2.id
ip = "172.16.100.113"
}
nic {
network_mode_auto = true
}
nic {
network_id = opennebula_virtual_network.network1.id
ip = "172.16.100.133"
Expand Down Expand Up @@ -497,6 +500,9 @@ var testAccVirtualMachineTemplateConfigMultipleNICsOrderedUpdate = testNICVNetRe
network_id = opennebula_virtual_network.network2.id
ip = "172.16.100.113"
}
nic {
network_mode_auto = true
}
nic {
network_id = opennebula_virtual_network.network1.id
ip = "172.16.100.133"
Expand Down Expand Up @@ -568,6 +574,9 @@ resource "opennebula_template" "template" {
model = "virtio"
virtio_queues = "2"
}
nic {
network_mode_auto = true
}
os {
arch = "x86_64"
Expand Down
59 changes: 48 additions & 11 deletions opennebula/shared_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ func nicFields() map[string]*schema.Schema {
},
"network_id": {
Type: schema.TypeInt,
Required: true,
Optional: true,
Default: -1,
},
"network": {
Type: schema.TypeString,
Expand All @@ -224,6 +225,18 @@ func nicFields() map[string]*schema.Schema {
Type: schema.TypeInt,
},
},
"network_mode_auto": {
Type: schema.TypeBool,
Optional: true,
},
"sched_requirements": {
Type: schema.TypeString,
Optional: true,
},
"sched_rank": {
Type: schema.TypeString,
Optional: true,
},
}
}

Expand Down Expand Up @@ -536,7 +549,10 @@ func makeNICVector(nicConfig map[string]interface{}) *shared.NIC {
for k, v := range nicConfig {

if k == "network_id" {
nic.Add(shared.NetworkID, strconv.Itoa(v.(int)))
networkID := v.(int)
if networkID != -1 {
nic.Add(shared.NetworkID, strconv.Itoa(networkID))
}
continue
}

Expand All @@ -558,6 +574,15 @@ func makeNICVector(nicConfig map[string]interface{}) *shared.NIC {
case "security_groups":
nicSecGroups := ArrayToString(v.([]interface{}), ",")
nic.Add(shared.SecurityGroups, nicSecGroups)
case "network_mode_auto":
if v.(bool) {
nic.Add(shared.NetworkMode, "auto")
}
case "sched_requirements":
nic.Add(shared.SchedRequirements, v.(string))
case "sched_rank":
nic.Add(shared.SchedRank, v.(string))

}
}

Expand Down Expand Up @@ -774,8 +799,17 @@ func flattenNIC(nic shared.NIC) map[string]interface{} {
model, _ := nic.Get(shared.Model)
virtioQueues, _ := nic.GetStr("VIRTIO_QUEUES")
networkId, _ := nic.GetI(shared.NetworkID)
securityGroupsArray, _ := nic.Get(shared.SecurityGroups)

networkModeBool := false
networkMode, err := nic.Get(shared.NetworkMode)
if err == nil && networkMode == "auto" {
networkModeBool = true
}

schedReqs, _ := nic.Get(shared.SchedRequirements)
schedRank, _ := nic.Get(shared.SchedRank)

securityGroupsArray, _ := nic.Get(shared.SecurityGroups)
if len(securityGroupsArray) > 0 {
sgString := strings.Split(securityGroupsArray, ",")
for _, s := range sgString {
Expand All @@ -785,14 +819,17 @@ func flattenNIC(nic shared.NIC) map[string]interface{} {
}

return map[string]interface{}{
"ip": ip,
"mac": mac,
"network_id": networkId,
"physical_device": physicalDevice,
"network": network,
"model": model,
"virtio_queues": virtioQueues,
"security_groups": sg,
"ip": ip,
"mac": mac,
"network_id": networkId,
"physical_device": physicalDevice,
"network": network,
"model": model,
"virtio_queues": virtioQueues,
"security_groups": sg,
"network_mode_auto": networkModeBool,
"sched_requirements": schedReqs,
"sched_rank": schedRank,
}
}

Expand Down
3 changes: 3 additions & 0 deletions website/docs/r/template.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ Minimum 1 item. Maximum 8 items.
* `model` - (Optional) Nic model driver. Example: `virtio`.
* `physical_device` - (Optional) Physical device hosting the virtual network.
* `security_groups` - (Optional) List of security group IDs to use on the virtual network.
* `network_mode_auto` - (Optional) A boolean letting the scheduler pick the Virtual Networks the VM NICs will be attached to.
* `sched_requirements` - (Optional) A boolean expression to select virtual networks (evaluates to true) to attach the NIC.
* `sched_rank` - (Optional) Arithmetic expression to sort the suitable Virtual Networks for this NIC.

Minimum 1 item. Maximum 8 items.

Expand Down
3 changes: 3 additions & 0 deletions website/docs/r/virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ A disk update will be triggered in adding or removing a `disk` section, or by a
* `virtio_queues` - (Optional) Virtio multi-queue size. Only if `model` is `virtio`.
* `physical_device` - (Optional) Physical device hosting the virtual network.
* `security_groups` - (Optional) List of security group IDs to use on the virtual network.
* `network_mode_auto` - (Optional) A boolean letting the scheduler pick the Virtual Networks the VM NICs will be attached to.
* `sched_requirements` - (Optional) A boolean expression to select virtual networks (evaluates to true) to attach the NIC.
* `sched_rank` - (Optional) Arithmetic expression to sort the suitable Virtual Networks for this NIC.

Minimum 1 item. Maximum 8 items.

Expand Down

0 comments on commit a7ed71b

Please sign in to comment.