github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/vm_dhcp_test.go (about)

     1  //go:build nsxv || vm || functional || ALL
     2  
     3  /*
     4   * Copyright 2020 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     5   */
     6  
     7  package govcd
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    13  	. "gopkg.in/check.v1"
    14  )
    15  
    16  // Test_VMGetDhcpAddress proves that it is possible to wait until DHCP lease is acquired by VM and
    17  // report the IP even if VM does not have guest tools installed.
    18  // The test does below actions:
    19  // 1. Creates VM
    20  // 2. Ensures there is a DHCP configuration for network
    21  // 3. Powers off VM
    22  // 4. Sets VM network adapter to use DHCP
    23  // 5. Powers on VM and checks for a DHCP lease assigned to VM
    24  // 6. Cleans up
    25  func (vcd *TestVCD) Test_VMGetDhcpAddress(check *C) {
    26  	if vcd.config.VCD.EdgeGateway == "" {
    27  		check.Skip("Skipping test because no edge gateway given")
    28  	}
    29  
    30  	// Construct new VM for test
    31  	vapp, err := deployVappForTest(vcd, "GetDhcpAddress")
    32  	check.Assert(err, IsNil)
    33  	vmType, _ := vcd.findFirstVm(*vapp)
    34  	vm := &VM{
    35  		VM:     &vmType,
    36  		client: vapp.client,
    37  	}
    38  
    39  	edgeGateway, err := vcd.vdc.GetEdgeGatewayByName(vcd.config.VCD.EdgeGateway, false)
    40  	if err != nil {
    41  		check.Skip(fmt.Sprintf("Edge Gateway %s not found", vcd.config.VCD.EdgeGateway))
    42  	}
    43  
    44  	// Setup Org network with a single IP in DHCP pool
    45  	network := makeOrgVdcNetworkWithDhcp(vcd, check, edgeGateway)
    46  
    47  	// Attach Org network to vApp
    48  	_, err = vapp.AddOrgNetwork(&VappNetworkSettings{}, network.OrgVDCNetwork, false)
    49  	check.Assert(err, IsNil)
    50  
    51  	// Get network config and update it to use DHCP
    52  	netCfg, err := vm.GetNetworkConnectionSection()
    53  	check.Assert(err, IsNil)
    54  	check.Assert(netCfg, NotNil)
    55  
    56  	netCfg.NetworkConnection[0].Network = network.OrgVDCNetwork.Name
    57  	netCfg.NetworkConnection[0].IPAddressAllocationMode = types.IPAllocationModeDHCP
    58  	netCfg.NetworkConnection[0].IsConnected = true
    59  
    60  	secondNic := &types.NetworkConnection{
    61  		Network:                 network.OrgVDCNetwork.Name,
    62  		IPAddressAllocationMode: types.IPAllocationModeDHCP,
    63  		NetworkConnectionIndex:  1,
    64  		IsConnected:             true,
    65  	}
    66  	netCfg.NetworkConnection = append(netCfg.NetworkConnection, secondNic)
    67  
    68  	// Update network configuration to use DHCP
    69  	err = vm.UpdateNetworkConnectionSection(netCfg)
    70  	check.Assert(err, IsNil)
    71  
    72  	if testVerbose {
    73  		fmt.Printf("# Time out waiting for DHCP IPs on powered off VMs: ")
    74  	}
    75  	// Pretend we are waiting for DHCP addresses when VM is powered off - it must timeout
    76  	ips, hasTimedOut, err := vm.WaitForDhcpIpByNicIndexes([]int{0, 1}, 10, true)
    77  	check.Assert(err, IsNil)
    78  	check.Assert(hasTimedOut, Equals, true)
    79  	check.Assert(ips, HasLen, 2)
    80  	check.Assert(ips[0], Equals, "")
    81  	check.Assert(ips[1], Equals, "")
    82  
    83  	if testVerbose {
    84  		fmt.Println("OK")
    85  	}
    86  
    87  	// err = vm.PowerOnAndForceCustomization()
    88  	task, err := vapp.PowerOn()
    89  	check.Assert(err, IsNil)
    90  	err = task.WaitTaskCompletion()
    91  	check.Assert(err, IsNil)
    92  
    93  	if testVerbose {
    94  		fmt.Printf("# Get IPs for NICs 0 and 1: ")
    95  	}
    96  	// Wait and check DHCP lease acquired
    97  	ips, hasTimedOut, err = vm.WaitForDhcpIpByNicIndexes([]int{0, 1}, 300, true)
    98  	check.Assert(err, IsNil)
    99  	check.Assert(hasTimedOut, Equals, false)
   100  	check.Assert(ips, HasLen, 2)
   101  	check.Assert(ips[0], Matches, `^32.32.32.\d{1,3}$`)
   102  	check.Assert(ips[1], Matches, `^32.32.32.\d{1,3}$`)
   103  
   104  	if testVerbose {
   105  		fmt.Printf("OK:(NICs 0 and 1): %s, %s\n", ips[0], ips[1])
   106  	}
   107  
   108  	// DHCP lease was received so VMs MAC address should have an active lease
   109  	if testVerbose {
   110  		fmt.Printf("# Get active lease for NICs with MAC 0: ")
   111  	}
   112  	lease, err := edgeGateway.GetNsxvActiveDhcpLeaseByMac(netCfg.NetworkConnection[0].MACAddress)
   113  	check.Assert(err, IsNil)
   114  	check.Assert(lease, NotNil)
   115  	// This check fails for a known bug in vCD
   116  	//check.Assert(lease.IpAddress, Matches, `^32.32.32.\d{1,3}$`)
   117  	if testVerbose {
   118  		fmt.Printf("Ok. (Got active lease for MAC 0: %s)\n", lease.IpAddress)
   119  	}
   120  
   121  	if testVerbose {
   122  		fmt.Printf("# Check number of leases on Edge Gateway: ")
   123  	}
   124  	allLeases, err := edgeGateway.GetAllNsxvDhcpLeases()
   125  	check.Assert(err, IsNil)
   126  	check.Assert(allLeases, NotNil)
   127  	check.Assert(len(allLeases) > 0, Equals, true)
   128  	if testVerbose {
   129  		fmt.Printf("OK: (%d leases found)\n", len(allLeases))
   130  	}
   131  
   132  	// Check for a single NIC
   133  	if testVerbose {
   134  		fmt.Printf("# Get IP for single NIC 0: ")
   135  	}
   136  	ips, hasTimedOut, err = vm.WaitForDhcpIpByNicIndexes([]int{0}, 300, true)
   137  	check.Assert(err, IsNil)
   138  	check.Assert(hasTimedOut, Equals, false)
   139  	check.Assert(ips, HasLen, 1)
   140  
   141  	// This check fails for a known bug in vCD
   142  	// TODO: re-enable when the bug is fixed
   143  	//check.Assert(ips[0], Matches, `^32.32.32.\d{1,3}$`)
   144  	if testVerbose {
   145  		fmt.Printf("OK: Got IP for NICs 0: %s\n", ips[0])
   146  	}
   147  
   148  	// Check if IPs are reported by only using VMware tools
   149  	if testVerbose {
   150  		fmt.Printf("# Get IPs for NICs 0 and 1 (only using guest tools): ")
   151  	}
   152  	ips, hasTimedOut, err = vm.WaitForDhcpIpByNicIndexes([]int{0, 1}, 300, false)
   153  	check.Assert(err, IsNil)
   154  	check.Assert(hasTimedOut, Equals, false)
   155  	check.Assert(ips, HasLen, 2)
   156  	// This check fails for a known bug in vCD
   157  	//check.Assert(ips[0], Matches, `^32.32.32.\d{1,3}$`)
   158  	//check.Assert(ips[1], Matches, `^32.32.32.\d{1,3}$`)
   159  	if testVerbose {
   160  		fmt.Printf("OK: IPs for NICs 0 and 1 (via guest tools): %s, %s\n", ips[0], ips[1])
   161  	}
   162  
   163  	// Cleanup vApp
   164  	err = deleteVapp(vcd, vapp.VApp.Name)
   165  	check.Assert(err, IsNil)
   166  	task, err = network.Delete()
   167  	check.Assert(err, IsNil)
   168  	err = task.WaitTaskCompletion()
   169  	check.Assert(err, IsNil)
   170  }
   171  
   172  // makeOrgVdcNetworkWithDhcp is a helper that creates a routed Org network and a DHCP pool with
   173  // single IP address to be assigned. Org vDC network and IP address assigned to DHCP pool are
   174  // returned
   175  func makeOrgVdcNetworkWithDhcp(vcd *TestVCD, check *C, edgeGateway *EdgeGateway) *OrgVDCNetwork {
   176  	var networkConfig = types.OrgVDCNetwork{
   177  		Xmlns:       types.XMLNamespaceVCloud,
   178  		Name:        TestCreateOrgVdcNetworkDhcp,
   179  		Description: TestCreateOrgVdcNetworkDhcp,
   180  		Configuration: &types.NetworkConfiguration{
   181  			FenceMode: types.FenceModeNAT,
   182  			IPScopes: &types.IPScopes{
   183  				IPScope: []*types.IPScope{&types.IPScope{
   184  					IsInherited: false,
   185  					Gateway:     "32.32.32.1",
   186  					Netmask:     "255.255.255.0",
   187  					IPRanges: &types.IPRanges{
   188  						IPRange: []*types.IPRange{
   189  							&types.IPRange{
   190  								StartAddress: "32.32.32.10",
   191  								EndAddress:   "32.32.32.20",
   192  							},
   193  						},
   194  					},
   195  				},
   196  				},
   197  			},
   198  			BackwardCompatibilityMode: true,
   199  		},
   200  		EdgeGateway: &types.Reference{
   201  			HREF: edgeGateway.EdgeGateway.HREF,
   202  			ID:   edgeGateway.EdgeGateway.ID,
   203  			Name: edgeGateway.EdgeGateway.Name,
   204  			Type: edgeGateway.EdgeGateway.Type,
   205  		},
   206  		IsShared: false,
   207  	}
   208  
   209  	// Create network
   210  	err := vcd.vdc.CreateOrgVDCNetworkWait(&networkConfig)
   211  	if err != nil {
   212  		fmt.Printf("error creating Network <%s>: %s\n", TestCreateOrgVdcNetworkDhcp, err)
   213  	}
   214  	check.Assert(err, IsNil)
   215  	AddToCleanupList(TestCreateOrgVdcNetworkDhcp, "network", vcd.org.Org.Name+"|"+vcd.vdc.Vdc.Name, "TestCreateOrgVdcNetworkDhcp")
   216  	network, err := vcd.vdc.GetOrgVdcNetworkByName(TestCreateOrgVdcNetworkDhcp, true)
   217  	check.Assert(err, IsNil)
   218  
   219  	// Add DHCP pool
   220  	dhcpPoolConfig := make([]interface{}, 1)
   221  	dhcpPool := make(map[string]interface{})
   222  	dhcpPool["start_address"] = "32.32.32.21"
   223  	dhcpPool["end_address"] = "32.32.32.250"
   224  	dhcpPool["default_lease_time"] = 3600
   225  	dhcpPool["max_lease_time"] = 7200
   226  	dhcpPoolConfig[0] = dhcpPool
   227  	task, err := edgeGateway.AddDhcpPool(network.OrgVDCNetwork, dhcpPoolConfig)
   228  	check.Assert(err, IsNil)
   229  	err = task.WaitTaskCompletion()
   230  	check.Assert(err, IsNil)
   231  
   232  	return network
   233  }