Skip to content

Commit

Permalink
Edge Gateway DHCPv6 and a few IPv6 settings (#582)
Browse files Browse the repository at this point in the history
  • Loading branch information
Didainius authored Jul 17, 2023
1 parent a329d75 commit 49c9ba9
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 7 deletions.
1 change: 0 additions & 1 deletion .changes/v2.21.0/572-notes.md
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* Changed Org enablement status during tests for VCD 10.4.2, to circumvent a VCD bug that prevents creation of disabled Orgs [GH-572]

1 change: 0 additions & 1 deletion .changes/v2.21.0/574-notes.md
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* Skipped test `Test_VdcDuplicatedVmPlacementPolicyGetsACleanError` in 10.4.2 as the relevant bug we check for is fixed in that version [GH-574]

2 changes: 2 additions & 0 deletions .changes/v2.21.0/582-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Added NSX-T Edge Gateway SLAAC Profile (DHCPv6) configuration support
`NsxtEdgeGateway.GetSlaacProfile` and `NsxtEdgeGateway.UpdateSlaacProfile` [GH-582]
4 changes: 4 additions & 0 deletions .changes/v2.21.0/582-improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* NSX-T ALB Virtual Service supports IPv6 Virtual Service using field`IPv6VirtualIpAddress` in
`types.NsxtAlbVirtualService` for VCD 10.4.0+ [GH-582]
* Add field `EnableDualSubnetNetwork` to enable Dual-Stack mode for Org VDC networks in
`types.OpenApiOrgVdcNetwork` [GH-582]
13 changes: 13 additions & 0 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,19 @@ func (vcd *TestVCD) removeLeftoverEntities(entity CleanupEntity) {
vcd.infoCleanup(notDeletedMsg, entity.EntityType, entity.Name, err)
}

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

_, err = edge.UpdateSlaacProfile(&types.NsxtEdgeGatewaySlaacProfile{Enabled: false, Mode: "SLAAC"})
if err != nil {
vcd.infoCleanup(notDeletedMsg, entity.EntityType, entity.Name, err)
}

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

Expand Down
7 changes: 7 additions & 0 deletions govcd/nsxt_alb_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ func setupAlbPoolPrerequisites(check *C, vcd *TestVCD) (*NsxtAlbController, *Nsx
albSettingsConfig.SupportedFeatureSet = "PREMIUM"
}

// Enable IPv6 service network definition (VCD 10.4.0+)
if vcd.client.Client.APIVCDMaxVersionIs(">= 37.0") {
printVerbose("# Enabling IPv6 service network definition (VCD 10.4.0+)\n")
albSettingsConfig.ServiceNetworkDefinition = "192.168.255.125/25"
albSettingsConfig.Ipv6ServiceNetworkDefinition = "2001:0db8:85a3:0000:0000:8a2e:0370:7334/120"
}

// Enable Transparent mode on VCD >= 10.4.1
if vcd.client.Client.APIVCDMaxVersionIs(">= 37.1") {
printVerbose("# Enabling Transparent mode on Edge Gateway (VCD 10.4.1+)\n")
Expand Down
10 changes: 5 additions & 5 deletions govcd/nsxt_alb_virtual_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (vcdClient *VCDClient) GetAllAlbVirtualServiceSummaries(edgeGatewayId strin
client := vcdClient.Client

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServiceSummaries
apiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -104,7 +104,7 @@ func (vcdClient *VCDClient) GetAlbVirtualServiceById(id string) (*NsxtAlbVirtual
}

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices
apiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -133,7 +133,7 @@ func (vcdClient *VCDClient) CreateNsxtAlbVirtualService(albVirtualServiceConfig
client := vcdClient.Client

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
minimumApiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}
Expand All @@ -160,7 +160,7 @@ func (vcdClient *VCDClient) CreateNsxtAlbVirtualService(albVirtualServiceConfig
func (nsxtAlbVirtualService *NsxtAlbVirtualService) Update(albVirtualServiceConfig *types.NsxtAlbVirtualService) (*NsxtAlbVirtualService, error) {
client := nsxtAlbVirtualService.vcdClient.Client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
minimumApiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -191,7 +191,7 @@ func (nsxtAlbVirtualService *NsxtAlbVirtualService) Update(albVirtualServiceConf
func (nsxtAlbVirtualService *NsxtAlbVirtualService) Delete() error {
client := nsxtAlbVirtualService.vcdClient.Client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
minimumApiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return err
}
Expand Down
71 changes: 71 additions & 0 deletions govcd/nsxt_alb_virtual_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,21 @@ func (vcd *TestVCD) Test_AlbVirtualService(check *C) {
testVirtualServiceConfigWithCertHTTPS(check, edge, albPool, seGroup, vcd, vcd.client)
testMinimalVirtualServiceConfigL4(check, edge, albPool, seGroup, vcd, vcd.client)
testMinimalVirtualServiceConfigL4TLS(check, edge, albPool, seGroup, vcd, vcd.client)
if vcd.client.Client.APIVCDMaxVersionIs(">= 37.0") {
printVerbose("# Running 10.4.0+ IPv6 Virtual Service test as Sysadmin user\n")
testVirtualServiceConfigHTTPIPv6(check, edge, albPool, seGroup, vcd, vcd.client)
}

printVerbose("# Running tests as Org user\n")
// Run tests with Org admin user
testMinimalVirtualServiceConfigHTTP(check, edge, albPool, seGroup, vcd, orgUserVcdClient)
testVirtualServiceConfigWithCertHTTPS(check, edge, albPool, seGroup, vcd, orgUserVcdClient)
testMinimalVirtualServiceConfigL4(check, edge, albPool, seGroup, vcd, orgUserVcdClient)
testMinimalVirtualServiceConfigL4TLS(check, edge, albPool, seGroup, vcd, orgUserVcdClient)
if vcd.client.Client.APIVCDMaxVersionIs(">= 37.0") {
printVerbose("# Running 10.4.0+ IPv6 Virtual Service test as Org user\n")
testVirtualServiceConfigHTTPIPv6(check, edge, albPool, seGroup, vcd, orgUserVcdClient)
}

// Test 10.4.1 Transparent mode on VCD >= 10.4.1
if vcd.client.Client.APIVCDMaxVersionIs(">= 37.1") {
Expand Down Expand Up @@ -124,6 +132,69 @@ func testMinimalVirtualServiceConfigHTTP(check *C, edge *NsxtEdgeGateway, pool *
testAlbVirtualServiceConfig(check, vcd, "MinimalHTTP", virtualServiceConfig, virtualServiceConfigUpdated, client)
}

func testVirtualServiceConfigHTTPIPv6(check *C, edge *NsxtEdgeGateway, pool *NsxtAlbPool, seGroup *NsxtAlbServiceEngineGroup, vcd *TestVCD, client *VCDClient) {
// Enable SLAAC Profile - this is a property of Edge Gateway - it will be removed with Edge
// Gateway itself upon cleanup
_, err := edge.UpdateSlaacProfile(&types.NsxtEdgeGatewaySlaacProfile{Enabled: true, Mode: "SLAAC"})
check.Assert(err, IsNil)
defer func() {
_, err := edge.UpdateSlaacProfile(&types.NsxtEdgeGatewaySlaacProfile{Enabled: false, Mode: "DISABLED"})
check.Assert(err, IsNil)
}()

virtualServiceConfig := &types.NsxtAlbVirtualService{
Name: check.TestName(),
Enabled: addrOf(true),
ApplicationProfile: types.NsxtAlbVirtualServiceApplicationProfile{
SystemDefined: true,
Type: "HTTP",
},
GatewayRef: types.OpenApiReference{ID: edge.EdgeGateway.ID},
LoadBalancerPoolRef: types.OpenApiReference{ID: pool.NsxtAlbPool.ID},
ServiceEngineGroupRef: types.OpenApiReference{ID: seGroup.NsxtAlbServiceEngineGroup.ID},
ServicePorts: []types.NsxtAlbVirtualServicePort{
{
PortStart: addrOf(80),
},
},
VirtualIpAddress: edge.EdgeGateway.EdgeGatewayUplinks[0].Subnets.Values[0].PrimaryIP,
IPv6VirtualIpAddress: "2002:0:0:1234:abcd:ffff:c0a8:103",
}

virtualServiceConfigUpdated := &types.NsxtAlbVirtualService{
Name: check.TestName(),
Description: "Updated",
Enabled: addrOf(true),
ApplicationProfile: types.NsxtAlbVirtualServiceApplicationProfile{
SystemDefined: true,
Type: "HTTP",
},
GatewayRef: types.OpenApiReference{ID: edge.EdgeGateway.ID},
LoadBalancerPoolRef: types.OpenApiReference{ID: pool.NsxtAlbPool.ID},
ServiceEngineGroupRef: types.OpenApiReference{ID: seGroup.NsxtAlbServiceEngineGroup.ID},
ServicePorts: []types.NsxtAlbVirtualServicePort{
{
PortStart: addrOf(443),
PortEnd: addrOf(449),
SslEnabled: addrOf(false),
},
{
PortStart: addrOf(2000),
PortEnd: addrOf(2010),
SslEnabled: addrOf(false),
},
},
// Use Primary IP of Edge Gateway as virtual service IP
VirtualIpAddress: edge.EdgeGateway.EdgeGatewayUplinks[0].Subnets.Values[0].PrimaryIP,
IPv6VirtualIpAddress: "2002:0:0:1234:abcd:ffff:c0a8:103",
//HealthStatus: "",
//HealthMessage: "",
//DetailedHealthMessage: "",
}

testAlbVirtualServiceConfig(check, vcd, "IPv6", virtualServiceConfig, virtualServiceConfigUpdated, client)
}

func testMinimalVirtualServiceConfigHTTPTransparent(check *C, edge *NsxtEdgeGateway, poolWithMemberGroup *NsxtAlbPool, seGroup *NsxtAlbServiceEngineGroup, vcd *TestVCD, client *VCDClient, trueOnCreate bool) {
createTransparentMode := trueOnCreate
updateTransparentMode := !createTransparentMode
Expand Down
58 changes: 58 additions & 0 deletions govcd/nsxt_edgegateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,64 @@ func (egw *NsxtEdgeGateway) UpdateDhcpForwarder(dhcpForwarderConfig *types.NsxtE
return updatedDhcpForwarder, nil
}

// GetSlaacProfile gets SLAAC (Stateless Address Autoconfiguration) Profile configuration for an
// NSX-T Edge Gateway.
// Note. It represents DHCPv6 Edge Gateway configuration in UI
func (egw *NsxtEdgeGateway) GetSlaacProfile() (*types.NsxtEdgeGatewaySlaacProfile, error) {
if egw.EdgeGateway == nil || egw.client == nil || egw.EdgeGateway.ID == "" {
return nil, fmt.Errorf("cannot get SLAAC Profile for NSX-T Edge Gateway without ID")
}

client := egw.client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewaySlaacProfile
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
}

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

return slaacProfile, nil
}

// UpdateSlaacProfile creates a SLAAC (Stateless Address Autoconfiguration) profile or updates the
// existing one if it already exists.
// Note. It represents DHCPv6 Edge Gateway configuration in UI
func (egw *NsxtEdgeGateway) UpdateSlaacProfile(slaacProfileConfig *types.NsxtEdgeGatewaySlaacProfile) (*types.NsxtEdgeGatewaySlaacProfile, error) {
if egw.EdgeGateway == nil || egw.client == nil || egw.EdgeGateway.ID == "" {
return nil, fmt.Errorf("cannot update SLAAC Profile for NSX-T Edge Gateway without ID")
}

client := egw.client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewaySlaacProfile
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
}

updatedSlaacProfile := &types.NsxtEdgeGatewaySlaacProfile{}
err = client.OpenApiPutItem(apiVersion, urlRef, nil, slaacProfileConfig, updatedSlaacProfile, nil)
if err != nil {
return nil, err
}

return updatedSlaacProfile, 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
56 changes: 56 additions & 0 deletions govcd/nsxt_edgegateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,3 +584,59 @@ func (vcd *TestVCD) Test_NsxtEdgeDhcpForwarder(check *C) {
_, err = edge.UpdateDhcpForwarder(&types.NsxtEdgeGatewayDhcpForwarder{})
check.Assert(err, IsNil)
}

// Test_NsxtEdgeSlaacProfile tests SLAAC profile (NSX-T Edge Gateway DHCPv6) retrieval and update
func (vcd *TestVCD) Test_NsxtEdgeSlaacProfile(check *C) {
if vcd.skipAdminTests {
check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
}
skipNoNsxtConfiguration(vcd, check)
skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGatewaySlaacProfile)

edge, err := vcd.nsxtVdc.GetNsxtEdgeGatewayByName(vcd.config.VCD.Nsxt.EdgeGateway)
check.Assert(err, IsNil)
AddToCleanupList(vcd.config.VCD.Nsxt.EdgeGateway, "slaacProfile", vcd.config.VCD.Org, check.TestName())

// Fetch current SLAAC Profile
slaacProfile, err := edge.GetSlaacProfile()
check.Assert(err, IsNil)
check.Assert(slaacProfile, NotNil)
check.Assert(slaacProfile.Enabled, Equals, false)

// Create new SLAAC config in SLAAC mode
newSlaacProfile := &types.NsxtEdgeGatewaySlaacProfile{
Enabled: true,
Mode: "SLAAC",
DNSConfig: types.NsxtEdgeGatewaySlaacProfileDNSConfig{
DNSServerIpv6Addresses: []string{"2001:4860:4860::8888", "2001:4860:4860::8844"},
DomainNames: []string{"non-existing.org.tld", "fake.org.tld"},
},
}

// Update SLAAC profile
updatedSlaacProfile, err := edge.UpdateSlaacProfile(newSlaacProfile)
check.Assert(err, IsNil)
check.Assert(updatedSlaacProfile, NotNil)
check.Assert(updatedSlaacProfile, DeepEquals, newSlaacProfile)

// Create new SLAAC config in DHCPv6 mode
newSlaacProfileDhcpv6 := &types.NsxtEdgeGatewaySlaacProfile{
Enabled: true,
Mode: "DHCPv6",
DNSConfig: types.NsxtEdgeGatewaySlaacProfileDNSConfig{
DNSServerIpv6Addresses: []string{},
DomainNames: []string{},
},
}

// Update SLAAC profile
updatedSlaacProfileDhcpv6, err := edge.UpdateSlaacProfile(newSlaacProfileDhcpv6)
check.Assert(err, IsNil)
check.Assert(updatedSlaacProfileDhcpv6, NotNil)
check.Assert(updatedSlaacProfileDhcpv6, DeepEquals, newSlaacProfileDhcpv6)

// Cleanup
updatedSlaacProfile, err = edge.UpdateSlaacProfile(&types.NsxtEdgeGatewaySlaacProfile{Enabled: false, Mode: "DISABLED"})
check.Assert(err, IsNil)
check.Assert(updatedSlaacProfile, NotNil)
}
12 changes: 12 additions & 0 deletions govcd/openapi_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var endpointMinApiVersions = map[string]string{
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.OpenApiEndpointEdgeGatewaySlaacProfile: "35.0",
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayStaticRoutes: "37.0", // VCD 10.4.0+ (NSX-T only)
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways: "34.0",
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayUsedIpAddresses: "34.0",
Expand Down Expand Up @@ -166,6 +167,17 @@ var endpointElevatedApiVersions = map[string][]string{
"37.0", // Deprecates LicenseType in favor of SupportedFeatureSet. Adds IPv6 service network definition support
"37.1", // Adds support for Transparent Mode
},
//
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices: {
//"35.0", // Basic minimum required version
"37.0", // Adds IPv6 Virtual Service Support
"37.1", // Adds support for Transparent Mode
},
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServiceSummaries: {
//"35.0", // Basic minimum required version
"37.0", // Adds IPv6 Virtual Service Support
"37.1", // Adds support for Transparent Mode
},
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcNetworkProfile: {
//"36.0", // Introduced support
"36.2", // 2 additional fields vappNetworkSegmentProfileTemplateRef and vdcNetworkSegmentProfileTemplateRef added
Expand Down
1 change: 1 addition & 0 deletions types/v56/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ const (
OpenApiEndpointEdgeGateways = "edgeGateways/"
OpenApiEndpointEdgeGatewayQos = "edgeGateways/%s/qos"
OpenApiEndpointEdgeGatewayDhcpForwarder = "edgeGateways/%s/dhcpForwarder"
OpenApiEndpointEdgeGatewaySlaacProfile = "edgeGateways/%s/slaacProfile"
OpenApiEndpointEdgeGatewayStaticRoutes = "edgeGateways/%s/routing/staticRoutes/"
OpenApiEndpointEdgeGatewayUsedIpAddresses = "edgeGateways/%s/usedIpAddresses"
OpenApiEndpointNsxtFirewallRules = "edgeGateways/%s/firewall/rules"
Expand Down
24 changes: 24 additions & 0 deletions types/v56/nsxt_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ type OpenApiOrgVdcNetwork struct {

// Shared shares network with other VDCs in the organization
Shared *bool `json:"shared,omitempty"`

// EnableDualSubnetNetwork defines whether or not this network will support two subnets (IPv4
// and IPv6)
EnableDualSubnetNetwork *bool `json:"enableDualSubnetNetwork,omitempty"`
}

// OrgVdcNetworkSubnetIPRanges is a type alias to reuse the same definitions with appropriate names
Expand Down Expand Up @@ -1240,6 +1244,10 @@ type NsxtAlbVirtualService struct {
// VirtualIpAddress to be used for exposing this virtual service
VirtualIpAddress string `json:"virtualIpAddress"`

// IPv6VirtualIpAddress defined IPv6 address to be used for this virtual service
// This field is only available in VCD 10.4.0 (v37.0+)
IPv6VirtualIpAddress string `json:"ipv6VirtualIpAddress,omitempty"`

// TransparentModeEnabled allows to configure Preserve Client IP on a Virtual Service
// This field is only available for VCD 10.4.1+ (v37.1+)
// Note. `types.NsxtAlbConfig.TransparentModeEnabled` must be set to `true` for this field to be
Expand Down Expand Up @@ -1709,6 +1717,22 @@ type VcenterImportableDvpg struct {
Vlan string `json:"vlan"`
}

// NsxtEdgeGatewaySlaacProfile provides configuration for NSX-T Edge Gateway IPv6 configuration
type NsxtEdgeGatewaySlaacProfile struct {
Enabled bool `json:"enabled"`
// Mode is 'SLAAC' ,'DHCPv6', 'DISABLED'
Mode string `json:"mode"`
// DNSConfig provides additional configuration when Mode is set to 'SLAAC'
DNSConfig NsxtEdgeGatewaySlaacProfileDNSConfig `json:"dnsConfig,omitempty"`
}

// NsxtEdgeGatewaySlaacProfileDNSConfig contains additional NSX-T Edge Gateway IPv6 configuration
// when it is configured for 'SLAAC' mode
type NsxtEdgeGatewaySlaacProfileDNSConfig struct {
DNSServerIpv6Addresses []string `json:"dnsServerIpv6Addresses,omitempty"`
DomainNames []string `json:"domainNames,omitempty"`
}

// NsxtEdgeGatewayStaticRoute provides configuration structure for NSX-T Edge Gateway static route
// configuration
type NsxtEdgeGatewayStaticRoute struct {
Expand Down

0 comments on commit 49c9ba9

Please sign in to comment.