Skip to content

Commit f2c56b3

Browse files
author
elweb9858
committed
Added distribution type option to loadbalancer
1 parent 3cb5e37 commit f2c56b3

File tree

5 files changed

+61
-10
lines changed

5 files changed

+61
-10
lines changed

hcn/hcn.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ func AclSupportForProtocol252Supported() error {
179179
return platformDoesNotSupportError("HNS ACL Policies to support protocol 252 for VXLAN")
180180
}
181181

182+
// SessionAffinitySupported returns an error if the HCN version does not support Session Affinity.
183+
func SessionAffinitySupported() error {
184+
supported := GetSupportedFeatures()
185+
if supported.SessionAffinity {
186+
return nil
187+
}
188+
return platformDoesNotSupportError("Session Affinity")
189+
}
190+
182191
// RequestType are the different operations performed to settings.
183192
// Used to update the settings of Endpoint/Namespace objects.
184193
type RequestType string

hcn/hcnglobals.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ var (
4949
VersionRange{MinVersion: Version{Major: 9, Minor: 3}, MaxVersion: Version{Major: 9, Minor: math.MaxInt32}},
5050
VersionRange{MinVersion: Version{Major: 10, Minor: 4}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
5151
}
52+
// HNS 11.10 allows for session affinity for loadbalancing
53+
SessionAffinityVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 11, Minor: 10}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
5254
)
5355

5456
// GetGlobals returns the global properties of the HCN Service.

