diff --git a/.github/scripts/oned.sh b/.github/scripts/oned.sh index 2bfe24e6c..63a8e1819 100755 --- a/.github/scripts/oned.sh +++ b/.github/scripts/oned.sh @@ -28,7 +28,7 @@ sed '/DATASTORE_MAD/,+3 d' -i /etc/one/oned.conf echo 'IM_MAD = [ NAME="dummy", SUNSTONE_NAME="Dummy", EXECUTABLE="one_im_sh", ARGUMENTS="-r 3 -t 15 -w 90 dummy", THREADS=0]' >> /etc/one/monitord.conf echo 'VM_MAD = [ NAME="dummy", SUNSTONE_NAME="Testing", EXECUTABLE="one_vmm_dummy",TYPE="xml" ]' >> /etc/one/oned.conf echo 'DATASTORE_MAD = [ EXECUTABLE = "one_datastore", ARGUMENTS = "-t 15 -d dummy,fs,lvm,ceph,dev,iscsi_libvirt,vcenter -s dummy,shared,ssh,ceph,fs_lvm,fs_lvm_ssh,qcow2,vcenter"]' >> /etc/one/oned.conf - +echo 'INHERIT_VNET_ATTR = "DNS"' >> /etc/one/oned.conf # start oned sudo systemctl start opennebula diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ce34a423..aaaaaf767 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FEATURES: * resources/opennebula_virtual_network: allow to modify the user owning the resource (#529) * resources/opennebula_virtual_machine: add nil checks before type casting (#530) * resources/opennebula_virtual_router_nic: add floating_only nic argument (#547) +* resources/opennebula_virtual_machine: add method, gateway, dns arguments for nics (#548) ENHANCEMENTS: diff --git a/opennebula/resource_opennebula_virtual_machine.go b/opennebula/resource_opennebula_virtual_machine.go index 8efbe5fde..0d6c5df30 100644 --- a/opennebula/resource_opennebula_virtual_machine.go +++ b/opennebula/resource_opennebula_virtual_machine.go @@ -104,6 +104,18 @@ func nicComputedVMFields() map[string]*schema.Schema { Type: schema.TypeInt, }, }, + "computed_method": { + Type: schema.TypeString, + Computed: true, + }, + "computed_gateway": { + Type: schema.TypeString, + Computed: true, + }, + "computed_dns": { + Type: schema.TypeString, + Computed: true, + }, } } @@ -876,6 +888,10 @@ func flattenNICComputed(nic shared.NIC, ignoreSGIDs []int) map[string]interface{ sg = append(sg, int(sgInt)) } + method, _ := nic.Get(shared.Method) + gateway, _ := nic.Get(shared.Gateway) + dns, _ := nic.Get(shared.DNS) + return map[string]interface{}{ "nic_id": nicID, "network": network, @@ -885,6 +901,9 @@ func flattenNICComputed(nic shared.NIC, ignoreSGIDs []int) map[string]interface{ "computed_model": model, "computed_virtio_queues": virtioQueues, "computed_security_groups": sg, + "computed_method": method, + "computed_gateway": gateway, + "computed_dns": dns, } } @@ -910,6 +929,15 @@ func flattenVMNICComputed(NICConfig map[string]interface{}, NIC shared.NIC) map[ if len(NICConfig["security_groups"].([]interface{})) > 0 { NICMap["security_groups"] = NICMap["computed_security_groups"] } + if len(NICConfig["method"].(string)) > 0 { + NICMap["method"] = NICMap["computed_method"] + } + if len(NICConfig["gateway"].(string)) > 0 { + NICMap["gateway"] = NICMap["computed_gateway"] + } + if len(NICConfig["dns"].(string)) > 0 { + NICMap["dns"] = NICMap["computed_dns"] + } networkMode, err := NIC.Get(shared.NetworkMode) if err == nil && networkMode == "auto" { @@ -1000,11 +1028,18 @@ func matchNIC(NICConfig map[string]interface{}, NIC shared.NIC) bool { } + method, _ := NIC.Get(shared.Method) + gateway, _ := NIC.Get(shared.Gateway) + dns, _ := NIC.Get(shared.DNS) + return emptyOrEqual(NICConfig["ip"], ip) && emptyOrEqual(NICConfig["mac"], mac) && emptyOrEqual(NICConfig["physical_device"], physicalDevice) && emptyOrEqual(NICConfig["model"], model) && emptyOrEqual(NICConfig["virtio_queues"], virtioQueues) && + emptyOrEqual(NICConfig["method"], method) && + emptyOrEqual(NICConfig["gateway"], gateway) && + emptyOrEqual(NICConfig["dns"], dns) && emptyOrEqual(NICConfig["sched_requirements"], schedRequirements) && emptyOrEqual(NICConfig["sched_rank"], schedRank) && (NICConfig["network_mode_auto"].(bool) == false || networkMode == "auto") @@ -1036,11 +1071,18 @@ func matchNICComputed(NICConfig map[string]interface{}, NIC shared.NIC) bool { } } + method, _ := NIC.Get(shared.Method) + gateway, _ := NIC.Get(shared.Gateway) + dns, _ := NIC.Get(shared.DNS) + return ip == NICConfig["computed_ip"].(string) && mac == NICConfig["computed_mac"].(string) && physicalDevice == NICConfig["computed_physical_device"].(string) && model == NICConfig["computed_model"].(string) && - virtioQueues == NICConfig["computed_virtio_queues"].(string) + virtioQueues == NICConfig["computed_virtio_queues"].(string) && + method == NICConfig["computed_method"].(string) && + gateway == NICConfig["computed_gateway"].(string) && + dns == NICConfig["computed_dns"].(string) } // flattenVMNIC is similar to flattenNIC but deal with computed_* attributes @@ -1900,6 +1942,9 @@ func updateNIC(ctx context.Context, d *schema.ResourceData, meta interface{}) er "model", "virtio_queues", "physical_device", + "method", + "gateway", + "dns", "network_mode_auto", "sched_requirements", "sched_rank", diff --git a/opennebula/resource_opennebula_virtual_machine_nic_test.go b/opennebula/resource_opennebula_virtual_machine_nic_test.go index 14b7fcebd..52603e98e 100644 --- a/opennebula/resource_opennebula_virtual_machine_nic_test.go +++ b/opennebula/resource_opennebula_virtual_machine_nic_test.go @@ -52,9 +52,23 @@ func TestAccVirtualMachineNICUpdate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"), resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.#", "2"), resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_ip", "172.16.100.131"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_gateway", "172.16.100.1"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_dns", "8.8.8.8"), resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.1.computed_ip", "172.16.100.112"), ), }, + { + Config: testAccVirtualMachineTemplateConfigNICExtraUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.#", "2"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_ip", "172.16.100.131"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_gateway", "172.16.100.254"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.0.computed_dns", "1.1.1.1"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.1.computed_ip", "172.16.100.112"), + resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "nic.1.computed_method", "skip"), + ), + }, { Config: testAccVirtualMachineTemplateConfigMultipleNICs, Check: resource.ComposeTestCheckFunc( @@ -210,6 +224,8 @@ resource "opennebula_virtual_network" "network1" { group = "oneadmin" security_groups = [0] cluster_ids = [0] + gateway = "172.16.100.1" + dns = "8.8.8.8" } resource "opennebula_virtual_network" "network2" { @@ -321,23 +337,23 @@ var testAccVirtualMachineTemplateConfigNICUpdate = testNICVNetResources + ` permissions = "642" memory = 128 cpu = 0.1 - + context = { NETWORK = "YES" SET_HOSTNAME = "$NAME" } - + graphics { type = "VNC" listen = "0.0.0.0" keymap = "en-us" } - + os { arch = "x86_64" boot = "" } - + tags = { env = "prod" customer = "test" @@ -352,7 +368,7 @@ var testAccVirtualMachineTemplateConfigNICUpdate = testNICVNetResources + ` network_id = opennebula_virtual_network.network2.id ip = "172.16.100.111" } - + timeout = 5 } ` @@ -365,23 +381,23 @@ var testAccVirtualMachineTemplateConfigNICIPUpdate = testNICVNetResources + ` permissions = "642" memory = 128 cpu = 0.1 - + context = { NETWORK = "YES" SET_HOSTNAME = "$NAME" } - + graphics { type = "VNC" listen = "0.0.0.0" keymap = "en-us" } - + os { arch = "x86_64" boot = "" } - + tags = { env = "prod" customer = "test" @@ -397,6 +413,52 @@ var testAccVirtualMachineTemplateConfigNICIPUpdate = testNICVNetResources + ` ip = "172.16.100.112" } + timeout = 5 +} +` + +var testAccVirtualMachineTemplateConfigNICExtraUpdate = testNICVNetResources + ` + + resource "opennebula_virtual_machine" "test" { + name = "test-virtual_machine" + group = "oneadmin" + permissions = "642" + memory = 128 + cpu = 0.1 + + context = { + NETWORK = "YES" + SET_HOSTNAME = "$NAME" + } + + graphics { + type = "VNC" + listen = "0.0.0.0" + keymap = "en-us" + } + + os { + arch = "x86_64" + boot = "" + } + + tags = { + env = "prod" + customer = "test" + } + + nic { + network_id = opennebula_virtual_network.network1.id + ip = "172.16.100.131" + security_groups = [opennebula_security_group.mysecgroup.id] + gateway = "172.16.100.254" + dns = "1.1.1.1" + } + nic { + network_id = opennebula_virtual_network.network2.id + ip = "172.16.100.112" + method = "skip" # IP is assigned normally in oned, but then one-context ignores it. + } timeout = 5 } diff --git a/opennebula/shared_schemas.go b/opennebula/shared_schemas.go index 18be3513d..e47b47e41 100644 --- a/opennebula/shared_schemas.go +++ b/opennebula/shared_schemas.go @@ -225,6 +225,18 @@ func nicFields() map[string]*schema.Schema { Type: schema.TypeInt, }, }, + "method": { + Type: schema.TypeString, + Optional: true, + }, + "gateway": { + Type: schema.TypeString, + Optional: true, + }, + "dns": { + Type: schema.TypeString, + Optional: true, + }, "network_mode_auto": { Type: schema.TypeBool, Optional: true, @@ -584,6 +596,12 @@ func makeNICVector(nicConfig map[string]interface{}) *shared.NIC { case "security_groups": nicSecGroups := ArrayToString(v.([]interface{}), ",") nic.Add(shared.SecurityGroups, nicSecGroups) + case "method": + nic.Add(shared.Method, v.(string)) + case "gateway": + nic.Add(shared.Gateway, v.(string)) + case "dns": + nic.Add(shared.DNS, v.(string)) case "network_mode_auto": if v.(bool) { nic.Add(shared.NetworkMode, "auto") @@ -592,7 +610,6 @@ func makeNICVector(nicConfig map[string]interface{}) *shared.NIC { nic.Add(shared.SchedRequirements, v.(string)) case "sched_rank": nic.Add(shared.SchedRank, v.(string)) - } } @@ -857,6 +874,10 @@ func flattenNIC(nic shared.NIC) map[string]interface{} { } } + method, _ := nic.Get(shared.Method) + gateway, _ := nic.Get(shared.Gateway) + dns, _ := nic.Get(shared.DNS) + return map[string]interface{}{ "ip": ip, "mac": mac, @@ -866,6 +887,9 @@ func flattenNIC(nic shared.NIC) map[string]interface{} { "model": model, "virtio_queues": virtioQueues, "security_groups": sg, + "method": method, + "gateway": gateway, + "dns": dns, "network_mode_auto": networkModeBool, "sched_requirements": schedReqs, "sched_rank": schedRank, diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown index 3d3d6ae61..0b78586ca 100644 --- a/website/docs/r/virtual_machine.html.markdown +++ b/website/docs/r/virtual_machine.html.markdown @@ -57,6 +57,9 @@ resource "opennebula_virtual_machine" "example" { model = "virtio" network_id = var.vnetid security_groups = [opennebula_security_group.example.id] + + # NOTE: To make this work properly ensure /etc/one/oned.conf contains: INHERIT_VNET_ATTR="DNS" + dns = "1.1.1.1" } vmgroup { @@ -153,6 +156,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. +* `method` - (Optional) Method of obtaining IP addresses (empty or `static`, `dhcp`, `skip`). +* `gateway` - (Optional) Default gateway set for the NIC. +* `dns` - (Optional) DNS server set for the NIC. **Please make sure `INHERIT_VNET_ATTR="DNS"` is added to `/etc/one/oned.conf`.** * `network_mode_auto` - (Optional) A boolean letting the scheduler pick the Virtual Networks the VM NICs will be attached to. Can only be used at VM creation. * `sched_requirements` - (Optional) A boolean expression to select virtual networks (evaluates to true) to attach the NIC, when `network_mode_auto` is true. Can only be used at VM creation. * `sched_rank` - (Optional) Arithmetic expression to sort the suitable Virtual Networks for this NIC, when `network_mode_auto` is true. Can only be used at VM creation. @@ -211,6 +217,9 @@ The following attribute are exported: * `computed_virtio_queues` - Virtio multi-queue size. * `computed_physical_device` - Physical device hosting the virtual network. * `computed_security_groups` - List of security group IDs to use on the virtual. +* `computed_method` - Method of obtaining IP addresses (empty or `static`, `dhcp`, `skip`). +* `computed_gateway` - Default gateway set for the NIC. +* `computed_dns` - DNS server set for the NIC. ### Template disk @@ -230,6 +239,9 @@ The following attribute are exported: * `computed_virtio_queues` - Virtio multi-queue size. * `computed_physical_device` - Physical device hosting the virtual network. * `computed_security_groups` - List of security group IDs to use on the virtual. +* `computed_method` - Method of obtaining IP addresses (empty or `static`, `dhcp`, `skip`). +* `computed_gateway` - Default gateway set for the NIC. +* `computed_dns` - DNS server set for the NIC. ### Disk