Skip to content

Commit

Permalink
Support Edge Gateway DHCP Forwarding endpoint (#573)
Browse files Browse the repository at this point in the history
* Add support for DHCP forwarding management in NSXT Edge gateways
---------

Signed-off-by: Adam Jasinski <jasinskia@vmware.com>
  • Loading branch information
adezxc committed Jun 1, 2023
1 parent de4d321 commit aca7fec
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .changes/v2.21.0/573-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Added NSX-T Edge Gateway DHCP forwarding configuration support `NsxtEdgeGateway.GetDhcpForwarder` and
`NsxtEdgeGateway.UpdateDhcpForwarder` [GH-573]
24 changes: 24 additions & 0 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1615,6 +1615,30 @@ func (vcd *TestVCD) removeLeftoverEntities(entity CleanupEntity) {
}
return

case "nsxtDhcpForwarder":
edge, err := vcd.nsxtVdc.GetNsxtEdgeGatewayByName(entity.Name)
if err != nil {
vcd.infoCleanup("removeLeftoverEntries: [ERROR] %s \n", err)
}

dhcpForwarder, err := edge.GetDhcpForwarder()
if err != nil {
vcd.infoCleanup("removeLeftoverEntries: [ERROR] %s \n", err)
}

if dhcpForwarder.Enabled == false && len(dhcpForwarder.DhcpServers) == 0 {
vcd.infoCleanup(notFoundMsg, "dhcpForwarder", entity.Name)
return
}

_, err = edge.UpdateDhcpForwarder(&types.NsxtEdgeGatewayDhcpForwarder{})
if err != nil {
vcd.infoCleanup(notDeletedMsg, entity.EntityType, entity.Name, err)
}

vcd.infoCleanup(removedMsg, entity.EntityType, entity.Name, entity.CreatedBy)
return

default:
// If we reach this point, we are trying to clean up an entity that
// we aren't prepared for yet.
Expand Down
60 changes: 60 additions & 0 deletions govcd/nsxt_edgegateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,66 @@ func (egw *NsxtEdgeGateway) UpdateQoS(qosConfig *types.NsxtEdgeGatewayQos) (*typ
return updatedQos, nil
}

// GetDhcpForwarder gets DHCP forwarder configuration for an NSX-T Edge Gateway
func (egw *NsxtEdgeGateway) GetDhcpForwarder() (*types.NsxtEdgeGatewayDhcpForwarder, error) {
if egw.EdgeGateway == nil || egw.client == nil || egw.EdgeGateway.ID == "" {
return nil, fmt.Errorf("cannot get DHCP forwarder for NSX-T Edge Gateway without ID")
}

client := egw.client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayDhcpForwarder
apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}

urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, egw.EdgeGateway.ID))
if err != nil {
return nil, err
}

dhcpForwarder := &types.NsxtEdgeGatewayDhcpForwarder{}
err = client.OpenApiGetItem(apiVersion, urlRef, nil, dhcpForwarder, nil)
if err != nil {
return nil, err
}

return dhcpForwarder, nil
}

// UpdateDhcpForwarder updates DHCP forwarder configuration for an NSX-T Edge Gateway
func (egw *NsxtEdgeGateway) UpdateDhcpForwarder(dhcpForwarderConfig *types.NsxtEdgeGatewayDhcpForwarder) (*types.NsxtEdgeGatewayDhcpForwarder, error) {
if egw.EdgeGateway == nil || egw.client == nil || egw.EdgeGateway.ID == "" {
return nil, fmt.Errorf("cannot update DHCP forwarder for NSX-T Edge Gateway without ID")
}

client := egw.client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayDhcpForwarder
apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}

urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, egw.EdgeGateway.ID))
if err != nil {
return nil, err
}

// update DHCP forwarder with given dhcpForwarderConfig
updatedDhcpForwarder, err := egw.GetDhcpForwarder()
if err != nil {
return nil, err
}
dhcpForwarderConfig.Version = updatedDhcpForwarder.Version

err = client.OpenApiPutItem(apiVersion, urlRef, nil, dhcpForwarderConfig, updatedDhcpForwarder, nil)
if err != nil {
return nil, err
}

return updatedDhcpForwarder, nil
}