hcn/hcnloadbalancer.go

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import (
1010

1111
// LoadBalancerPortMapping is associated with HostComputeLoadBalancer
1212
type LoadBalancerPortMapping struct {
13-
Protocol uint32 `json:",omitempty"` // EX: TCP = 6, UDP = 17
14-
InternalPort uint16 `json:",omitempty"`
15-
ExternalPort uint16 `json:",omitempty"`
16-
Flags LoadBalancerPortMappingFlags `json:",omitempty"`
13+
Protocol uint32 `json:",omitempty"` // EX: TCP = 6, UDP = 17
14+
InternalPort uint16 `json:",omitempty"`
15+
ExternalPort uint16 `json:",omitempty"`
16+
DistributionType LoadBalancerDistribution `json:",omitempty"` // EX: Distribute per connection = 0, distribute traffic of the same protocol per client IP = 1, distribute per client IP = 2
17+
Flags LoadBalancerPortMappingFlags `json:",omitempty"`
1718
}
1819

1920
// HostComputeLoadBalancer represents software load balancer.
@@ -53,6 +54,22 @@ var (
5354
LoadBalancerPortMappingFlagsPreserveDIP LoadBalancerPortMappingFlags = 8
5455
)
5556

57+
// LoadBalancerDistribution specifies how the loadbalancer distributes traffic.
58+
type LoadBalancerDistribution uint32
59+
60+
var (
61+
// LoadBalancerDistributionNone is the default and loadbalances each connection to the same pod.
62+
LoadBalancerDistributionNone LoadBalancerDistribution
63+
// LoadBalancerDistributionSourceIPProtocol loadbalances all traffic of the same protocol from a client IP to the same pod.
64+
LoadBalancerDistributionSourceIPProtocol LoadBalancerDistribution = 1
65+
// LoadBalancerDistributionSourceIP loadbalances all traffic from a client IP to the same pod.
66+
LoadBalancerDistributionSourceIP LoadBalancerDistribution = 2
67+
)
68+
69+
func (distributionType LoadBalancerDistribution) String() string {
70+
return [...]string{"None", "SourceIPProtocol", "SourceIP"}[distributionType]
71+
}
72+
5673
func getLoadBalancer(loadBalancerGuid guid.GUID, query string) (*HostComputeLoadBalancer, error) {
5774
// Open loadBalancer.
5875
var (
@@ -312,17 +329,18 @@ func (loadBalancer *HostComputeLoadBalancer) RemoveEndpoint(endpoint *HostComput
312329
}
313330

314331
// AddLoadBalancer for the specified endpoints
315-
func AddLoadBalancer(endpoints []HostComputeEndpoint, flags LoadBalancerFlags, portMappingFlags LoadBalancerPortMappingFlags, sourceVIP string, frontendVIPs []string, protocol uint16, internalPort uint16, externalPort uint16) (*HostComputeLoadBalancer, error) {
316-
logrus.Debugf("hcn::HostComputeLoadBalancer::AddLoadBalancer endpointId=%v, LoadBalancerFlags=%v, LoadBalancerPortMappingFlags=%v, sourceVIP=%s, frontendVIPs=%v, protocol=%v, internalPort=%v, externalPort=%v", endpoints, flags, portMappingFlags, sourceVIP, frontendVIPs, protocol, internalPort, externalPort)
332+
func AddLoadBalancer(endpoints []HostComputeEndpoint, flags LoadBalancerFlags, portMappingFlags LoadBalancerPortMappingFlags, sourceVIP string, frontendVIPs []string, protocol uint16, internalPort uint16, externalPort uint16, additionalParams ...string) (*HostComputeLoadBalancer, error) {
333+
logrus.Debugf("hcn::HostComputeLoadBalancer::AddLoadBalancer endpointId=%v, LoadBalancerFlags=%v, LoadBalancerPortMappingFlags=%v, sourceVIP=%s, frontendVIPs=%v, protocol=%v, internalPort=%v, externalPort=%v, additionalParams=%v", endpoints, flags, portMappingFlags, sourceVIP, frontendVIPs, protocol, internalPort, externalPort, additionalParams)
317334

318335
loadBalancer := &HostComputeLoadBalancer{
319336
SourceVIP: sourceVIP,
320337
PortMappings: []LoadBalancerPortMapping{
321338
{
322-
Protocol: uint32(protocol),
323-
InternalPort: internalPort,
324-
ExternalPort: externalPort,
325-
Flags: portMappingFlags,
339+
Protocol: uint32(protocol),
340+
InternalPort: internalPort,
341+
ExternalPort: externalPort,
342+
DistributionType: LoadBalancerDistributionNone,
343+
Flags: portMappingFlags,
326344
},
327345
},
328346
FrontendVIPs: frontendVIPs,
@@ -333,6 +351,15 @@ func AddLoadBalancer(endpoints []HostComputeEndpoint, flags LoadBalancerFlags, p
333351
Flags: flags,
334352
}
335353

354+
if additionalParams != nil {
355+
switch additionalParams[0] {
356+
case "SourceIPProtocol":
357+
loadBalancer.PortMappings[0].DistributionType = LoadBalancerDistributionSourceIPProtocol
358+
case "SourceIP":
359+
loadBalancer.PortMappings[0].DistributionType = LoadBalancerDistributionSourceIP
360+
}
361+
}
362+
336363
for _, endpoint := range endpoints {
337364
loadBalancer.HostComputeEndpoints = append(loadBalancer.HostComputeEndpoints, endpoint.Id)
338365
}

hcn/hcnsupport.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type SupportedFeatures struct {
1313
DSR bool `json:"DSR"`
1414
Slash32EndpointPrefixes bool `json:"Slash32EndpointPrefixes"`
1515
AclSupportForProtocol252 bool `json:"AclSupportForProtocol252"`
16+
SessionAffinity bool `json:"SessionAffinity"`
1617
}
1718

1819
// AclFeatures are the supported ACL possibilities.
@@ -57,6 +58,7 @@ func GetSupportedFeatures() SupportedFeatures {
5758
features.DSR = isFeatureSupported(globals.Version, DSRVersion)
5859
features.Slash32EndpointPrefixes = isFeatureSupported(globals.Version, Slash32EndpointPrefixesVersion)
5960
features.AclSupportForProtocol252 = isFeatureSupported(globals.Version, AclSupportForProtocol252Version)
61+
features.SessionAffinity = isFeatureSupported(globals.Version, SessionAffinityVersion)
6062

6163
return features
6264
}

hcn/hcnsupport_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ func TestAclSupportForProtocol252Support(t *testing.T) {
8383
}
8484
}
8585

86+
func TestSessionAffinitySupport(t *testing.T) {
87+
supportedFeatures := GetSupportedFeatures()
88+
err := SessionAffinitySupported()
89+
if supportedFeatures.SessionAffinity && err != nil {
90+
t.Fatal(err)
91+
}
92+
if !supportedFeatures.SessionAffinity && err == nil {
93+
t.Fatal(err)
94+
}
95+
}
96+
8697
func TestIsFeatureSupported(t *testing.T) {
8798
// HNSVersion1803 testing (single range tests)
8899
if isFeatureSupported(Version{Major: 0, Minor: 0}, HNSVersion1803) {

0 commit comments

Comments
 (0)