Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,42 @@ func Convert_v1beta2_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(
return nil
}

func Convert_v1beta1_OpenStackClusterSpec_To_v1beta2_OpenStackClusterSpec(
in *OpenStackClusterSpec,
out *infrav1.OpenStackClusterSpec,
s apiconversion.Scope,
) error {
if err := autoConvert_v1beta1_OpenStackClusterSpec_To_v1beta2_OpenStackClusterSpec(in, out, s); err != nil {
return err
}

if in.NetworkMTU != nil || in.DisablePortSecurity != nil {
out.ManagedNetwork = &infrav1.ManagedNetwork{
MTU: in.NetworkMTU,
DisablePortSecurity: in.DisablePortSecurity,
}
}

return nil
}

func Convert_v1beta2_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(
in *infrav1.OpenStackClusterSpec,
out *OpenStackClusterSpec,
s apiconversion.Scope,
) error {
if err := autoConvert_v1beta2_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in, out, s); err != nil {
return err
}

if in.ManagedNetwork != nil {
out.NetworkMTU = in.ManagedNetwork.MTU
out.DisablePortSecurity = in.ManagedNetwork.DisablePortSecurity
}

return nil
}

// LegacyCalicoSecurityGroupRules returns a list of security group rules for calico
// that need to be applied to the control plane and worker security groups when
// managed security groups are enabled and upgrading to v1beta1.
Expand Down
64 changes: 64 additions & 0 deletions api/v1beta1/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func TestOpenStackClusterConversion(t *testing.T) {
g.Expect(dst.Namespace).To(Equal("default"))
g.Expect(dst.Spec.IdentityRef.Name).To(Equal("cloud-config"))
g.Expect(dst.Spec.ManagedSubnets).To(HaveLen(1))
g.Expect(dst.Spec.ManagedNetwork).To(BeNil())

// Verify flavor mapping (name -> FlavorParam.Filter.Name)
g.Expect(dst.Spec.Bastion.Spec.Flavor.ID).To(BeNil())
Expand Down Expand Up @@ -136,6 +137,8 @@ func TestOpenStackClusterConversion(t *testing.T) {
g.Expect(restored.Spec.IdentityRef).To(Equal(src.Spec.IdentityRef))
g.Expect(restored.Status.Ready).To(BeTrue())
g.Expect(restored.Status.Conditions).To(HaveLen(2))
g.Expect(restored.Spec.NetworkMTU).To(BeNil())
g.Expect(restored.Spec.DisablePortSecurity).To(BeNil())

// Severity is lost during conversion, so it won't match exactly
g.Expect(restored.Status.Conditions[0].Type).To(Equal(src.Status.Conditions[0].Type))
Expand Down Expand Up @@ -967,3 +970,64 @@ func TestIsReadyHelper(t *testing.T) {
g.Expect(infrav1.IsReady(nil)).To(BeFalse())
g.Expect(infrav1.IsReady([]metav1.Condition{})).To(BeFalse())
}

func TestOpenStackCluster_RoundTrip_ManagedNetwork(t *testing.T) {
mtu := optional.Int(ptr.To(1500))
disablePS := optional.Bool(ptr.To(true))

tests := []struct {
name string
in OpenStackCluster
}{
{
name: "both fields set",
in: OpenStackCluster{
Spec: OpenStackClusterSpec{
NetworkMTU: mtu,
DisablePortSecurity: disablePS,
},
},
},
{
name: "only MTU set",
in: OpenStackCluster{
Spec: OpenStackClusterSpec{NetworkMTU: mtu},
},
},
{
name: "only DisablePortSecurity set",
in: OpenStackCluster{
Spec: OpenStackClusterSpec{DisablePortSecurity: disablePS},
},
},
{
name: "neither set — ManagedNetwork stays nil",
in: OpenStackCluster{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

hub := &infrav1.OpenStackCluster{}
g.Expect(tt.in.ConvertTo(hub)).To(Succeed())

// Verify intermediate v1beta2 state
if tt.in.Spec.NetworkMTU == nil && tt.in.Spec.DisablePortSecurity == nil {
g.Expect(hub.Spec.ManagedNetwork).To(BeNil())
} else {
g.Expect(hub.Spec.ManagedNetwork).NotTo(BeNil())
g.Expect(hub.Spec.ManagedNetwork.MTU).To(Equal(tt.in.Spec.NetworkMTU))
g.Expect(hub.Spec.ManagedNetwork.DisablePortSecurity).To(Equal(tt.in.Spec.DisablePortSecurity))
}

restored := &OpenStackCluster{}
g.Expect(restored.ConvertFrom(hub)).To(Succeed())

// Verify final v1beta1 state
g.Expect(restored.Spec.NetworkMTU).To(Equal(tt.in.Spec.NetworkMTU))
g.Expect(restored.Spec.DisablePortSecurity).To(Equal(tt.in.Spec.DisablePortSecurity))
})
}
}
39 changes: 14 additions & 25 deletions api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 29 additions & 20 deletions api/v1beta2/openstackcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,6 @@ type OpenStackClusterSpec struct {
// +optional
ManagedSubnets []SubnetSpec `json:"managedSubnets,omitempty"`

// Router specifies an existing router to be used if ManagedSubnets are
// specified. If specified, no new router will be created.
// +optional
Router *RouterParam `json:"router,omitempty"`

// Network specifies an existing network to use if no ManagedSubnets
// are specified.
// +optional
Network *NetworkParam `json:"network,omitempty"`

// Subnets specifies existing subnets to use if not ManagedSubnets are
// specified. All subnets must be in the network specified by Network.
// There can be zero, one, or two subnets. If no subnets are specified,
Expand All @@ -61,12 +51,21 @@ type OpenStackClusterSpec struct {
// +optional
Subnets []SubnetParam `json:"subnets,omitempty"`

// NetworkMTU sets the maximum transmission unit (MTU) value to address fragmentation for the private network ID.
// This value will be used only if the Cluster actuator creates the network.
// If left empty, the network will have the default MTU defined in Openstack network service.
// To use this field, the Openstack installation requires the net-mtu neutron API extension.
// Router specifies an existing router to be used if ManagedSubnets are
// specified. If specified, no new router will be created.
// +optional
NetworkMTU optional.Int `json:"networkMTU,omitempty"`
Router *RouterParam `json:"router,omitempty"`

// ManagedNetwork specifies attributes of the network. The values are used only
// if the Cluster actuator creates the network.
// +kubebuilder:validation:XValidation:rule="self == null || has(self.mtu) || has(self.disablePortSecurity)",message="managedNetwork must not be empty if set"
// +optional
ManagedNetwork *ManagedNetwork `json:"managedNetwork,omitempty"`

// Network specifies an existing network to use if no ManagedSubnets
// are specified.
// +optional
Network *NetworkParam `json:"network,omitempty"`

// ExternalRouterIPs is an array of externalIPs on the respective subnets.
// This is necessary if the router needs a fixed ip in a specific subnet.
Expand Down Expand Up @@ -148,11 +147,6 @@ type OpenStackClusterSpec struct {
// +optional
ManagedSecurityGroups *ManagedSecurityGroups `json:"managedSecurityGroups,omitempty"`

// DisablePortSecurity disables the port security of the network created for the
// Kubernetes cluster, which also disables SecurityGroups
// +optional
DisablePortSecurity optional.Bool `json:"disablePortSecurity,omitempty"`

// Tags to set on all resources in cluster which support tags
// +listType=set
// +optional
Expand Down Expand Up @@ -285,6 +279,21 @@ type OpenStackClusterList struct {
Items []OpenStackCluster `json:"items"`
}

// ManagedNetwork specifies attributes of the network.
type ManagedNetwork struct {
// MTU sets the maximum transmission unit (MTU) value to address fragmentation for the private network ID.
// This value will be used only if the Cluster actuator creates the network.
// If left empty, the network will have the default MTU defined in Openstack network service.
// To use this field, the Openstack installation requires the net-mtu neutron API extension.
// +optional
MTU optional.Int `json:"mtu,omitempty"`

// DisablePortSecurity disables the port security of the network created for the
// Kubernetes cluster, which also disables SecurityGroups
// +optional
DisablePortSecurity optional.Bool `json:"disablePortSecurity,omitempty"`
}

// ManagedSecurityGroups defines the desired state of security groups and rules for the cluster.
type ManagedSecurityGroups struct {
// allNodesSecurityGroupRules defines the rules that should be applied to all nodes.
Expand Down
54 changes: 37 additions & 17 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading