Skip to content

Commit fcbe290

Browse files
authored
Merge pull request #2270 from kubernetes-sigs/backport-0.10-fip
[release-0.10] 🐛 Better checks before creating Floating IPs
2 parents 4d9dadf + ba5d0a5 commit fcbe290

8 files changed

+62
-4
lines changed

api/v1beta1/openstackcluster_types.go

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const (
3131
)
3232

3333
// OpenStackClusterSpec defines the desired state of OpenStackCluster.
34+
// +kubebuilder:validation:XValidation:rule="has(self.disableExternalNetwork) && self.disableExternalNetwork ? !has(self.bastion) || !has(self.bastion.floatingIP) : true",message="bastion floating IP cannot be set when disableExternalNetwork is true"
35+
// +kubebuilder:validation:XValidation:rule="has(self.disableExternalNetwork) && self.disableExternalNetwork ? has(self.disableAPIServerFloatingIP) && self.disableAPIServerFloatingIP : true",message="disableAPIServerFloatingIP cannot be false when disableExternalNetwork is true"
3436
type OpenStackClusterSpec struct {
3537
// ManagedSubnets describe OpenStack Subnets to be created. Cluster actuator will create a network,
3638
// subnets with the defined CIDR, and a router connected to these subnets. Currently only one IPv4

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

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controllers/openstackcluster_controller.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,11 @@ func reconcileBastion(scope *scope.WithLogger, cluster *clusterv1.Cluster, openS
507507
return nil, err
508508
}
509509

510-
return bastionAddFloatingIP(openStackCluster, clusterResourceName, port, networkingService)
510+
if !ptr.Deref(openStackCluster.Spec.DisableExternalNetwork, false) {
511+
return bastionAddFloatingIP(openStackCluster, clusterResourceName, port, networkingService)
512+
}
513+
514+
return nil, nil
511515
}
512516

513517
func bastionAddFloatingIP(openStackCluster *infrav1.OpenStackCluster, clusterResourceName string, port *ports.Port, networkingService *networking.Service) (*reconcile.Result, error) {
@@ -841,9 +845,9 @@ func reconcileControlPlaneEndpoint(scope *scope.WithLogger, networkingService *n
841845
case openStackCluster.Spec.ControlPlaneEndpoint != nil && openStackCluster.Spec.ControlPlaneEndpoint.IsValid():
842846
host = openStackCluster.Spec.ControlPlaneEndpoint.Host
843847

844-
// API server load balancer is disabled, but floating IP is not. Create
848+
// API server load balancer is disabled, but external netowork and floating IP are not. Create
845849
// a floating IP to be attached directly to a control plane host.
846-
case !ptr.Deref(openStackCluster.Spec.DisableAPIServerFloatingIP, false):
850+
case !ptr.Deref(openStackCluster.Spec.DisableAPIServerFloatingIP, false) && !ptr.Deref(openStackCluster.Spec.DisableExternalNetwork, false):
847851
fp, err := networkingService.GetOrCreateFloatingIP(openStackCluster, openStackCluster, clusterResourceName, openStackCluster.Spec.APIServerFloatingIP)
848852
if err != nil {
849853
handleUpdateOSCError(openStackCluster, fmt.Errorf("floating IP cannot be got or created: %w", err))

controllers/openstackmachine_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ func (r *OpenStackMachineReconciler) reconcileAPIServerLoadBalancer(scope *scope
708708
conditions.MarkFalse(openStackMachine, infrav1.APIServerIngressReadyCondition, infrav1.LoadBalancerMemberErrorReason, clusterv1.ConditionSeverityError, "Reconciling load balancer member failed: %v", err)
709709
return fmt.Errorf("reconcile load balancer member: %w", err)
710710
}
711-
} else if !ptr.Deref(openStackCluster.Spec.DisableAPIServerFloatingIP, false) {
711+
} else if !ptr.Deref(openStackCluster.Spec.DisableAPIServerFloatingIP, false) && !ptr.Deref(openStackCluster.Spec.DisableExternalNetwork, false) {
712712
var floatingIPAddress *string
713713
switch {
714714
case openStackCluster.Spec.ControlPlaneEndpoint != nil && openStackCluster.Spec.ControlPlaneEndpoint.IsValid():

docs/book/src/clusteropenstack/configuration.md

+4
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ associated to the first controller node and the other controller nodes have no f
270270
to any other controller node. So we recommend to only set one controller node when floating IP is needed,
271271
or please consider using load balancer instead, see [issue #1265](https://github.com/kubernetes-sigs/cluster-api-provider-openstack/issues/1265) for further information.
272272

273+
Note: `spec.disableExternalNetwork` must be unset or set to `false` to allow the API server to have a floating IP.
274+
273275
### Disabling the API server floating IP
274276

275277
It is possible to provision a cluster without a floating IP for the API server by setting
@@ -715,6 +717,8 @@ spec:
715717
floatingIP: <Floating IP address>
716718
```
717719

720+
Note: A floating IP can only be added if `OpenStackCluster.Spec.DisableExternalNetwork` is not set or set to `false`.
721+
718722
If `managedSecurityGroups` is set to a non-nil value (e.g. `{}`), security group rule opening 22/tcp is added to security groups for bastion, controller, and worker nodes respectively. Otherwise, you have to add `securityGroups` to the `bastion` in `OpenStackCluster` spec and `OpenStackMachineTemplate` spec template respectively.
719723

720724
### Making changes to the bastion host

pkg/cloud/services/networking/floatingip.go

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ func (s *Service) GetOrCreateFloatingIP(eventObject runtime.Object, openStackClu
3838
var err error
3939
var fpCreateOpts floatingips.CreateOpts
4040

41+
// This is a safeguard, we shouldn't reach it and if we do, it's something to fix in the caller of the function.
42+
if openStackCluster.Status.ExternalNetwork == nil {
43+
return nil, fmt.Errorf("external network not found")
44+
}
45+
4146
if ptr.Deref(ip, "") != "" {
4247
fp, err = s.GetFloatingIP(*ip)
4348
if err != nil {

test/e2e/suites/apivalidations/openstackcluster_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,29 @@ var _ = Describe("OpenStackCluster API validations", func() {
169169
}
170170
Expect(createObj(cluster)).NotTo(Succeed(), "OpenStackCluster creation should not succeed")
171171
})
172+
173+
It("should not allow a bastion floating IP with DisableExternalNetwork set to true", func() {
174+
cluster.Spec.Bastion = &infrav1.Bastion{
175+
Enabled: ptr.To(true),
176+
Spec: &infrav1.OpenStackMachineSpec{
177+
Flavor: "flavor-name",
178+
Image: infrav1.ImageParam{
179+
Filter: &infrav1.ImageFilter{
180+
Name: ptr.To("fake-image"),
181+
},
182+
},
183+
},
184+
FloatingIP: ptr.To("10.0.0.0"),
185+
}
186+
cluster.Spec.DisableExternalNetwork = ptr.To(true)
187+
Expect(createObj(cluster)).ToNot(Succeed(), "OpenStackCluster creation should not succeed")
188+
})
189+
190+
It("should not allow DisableAPIServerFloatingIP to be false with DisableExternalNetwork set to true", func() {
191+
cluster.Spec.DisableAPIServerFloatingIP = ptr.To(false)
192+
cluster.Spec.DisableExternalNetwork = ptr.To(true)
193+
Expect(createObj(cluster)).ToNot(Succeed(), "OpenStackCluster creation should not succeed")
194+
})
172195
})
173196

174197
Context("v1alpha7", func() {

0 commit comments

Comments
 (0)