Skip to content

Commit c9239d5

Browse files
authored
Merge pull request #1529 from Jeremy-Boyle/backport-ovn-lb-0.7
✨ Backport Provider to release-0.7
2 parents d31913d + 19b3975 commit c9239d5

File tree

9 files changed

+66
-23
lines changed

9 files changed

+66
-23
lines changed

api/v1alpha3/conversion_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ func TestFuzzyConversion(t *testing.T) {
231231
v1alpha6Cluster.Spec.AllowAllInClusterTraffic = false
232232
v1alpha6Cluster.Spec.DisableAPIServerFloatingIP = false
233233
v1alpha6Cluster.Spec.APIServerLoadBalancer.AllowedCIDRs = nil
234+
v1alpha6Cluster.Spec.APIServerLoadBalancer.Provider = ""
234235
if v1alpha6Cluster.Spec.Bastion != nil {
235236
v1alpha6Cluster.Spec.Bastion.Instance.ImageUUID = ""
236237
v1alpha6Cluster.Spec.Bastion.Instance.Ports = nil

api/v1alpha4/conversion_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ func TestFuzzyConversion(t *testing.T) {
331331

332332
v1alpha6Cluster.Spec.APIServerLoadBalancer.AllowedCIDRs = nil
333333

334+
v1alpha6Cluster.Spec.APIServerLoadBalancer.Provider = ""
335+
334336
v1alpha6Cluster.Spec.ControlPlaneOmitAvailabilityZone = false
335337

336338
if v1alpha6Cluster.Spec.Bastion != nil {
@@ -407,6 +409,8 @@ func TestFuzzyConversion(t *testing.T) {
407409

408410
v1alpha6ClusterTemplate.Spec.Template.Spec.APIServerLoadBalancer.AllowedCIDRs = nil
409411

412+
v1alpha6ClusterTemplate.Spec.Template.Spec.APIServerLoadBalancer.Provider = ""
413+
410414
v1alpha6ClusterTemplate.Spec.Template.Spec.ControlPlaneOmitAvailabilityZone = false
411415

412416
if v1alpha6ClusterTemplate.Spec.Template.Spec.Bastion != nil {

api/v1alpha5/conversion.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,8 @@ func Convert_v1alpha6_OpenStackClusterSpec_To_v1alpha5_OpenStackClusterSpec(in *
202202
// Our new flag has no equivalent in v1alpha5
203203
return autoConvert_v1alpha6_OpenStackClusterSpec_To_v1alpha5_OpenStackClusterSpec(in, out, s)
204204
}
205+
206+
func Convert_v1alpha6_APIServerLoadBalancer_To_v1alpha5_APIServerLoadBalancer(in *infrav1.APIServerLoadBalancer, out *APIServerLoadBalancer, s conversion.Scope) error {
207+
// Provider has been added in v1alpha6 but has no equivalent in v1alpha5
208+
return autoConvert_v1alpha6_APIServerLoadBalancer_To_v1alpha5_APIServerLoadBalancer(in, out, s)
209+
}

api/v1alpha5/zz_generated.conversion.go

Lines changed: 6 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha6/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,6 @@ type APIServerLoadBalancer struct {
313313
AdditionalPorts []int `json:"additionalPorts,omitempty"`
314314
// AllowedCIDRs restrict access to all API-Server listeners to the given address CIDRs.
315315
AllowedCIDRs []string `json:"allowedCidrs,omitempty"`
316+
// Octavia Provider Used to create load balancer
317+
Provider string `json:"provider,omitempty"`
316318
}

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4283,6 +4283,9 @@ spec:
42834283
description: Enabled defines whether a load balancer should be
42844284
created.
42854285
type: boolean
4286+
provider:
4287+
description: Octavia Provider Used to create load balancer
4288+
type: string
42864289
type: object
42874290
apiServerPort:
42884291
description: APIServerPort is the port on which the listener on the

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,9 @@ spec:
15081508
description: Enabled defines whether a load balancer should
15091509
be created.
15101510
type: boolean
1511+
provider:
1512+
description: Octavia Provider Used to create load balancer
1513+
type: string
15111514
type: object
15121515
apiServerPort:
15131516
description: APIServerPort is the port on which the listener

pkg/cloud/services/loadbalancer/loadbalancer.go

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ import (
4040
)
4141

4242
const (
43-
networkPrefix string = "k8s-clusterapi"
44-
kubeapiLBSuffix string = "kubeapi"
45-
defaultLoadBalancerProvider string = "amphora"
43+
networkPrefix string = "k8s-clusterapi"
44+
kubeapiLBSuffix string = "kubeapi"
4645
)
4746

4847
const loadBalancerProvisioningStatusActive = "ACTIVE"
@@ -64,13 +63,18 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
6463
return err
6564
}
6665

67-
// As mostly all LoadBalancer features are only supported on "amphora" we explicitly set the provider
68-
// in the LoadBalancer create call to make sure to get the desired features - even if multiple providers exist.
69-
var lbProvider string
70-
for _, v := range providers {
71-
if v.Name == defaultLoadBalancerProvider {
72-
lbProvider = v.Name
73-
break
66+
// Choose the selected provider if it is set in cluster spec, if not, omit the field and Octavia will use the default provider.
67+
lbProvider := ""
68+
if openStackCluster.Spec.APIServerLoadBalancer.Provider != "" {
69+
for _, v := range providers {
70+
if v.Name == openStackCluster.Spec.APIServerLoadBalancer.Provider {
71+
lbProvider = v.Name
72+
break
73+
}
74+
}
75+
if lbProvider == "" {
76+
record.Warnf(openStackCluster, "OctaviaProviderNotFound", "Provider specified for Octavia not found.")
77+
record.Eventf(openStackCluster, "OctaviaProviderNotFound", "Provider %s specified for Octavia not found, using the default provider.", openStackCluster.Spec.APIServerLoadBalancer.Provider)
7478
}
7579
}
7680

@@ -124,7 +128,7 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
124128
return err
125129
}
126130

127-
pool, err := s.getOrCreatePool(openStackCluster, lbPortObjectsName, listener.ID, lb.ID)
131+
pool, err := s.getOrCreatePool(openStackCluster, lbPortObjectsName, listener.ID, lb.ID, lb.Provider)
128132
if err != nil {
129133
return err
130134
}
@@ -296,7 +300,7 @@ func validateIPs(openStackCluster *infrav1.OpenStackCluster, definedCIDRs []stri
296300
return marshaledCIDRs
297301
}
298302

299-
func (s *Service) getOrCreatePool(openStackCluster *infrav1.OpenStackCluster, poolName, listenerID, lbID string) (*pools.Pool, error) {
303+
func (s *Service) getOrCreatePool(openStackCluster *infrav1.OpenStackCluster, poolName, listenerID, lbID, lbProvider string) (*pools.Pool, error) {
300304
pool, err := s.checkIfPoolExists(poolName)
301305
if err != nil {
302306
return nil, err
@@ -308,12 +312,19 @@ func (s *Service) getOrCreatePool(openStackCluster *infrav1.OpenStackCluster, po
308312

309313
s.scope.Logger.Info(fmt.Sprintf("Creating load balancer pool for listener %q", listenerID), "name", poolName, "lb-id", lbID)
310314

315+
method := pools.LBMethodRoundRobin
316+
317+
if lbProvider == "ovn" {
318+
method = pools.LBMethodSourceIpPort
319+
}
320+
311321
poolCreateOpts := pools.CreateOpts{
312322
Name: poolName,
313323
Protocol: "TCP",
314-
LBMethod: pools.LBMethodRoundRobin,
324+
LBMethod: method,
315325
ListenerID: listenerID,
316326
}
327+
317328
pool, err = s.loadbalancerClient.CreatePool(poolCreateOpts)
318329
if err != nil {
319330
record.Warnf(openStackCluster, "FailedCreatePool", "Failed to create pool %s: %v", poolName, err)
@@ -351,6 +362,13 @@ func (s *Service) getOrCreateMonitor(openStackCluster *infrav1.OpenStackCluster,
351362
Timeout: 5,
352363
}
353364
monitor, err = s.loadbalancerClient.CreateMonitor(monitorCreateOpts)
365+
// Skip creating monitor if it is not supported by Octavia provider
366+
if capoerrors.IsNotImplementedError(err) {
367+
record.Warnf(openStackCluster, "SkippedCreateMonitor", "Health monitors are not supported with the current Octavia provider.")
368+
record.Eventf(openStackCluster, "SkippedCreateMonitor", "Health Monitor is not created as it's not implemented with the current Octavia provider.")
369+
return nil
370+
}
371+
354372
if err != nil {
355373
record.Warnf(openStackCluster, "FailedCreateMonitor", "Failed to create monitor %s: %v", monitorName, err)
356374
return err

pkg/utils/errors/errors.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,14 @@ func IsConflict(err error) bool {
8484

8585
return false
8686
}
87+
88+
func IsNotImplementedError(err error) bool {
89+
var errUnexpectedResponseCode gophercloud.ErrUnexpectedResponseCode
90+
if errors.As(err, &errUnexpectedResponseCode) {
91+
if errUnexpectedResponseCode.Actual == http.StatusNotImplemented {
92+
return true
93+
}
94+
}
95+
96+
return false
97+
}

0 commit comments

Comments
 (0)