func getAllUnusedExternalIPAddresses(uplinks []types.EdgeGatewayUplinks, usedIpAddresses []*types.GatewayUsedIpAddress, optionalSubnet netip.Prefix) ([]netip.Addr, error) {
// 1. Flatten all IP ranges in Edge Gateway using Go's native 'netip.Addr' IP container instead
// of plain strings because it is more robust (supports IPv4 and IPv6 and also comparison
Expand Down
82 changes: 82 additions & 0 deletions govcd/nsxt_edgegateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,85 @@ func (vcd *TestVCD) Test_NsxtEdgeQoS(check *C) {
check.Assert(err, IsNil)
check.Assert(updatedEdgeQosConfig, NotNil)
}

func (vcd *TestVCD) Test_NsxtEdgeDhcpForwarder(check *C) {
if vcd.skipAdminTests {
check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
}
skipNoNsxtConfiguration(vcd, check)
skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGatewayDhcpForwarder)

org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
check.Assert(err, IsNil)
nsxtVdc, err := org.GetVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
check.Assert(err, IsNil)
edge, err := nsxtVdc.GetNsxtEdgeGatewayByName(vcd.config.VCD.Nsxt.EdgeGateway)
check.Assert(err, IsNil)
AddToCleanupList(vcd.config.VCD.Nsxt.EdgeGateway, "nsxtDhcpForwarder", vcd.config.VCD.Org, check.TestName())

// Fetch current DHCP forwarder config
dhcpForwarderConfig, err := edge.GetDhcpForwarder()
check.Assert(err, IsNil)
check.Assert(dhcpForwarderConfig.Enabled, Equals, false)
check.Assert(dhcpForwarderConfig.DhcpServers, DeepEquals, []string(nil))

// Create new DHCP Forwarder config
testDhcpServers := []string{
"1.1.1.1",
"192.168.2.254",
"fe80::abcd",
}

newDhcpForwarderConfig := &types.NsxtEdgeGatewayDhcpForwarder{
Enabled: true,
DhcpServers: testDhcpServers,
}

// Update DHCP forwarder config
updatedEdgeDhcpForwarderConfig, err := edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
check.Assert(err, IsNil)
check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)

// Check that updates were applied
check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, true)
check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)

// remove the last dhcp server from the list
testDhcpServers = testDhcpServers[0:2]
newDhcpForwarderConfig.DhcpServers = testDhcpServers

updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
check.Assert(err, IsNil)
check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)

// Check that updates were applied
check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, true)
check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)

// Add servers to the list
testDhcpServers = append(testDhcpServers, "192.254.0.2")
newDhcpForwarderConfig.DhcpServers = testDhcpServers

updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
check.Assert(err, IsNil)
check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)

// Check that updates were applied
check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, true)
check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)

// Disable DHCP forwarder config
newDhcpForwarderConfig.Enabled = false

// Update DHCP forwarder config
updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
check.Assert(err, IsNil)
check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)

// Check that updates were applied
check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, false)
check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)

_, err = edge.UpdateDhcpForwarder(&types.NsxtEdgeGatewayDhcpForwarder{})
check.Assert(err, IsNil)
}
1 change: 1 addition & 0 deletions govcd/openapi_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var endpointMinApiVersions = map[string]string{
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeClusters: "34.0", // VCD 10.1+
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointQosProfiles: "36.2", // VCD 10.3.2+ (NSX-T only)
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayQos: "36.2", // VCD 10.3.2+ (NSX-T only)
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayDhcpForwarder: "36.1", // VCD 10.3.1+ (NSX-T only)
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways: "34.0",
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayUsedIpAddresses: "34.0",

Expand Down
1 change: 1 addition & 0 deletions types/v56/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ const (
OpenApiEndpointVdcNetworkProfile = "vdcs/%s/networkProfile"
OpenApiEndpointEdgeGateways = "edgeGateways/"
OpenApiEndpointEdgeGatewayQos = "edgeGateways/%s/qos"
OpenApiEndpointEdgeGatewayDhcpForwarder = "edgeGateways/%s/dhcpForwarder"
OpenApiEndpointEdgeGatewayUsedIpAddresses = "edgeGateways/%s/usedIpAddresses"
OpenApiEndpointNsxtFirewallRules = "edgeGateways/%s/firewall/rules"
OpenApiEndpointFirewallGroups = "firewallGroups/"
Expand Down
8 changes: 8 additions & 0 deletions types/v56/nsxt_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,14 @@ type NsxtEdgeGatewayQos struct {
IngressProfile *OpenApiReference `json:"ingressProfile"`
}

// NsxtEdgeGatewayDhcpForwarder provides DHCP forwarding configuration on an Edge Gateway by defining
// DHCP servers
type NsxtEdgeGatewayDhcpForwarder struct {
Enabled bool `json:"enabled"`
DhcpServers []string `json:"dhcpServers"`
Version VersionField `json:"version,omitempty"`
}

// VcenterImportableDvpg defines a Distributed Port Group that can be imported into VCD
// from a vCenter Server.
//
Expand Down

0 comments on commit aca7fec

Please sign in to comment.