Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for more fields to Edge gateway configuration, add multiple subnet support #267

Merged
merged 15 commits into from
Nov 29, 2019
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
* Increment vCD API version used from 27.0 to 29.0
* Remove fields `VdcEnabled`, `VAppParentHREF`, `VAppParentName`, `HighestSupportedVersion`, `VmToolsVersion`, `TaskHREF`, `TaskStatusName`, `TaskDetails`, `TaskStatus` from `QueryResultVMRecordType`
* Add fields `ID, Type, ContainerName, ContainerID, OwnerName, Owner, NetworkHref, IpAddress, CatalogName, VmToolsStatus, GcStatus, AutoUndeployDate, AutoDeleteDate, AutoUndeployNotified, AutoDeleteNotified, Link, MetaData` to `QueryResultVMRecordType`, `DistributedInterface` to `NetworkConfiguration` and `RegenerateBiosUuid` to `VMGeneralParams`
* Change to pointers `DistributedRoutingEnabled` in `GatewayConfiguration` and `DistributedInterface` in `NetworkConfiguration`
* Change to pointers `DistributedRoutingEnabled` in `GatewayConfiguration` and
`DistributedInterface` in `NetworkConfiguration`
* Add new field to type `GatewayConfiguration`: `FipsModeEnabled` -
[#267](https://github.com/vmware/go-vcloud-director/pull/267)
* Change bool to bool pointer for fields in type `GatewayConfiguration`: `HaEnabled`,
`UseDefaultRouteForDNSRelay`, `AdvancedNetworkingEnabled` -
[#267](https://github.com/vmware/go-vcloud-director/pull/267)
* Added method `EdgeGateway.GetLbVirtualServers` that gets all virtual servers configured on NSX load balancer. [#266](https://github.com/vmware/go-vcloud-director/pull/266)
* Added method `EdgeGateway.GetLbServerPools` that gets all pools configured on NSX load balancer. [#266](https://github.com/vmware/go-vcloud-director/pull/266)
* Added method `EdgeGateway.GetLbServiceMonitors` that gets all service monitors configured on NSX load balancer. [#266](https://github.com/vmware/go-vcloud-director/pull/266)
Expand Down
2 changes: 1 addition & 1 deletion govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ func (vcd *TestVCD) SetUpSuite(check *C) {
}
} else {
vcd.skipVappTests = true
fmt.Printf("Skipping all vapp tests because one of the following wasn't given: Network, StorageProfile, Catalog, Catalogitem")
fmt.Println("Skipping all vapp tests because one of the following wasn't given: Network, StorageProfile, Catalog, Catalogitem")
}
}

Expand Down
4 changes: 3 additions & 1 deletion govcd/edgegateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,9 @@ func (egw *EdgeGateway) HasDefaultGateway() bool {

// HasAdvancedNetworking returns true if the edge gateway has advanced network configuration enabled
func (egw *EdgeGateway) HasAdvancedNetworking() bool {
return egw.EdgeGateway.Configuration != nil && egw.EdgeGateway.Configuration.AdvancedNetworkingEnabled
return egw.EdgeGateway.Configuration != nil &&
egw.EdgeGateway.Configuration.AdvancedNetworkingEnabled != nil &&
*egw.EdgeGateway.Configuration.AdvancedNetworkingEnabled
}

// buildProxiedEdgeEndpointURL helps to get root endpoint for Edge Gateway using the
Expand Down
71 changes: 65 additions & 6 deletions govcd/externalnetwork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package govcd
import (
"fmt"
"net/url"
"sort"

. "gopkg.in/check.v1"

Expand Down Expand Up @@ -89,7 +90,33 @@ func (vcd *TestVCD) testCreateExternalNetwork(testName, networkName, dnsSuffix s
IPRange: []*types.IPRange{
&types.IPRange{
StartAddress: "192.168.201.3",
EndAddress: "192.168.201.250",
EndAddress: "192.168.201.100",
},
&types.IPRange{
StartAddress: "192.168.201.105",
EndAddress: "192.168.201.140",
},
},
},
}, &types.IPScope{
Gateway: "192.168.231.1",
Netmask: "255.255.255.0",
DNS1: "192.168.232.253",
DNS2: "192.168.232.254",
DNSSuffix: dnsSuffix,
IPRanges: &types.IPRanges{
IPRange: []*types.IPRange{
&types.IPRange{
StartAddress: "192.168.231.3",
EndAddress: "192.168.231.100",
},
&types.IPRange{
StartAddress: "192.168.231.105",
EndAddress: "192.168.231.140",
},
&types.IPRange{
StartAddress: "192.168.231.145",
EndAddress: "192.168.231.150",
},
},
},
Expand Down Expand Up @@ -183,16 +210,48 @@ func (vcd *TestVCD) Test_CreateExternalNetwork(check *C) {
check.Assert(newExternalNetwork.ExternalNetwork.Name, Equals, TestCreateExternalNetwork)

ipScope := newExternalNetwork.ExternalNetwork.Configuration.IPScopes.IPScope

// Sort returned IP scopes by gateway because API is not guaranteed to return it in the same
// order
sort.SliceStable(ipScope, func(i, j int) bool {
return ipScope[i].Gateway < ipScope[j].Gateway
})

check.Assert(len(ipScope), Equals, 2)
// Check IPScope 1
check.Assert(ipScope[0].Gateway, Equals, "192.168.201.1")
check.Assert(ipScope[0].Netmask, Equals, "255.255.255.0")
check.Assert(ipScope[0].DNS1, Equals, "192.168.202.253")
check.Assert(ipScope[0].DNS2, Equals, "192.168.202.254")
check.Assert(ipScope[0].DNSSuffix, Equals, dnsSuffix)

check.Assert(len(ipScope[0].IPRanges.IPRange), Equals, 1)
ipRange := ipScope[0].IPRanges.IPRange[0]
check.Assert(ipRange.StartAddress, Equals, "192.168.201.3")
check.Assert(ipRange.EndAddress, Equals, "192.168.201.250")
// Check IPScope 2
check.Assert(ipScope[1].Gateway, Equals, "192.168.231.1")
check.Assert(ipScope[1].Netmask, Equals, "255.255.255.0")
check.Assert(ipScope[1].DNS1, Equals, "192.168.232.253")
check.Assert(ipScope[1].DNS2, Equals, "192.168.232.254")
check.Assert(ipScope[1].DNSSuffix, Equals, dnsSuffix)
// Check IP ranges on IPScope 1
check.Assert(len(ipScope[0].IPRanges.IPRange), Equals, 2)
ipRange1 := ipScope[0].IPRanges.IPRange[0]
check.Assert(ipRange1.StartAddress, Equals, "192.168.201.3")
check.Assert(ipRange1.EndAddress, Equals, "192.168.201.100")

ipRange2 := ipScope[0].IPRanges.IPRange[1]
check.Assert(ipRange2.StartAddress, Equals, "192.168.201.105")
check.Assert(ipRange2.EndAddress, Equals, "192.168.201.140")

// Check IP ranges on IPScope 2
ipRange1 = ipScope[1].IPRanges.IPRange[0]
check.Assert(ipRange1.StartAddress, Equals, "192.168.231.3")
check.Assert(ipRange1.EndAddress, Equals, "192.168.231.100")

ipRange2 = ipScope[1].IPRanges.IPRange[1]
check.Assert(ipRange2.StartAddress, Equals, "192.168.231.105")
check.Assert(ipRange2.EndAddress, Equals, "192.168.231.140")

ipRange3 := ipScope[1].IPRanges.IPRange[2]
check.Assert(ipRange3.StartAddress, Equals, "192.168.231.145")
check.Assert(ipRange3.EndAddress, Equals, "192.168.231.150")

check.Assert(newExternalNetwork.ExternalNetwork.Configuration.FenceMode, Equals, "isolated")
check.Assert(newExternalNetwork.ExternalNetwork.Description, Equals, "Test Create External Network")
Expand Down
4 changes: 0 additions & 4 deletions govcd/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ func (vcd *TestVCD) Test_AddMetadataOnVm(check *C) {
check.Skip("skipping test because no VM is found")
}

fmt.Printf("Running: %s\n", check.TestName())

vm := NewVM(&vcd.client.Client)
vm.VM = &vmType

Expand Down Expand Up @@ -164,8 +162,6 @@ func (vcd *TestVCD) Test_DeleteMetadataOnVm(check *C) {
check.Skip("skipping test because no VM is found")
}

fmt.Printf("Running: %s\n", check.TestName())

vm := NewVM(&vcd.client.Client)
vm.VM = &vmType

Expand Down
4 changes: 0 additions & 4 deletions govcd/nsxv_ipset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,3 @@ func (vcd *TestVCD) Test_NsxvIpSet(check *C) {
check.Assert(err, IsNil)

}

func takeBoolPointer(value bool) *bool {
return &value
}
6 changes: 3 additions & 3 deletions govcd/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ func CreateEdgeGatewayAsync(vcdClient *VCDClient, egwc EdgeGatewayCreation) (Tas
Name: egwc.Name,
Description: egwc.Description,
Configuration: &types.GatewayConfiguration{
UseDefaultRouteForDNSRelay: egwc.UseDefaultRouteForDNSRelay,
HaEnabled: egwc.HAEnabled,
UseDefaultRouteForDNSRelay: &egwc.UseDefaultRouteForDNSRelay,
HaEnabled: &egwc.HAEnabled,
GatewayBackingConfig: egwc.BackingConfiguration,
AdvancedNetworkingEnabled: egwc.AdvancedNetworkingEnabled,
AdvancedNetworkingEnabled: &egwc.AdvancedNetworkingEnabled,
DistributedRoutingEnabled: &distributed,
GatewayInterfaces: &types.GatewayInterfaces{
GatewayInterface: []*types.GatewayInterface{},
Expand Down
139 changes: 137 additions & 2 deletions govcd/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func (vcd *TestVCD) Test_CreateDeleteEdgeGateway(check *C) {
// -1 : creation error
check.Assert(edge.EdgeGateway.Status, Equals, 1)

check.Assert(edge.EdgeGateway.Configuration.AdvancedNetworkingEnabled, Equals, true)
check.Assert(edge.EdgeGateway.Configuration.AdvancedNetworkingEnabled, NotNil)
check.Assert(*edge.EdgeGateway.Configuration.AdvancedNetworkingEnabled, Equals, true)
util.Logger.Printf("Edge Gateway:\n%s\n", prettyEdgeGateway(*edge.EdgeGateway))

check.Assert(edge.HasDefaultGateway(), Equals, builtWithDefaultGateway)
Expand All @@ -221,11 +222,145 @@ func (vcd *TestVCD) Test_CreateDeleteEdgeGateway(check *C) {

// Once deleted, look for the edge gateway again. It should return an error
newEdge, err := vcd.vdc.GetEdgeGatewayByName(egc.Name, true)
check.Assert(err, NotNil)
check.Assert(err, Equals, ErrorEntityNotFound)
check.Assert(newEdge, IsNil)
}
}

// Test_CreateDeleteEdgeGatewayAdvanced sets up external network which has multiple IP scopes and IP
// ranges defined. This helps to test edge gateway capabilities for multiple networks and scopes
func (vcd *TestVCD) Test_CreateDeleteEdgeGatewayAdvanced(check *C) {
// Setup external network with multiple IP scopes and multiple ranges
dnsSuffix := "some.net"
skippingReason, externalNetwork, task, err := vcd.testCreateExternalNetwork(check.TestName(), check.TestName(), dnsSuffix)
if skippingReason != "" {
check.Skip(skippingReason)
}

check.Assert(err, IsNil)
check.Assert(task.Task, Not(Equals), types.Task{})

AddToCleanupList(externalNetwork.Name, "externalNetwork", "", check.TestName())
err = task.WaitTaskCompletion()
check.Assert(err, IsNil)

// "Refresh" external network to fill in all fields (like HREF)
extNet, err := vcd.client.GetExternalNetworkByName(externalNetwork.Name)
check.Assert(err, IsNil)
externalNetwork = extNet.ExternalNetwork

edgeName := "Test-Multi-Scope-Gw"
// Initialize edge gateway structure
edgeGatewayConfig := &types.EdgeGateway{
Xmlns: types.XMLNamespaceVCloud,
Name: edgeName,
Description: edgeName,
Configuration: &types.GatewayConfiguration{
HaEnabled: takeBoolPointer(false),
GatewayBackingConfig: "compact",
GatewayInterfaces: &types.GatewayInterfaces{
GatewayInterface: []*types.GatewayInterface{},
},
AdvancedNetworkingEnabled: takeBoolPointer(true),
DistributedRoutingEnabled: takeBoolPointer(false),
FipsModeEnabled: takeBoolPointer(false),
UseDefaultRouteForDNSRelay: takeBoolPointer(true),
},
}

// Create subnet participation structure
subnetParticipation := make([]*types.SubnetParticipation, len(externalNetwork.Configuration.IPScopes.IPScope))
// Loop over IP scopes
for ipScopeIndex, ipScope := range externalNetwork.Configuration.IPScopes.IPScope {
subnetParticipation[ipScopeIndex] = &types.SubnetParticipation{
Gateway: ipScope.Gateway,
Netmask: ipScope.Netmask,
// IPAddress: string, // Can be set to specify IP address of edge gateway
// UseForDefaultRoute: bool, // Can be specified to use subnet as default gateway
IPRanges: &types.IPRanges{},
}
}

// Setup network interface config
networkConf := &types.GatewayInterface{
Name: externalNetwork.Name,
DisplayName: externalNetwork.Name,
InterfaceType: "uplink",
Network: &types.Reference{
HREF: externalNetwork.HREF,
ID: externalNetwork.ID,
Type: "application/vnd.vmware.admin.network+xml",
Name: externalNetwork.Name,
},
UseForDefaultRoute: true,
SubnetParticipation: subnetParticipation,
}

// Sort by subnet participation gateway so that below injected variables are not being added to
// incorrect network
networkConf.SortBySubnetParticipationGateway()
// Set static IP assignment
networkConf.SubnetParticipation[0].IPAddress = "192.168.201.100"
// Set default gateway subnet
networkConf.SubnetParticipation[1].UseForDefaultRoute = true
// Inject an IP range (in UI it is called "sub-allocated pools" in separate tab)
networkConf.SubnetParticipation[0].IPRanges = &types.IPRanges{
IPRange: []*types.IPRange{
&types.IPRange{
StartAddress: "192.168.201.120",
EndAddress: "192.168.201.130",
},
},
}

edgeGatewayConfig.Configuration.GatewayInterfaces.GatewayInterface =
append(edgeGatewayConfig.Configuration.GatewayInterfaces.GatewayInterface, networkConf)

orgName := vcd.config.VCD.Org
vdcName := vcd.config.VCD.Vdc

edge, err := CreateAndConfigureEdgeGateway(vcd.client, orgName, vdcName, edgeName, edgeGatewayConfig)
check.Assert(err, IsNil)
PrependToCleanupList(edge.EdgeGateway.Name, "edgegateway", orgName+"|"+vdcName, "Test_CreateDeleteEdgeGateway")

// Patch known differences for comparison deep comparison
edgeGatewayConfig.Configuration.GatewayInterfaces.GatewayInterface[0].SubnetParticipation[1].IPAddress = "192.168.231.3"
edgeGatewayConfig.Configuration.GatewayInterfaces.GatewayInterface[0].Network.HREF =
edge.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].Network.HREF

// Sort gateway interfaces so that comparison is easier
edgeGatewayConfig.Configuration.GatewayInterfaces.GatewayInterface[0].SortBySubnetParticipationGateway()
edge.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0].SortBySubnetParticipationGateway()

check.Assert(edge.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[0], DeepEquals,
edgeGatewayConfig.Configuration.GatewayInterfaces.GatewayInterface[0])
check.Assert(edge.EdgeGateway.Configuration.DistributedRoutingEnabled, NotNil)
check.Assert(*edge.EdgeGateway.Configuration.DistributedRoutingEnabled, Equals, false)

// FIPS mode is not being returned from API (neither when it is enabled, nor when disabled), but
// does allow to turn it on.
// check.Assert(edge.EdgeGateway.Configuration.FipsModeEnabled, NotNil)
// check.Assert(*edge.EdgeGateway.Configuration.FipsModeEnabled, Equals, true)

check.Assert(edge.EdgeGateway.Configuration.AdvancedNetworkingEnabled, NotNil)
check.Assert(*edge.EdgeGateway.Configuration.AdvancedNetworkingEnabled, Equals, true)
check.Assert(edge.EdgeGateway.Configuration.UseDefaultRouteForDNSRelay, NotNil)
check.Assert(*edge.EdgeGateway.Configuration.UseDefaultRouteForDNSRelay, Equals, true)
check.Assert(edge.EdgeGateway.Configuration.HaEnabled, NotNil)
check.Assert(*edge.EdgeGateway.Configuration.HaEnabled, Equals, false)

// Remove created objects to free them up
err = edge.Delete(true, false)
check.Assert(err, IsNil)

err = extNet.DeleteWait()
check.Assert(err, IsNil)
}

func takeBoolPointer(value bool) *bool {
return &value
}

func (vcd *TestVCD) Test_FindBadlyNamedStorageProfile(check *C) {
reNotFound := `can't find any VDC Storage_profiles`
_, err := vcd.vdc.FindStorageProfileReference("name with spaces")
Expand Down
24 changes: 9 additions & 15 deletions govcd/vapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,21 +646,15 @@ func (vcd *TestVCD) Test_RemoveAllNetworks(check *C) {
}

vappNetworkSettings2 := &VappNetworkSettings{
Name: networkName2,
Gateway: gateway,
NetMask: netmask,
DNS1: dns1,
DNS2: dns2,
DNSSuffix: dnsSuffix,
StaticIPRanges: []*types.IPRange{{StartAddress: startAddress, EndAddress: endAddress}},
DhcpSettings: &DhcpSettings{IsEnabled: true, MaxLeaseTime: maxLeaseTime, DefaultLeaseTime: defaultLeaseTime, IPRange: &types.IPRange{StartAddress: dhcpStartAddress, EndAddress: dhcpEndAddress}},
}

// vCD 8.20 does not support sending guestVlanAllowed
if vcd.client.APIVCDMaxVersionIs("> 27.0") {
vappNetworkSettings.GuestVLANAllowed = &guestVlanAllowed
} else {
fmt.Printf("Skipping GuestVLANAllowed parameter as it is not supported on vCD 8.20")
Name: networkName2,
Gateway: gateway,
NetMask: netmask,
DNS1: dns1,
DNS2: dns2,
DNSSuffix: dnsSuffix,
StaticIPRanges: []*types.IPRange{{StartAddress: startAddress, EndAddress: endAddress}},
DhcpSettings: &DhcpSettings{IsEnabled: true, MaxLeaseTime: maxLeaseTime, DefaultLeaseTime: defaultLeaseTime, IPRange: &types.IPRange{StartAddress: dhcpStartAddress, EndAddress: dhcpEndAddress}},
GuestVLANAllowed: &guestVlanAllowed,
}

task, err := vcd.vapp.AddIsolatedNetwork(vappNetworkSettings)
Expand Down
Loading