diff --git a/api/v1alpha5/conversion.go b/api/v1alpha5/conversion.go index b8190e088a..19397b6956 100644 --- a/api/v1alpha5/conversion.go +++ b/api/v1alpha5/conversion.go @@ -217,7 +217,7 @@ func Convert_v1beta1_OpenStackClusterSpec_To_v1alpha5_OpenStackClusterSpec(in *i if in.Subnets != nil { if len(in.Subnets) >= 1 { - if err := Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { return err } } @@ -254,11 +254,11 @@ func Convert_v1alpha5_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in *O emptySubnet := SubnetFilter{} if in.Subnet != emptySubnet { - subnet := infrav1.SubnetFilter{} - if err := Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetFilter(&in.Subnet, &subnet, s); err != nil { + subnet := infrav1.SubnetParam{} + if err := Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetParam(&in.Subnet, &subnet, s); err != nil { return err } - out.Subnets = []infrav1.SubnetFilter{subnet} + out.Subnets = []infrav1.SubnetParam{subnet} } if len(in.NodeCIDR) > 0 { @@ -547,25 +547,56 @@ func Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupParam(in *infr return nil } -func Convert_v1alpha5_SubnetParam_To_v1beta1_SubnetFilter(in *SubnetParam, out *infrav1.SubnetFilter, s conversion.Scope) error { - if err := Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetFilter(&in.Filter, out, s); err != nil { +func Convert_v1alpha5_SubnetParam_To_v1beta1_SubnetParam(in *SubnetParam, out *infrav1.SubnetParam, s conversion.Scope) error { + if in.UUID != "" { + out.ID = &in.UUID + return nil + } + outFilter := &infrav1.SubnetFilter{} + if err := Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetFilter(&in.Filter, outFilter, s); err != nil { return err } - if in.UUID != "" { - out.ID = in.UUID + if !outFilter.IsZero() { + out.Filter = outFilter } return nil } -func Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetParam(in *infrav1.SubnetFilter, out *SubnetParam, s conversion.Scope) error { - if err := Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetFilter(in, &out.Filter, s); err != nil { - return err +func Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetParam(in *infrav1.SubnetParam, out *SubnetParam, s conversion.Scope) error { + if in.ID != nil { + out.UUID = *in.ID + return nil + } + + if in.Filter != nil { + if err := Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetFilter(in.Filter, &out.Filter, s); err != nil { + return err + } } - out.UUID = in.ID return nil } +func Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetParam(in *SubnetFilter, out *infrav1.SubnetParam, s conversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + out.Filter = &infrav1.SubnetFilter{} + return Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetFilter(in, out.Filter, s) +} + +func Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetFilter(in *infrav1.SubnetParam, out *SubnetFilter, s conversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + if in.Filter != nil { + return Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetFilter(in.Filter, out, s) + } + return nil +} + func Convert_Map_string_To_Interface_To_v1beta1_BindingProfile(in map[string]string, out *infrav1.BindingProfile, _ conversion.Scope) error { for k, v := range in { if k == "capabilities" { diff --git a/api/v1alpha5/zz_generated.conversion.go b/api/v1alpha5/zz_generated.conversion.go index e8376912a3..8d24ce309a 100644 --- a/api/v1alpha5/zz_generated.conversion.go +++ b/api/v1alpha5/zz_generated.conversion.go @@ -317,8 +317,13 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*SubnetParam)(nil), (*v1beta1.SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha5_SubnetParam_To_v1beta1_SubnetFilter(a.(*SubnetParam), b.(*v1beta1.SubnetFilter), scope) + if err := s.AddConversionFunc((*SubnetFilter)(nil), (*v1beta1.SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetParam(a.(*SubnetFilter), b.(*v1beta1.SubnetParam), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SubnetParam)(nil), (*v1beta1.SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha5_SubnetParam_To_v1beta1_SubnetParam(a.(*SubnetParam), b.(*v1beta1.SubnetParam), scope) }); err != nil { return err } @@ -417,8 +422,13 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.SubnetFilter)(nil), (*SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetParam(a.(*v1beta1.SubnetFilter), b.(*SubnetParam), scope) + if err := s.AddConversionFunc((*v1beta1.SubnetParam)(nil), (*SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetFilter(a.(*v1beta1.SubnetParam), b.(*SubnetFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SubnetParam)(nil), (*SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetParam(a.(*v1beta1.SubnetParam), b.(*SubnetParam), scope) }); err != nil { return err } @@ -496,7 +506,7 @@ func autoConvert_v1beta1_Bastion_To_v1alpha5_Bastion(in *v1beta1.Bastion, out *B func autoConvert_v1alpha5_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in *ExternalRouterIPParam, out *v1beta1.ExternalRouterIPParam, s conversion.Scope) error { out.FixedIP = in.FixedIP - if err := Convert_v1alpha5_SubnetParam_To_v1beta1_SubnetFilter(&in.Subnet, &out.Subnet, s); err != nil { + if err := Convert_v1alpha5_SubnetParam_To_v1beta1_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { return err } return nil @@ -509,7 +519,7 @@ func Convert_v1alpha5_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in func autoConvert_v1beta1_ExternalRouterIPParam_To_v1alpha5_ExternalRouterIPParam(in *v1beta1.ExternalRouterIPParam, out *ExternalRouterIPParam, s conversion.Scope) error { out.FixedIP = in.FixedIP - if err := Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { return err } return nil @@ -523,8 +533,8 @@ func Convert_v1beta1_ExternalRouterIPParam_To_v1alpha5_ExternalRouterIPParam(in func autoConvert_v1alpha5_FixedIP_To_v1beta1_FixedIP(in *FixedIP, out *v1beta1.FixedIP, s conversion.Scope) error { if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet - *out = new(v1beta1.SubnetFilter) - if err := Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetFilter(*in, *out, s); err != nil { + *out = new(v1beta1.SubnetParam) + if err := Convert_v1alpha5_SubnetFilter_To_v1beta1_SubnetParam(*in, *out, s); err != nil { return err } } else { @@ -545,7 +555,7 @@ func autoConvert_v1beta1_FixedIP_To_v1alpha5_FixedIP(in *v1beta1.FixedIP, out *F if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet *out = new(SubnetFilter) - if err := Convert_v1beta1_SubnetFilter_To_v1alpha5_SubnetFilter(*in, *out, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha5_SubnetFilter(*in, *out, s); err != nil { return err } } else { @@ -1567,7 +1577,7 @@ func autoConvert_v1alpha5_SubnetFilter_To_v1beta1_SubnetFilter(in *SubnetFilter, out.CIDR = in.CIDR out.IPv6AddressMode = in.IPv6AddressMode out.IPv6RAMode = in.IPv6RAMode - out.ID = in.ID + // WARNING: in.ID requires manual conversion: does not exist in peer-type // WARNING: in.Tags requires manual conversion: does not exist in peer-type // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type // WARNING: in.NotTags requires manual conversion: does not exist in peer-type @@ -1584,7 +1594,18 @@ func autoConvert_v1beta1_SubnetFilter_To_v1alpha5_SubnetFilter(in *v1beta1.Subne out.CIDR = in.CIDR out.IPv6AddressMode = in.IPv6AddressMode out.IPv6RAMode = in.IPv6RAMode - out.ID = in.ID // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type return nil } + +func autoConvert_v1alpha5_SubnetParam_To_v1beta1_SubnetParam(in *SubnetParam, out *v1beta1.SubnetParam, s conversion.Scope) error { + // WARNING: in.UUID requires manual conversion: does not exist in peer-type + // WARNING: in.Filter requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha5.SubnetFilter vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.SubnetFilter) + return nil +} + +func autoConvert_v1beta1_SubnetParam_To_v1alpha5_SubnetParam(in *v1beta1.SubnetParam, out *SubnetParam, s conversion.Scope) error { + // WARNING: in.ID requires manual conversion: does not exist in peer-type + // WARNING: in.Filter requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.SubnetFilter vs sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha5.SubnetFilter) + return nil +} diff --git a/api/v1alpha6/conversion_test.go b/api/v1alpha6/conversion_test.go index 0c1352767d..1456680359 100644 --- a/api/v1alpha6/conversion_test.go +++ b/api/v1alpha6/conversion_test.go @@ -286,8 +286,8 @@ func TestNetworksToPorts(t *testing.T) { }, FixedIPs: []infrav1.FixedIP{ { - Subnet: &infrav1.SubnetFilter{ - ID: subnetuuid, + Subnet: &infrav1.SubnetParam{ + ID: pointer.String(subnetuuid), }, }, }, @@ -330,20 +330,22 @@ func TestNetworksToPorts(t *testing.T) { }, FixedIPs: []infrav1.FixedIP{ { - Subnet: &infrav1.SubnetFilter{ - Name: "subnet-name", - Description: "subnet-description", - ProjectID: "project-id", - IPVersion: 6, - GatewayIP: "x.x.x.x", - CIDR: "y.y.y.y", - IPv6AddressMode: "address-mode", - IPv6RAMode: "ra-mode", - FilterByNeutronTags: infrav1.FilterByNeutronTags{ - Tags: []infrav1.NeutronTag{"tags"}, - TagsAny: []infrav1.NeutronTag{"tags-any"}, - NotTags: []infrav1.NeutronTag{"not-tags"}, - NotTagsAny: []infrav1.NeutronTag{"not-tags-any"}, + Subnet: &infrav1.SubnetParam{ + Filter: &infrav1.SubnetFilter{ + Name: "subnet-name", + Description: "subnet-description", + ProjectID: "project-id", + IPVersion: 6, + GatewayIP: "x.x.x.x", + CIDR: "y.y.y.y", + IPv6AddressMode: "address-mode", + IPv6RAMode: "ra-mode", + FilterByNeutronTags: infrav1.FilterByNeutronTags{ + Tags: []infrav1.NeutronTag{"tags"}, + TagsAny: []infrav1.NeutronTag{"tags-any"}, + NotTags: []infrav1.NeutronTag{"not-tags"}, + NotTagsAny: []infrav1.NeutronTag{"not-tags-any"}, + }, }, }, }, @@ -390,8 +392,8 @@ func TestNetworksToPorts(t *testing.T) { }, FixedIPs: []infrav1.FixedIP{ { - Subnet: &infrav1.SubnetFilter{ - ID: subnetuuid, + Subnet: &infrav1.SubnetParam{ + ID: pointer.String(subnetuuid), }, }, }, @@ -402,20 +404,22 @@ func TestNetworksToPorts(t *testing.T) { }, FixedIPs: []infrav1.FixedIP{ { - Subnet: &infrav1.SubnetFilter{ - Name: "subnet-name", - Description: "subnet-description", - ProjectID: "project-id", - IPVersion: 6, - GatewayIP: "x.x.x.x", - CIDR: "y.y.y.y", - IPv6AddressMode: "address-mode", - IPv6RAMode: "ra-mode", - FilterByNeutronTags: infrav1.FilterByNeutronTags{ - Tags: []infrav1.NeutronTag{"tags"}, - TagsAny: []infrav1.NeutronTag{"tags-any"}, - NotTags: []infrav1.NeutronTag{"not-tags"}, - NotTagsAny: []infrav1.NeutronTag{"not-tags-any"}, + Subnet: &infrav1.SubnetParam{ + Filter: &infrav1.SubnetFilter{ + Name: "subnet-name", + Description: "subnet-description", + ProjectID: "project-id", + IPVersion: 6, + GatewayIP: "x.x.x.x", + CIDR: "y.y.y.y", + IPv6AddressMode: "address-mode", + IPv6RAMode: "ra-mode", + FilterByNeutronTags: infrav1.FilterByNeutronTags{ + Tags: []infrav1.NeutronTag{"tags"}, + TagsAny: []infrav1.NeutronTag{"tags-any"}, + NotTags: []infrav1.NeutronTag{"not-tags"}, + NotTagsAny: []infrav1.NeutronTag{"not-tags-any"}, + }, }, }, }, diff --git a/api/v1alpha6/openstackcluster_conversion.go b/api/v1alpha6/openstackcluster_conversion.go index 68242edd8c..66fd5896bb 100644 --- a/api/v1alpha6/openstackcluster_conversion.go +++ b/api/v1alpha6/openstackcluster_conversion.go @@ -152,7 +152,7 @@ func restorev1alpha6ClusterSpec(previous *OpenStackClusterSpec, dst *OpenStackCl if len(dst.ExternalRouterIPs) == len(previous.ExternalRouterIPs) { for i := range dst.ExternalRouterIPs { - restorev1alpha6SubnetFilter(&previous.ExternalRouterIPs[i].Subnet.Filter, &dst.ExternalRouterIPs[i].Subnet.Filter) + restorev1alpha6SubnetParam(&previous.ExternalRouterIPs[i].Subnet, &dst.ExternalRouterIPs[i].Subnet) } } @@ -179,10 +179,19 @@ func restorev1beta1ClusterSpec(previous *infrav1.OpenStackClusterSpec, dst *infr dst.NetworkMTU = previous.NetworkMTU dst.DisableExternalNetwork = previous.DisableExternalNetwork + if len(previous.Subnets) > 0 && len(dst.Subnets) > 0 { + restorev1beta1SubnetParam(&previous.Subnets[0], &dst.Subnets[0]) + } if len(previous.Subnets) > 1 { dst.Subnets = append(dst.Subnets, previous.Subnets[1:]...) } + if len(previous.ExternalRouterIPs) == len(dst.ExternalRouterIPs) { + for i := range dst.ExternalRouterIPs { + restorev1beta1SubnetParam(&previous.ExternalRouterIPs[i].Subnet, &dst.ExternalRouterIPs[i].Subnet) + } + } + dst.ManagedSubnets = previous.ManagedSubnets if previous.ManagedSecurityGroups != nil { @@ -232,11 +241,11 @@ func Convert_v1alpha6_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in *O emptySubnet := SubnetFilter{} if in.Subnet != emptySubnet { - subnet := infrav1.SubnetFilter{} - if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(&in.Subnet, &subnet, s); err != nil { + subnet := infrav1.SubnetParam{} + if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetParam(&in.Subnet, &subnet, s); err != nil { return err } - out.Subnets = []infrav1.SubnetFilter{subnet} + out.Subnets = []infrav1.SubnetParam{subnet} } // DNSNameservers without NodeCIDR doesn't make sense, so we drop that. @@ -295,7 +304,7 @@ func Convert_v1beta1_OpenStackClusterSpec_To_v1alpha6_OpenStackClusterSpec(in *i } if len(in.Subnets) >= 1 { - if err := Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { return err } } diff --git a/api/v1alpha6/openstackmachine_conversion.go b/api/v1alpha6/openstackmachine_conversion.go index 9ab01741ea..d13eb5c124 100644 --- a/api/v1alpha6/openstackmachine_conversion.go +++ b/api/v1alpha6/openstackmachine_conversion.go @@ -223,18 +223,18 @@ func convertNetworksToPorts(networks []NetworkParam, s apiconversion.Scope) ([]i ports = append(ports, infrav1.PortOpts{ Network: networkFilter, FixedIPs: []infrav1.FixedIP{ - {Subnet: &infrav1.SubnetFilter{ID: subnet.UUID}}, + {Subnet: &infrav1.SubnetParam{ID: &subnet.UUID}}, }, }) } else { - subnetFilter := &infrav1.SubnetFilter{} - if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(&subnet.Filter, subnetFilter, s); err != nil { + subnetParam := &infrav1.SubnetParam{} + if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetParam(&subnet.Filter, subnetParam, s); err != nil { return nil, err } ports = append(ports, infrav1.PortOpts{ Network: networkFilter, FixedIPs: []infrav1.FixedIP{ - {Subnet: subnetFilter}, + {Subnet: subnetParam}, }, }) } diff --git a/api/v1alpha6/types_conversion.go b/api/v1alpha6/types_conversion.go index 80cefb86fc..1b2a642f34 100644 --- a/api/v1alpha6/types_conversion.go +++ b/api/v1alpha6/types_conversion.go @@ -24,6 +24,7 @@ import ( "k8s.io/utils/pointer" infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + optional "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" ) const trueString = "true" @@ -164,29 +165,81 @@ func Convert_v1beta1_NetworkParam_To_v1alpha6_NetworkFilter(in *infrav1.NetworkP /* SubnetParam, SubnetFilter */ func restorev1alpha6SubnetFilter(previous *SubnetFilter, dst *SubnetFilter) { + if previous == nil || dst == nil { + return + } + // The edge cases with multiple commas are too tricky in this direction, // so we just restore the whole thing. dst.Tags = previous.Tags dst.TagsAny = previous.TagsAny dst.NotTags = previous.NotTags dst.NotTagsAny = previous.NotTagsAny + + // We didn't convert other fields if ID was set + if previous.ID != "" { + dst.Name = previous.Name + dst.Description = previous.Description + dst.ProjectID = previous.ProjectID + dst.IPVersion = previous.IPVersion + dst.GatewayIP = previous.GatewayIP + dst.CIDR = previous.CIDR + dst.IPv6AddressMode = previous.IPv6AddressMode + dst.IPv6RAMode = previous.IPv6RAMode + } } -func Convert_v1alpha6_SubnetParam_To_v1beta1_SubnetFilter(in *SubnetParam, out *infrav1.SubnetFilter, s apiconversion.Scope) error { - if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(&in.Filter, out, s); err != nil { - return err +func restorev1alpha6SubnetParam(previous *SubnetParam, dst *SubnetParam) { + if previous == nil || dst == nil { + return + } + + if previous.UUID != "" { + dst.Filter = previous.Filter + } else { + restorev1alpha6SubnetFilter(&previous.Filter, &dst.Filter) } +} + +func restorev1beta1SubnetParam(previous *infrav1.SubnetParam, dst *infrav1.SubnetParam) { + if previous == nil || dst == nil { + return + } + + optional.RestoreString(&previous.ID, &dst.ID) + + if dst.Filter != nil { + dst.Filter.FilterByNeutronTags = previous.Filter.FilterByNeutronTags + } +} + +func Convert_v1alpha6_SubnetParam_To_v1beta1_SubnetParam(in *SubnetParam, out *infrav1.SubnetParam, s apiconversion.Scope) error { if in.UUID != "" { - out.ID = in.UUID + out.ID = &in.UUID + return nil + } + + outFilter := &infrav1.SubnetFilter{} + if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(&in.Filter, outFilter, s); err != nil { + return err + } + if !outFilter.IsZero() { + out.Filter = outFilter } return nil } -func Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetParam(in *infrav1.SubnetFilter, out *SubnetParam, s apiconversion.Scope) error { - if err := Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(in, &out.Filter, s); err != nil { - return err +func Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetParam(in *infrav1.SubnetParam, out *SubnetParam, s apiconversion.Scope) error { + if in.ID != nil { + out.UUID = *in.ID + return nil + } + + if in.Filter != nil { + if err := Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(in.Filter, &out.Filter, s); err != nil { + return err + } } - out.UUID = in.ID return nil } @@ -207,6 +260,36 @@ func Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(in *infrav1.SubnetFil return nil } +func Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetParam(in *SubnetFilter, out *infrav1.SubnetParam, s apiconversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + + outFilter := &infrav1.SubnetFilter{} + if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(in, outFilter, s); err != nil { + return err + } + if !outFilter.IsZero() { + out.Filter = outFilter + } + return nil +} + +func Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetFilter(in *infrav1.SubnetParam, out *SubnetFilter, s apiconversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + + if in.Filter != nil { + if err := Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(in.Filter, out, s); err != nil { + return err + } + } + return nil +} + /* PortOpts, BindingProfile */ func restorev1alpha6Port(previous *PortOpts, dst *PortOpts) { diff --git a/api/v1alpha6/zz_generated.conversion.go b/api/v1alpha6/zz_generated.conversion.go index 34023deb82..9862d40792 100644 --- a/api/v1alpha6/zz_generated.conversion.go +++ b/api/v1alpha6/zz_generated.conversion.go @@ -336,8 +336,13 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*SubnetParam)(nil), (*v1beta1.SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha6_SubnetParam_To_v1beta1_SubnetFilter(a.(*SubnetParam), b.(*v1beta1.SubnetFilter), scope) + if err := s.AddConversionFunc((*SubnetFilter)(nil), (*v1beta1.SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetParam(a.(*SubnetFilter), b.(*v1beta1.SubnetParam), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SubnetParam)(nil), (*v1beta1.SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha6_SubnetParam_To_v1beta1_SubnetParam(a.(*SubnetParam), b.(*v1beta1.SubnetParam), scope) }); err != nil { return err } @@ -431,8 +436,13 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*v1beta1.SubnetFilter)(nil), (*SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetParam(a.(*v1beta1.SubnetFilter), b.(*SubnetParam), scope) + if err := s.AddConversionFunc((*v1beta1.SubnetParam)(nil), (*SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetFilter(a.(*v1beta1.SubnetParam), b.(*SubnetFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SubnetParam)(nil), (*SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetParam(a.(*v1beta1.SubnetParam), b.(*SubnetParam), scope) }); err != nil { return err } @@ -520,7 +530,7 @@ func autoConvert_v1beta1_Bastion_To_v1alpha6_Bastion(in *v1beta1.Bastion, out *B func autoConvert_v1alpha6_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in *ExternalRouterIPParam, out *v1beta1.ExternalRouterIPParam, s conversion.Scope) error { out.FixedIP = in.FixedIP - if err := Convert_v1alpha6_SubnetParam_To_v1beta1_SubnetFilter(&in.Subnet, &out.Subnet, s); err != nil { + if err := Convert_v1alpha6_SubnetParam_To_v1beta1_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { return err } return nil @@ -533,7 +543,7 @@ func Convert_v1alpha6_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in func autoConvert_v1beta1_ExternalRouterIPParam_To_v1alpha6_ExternalRouterIPParam(in *v1beta1.ExternalRouterIPParam, out *ExternalRouterIPParam, s conversion.Scope) error { out.FixedIP = in.FixedIP - if err := Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { return err } return nil @@ -547,8 +557,8 @@ func Convert_v1beta1_ExternalRouterIPParam_To_v1alpha6_ExternalRouterIPParam(in func autoConvert_v1alpha6_FixedIP_To_v1beta1_FixedIP(in *FixedIP, out *v1beta1.FixedIP, s conversion.Scope) error { if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet - *out = new(v1beta1.SubnetFilter) - if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(*in, *out, s); err != nil { + *out = new(v1beta1.SubnetParam) + if err := Convert_v1alpha6_SubnetFilter_To_v1beta1_SubnetParam(*in, *out, s); err != nil { return err } } else { @@ -569,7 +579,7 @@ func autoConvert_v1beta1_FixedIP_To_v1alpha6_FixedIP(in *v1beta1.FixedIP, out *F if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet *out = new(SubnetFilter) - if err := Convert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(*in, *out, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha6_SubnetFilter(*in, *out, s); err != nil { return err } } else { @@ -1603,7 +1613,7 @@ func autoConvert_v1alpha6_SubnetFilter_To_v1beta1_SubnetFilter(in *SubnetFilter, out.CIDR = in.CIDR out.IPv6AddressMode = in.IPv6AddressMode out.IPv6RAMode = in.IPv6RAMode - out.ID = in.ID + // WARNING: in.ID requires manual conversion: does not exist in peer-type // WARNING: in.Tags requires manual conversion: does not exist in peer-type // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type // WARNING: in.NotTags requires manual conversion: does not exist in peer-type @@ -1620,11 +1630,22 @@ func autoConvert_v1beta1_SubnetFilter_To_v1alpha6_SubnetFilter(in *v1beta1.Subne out.CIDR = in.CIDR out.IPv6AddressMode = in.IPv6AddressMode out.IPv6RAMode = in.IPv6RAMode - out.ID = in.ID // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type return nil } +func autoConvert_v1alpha6_SubnetParam_To_v1beta1_SubnetParam(in *SubnetParam, out *v1beta1.SubnetParam, s conversion.Scope) error { + // WARNING: in.UUID requires manual conversion: does not exist in peer-type + // WARNING: in.Filter requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha6.SubnetFilter vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.SubnetFilter) + return nil +} + +func autoConvert_v1beta1_SubnetParam_To_v1alpha6_SubnetParam(in *v1beta1.SubnetParam, out *SubnetParam, s conversion.Scope) error { + // WARNING: in.ID requires manual conversion: does not exist in peer-type + // WARNING: in.Filter requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.SubnetFilter vs sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha6.SubnetFilter) + return nil +} + func autoConvert_v1alpha6_ValueSpec_To_v1beta1_ValueSpec(in *ValueSpec, out *v1beta1.ValueSpec, s conversion.Scope) error { out.Name = in.Name out.Key = in.Key diff --git a/api/v1alpha7/openstackcluster_conversion.go b/api/v1alpha7/openstackcluster_conversion.go index 7ff49ecdcf..75e92032d1 100644 --- a/api/v1alpha7/openstackcluster_conversion.go +++ b/api/v1alpha7/openstackcluster_conversion.go @@ -191,10 +191,19 @@ func restorev1beta1ClusterSpec(previous *infrav1.OpenStackClusterSpec, dst *infr restorev1beta1NetworkParam(previous.Network, dst.Network) + if len(previous.Subnets) > 0 && len(dst.Subnets) > 0 { + restorev1beta1SubnetParam(&previous.Subnets[0], &dst.Subnets[0]) + } if len(previous.Subnets) > 1 { dst.Subnets = append(dst.Subnets, previous.Subnets[1:]...) } + if len(previous.ExternalRouterIPs) == len(dst.ExternalRouterIPs) { + for i := range dst.ExternalRouterIPs { + restorev1beta1SubnetParam(&previous.ExternalRouterIPs[i].Subnet, &dst.ExternalRouterIPs[i].Subnet) + } + } + dst.ManagedSubnets = previous.ManagedSubnets if previous.ManagedSecurityGroups != nil { @@ -244,11 +253,11 @@ func Convert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in *O emptySubnet := SubnetFilter{} if in.Subnet != emptySubnet { - subnet := infrav1.SubnetFilter{} - if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(&in.Subnet, &subnet, s); err != nil { + subnet := infrav1.SubnetParam{} + if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(&in.Subnet, &subnet, s); err != nil { return err } - out.Subnets = []infrav1.SubnetFilter{subnet} + out.Subnets = []infrav1.SubnetParam{subnet} } // DNSNameservers without NodeCIDR doesn't make sense, so we drop that. @@ -307,7 +316,7 @@ func Convert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(in *i } if len(in.Subnets) >= 1 { - if err := Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { return err } } diff --git a/api/v1alpha7/types_conversion.go b/api/v1alpha7/types_conversion.go index 1139ebe05a..a63cd212ed 100644 --- a/api/v1alpha7/types_conversion.go +++ b/api/v1alpha7/types_conversion.go @@ -126,27 +126,74 @@ func Convert_v1beta1_NetworkParam_To_v1alpha7_NetworkFilter(in *infrav1.NetworkP /* SubnetFilter */ func restorev1alpha7SubnetFilter(previous *SubnetFilter, dst *SubnetFilter) { + if previous == nil || dst == nil { + return + } + // The edge cases with multiple commas are too tricky in this direction, // so we just restore the whole thing. dst.Tags = previous.Tags dst.TagsAny = previous.TagsAny dst.NotTags = previous.NotTags dst.NotTagsAny = previous.NotTagsAny + + // If ID was set we will have lost all other fields in up-conversion + if previous.ID != "" { + dst.Name = previous.Name + dst.Description = previous.Description + dst.ProjectID = previous.ProjectID + dst.IPVersion = previous.IPVersion + dst.GatewayIP = previous.GatewayIP + dst.CIDR = previous.CIDR + dst.IPv6AddressMode = previous.IPv6AddressMode + dst.IPv6RAMode = previous.IPv6RAMode + } } -func Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(in *SubnetFilter, out *infrav1.SubnetFilter, s apiconversion.Scope) error { - if err := autoConvert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(in, out, s); err != nil { +func restorev1beta1SubnetParam(previous *infrav1.SubnetParam, dst *infrav1.SubnetParam) { + if previous == nil || dst == nil { + return + } + + optional.RestoreString(&previous.ID, &dst.ID) + + if dst.Filter != nil { + dst.Filter.FilterByNeutronTags = previous.Filter.FilterByNeutronTags + } +} + +func Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(in *SubnetFilter, out *infrav1.SubnetParam, s apiconversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + + filter := &infrav1.SubnetFilter{} + if err := autoConvert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(in, filter, s); err != nil { return err } - infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &out.FilterByNeutronTags) + infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &filter.FilterByNeutronTags) + + if !filter.IsZero() { + out.Filter = filter + } return nil } -func Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(in *infrav1.SubnetFilter, out *SubnetFilter, s apiconversion.Scope) error { - if err := autoConvert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(in, out, s); err != nil { +func Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(in *infrav1.SubnetParam, out *SubnetFilter, s apiconversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + + if in.Filter == nil { + return nil + } + + if err := autoConvert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(in.Filter, out, s); err != nil { return err } - infrav1.ConvertAllTagsFrom(&in.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny) + infrav1.ConvertAllTagsFrom(&in.Filter.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny) return nil } @@ -214,9 +261,8 @@ func restorev1beta1Port(previous *infrav1.PortOpts, dst *infrav1.PortOpts) { prevFixedIP := &previous.FixedIPs[j] dstFixedIP := &dst.FixedIPs[j] - if dstFixedIP.IPAddress == nil || *dstFixedIP.IPAddress == "" { - dstFixedIP.IPAddress = prevFixedIP.IPAddress - } + optional.RestoreString(&prevFixedIP.IPAddress, &dstFixedIP.IPAddress) + restorev1beta1SubnetParam(prevFixedIP.Subnet, dstFixedIP.Subnet) } } @@ -225,9 +271,7 @@ func restorev1beta1Port(previous *infrav1.PortOpts, dst *infrav1.PortOpts) { prevAAP := &previous.AllowedAddressPairs[j] dstAAP := &dst.AllowedAddressPairs[j] - if dstAAP.MACAddress == nil || *dstAAP.MACAddress == "" { - dstAAP.MACAddress = prevAAP.MACAddress - } + optional.RestoreString(&prevAAP.MACAddress, &dstAAP.MACAddress) } } @@ -395,6 +439,14 @@ func Convert_v1beta1_OpenStackIdentityReference_To_v1alpha7_OpenStackIdentityRef // conversion-gen registers these functions so we must provider stubs, but // nothing should ever call them +func Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(_ *SubnetFilter, _ *infrav1.SubnetFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter should not be called") +} + +func Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(_ *infrav1.SubnetFilter, _ *SubnetFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter should not be called") +} + func Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkFilter(_ *NetworkFilter, _ *infrav1.NetworkFilter, _ apiconversion.Scope) error { return errors.New("Convert_v1alpha6_NetworkFilter_To_v1beta1_NetworkFilter should not be called") } diff --git a/api/v1alpha7/zz_generated.conversion.go b/api/v1alpha7/zz_generated.conversion.go index 8b070e14bf..e2ae6041c7 100644 --- a/api/v1alpha7/zz_generated.conversion.go +++ b/api/v1alpha7/zz_generated.conversion.go @@ -381,6 +381,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*SubnetFilter)(nil), (*v1beta1.SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(a.(*SubnetFilter), b.(*v1beta1.SubnetParam), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.BastionStatus)(nil), (*BastionStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_BastionStatus_To_v1alpha7_BastionStatus(a.(*v1beta1.BastionStatus), b.(*BastionStatus), scope) }); err != nil { @@ -451,6 +456,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.SubnetParam)(nil), (*SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(a.(*v1beta1.SubnetParam), b.(*SubnetFilter), scope) + }); err != nil { + return err + } return nil } @@ -664,7 +674,7 @@ func Convert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume(in *v1beta1 func autoConvert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in *ExternalRouterIPParam, out *v1beta1.ExternalRouterIPParam, s conversion.Scope) error { out.FixedIP = in.FixedIP - if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(&in.Subnet, &out.Subnet, s); err != nil { + if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { return err } return nil @@ -677,7 +687,7 @@ func Convert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in func autoConvert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(in *v1beta1.ExternalRouterIPParam, out *ExternalRouterIPParam, s conversion.Scope) error { out.FixedIP = in.FixedIP - if err := Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(&in.Subnet, &out.Subnet, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(&in.Subnet, &out.Subnet, s); err != nil { return err } return nil @@ -691,8 +701,8 @@ func Convert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(in func autoConvert_v1alpha7_FixedIP_To_v1beta1_FixedIP(in *FixedIP, out *v1beta1.FixedIP, s conversion.Scope) error { if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet - *out = new(v1beta1.SubnetFilter) - if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(*in, *out, s); err != nil { + *out = new(v1beta1.SubnetParam) + if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(*in, *out, s); err != nil { return err } } else { @@ -713,7 +723,7 @@ func autoConvert_v1beta1_FixedIP_To_v1alpha7_FixedIP(in *v1beta1.FixedIP, out *F if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet *out = new(SubnetFilter) - if err := Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(*in, *out, s); err != nil { + if err := Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(*in, *out, s); err != nil { return err } } else { @@ -1783,7 +1793,7 @@ func autoConvert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(in *SubnetFilter, out.CIDR = in.CIDR out.IPv6AddressMode = in.IPv6AddressMode out.IPv6RAMode = in.IPv6RAMode - out.ID = in.ID + // WARNING: in.ID requires manual conversion: does not exist in peer-type // WARNING: in.Tags requires manual conversion: does not exist in peer-type // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type // WARNING: in.NotTags requires manual conversion: does not exist in peer-type @@ -1800,7 +1810,6 @@ func autoConvert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(in *v1beta1.Subne out.CIDR = in.CIDR out.IPv6AddressMode = in.IPv6AddressMode out.IPv6RAMode = in.IPv6RAMode - out.ID = in.ID // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type return nil } diff --git a/api/v1beta1/openstackcluster_types.go b/api/v1beta1/openstackcluster_types.go index 35a2bf5505..b1566c01ac 100644 --- a/api/v1beta1/openstackcluster_types.go +++ b/api/v1beta1/openstackcluster_types.go @@ -58,7 +58,7 @@ type OpenStackClusterSpec struct { // +kubebuilder:validation:MaxItems=2 // +listType=atomic // +optional - Subnets []SubnetFilter `json:"subnets,omitempty"` + 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. diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go index 34633a9261..0fe2f4a1f7 100644 --- a/api/v1beta1/types.go +++ b/api/v1beta1/types.go @@ -48,7 +48,7 @@ type ExternalRouterIPParam struct { // The FixedIP in the corresponding subnet FixedIP string `json:"fixedIP,omitempty"` // The subnet in which the FixedIP is used for the Gateway of this router - Subnet SubnetFilter `json:"subnet"` + Subnet SubnetParam `json:"subnet"` } // NeutronTag represents a tag on a Neutron resource. @@ -85,7 +85,7 @@ type FilterByNeutronTags struct { } func (f *FilterByNeutronTags) IsZero() bool { - return f == nil || len(f.Tags) == 0 && len(f.TagsAny) == 0 && len(f.NotTags) == 0 && len(f.NotTagsAny) == 0 + return f == nil || (len(f.Tags) == 0 && len(f.TagsAny) == 0 && len(f.NotTags) == 0 && len(f.NotTagsAny) == 0) } type SecurityGroupFilter struct { @@ -131,6 +131,22 @@ func (networkFilter *NetworkFilter) IsZero() bool { networkFilter.FilterByNeutronTags.IsZero() } +// SubnetParam specifies an OpenStack subnet to use. It may be specified by either ID or filter, but not both. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type SubnetParam struct { + // ID is the uuid of the subnet. It will not be validated. + // +kubebuilder:validation:Format:=uuid + // +optional + ID optional.String `json:"id,omitempty"` + + // Filter specifies a filter to select the subnet. It must match exactly one subnet. + // +optional + Filter *SubnetFilter `json:"filter,omitempty"` +} + +// SubnetFilter specifies a filter to select a subnet. At least one parameter must be specified. +// +kubebuilder:validation:MinProperties:=1 type SubnetFilter struct { Name string `json:"name,omitempty"` Description string `json:"description,omitempty"` @@ -140,11 +156,25 @@ type SubnetFilter struct { CIDR string `json:"cidr,omitempty"` IPv6AddressMode string `json:"ipv6AddressMode,omitempty"` IPv6RAMode string `json:"ipv6RAMode,omitempty"` - ID string `json:"id,omitempty"` FilterByNeutronTags `json:",inline"` } +func (subnetFilter *SubnetFilter) IsZero() bool { + if subnetFilter == nil { + return true + } + return subnetFilter.Name == "" && + subnetFilter.Description == "" && + subnetFilter.ProjectID == "" && + subnetFilter.IPVersion == 0 && + subnetFilter.GatewayIP == "" && + subnetFilter.CIDR == "" && + subnetFilter.IPv6AddressMode == "" && + subnetFilter.IPv6RAMode == "" && + subnetFilter.FilterByNeutronTags.IsZero() +} + type RouterFilter struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` @@ -335,7 +365,7 @@ type FixedIP struct { // Subnet is an openstack subnet query that will return the id of a subnet to create // the fixed IP of a port in. This query must not return more than one subnet. // +optional - Subnet *SubnetFilter `json:"subnet,omitempty"` + Subnet *SubnetParam `json:"subnet,omitempty"` // IPAddress is a specific IP address to assign to the port. If Subnet // is also specified, IPAddress must be a valid IP address in the diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index bc21785a3b..6255ef3438 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -284,7 +284,7 @@ func (in *FixedIP) DeepCopyInto(out *FixedIP) { *out = *in if in.Subnet != nil { in, out := &in.Subnet, &out.Subnet - *out = new(SubnetFilter) + *out = new(SubnetParam) (*in).DeepCopyInto(*out) } if in.IPAddress != nil { @@ -566,7 +566,7 @@ func (in *OpenStackClusterSpec) DeepCopyInto(out *OpenStackClusterSpec) { } if in.Subnets != nil { in, out := &in.Subnets, &out.Subnets - *out = make([]SubnetFilter, len(*in)) + *out = make([]SubnetParam, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1551,6 +1551,31 @@ func (in *SubnetFilter) DeepCopy() *SubnetFilter { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetParam) DeepCopyInto(out *SubnetParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(SubnetFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetParam. +func (in *SubnetParam) DeepCopy() *SubnetParam { + if in == nil { + return nil + } + out := new(SubnetParam) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SubnetSpec) DeepCopyInto(out *SubnetSpec) { *out = *in diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml index f8146a4dc0..2a0546bb8c 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml @@ -5140,78 +5140,90 @@ spec: description: |- Subnet is an openstack subnet query that will return the id of a subnet to create the fixed IP of a port in. This query must not return more than one subnet. + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to + select the subnet. It must match exactly + one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. + It will not be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object type: object type: array @@ -5761,78 +5773,89 @@ spec: subnet: description: The subnet in which the FixedIP is used for the Gateway of this router + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to select the subnet. + It must match exactly one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. It will not be + validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object required: - subnet @@ -6157,78 +6180,90 @@ spec: all subnets in Network will be used. If 2 subnets are specified, one must be IPv4 and the other IPv6. items: + description: SubnetParam specifies an OpenStack subnet to use. It + may be specified by either ID or filter, but not both. + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to select the subnet. + It must match exactly one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. It will not be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object maxItems: 2 type: array diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml index 72e9aabe49..1eaba9daf1 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml @@ -2570,78 +2570,90 @@ spec: description: |- Subnet is an openstack subnet query that will return the id of a subnet to create the fixed IP of a port in. This query must not return more than one subnet. + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter + to select the subnet. It must match + exactly one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the + subnet. It will not be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object type: object type: array @@ -3197,78 +3209,89 @@ spec: subnet: description: The subnet in which the FixedIP is used for the Gateway of this router + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to select + the subnet. It must match exactly one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. It will + not be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object required: - subnet @@ -3596,78 +3619,92 @@ spec: all subnets in Network will be used. If 2 subnets are specified, one must be IPv4 and the other IPv6. items: + description: SubnetParam specifies an OpenStack subnet to + use. It may be specified by either ID or filter, but not + both. + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to select the + subnet. It must match exactly one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. It will not + be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object maxItems: 2 type: array diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml index bc3d9658b0..c0463608c0 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml @@ -1918,78 +1918,89 @@ spec: description: |- Subnet is an openstack subnet query that will return the id of a subnet to create the fixed IP of a port in. This query must not return more than one subnet. + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to select the + subnet. It must match exactly one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. It will + not be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object type: object type: array diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml index 7c481ff2b8..2407fa4a06 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml @@ -1594,78 +1594,90 @@ spec: description: |- Subnet is an openstack subnet query that will return the id of a subnet to create the fixed IP of a port in. This query must not return more than one subnet. + maxProperties: 1 + minProperties: 1 properties: - cidr: - type: string - description: - type: string - gatewayIP: - type: string + filter: + description: Filter specifies a filter to + select the subnet. It must match exactly + one subnet. + minProperties: 1 + properties: + cidr: + type: string + description: + type: string + gatewayIP: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RAMode: + type: string + name: + type: string + notTags: + description: |- + NotTags is a list of tags to filter by. If specified, resources which + contain all of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + notTagsAny: + description: |- + NotTagsAny is a list of tags to filter by. If specified, resources + which contain any of the given tags will be excluded from the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + projectID: + type: string + tags: + description: |- + Tags is a list of tags to filter by. If specified, the resource must + have all of the tags specified to be included in the result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + tagsAny: + description: |- + TagsAny is a list of tags to filter by. If specified, the resource + must have at least one of the tags specified to be included in the + result. + items: + description: |- + NeutronTag represents a tag on a Neutron resource. + It may not be empty and may not contain commas. + minLength: 1 + pattern: ^[^,]+$ + type: string + type: array + x-kubernetes-list-type: set + type: object id: + description: ID is the uuid of the subnet. + It will not be validated. + format: uuid type: string - ipVersion: - type: integer - ipv6AddressMode: - type: string - ipv6RAMode: - type: string - name: - type: string - notTags: - description: |- - NotTags is a list of tags to filter by. If specified, resources which - contain all of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - notTagsAny: - description: |- - NotTagsAny is a list of tags to filter by. If specified, resources - which contain any of the given tags will be excluded from the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - projectID: - type: string - tags: - description: |- - Tags is a list of tags to filter by. If specified, the resource must - have all of the tags specified to be included in the result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set - tagsAny: - description: |- - TagsAny is a list of tags to filter by. If specified, the resource - must have at least one of the tags specified to be included in the - result. - items: - description: |- - NeutronTag represents a tag on a Neutron resource. - It may not be empty and may not contain commas. - minLength: 1 - pattern: ^[^,]+$ - type: string - type: array - x-kubernetes-list-type: set type: object type: object type: array diff --git a/controllers/openstackcluster_controller.go b/controllers/openstackcluster_controller.go index 9c6e091254..c9283f11b7 100644 --- a/controllers/openstackcluster_controller.go +++ b/controllers/openstackcluster_controller.go @@ -885,9 +885,9 @@ func getClusterSubnets(networkingService *networking.Service, openStackCluster * } } else { for subnet := range openStackClusterSubnets { - filteredSubnet, err := networkingService.GetNetworkSubnetByFilter(networkID, &openStackClusterSubnets[subnet]) + filteredSubnet, err := networkingService.GetNetworkSubnetByParam(networkID, &openStackClusterSubnets[subnet]) if err != nil { - err = fmt.Errorf("failed to find subnet: %w", err) + err = fmt.Errorf("failed to find subnet %d in network %s: %w", subnet, networkID, err) if errors.Is(err, networking.ErrFilterMatch) { handleUpdateOSCError(openStackCluster, err) } diff --git a/controllers/openstackcluster_controller_test.go b/controllers/openstackcluster_controller_test.go index 7f2aa20f1b..0b6fe63784 100644 --- a/controllers/openstackcluster_controller_test.go +++ b/controllers/openstackcluster_controller_test.go @@ -595,9 +595,9 @@ var _ = Describe("OpenStackCluster controller", func() { Network: &infrav1.NetworkParam{ ID: pointer.String(clusterNetworkID), }, - Subnets: []infrav1.SubnetFilter{ - {ID: clusterSubnets[0]}, - {ID: clusterSubnets[1]}, + Subnets: []infrav1.SubnetParam{ + {ID: &clusterSubnets[0]}, + {ID: &clusterSubnets[1]}, }, } testCluster.Status = infrav1.OpenStackClusterStatus{ @@ -636,15 +636,17 @@ var _ = Describe("OpenStackCluster controller", func() { }, nil) networkClientRecorder.GetSubnet(clusterSubnets[0]).Return(&subnets.Subnet{ - ID: clusterSubnets[0], - Name: "cluster-subnet", - CIDR: "192.168.0.0/24", + ID: clusterSubnets[0], + NetworkID: clusterNetworkID, + Name: "cluster-subnet", + CIDR: "192.168.0.0/24", }, nil) networkClientRecorder.GetSubnet(clusterSubnets[1]).Return(&subnets.Subnet{ - ID: clusterSubnets[1], - Name: "cluster-subnet-v6", - CIDR: "2001:db8:2222:5555::/64", + ID: clusterSubnets[1], + NetworkID: clusterNetworkID, + Name: "cluster-subnet-v6", + CIDR: "2001:db8:2222:5555::/64", }, nil) err = reconcileNetworkComponents(scope, capiCluster, testCluster) @@ -661,8 +663,8 @@ var _ = Describe("OpenStackCluster controller", func() { DisableAPIServerFloatingIP: pointer.Bool(true), APIServerFixedIP: pointer.String("10.0.0.1"), DisableExternalNetwork: pointer.Bool(true), - Subnets: []infrav1.SubnetFilter{ - {ID: clusterSubnetID}, + Subnets: []infrav1.SubnetParam{ + {ID: pointer.String(clusterSubnetID)}, }, } err := k8sClient.Create(ctx, testCluster) diff --git a/docs/book/src/api/v1beta1/api.md b/docs/book/src/api/v1beta1/api.md index 527bf24ed0..24c303f15e 100644 --- a/docs/book/src/api/v1beta1/api.md +++ b/docs/book/src/api/v1beta1/api.md @@ -117,8 +117,8 @@ are specified.
subnets
subnet
subnet
subnets
subnets
(Appears on: -ExternalRouterIPParam, -FixedIP, -OpenStackClusterSpec) +SubnetParam)
+
SubnetFilter specifies a filter to select a subnet. At least one parameter must be specified.
+FilterByNeutronTags + + +FilterByNeutronTags + + + |
+
+
+(Members of |
+
+(Appears on: +ExternalRouterIPParam, +FixedIP, +OpenStackClusterSpec) +
++
SubnetParam specifies an OpenStack subnet to use. It may be specified by either ID or filter, but not both.
+ +Field | +Description | +
---|---|
id string |
+(Optional)
+ ID is the uuid of the subnet. It will not be validated. |
-FilterByNeutronTags + filter - -FilterByNeutronTags + +SubnetFilter |
-
-(Members of Filter specifies a filter to select the subnet. It must match exactly one subnet. |