@@ -438,44 +438,69 @@ func reconcileNetworkComponents(log logr.Logger, osProviderClient *gophercloud.P
438
438
return errors .Errorf ("failed to reconcile router: %v" , err )
439
439
}
440
440
}
441
- if ! openStackCluster .Spec .ControlPlaneEndpoint .IsValid () {
442
- var port int32
443
- if openStackCluster .Spec .APIServerPort == 0 {
444
- port = 6443
445
- } else {
446
- port = int32 (openStackCluster .Spec .APIServerPort )
447
- }
448
- fp , err := networkingService .GetOrCreateFloatingIP (openStackCluster , clusterName , openStackCluster .Spec .APIServerFloatingIP )
449
- if err != nil {
450
- handleUpdateOSCError (openStackCluster , errors .Errorf ("Floating IP cannot be got or created: %v" , err ))
451
- return errors .Errorf ("Floating IP cannot be got or created: %v" , err )
452
- }
453
- // Set APIEndpoints so the Cluster API Cluster Controller can pull them
454
- openStackCluster .Spec .ControlPlaneEndpoint = clusterv1.APIEndpoint {
455
- Host : fp .FloatingIP ,
456
- Port : port ,
457
- }
458
- }
459
441
460
442
err = networkingService .ReconcileSecurityGroups (openStackCluster , clusterName )
461
443
if err != nil {
462
444
handleUpdateOSCError (openStackCluster , errors .Errorf ("failed to reconcile security groups: %v" , err ))
463
445
return errors .Errorf ("failed to reconcile security groups: %v" , err )
464
446
}
465
447
448
+ // Calculate the port that we will use for the API server
449
+ var apiServerPort int
450
+ if openStackCluster .Spec .ControlPlaneEndpoint .IsValid () {
451
+ apiServerPort = int (openStackCluster .Spec .ControlPlaneEndpoint .Port )
452
+ } else if openStackCluster .Spec .APIServerPort != 0 {
453
+ apiServerPort = openStackCluster .Spec .APIServerPort
454
+ } else {
455
+ apiServerPort = 6443
456
+ }
457
+
466
458
if openStackCluster .Spec .ManagedAPIServerLoadBalancer {
467
459
loadBalancerService , err := loadbalancer .NewService (osProviderClient , clientOpts , log )
468
460
if err != nil {
469
461
return err
470
462
}
471
463
472
- err = loadBalancerService .ReconcileLoadBalancer (openStackCluster , clusterName )
464
+ err = loadBalancerService .ReconcileLoadBalancer (openStackCluster , clusterName , apiServerPort )
473
465
if err != nil {
474
466
handleUpdateOSCError (openStackCluster , errors .Errorf ("failed to reconcile load balancer: %v" , err ))
475
467
return errors .Errorf ("failed to reconcile load balancer: %v" , err )
476
468
}
477
469
}
478
470
471
+ if ! openStackCluster .Spec .ControlPlaneEndpoint .IsValid () {
472
+ var host string
473
+ // If there is a load balancer use the floating IP for it if set, falling back to the internal IP
474
+ if openStackCluster .Spec .ManagedAPIServerLoadBalancer {
475
+ if openStackCluster .Status .Network .APIServerLoadBalancer .IP != "" {
476
+ host = openStackCluster .Status .Network .APIServerLoadBalancer .IP
477
+ } else {
478
+ host = openStackCluster .Status .Network .APIServerLoadBalancer .InternalIP
479
+ }
480
+ } else if ! openStackCluster .Spec .DisableAPIServerFloatingIP {
481
+ // If floating IPs are not disabled, get one to use as the VIP for the control plane
482
+ fp , err := networkingService .GetOrCreateFloatingIP (openStackCluster , clusterName , openStackCluster .Spec .APIServerFloatingIP )
483
+ if err != nil {
484
+ handleUpdateOSCError (openStackCluster , errors .Errorf ("Floating IP cannot be got or created: %v" , err ))
485
+ return errors .Errorf ("Floating IP cannot be got or created: %v" , err )
486
+ }
487
+ host = fp .FloatingIP
488
+ } else {
489
+ // This case is not managed for now (i.e. no load balancer + no floating IP)
490
+ // We could manage a VIP port on the cluster network and set allowedAddressPairs accordingly
491
+ // when creating control plane machines, but this would require us to deploy software on the
492
+ // control plane hosts to manage the VIP (e.g. keepalived/kube-vip)
493
+ // It is still possible for a user to deploy this case manually using existing options
494
+ return errors .New ("unable to determine VIP for API server - either load balancer or floating IP must be enabled" )
495
+ }
496
+
497
+ // Set APIEndpoints so the Cluster API Cluster Controller can pull them
498
+ openStackCluster .Spec .ControlPlaneEndpoint = clusterv1.APIEndpoint {
499
+ Host : host ,
500
+ Port : int32 (apiServerPort ),
501
+ }
502
+ }
503
+
479
504
return nil
480
505
}
481
506
0 commit comments