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

NSX-T ALB Virtual Service Transparent mode and Pool Firewall Group membership (VCD 10.4.1+) #560

Merged
merged 12 commits into from
Mar 27, 2023
5 changes: 5 additions & 0 deletions .changes/v2.20.0/560-improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Add new field `TransparentModeEnabled` to `types.NsxtAlbVirtualService` which allows to preserve
client IP for NSX-T ALB Virtual Service (VCD 10.4.1+) [GH-560]
* Add new field `MemberGroupRef` to `types.NsxtAlbPool` which allows to define NSX-T ALB Pool
membership by using Edge Firewall Group (`NsxtFirewallGroup`) instead of plain IPs (VCD 10.4.1+)
[GH-560]
5 changes: 5 additions & 0 deletions govcd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,11 @@ func combinedTaskErrorMessage(task *types.Task, err error) string {
return extendedError
}

// addrOf is a generic function to return the address of a variable
func addrOf[T any](variable T) *T {
return &variable
}

func takeBoolPointer(value bool) *bool {
return &value
}
Expand Down
1 change: 1 addition & 0 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ type TestConfig struct {
NsxtAlbControllerUser string `yaml:"nsxtAlbControllerUser"`
NsxtAlbControllerPassword string `yaml:"nsxtAlbControllerPassword"`
NsxtAlbImportableCloud string `yaml:"nsxtAlbImportableCloud"`
NsxtAlbServiceEngineGroup string `yaml:"nsxtAlbServiceEngineGroup"`
} `yaml:"nsxt"`
} `yaml:"vcd"`
Logging struct {
Expand Down
6 changes: 6 additions & 0 deletions govcd/nsxt_alb_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ func setupAlbPoolPrerequisites(check *C, vcd *TestVCD) (*NsxtAlbController, *Nsx
albSettingsConfig.SupportedFeatureSet = "PREMIUM"
}

// 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")
albSettingsConfig.TransparentModeEnabled = addrOf(true)
}

