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

Support Edge Gateway DHCP Forwarding endpoint #573

Merged
merged 7 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]
18 changes: 18 additions & 0 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1615,6 +1615,24 @@ 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)
}

if IsNotFound(err) {
vcd.infoCleanup(notFoundMsg, entity.EntityType, 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
55 changes: 55 additions & 0 deletions govcd/nsxt_edgegateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,61 @@ 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 get DHCP forwarder for NSX-T Edge Gateway without ID")
adezxc marked this conversation as resolved.
Show resolved Hide resolved
}

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 := &types.NsxtEdgeGatewayDhcpForwarder{}
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
63 changes: 63 additions & 0 deletions govcd/nsxt_edgegateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,66 @@ 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))

// Defer removal of the DHCP forwarder config, so that it gets removed no matter the outcome of the test
defer func() {
_, err = edge.UpdateDhcpForwarder(&types.NsxtEdgeGatewayDhcpForwarder{})
check.Assert(err, IsNil)
}()

// 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)

disabledDhcpForwarderConfig := &types.NsxtEdgeGatewayDhcpForwarder{
Enabled: false,
DhcpServers: testDhcpServers,
}

// Update DHCP forwarder config
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(disabledDhcpForwarderConfig)
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)
}
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
7 changes: 7 additions & 0 deletions types/v56/nsxt_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,13 @@ 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"`
}
adezxc marked this conversation as resolved.
Show resolved Hide resolved

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