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 ipv6 support for vApp network configuration #550

Merged
merged 16 commits into from
Mar 10, 2023
1 change: 1 addition & 0 deletions .changes/v2.20.0/550-improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Added support for using subnet prefix length while creating vApp networks. [GH-550]
29 changes: 21 additions & 8 deletions govcd/vapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type VappNetworkSettings struct {
Description string
Gateway string
NetMask string
SubnetPrefixLength string
DNS1 string
DNS2 string
DNSSuffix string
Expand Down Expand Up @@ -920,14 +921,22 @@ func (vapp *VApp) CreateVappNetworkAsync(newNetworkSettings *VappNetworkSettings
FenceMode: types.FenceModeIsolated,
GuestVlanAllowed: newNetworkSettings.GuestVLANAllowed,
Features: networkFeatures,
IPScopes: &types.IPScopes{IPScope: []*types.IPScope{&types.IPScope{IsInherited: false, Gateway: newNetworkSettings.Gateway,
Netmask: newNetworkSettings.NetMask, DNS1: newNetworkSettings.DNS1,
DNS2: newNetworkSettings.DNS2, DNSSuffix: newNetworkSettings.DNSSuffix, IsEnabled: true,
IPRanges: &types.IPRanges{IPRange: newNetworkSettings.StaticIPRanges}}}},
IPScopes: &types.IPScopes{
IPScope: []*types.IPScope{{
IsInherited: false,
Gateway: newNetworkSettings.Gateway,
Netmask: newNetworkSettings.NetMask,
SubnetPrefixLength: newNetworkSettings.SubnetPrefixLength,
DNS1: newNetworkSettings.DNS1,
DNS2: newNetworkSettings.DNS2,
DNSSuffix: newNetworkSettings.DNSSuffix,
IsEnabled: true,
IPRanges: &types.IPRanges{IPRange: newNetworkSettings.StaticIPRanges}}}},
RetainNetInfoAcrossDeployments: newNetworkSettings.RetainIpMacEnabled,
},
IsDeployed: false,
}

if orgNetwork != nil {
vappConfiguration.Configuration.ParentNetwork = &types.Reference{
HREF: orgNetwork.HREF,
Expand Down Expand Up @@ -1072,6 +1081,10 @@ func (vapp *VApp) UpdateNetworkAsync(networkSettingsToUpdate *VappNetworkSetting
networkSettingsToUpdate.DhcpSettings.IPRange.EndAddress = networkSettingsToUpdate.DhcpSettings.IPRange.StartAddress
}

if networkToUpdate.Configuration.Features == nil {
networkToUpdate.Configuration.Features = &types.NetworkFeatures{}
}

// remove DHCP config
if networkSettingsToUpdate.DhcpSettings == nil {
networkToUpdate.Configuration.Features.DhcpService = nil
Expand Down Expand Up @@ -1174,12 +1187,12 @@ func validateNetworkConfigSettings(networkSettings *VappNetworkSettings) error {
return errors.New("network gateway IP is missing")
}

if networkSettings.NetMask == "" {
return errors.New("network mask config is missing")
if networkSettings.NetMask == "" && networkSettings.SubnetPrefixLength == "" {
return errors.New("network mask and subnet prefix length config is missing, exactly one is required")
}

if networkSettings.NetMask == "" {
return errors.New("network mask config is missing")
if networkSettings.NetMask != "" && networkSettings.SubnetPrefixLength != "" {
return errors.New("exactly one of netmask and prefix length can be supplied")
}

if networkSettings.DhcpSettings != nil && networkSettings.DhcpSettings.IPRange == nil {
Expand Down
92 changes: 92 additions & 0 deletions govcd/vapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,98 @@ func (vcd *TestVCD) Test_AddAndRemoveIsolatedVappNetwork(check *C) {
check.Assert(task.Task.Status, Equals, "success")
}

// Test_AddAndRemoveIsolatedVappNetworkIpv6 is identical to Test_AddAndRemoveIsolatedVappNetwork,
// but it uses ipv6 values for network specification.
func (vcd *TestVCD) Test_AddAndRemoveIsolatedVappNetworkIpv6(check *C) {
fmt.Printf("Running: %s\n", check.TestName())

vapp, err := deployVappForTest(vcd, "Test_AddAndRemoveIsolatedVappNetwork")
check.Assert(err, IsNil)
check.Assert(vapp, NotNil)

// Add Metadata
networkName := check.TestName()
description := "Created in test"
const gateway = "fe80:0:0:0:0:0:0:aaaa"
const prefixlength = "100"
// VCD API returns ipv6 addresses in expanded format, so this is
// needed to compare values properly.
const dns1 = "2001:4860:4860:0:0:0:0:8844"
const dns2 = "2001:4860:4860:0:0:0:0:8844"
const dnsSuffix = "biz.biz"
const startAddress = "fe80:0:0:0:0:0:0:aaab"
const endAddress = "fe80:0:0:0:0:0:0:bbbb"
const dhcpStartAddress = "fe80:0:0:0:0:0:0:cccc"
const dhcpEndAddress = "fe80:0:0:0:0:0:0:dddd"
const maxLeaseTime = 3500
const defaultLeaseTime = 2400
var guestVlanAllowed = true

vappNetworkSettings := &VappNetworkSettings{
Name: networkName,
Gateway: gateway,
SubnetPrefixLength: prefixlength,
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,
Description: description,
}

vappNetworkConfig, err := vapp.CreateVappNetwork(vappNetworkSettings, nil)
check.Assert(err, IsNil)
check.Assert(vappNetworkConfig, NotNil)

vappNetworkSettings.NetMask = "255.255.255.0"
vappNetworkConfig2, err := vapp.CreateVappNetwork(vappNetworkSettings, nil)
check.Assert(err, NotNil)
check.Assert(vappNetworkConfig2, IsNil)

networkFound := types.VAppNetworkConfiguration{}
for _, networkConfig := range vappNetworkConfig.NetworkConfig {
if networkConfig.NetworkName == networkName {
networkFound = networkConfig
}
}

check.Assert(networkFound.Description, Equals, description)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].Gateway, Equals, gateway)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].SubnetPrefixLength, Equals, prefixlength)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].DNS1, Equals, dns1)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].DNS2, Equals, dns2)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].DNSSuffix, Equals, dnsSuffix)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].IPRanges.IPRange[0].StartAddress, Equals, startAddress)
check.Assert(networkFound.Configuration.IPScopes.IPScope[0].IPRanges.IPRange[0].EndAddress, Equals, endAddress)

