diff --git a/api/v1alpha6/openstackcluster_conversion.go b/api/v1alpha6/openstackcluster_conversion.go index bc67f5a9ea..1ed1ed676d 100644 --- a/api/v1alpha6/openstackcluster_conversion.go +++ b/api/v1alpha6/openstackcluster_conversion.go @@ -478,7 +478,10 @@ func restorev1beta1Bastion(previous **infrav1.Bastion, dst **infrav1.Bastion) { optional.RestoreString(&(*previous).FloatingIP, &(*dst).FloatingIP) optional.RestoreString(&(*previous).AvailabilityZone, &(*dst).AvailabilityZone) - optional.RestoreBool(&(*previous).Enabled, &(*dst).Enabled) + + if (*dst).Enabled != nil && !*(*dst).Enabled { + (*dst).Enabled = (*previous).Enabled + } } func Convert_v1alpha6_Bastion_To_v1beta1_Bastion(in *Bastion, out *infrav1.Bastion, s apiconversion.Scope) error { diff --git a/api/v1alpha6/zz_generated.conversion.go b/api/v1alpha6/zz_generated.conversion.go index 59dba6198a..829e7d66a7 100644 --- a/api/v1alpha6/zz_generated.conversion.go +++ b/api/v1alpha6/zz_generated.conversion.go @@ -503,7 +503,7 @@ func Convert_v1beta1_AddressPair_To_v1alpha6_AddressPair(in *v1beta1.AddressPair } func autoConvert_v1alpha6_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.Bastion, s conversion.Scope) error { - if err := optional.Convert_bool_To_optional_Bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Instance requires manual conversion: does not exist in peer-type @@ -514,7 +514,7 @@ func autoConvert_v1alpha6_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.B } func autoConvert_v1beta1_Bastion_To_v1alpha6_Bastion(in *v1beta1.Bastion, out *Bastion, s conversion.Scope) error { - if err := optional.Convert_optional_Bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Spec requires manual conversion: does not exist in peer-type diff --git a/api/v1alpha7/openstackcluster_conversion.go b/api/v1alpha7/openstackcluster_conversion.go index c7598b9aea..7e1937caad 100644 --- a/api/v1alpha7/openstackcluster_conversion.go +++ b/api/v1alpha7/openstackcluster_conversion.go @@ -416,7 +416,10 @@ func restorev1beta1Bastion(previous **infrav1.Bastion, dst **infrav1.Bastion) { restorev1beta1MachineSpec((*previous).Spec, (*dst).Spec) optional.RestoreString(&(*previous).FloatingIP, &(*dst).FloatingIP) optional.RestoreString(&(*previous).AvailabilityZone, &(*dst).AvailabilityZone) - optional.RestoreBool(&(*previous).Enabled, &(*dst).Enabled) + + if (*dst).Enabled != nil && !*(*dst).Enabled { + (*dst).Enabled = (*previous).Enabled + } } func Convert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *infrav1.Bastion, s apiconversion.Scope) error { diff --git a/api/v1alpha7/zz_generated.conversion.go b/api/v1alpha7/zz_generated.conversion.go index f67c228983..a4144215b5 100644 --- a/api/v1alpha7/zz_generated.conversion.go +++ b/api/v1alpha7/zz_generated.conversion.go @@ -567,7 +567,7 @@ func Convert_v1beta1_AddressPair_To_v1alpha7_AddressPair(in *v1beta1.AddressPair } func autoConvert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.Bastion, s conversion.Scope) error { - if err := optional.Convert_bool_To_optional_Bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Instance requires manual conversion: does not exist in peer-type @@ -578,7 +578,7 @@ func autoConvert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.B } func autoConvert_v1beta1_Bastion_To_v1alpha7_Bastion(in *v1beta1.Bastion, out *Bastion, s conversion.Scope) error { - if err := optional.Convert_optional_Bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Spec requires manual conversion: does not exist in peer-type diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go index 7c13a3662d..5bbccb0504 100644 --- a/api/v1beta1/types.go +++ b/api/v1beta1/types.go @@ -795,7 +795,7 @@ type Bastion struct { // waiting until the bastion has been deleted. // +kubebuilder:default:=true // +optional - Enabled optional.Bool `json:"enabled,omitempty"` + Enabled *bool `json:"enabled,omitempty"` // Spec for the bastion itself Spec *OpenStackMachineSpec `json:"spec,omitempty"` diff --git a/test/e2e/suites/apivalidations/openstackcluster_test.go b/test/e2e/suites/apivalidations/openstackcluster_test.go index d0b1fddad7..84e4eac521 100644 --- a/test/e2e/suites/apivalidations/openstackcluster_test.go +++ b/test/e2e/suites/apivalidations/openstackcluster_test.go @@ -214,5 +214,23 @@ var _ = Describe("OpenStackCluster API validations", func() { Expect(cluster.Spec.ControlPlaneEndpoint).To(Equal(*infrav1Cluster.Spec.ControlPlaneEndpoint), "Control plane endpoint should be restored") Expect(cluster.Spec.IdentityRef.Kind).To(Equal("FakeKind"), "IdentityRef.Kind should be restored") }) + + It("should not enable an explicitly disabled bastion when converting to v1beta1", func() { + cluster.Spec.Bastion = &infrav1alpha7.Bastion{Enabled: false} + Expect(create(cluster)).To(Succeed(), "OpenStackCluster creation should succeed") + + // Fetch the infrav1 version of the cluster + infrav1Cluster := &infrav1.OpenStackCluster{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, infrav1Cluster)).To(Succeed(), "OpenStackCluster fetch should succeed") + + infrav1Bastion := infrav1Cluster.Spec.Bastion + + // NOTE(mdbooth): It may be reasonable to remove the + // bastion if it is disabled with no other properties. + // It would be reasonable to update the assertions + // accordingly if we did that. + Expect(infrav1Bastion).ToNot(BeNil(), "Bastion should not have been removed") + Expect(infrav1Bastion.Enabled).To(Equal(ptr.To(false)), "Bastion should remain disabled") + }) }) })