enabledSettings, err := edge.UpdateAlbSettings(albSettingsConfig)
if err != nil {
fmt.Printf("# error occured while enabling ALB on Edge Gateway. Cleaning up Service Engine Group, ALB Cloud and ALB Controller: %s", err)
Expand Down
6 changes: 3 additions & 3 deletions govcd/nsxt_alb_service_engine_groups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ func spawnAlbControllerCloudServiceEngineGroup(vcd *TestVCD, check *C, seGroupRe

albController, createdAlbCloud := spawnAlbControllerAndCloud(vcd, check)

importableSeGroups, err := vcd.client.GetAllAlbImportableServiceEngineGroups(createdAlbCloud.NsxtAlbCloud.ID, nil)
importableSeGroup, err := vcd.client.GetAlbImportableServiceEngineGroupByName(createdAlbCloud.NsxtAlbCloud.ID, vcd.config.VCD.Nsxt.NsxtAlbServiceEngineGroup)
check.Assert(err, IsNil)
check.Assert(len(importableSeGroups) > 0, Equals, true)

albSeGroup := &types.NsxtAlbServiceEngineGroup{
Name: check.TestName() + "SE-group",
Description: "Service Engine Group created by " + check.TestName(),
ReservationType: seGroupReservationType,
ServiceEngineGroupBacking: types.ServiceEngineGroupBacking{
BackingId: importableSeGroups[0].NsxtAlbImportableServiceEngineGroups.ID,
BackingId: importableSeGroup.NsxtAlbImportableServiceEngineGroups.ID,
LoadBalancerCloudRef: &types.OpenApiReference{
ID: createdAlbCloud.NsxtAlbCloud.ID,
},
Expand Down
118 changes: 118 additions & 0 deletions govcd/nsxt_alb_virtual_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,44 @@ func (vcd *TestVCD) Test_AlbVirtualService(check *C) {
orgUserVcdClient, err := newOrgUserConnection(adminOrg, "alb-virtual-service-testing", "CHANGE-ME", vcd.config.Provider.Url, true)
check.Assert(err, IsNil)

printVerbose("# Running tests as Sysadmin user\n")
// Run tests with System user
testMinimalVirtualServiceConfigHTTP(check, edge, albPool, seGroup, vcd, vcd.client)
testVirtualServiceConfigWithCertHTTPS(check, edge, albPool, seGroup, vcd, vcd.client)
testMinimalVirtualServiceConfigL4(check, edge, albPool, seGroup, vcd, vcd.client)
testMinimalVirtualServiceConfigL4TLS(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)

// Test 10.4.1 Transparent mode on VCD >= 10.4.1
if vcd.client.Client.APIVCDMaxVersionIs(">= 37.1") {
printVerbose("# Running 10.4.1+ tests as Sysadmin user\n")

printVerbose("## Creating ALB Pool with Member Group (VCD 10.4.1+) as Sysadmin\n")
ipSet, poolWithMemberGroup := setupAlbPoolFirewallGroupMembers(check, vcd, edge)

testMinimalVirtualServiceConfigHTTPTransparent(check, edge, poolWithMemberGroup, seGroup, vcd, vcd.client, true)
testMinimalVirtualServiceConfigHTTPTransparent(check, edge, poolWithMemberGroup, seGroup, vcd, vcd.client, false)

printVerbose("# Running 10.4.1+ tests as Org user\n")

printVerbose("## Creating ALB Pool with Member Group (VCD 10.4.1+) as Org user\n")
testMinimalVirtualServiceConfigHTTPTransparent(check, edge, poolWithMemberGroup, seGroup, vcd, orgUserVcdClient, true)
testMinimalVirtualServiceConfigHTTPTransparent(check, edge, poolWithMemberGroup, seGroup, vcd, orgUserVcdClient, false)

// cleanup ipset and pool membership
err = poolWithMemberGroup.Delete()
check.Assert(err, IsNil)

err = ipSet.Delete()
check.Assert(err, IsNil)
}

// teardown prerequisites
tearDownAlbVirtualServicePrerequisites(check, albPool, seGroupAssignment, edge, seGroup, cloud, controller)
}
Expand Down Expand Up @@ -94,6 +120,63 @@ func testMinimalVirtualServiceConfigHTTP(check *C, edge *NsxtEdgeGateway, pool *
testAlbVirtualServiceConfig(check, vcd, "MinimalHTTP", virtualServiceConfig, virtualServiceConfigUpdated, client)
}

func testMinimalVirtualServiceConfigHTTPTransparent(check *C, edge *NsxtEdgeGateway, poolWithMemberGroup *NsxtAlbPool, seGroup *NsxtAlbServiceEngineGroup, vcd *TestVCD, client *VCDClient, trueOnCreate bool) {
createTransparentMode := trueOnCreate
updateTransparentMode := !createTransparentMode

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

virtualServiceConfigUpdated := &types.NsxtAlbVirtualService{
Name: check.TestName(),
Description: "Updated",
Enabled: addrOf(true),
TransparentModeEnabled: addrOf(updateTransparentMode),
ApplicationProfile: types.NsxtAlbVirtualServiceApplicationProfile{
SystemDefined: true,
Type: "HTTP",
},
GatewayRef: types.OpenApiReference{ID: edge.EdgeGateway.ID},
LoadBalancerPoolRef: types.OpenApiReference{ID: poolWithMemberGroup.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,
//HealthStatus: "",
//HealthMessage: "",
//DetailedHealthMessage: "",
}

testAlbVirtualServiceConfig(check, vcd, fmt.Sprintf("MinimalHTTPWithTransparentModeOnCreate%t", createTransparentMode), virtualServiceConfig, virtualServiceConfigUpdated, client)
}

func testMinimalVirtualServiceConfigL4(check *C, edge *NsxtEdgeGateway, pool *NsxtAlbPool, seGroup *NsxtAlbServiceEngineGroup, vcd *TestVCD, client *VCDClient) {
virtualServiceConfig := &types.NsxtAlbVirtualService{
Name: check.TestName(),
Expand Down Expand Up @@ -363,6 +446,41 @@ func setupAlbVirtualServicePrerequisites(check *C, vcd *TestVCD) (*NsxtAlbContro
return controller, cloud, seGroup, edge, assignedSeGroup, albPool
}

func setupAlbPoolFirewallGroupMembers(check *C, vcd *TestVCD, edge *NsxtEdgeGateway) (*NsxtFirewallGroup, *NsxtAlbPool) {
// creates ip set
ipSetConfig := &types.NsxtFirewallGroup{
Name: check.TestName(),
OwnerRef: &types.OpenApiReference{ID: edge.EdgeGateway.ID},
Description: "Test IP Set",
Type: "IP_SET",
IpAddresses: []string{"1.1.1.1"},
}

ipSet, err := vcd.nsxtVdc.CreateNsxtFirewallGroup(ipSetConfig)
check.Assert(err, IsNil)

// add ip set to cleanup list
openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups + ipSet.NsxtFirewallGroup.ID
PrependToCleanupListOpenApi(ipSet.NsxtFirewallGroup.Name, check.TestName(), openApiEndpoint)

poolConfig := &types.NsxtAlbPool{
Name: check.TestName() + "-member-group",
Enabled: takeBoolPointer(true),
GatewayRef: types.OpenApiReference{ID: edge.EdgeGateway.ID},
MemberGroupRef: &types.OpenApiReference{
ID: ipSet.NsxtFirewallGroup.ID,
},
}

albPool, err := vcd.client.CreateNsxtAlbPool(poolConfig)
check.Assert(err, IsNil)

openApiEndpoint = types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPools + albPool.NsxtAlbPool.ID
PrependToCleanupListOpenApi(albPool.NsxtAlbPool.Name, check.TestName(), openApiEndpoint)

return ipSet, albPool
}

func tearDownAlbVirtualServicePrerequisites(check *C, albPool *NsxtAlbPool, assignment *NsxtAlbServiceEngineGroupAssignment, edge *NsxtEdgeGateway, seGroup *NsxtAlbServiceEngineGroup, cloud *NsxtAlbCloud, controller *NsxtAlbController) {
err := albPool.Delete()
check.Assert(err, IsNil)
Expand Down
8 changes: 8 additions & 0 deletions govcd/nsxt_edgegateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ func (vdcGroup *VdcGroup) GetNsxtEdgeGatewayByName(name string) (*NsxtEdgeGatewa
return returnSingleNsxtEdgeGateway(name, allEdges)
}

// GetAllNsxtEdgeGateways allows to retrieve all NSX-T Edge Gateways
func (vcdClient *VCDClient) GetAllNsxtEdgeGateways(queryParameters url.Values) ([]*NsxtEdgeGateway, error) {
if vcdClient == nil {
return nil, fmt.Errorf("vcdClient is empty")
}
return getAllNsxtEdgeGateways(&vcdClient.Client, queryParameters)
}

// GetAllNsxtEdgeGateways allows to retrieve all NSX-T edge gateways for Org Admins
func (adminOrg *AdminOrg) GetAllNsxtEdgeGateways(queryParameters url.Values) ([]*NsxtEdgeGateway, error) {
return getAllNsxtEdgeGateways(adminOrg.client, queryParameters)
Expand Down
10 changes: 10 additions & 0 deletions govcd/sample_govcd_test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ vcd:
nsxtImportSegment: vcd-org-vdc-imported-network-backing
# Existing NSX-T Edge Cluster name
nsxtEdgeCluster: existing-nsxt-edge-cluster
# AVI Controller URL
nsxtAlbControllerUrl: https://unknown-hostname.com
# AVI Controller username
nsxtAlbControllerUser: admin
# AVI Controller password
nsxtAlbControllerPassword: CHANGE-ME
# AVI Controller importable Cloud name
nsxtAlbImportableCloud: NSXT AVI Cloud
# Service Engine Group name within (Should be configured in Active Standby mode)
nsxtAlbServiceEngineGroup: active-standby-service-engine-group
# An Org catalog, possibly containing at least one item
catalog:
name: mycat
Expand Down
16 changes: 16 additions & 0 deletions types/v56/nsxt_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -962,8 +962,18 @@ type NsxtAlbPool struct {

// Members field defines list of destination servers which are used by the Load Balancer Pool to direct load balanced
// traffic.
//
// Note. Only one of Members or MemberGroupRef can be specified
Members []NsxtAlbPoolMember `json:"members,omitempty"`

// MemberGroupRef contains reference to the Edge Firewall Group (`types.NsxtFirewallGroup`)
// representing destination servers which are used by the Load Balancer Pool to direct load
// balanced traffic.
//
// This field is only available in VCD 10.4.1+ (v37.1+)
// Note. Only one of Members or MemberGroupRef can be specified
MemberGroupRef *OpenApiReference `json:"memberGroupRef,omitempty"`

// CaCertificateRefs point to root certificates to use when validating certificates presented by the pool members.
CaCertificateRefs []OpenApiReference `json:"caCertificateRefs,omitempty"`

Expand Down Expand Up @@ -1105,6 +1115,12 @@ type NsxtAlbVirtualService struct {
// VirtualIpAddress to be used for exposing this virtual service
VirtualIpAddress string `json:"virtualIpAddress"`

// 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
// available.
TransparentModeEnabled *bool `json:"transparentModeEnabled,omitempty"`

// HealthStatus contains status of the Load Balancer Cloud. Possible values are:
// UP - The cloud is healthy and ready to enable Load Balancer for an Edge Gateway.
// DOWN - The cloud is in a failure state. Enabling Load balancer on an Edge Gateway may not be possible.
Expand Down