check.Assert(networkFound.Configuration.Features.DhcpService.IsEnabled, Equals, true)
check.Assert(networkFound.Configuration.Features.DhcpService.MaxLeaseTime, Equals, maxLeaseTime)
check.Assert(networkFound.Configuration.Features.DhcpService.DefaultLeaseTime, Equals, defaultLeaseTime)
check.Assert(networkFound.Configuration.Features.DhcpService.IPRange.StartAddress, Equals, dhcpStartAddress)
check.Assert(networkFound.Configuration.Features.DhcpService.IPRange.EndAddress, Equals, dhcpEndAddress)

err = vapp.Refresh()
check.Assert(err, IsNil)
vappNetworkConfig, err = vapp.RemoveNetwork(networkName)
check.Assert(err, IsNil)
check.Assert(vappNetworkConfig, NotNil)

isExist := false
for _, networkConfig := range vappNetworkConfig.NetworkConfig {
if networkConfig.NetworkName == networkName {
isExist = true
}
}
check.Assert(isExist, Equals, false)

task, err := vapp.Delete()
check.Assert(err, IsNil)
err = task.WaitTaskCompletion()
check.Assert(err, IsNil)
check.Assert(task.Task.Status, Equals, "success")
}

func (vcd *TestVCD) Test_AddAndRemoveNatVappNetwork(check *C) {
fmt.Printf("Running: %s\n", check.TestName())

Expand Down
1 change: 1 addition & 0 deletions types/v56/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ type IPScope struct {
IsInherited bool `xml:"IsInherited"` // True if the IP scope is inherit from parent network.
Gateway string `xml:"Gateway,omitempty"` // Gateway of the network.
Netmask string `xml:"Netmask,omitempty"` // Network mask.
SubnetPrefixLength string `xml:"SubnetPrefixLength,omitempty"` // Prefix length.
DNS1 string `xml:"Dns1,omitempty"` // Primary DNS server.
DNS2 string `xml:"Dns2,omitempty"` // Secondary DNS server.
DNSSuffix string `xml:"DnsSuffix,omitempty"` // DNS suffix.
Expand Down