From 865933dc4087ba80a49a3f289f2396c9d93ec2bf Mon Sep 17 00:00:00 2001
From: Matthew Booth
Date: Wed, 27 Mar 2024 15:19:00 +0000
Subject: [PATCH 1/3] SecurityGroupFilter to SecurityGroupParam
---
api/v1alpha5/conversion.go | 83 +++---
api/v1alpha5/zz_generated.conversion.go | 32 ++-
api/v1alpha6/conversion_test.go | 16 +-
api/v1alpha6/openstackmachine_conversion.go | 6 +
api/v1alpha6/types_conversion.go | 99 +++----
api/v1alpha6/zz_generated.conversion.go | 40 ++-
api/v1alpha7/openstackmachine_conversion.go | 10 +
api/v1alpha7/types_conversion.go | 70 ++++-
api/v1alpha7/zz_generated.conversion.go | 19 +-
api/v1beta1/openstackmachine_types.go | 2 +-
api/v1beta1/types.go | 29 +-
api/v1beta1/zz_generated.deepcopy.go | 29 +-
...re.cluster.x-k8s.io_openstackclusters.yaml | 266 +++++++++--------
...er.x-k8s.io_openstackclustertemplates.yaml | 269 ++++++++++--------
...re.cluster.x-k8s.io_openstackmachines.yaml | 264 +++++++++--------
...er.x-k8s.io_openstackmachinetemplates.yaml | 266 +++++++++--------
.../openstackmachine_controller_test.go | 2 +-
docs/book/src/api/v1beta1/api.md | 76 +++--
pkg/cloud/services/networking/port_test.go | 12 +-
.../services/networking/securitygroups.go | 18 +-
pkg/utils/filterconvert/convert.go | 1 -
.../e2e/suites/apivalidations/filters_test.go | 54 +++-
test/e2e/suites/e2e/e2e_test.go | 2 +-
test/helpers/fuzzerfuncs.go | 4 +
24 files changed, 1015 insertions(+), 654 deletions(-)
diff --git a/api/v1alpha5/conversion.go b/api/v1alpha5/conversion.go
index b5d0cf0ff3..50944701eb 100644
--- a/api/v1alpha5/conversion.go
+++ b/api/v1alpha5/conversion.go
@@ -325,13 +325,8 @@ func Convert_v1beta1_PortOpts_To_v1alpha5_PortOpts(in *infrav1.PortOpts, out *Po
if len(in.SecurityGroups) > 0 {
out.SecurityGroupFilters = make([]SecurityGroupParam, len(in.SecurityGroups))
for i := range in.SecurityGroups {
- securityGroupParam := &out.SecurityGroupFilters[i]
- if in.SecurityGroups[i].ID != "" {
- securityGroupParam.UUID = in.SecurityGroups[i].ID
- } else {
- if err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupFilter(&in.SecurityGroups[i], &securityGroupParam.Filter, s); err != nil {
- return err
- }
+ if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha5_SecurityGroupParam(&in.SecurityGroups[i], &out.SecurityGroupFilters[i], s); err != nil {
+ return err
}
}
}
@@ -395,46 +390,48 @@ func Convert_v1alpha5_PortOpts_To_v1beta1_PortOpts(in *PortOpts, out *infrav1.Po
}
if len(in.SecurityGroups) > 0 || len(in.SecurityGroupFilters) > 0 {
- out.SecurityGroups = make([]infrav1.SecurityGroupFilter, 0, len(in.SecurityGroups)+len(in.SecurityGroupFilters))
+ out.SecurityGroups = make([]infrav1.SecurityGroupParam, 0, len(in.SecurityGroups)+len(in.SecurityGroupFilters))
for i := range in.SecurityGroupFilters {
sgParam := &in.SecurityGroupFilters[i]
switch {
case sgParam.UUID != "":
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{ID: sgParam.UUID})
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{ID: &sgParam.UUID})
case sgParam.Name != "":
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{Name: sgParam.Name})
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{Filter: &infrav1.SecurityGroupFilter{Name: sgParam.Name}})
case sgParam.Filter != (SecurityGroupFilter{}):
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{})
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{})
outSG := &out.SecurityGroups[len(out.SecurityGroups)-1]
- if err := Convert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&sgParam.Filter, outSG, s); err != nil {
+ outSG.Filter = &infrav1.SecurityGroupFilter{}
+ if err := Convert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&sgParam.Filter, outSG.Filter, s); err != nil {
return err
}
}
}
- for _, id := range in.SecurityGroups {
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{ID: id})
+ for i := range in.SecurityGroups {
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{ID: &in.SecurityGroups[i]})
}
}
if len(in.SecurityGroups) > 0 || len(in.SecurityGroupFilters) > 0 {
- out.SecurityGroups = make([]infrav1.SecurityGroupFilter, 0, len(in.SecurityGroups)+len(in.SecurityGroupFilters))
+ out.SecurityGroups = make([]infrav1.SecurityGroupParam, 0, len(in.SecurityGroups)+len(in.SecurityGroupFilters))
for i := range in.SecurityGroupFilters {
sgParam := &in.SecurityGroupFilters[i]
switch {
case sgParam.UUID != "":
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{ID: sgParam.UUID})
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{ID: &sgParam.UUID})
case sgParam.Name != "":
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{Name: sgParam.Name})
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{Filter: &infrav1.SecurityGroupFilter{Name: sgParam.Name}})
case sgParam.Filter != (SecurityGroupFilter{}):
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{})
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{})
outSG := &out.SecurityGroups[len(out.SecurityGroups)-1]
- if err := Convert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&sgParam.Filter, outSG, s); err != nil {
+ outSG.Filter = &infrav1.SecurityGroupFilter{}
+ if err := Convert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&sgParam.Filter, outSG.Filter, s); err != nil {
return err
}
}
}
- for _, id := range in.SecurityGroups {
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{ID: id})
+ for i := range in.SecurityGroups {
+ out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupParam{ID: &in.SecurityGroups[i]})
}
}
@@ -521,34 +518,40 @@ func Convert_v1beta1_NetworkStatus_To_v1alpha5_Network(in *infrav1.NetworkStatus
return nil
}
-func Convert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupFilter(in *SecurityGroupParam, out *infrav1.SecurityGroupFilter, s conversion.Scope) error {
- // SecurityGroupParam is replaced by its contained SecurityGroupFilter in v1beta1
- err := Convert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&in.Filter, out, s)
- if err != nil {
- return err
- }
-
+func Convert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupParam(in *SecurityGroupParam, out *infrav1.SecurityGroupParam, s conversion.Scope) error {
if in.UUID != "" {
- out.ID = in.UUID
+ out.ID = &in.UUID
+ return nil
}
+
+ outFilter := &infrav1.SecurityGroupFilter{}
if in.Name != "" {
- out.Name = in.Name
+ outFilter.Name = in.Name
+ } else {
+ // SecurityGroupParam is replaced by its contained SecurityGroupFilter in v1beta1
+ err := Convert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&in.Filter, outFilter, s)
+ if err != nil {
+ return err
+ }
+ }
+
+ if !outFilter.IsZero() {
+ out.Filter = outFilter
}
return nil
}
-func Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupParam(in *infrav1.SecurityGroupFilter, out *SecurityGroupParam, s conversion.Scope) error {
- // SecurityGroupParam is replaced by its contained SecurityGroupFilter in v1beta1
- err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupFilter(in, &out.Filter, s)
- if err != nil {
- return err
+func Convert_v1beta1_SecurityGroupParam_To_v1alpha5_SecurityGroupParam(in *infrav1.SecurityGroupParam, out *SecurityGroupParam, s conversion.Scope) error {
+ if in.ID != nil {
+ out.UUID = *in.ID
+ return nil
}
- if in.ID != "" {
- out.UUID = in.ID
- }
- if in.Name != "" {
- out.Name = in.Name
+ if in.Filter != nil {
+ err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupFilter(in.Filter, &out.Filter, s)
+ if err != nil {
+ return err
+ }
}
return nil
}
diff --git a/api/v1alpha5/zz_generated.conversion.go b/api/v1alpha5/zz_generated.conversion.go
index 8d24ce309a..2a335b80c5 100644
--- a/api/v1alpha5/zz_generated.conversion.go
+++ b/api/v1alpha5/zz_generated.conversion.go
@@ -302,8 +302,8 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
- if err := s.AddConversionFunc((*SecurityGroupParam)(nil), (*v1beta1.SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupFilter(a.(*SecurityGroupParam), b.(*v1beta1.SecurityGroupFilter), scope)
+ if err := s.AddConversionFunc((*SecurityGroupParam)(nil), (*v1beta1.SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupParam(a.(*SecurityGroupParam), b.(*v1beta1.SecurityGroupParam), scope)
}); err != nil {
return err
}
@@ -407,8 +407,8 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
- if err := s.AddConversionFunc((*v1beta1.SecurityGroupFilter)(nil), (*SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupParam(a.(*v1beta1.SecurityGroupFilter), b.(*SecurityGroupParam), scope)
+ if err := s.AddConversionFunc((*v1beta1.SecurityGroupParam)(nil), (*SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_SecurityGroupParam_To_v1alpha5_SecurityGroupParam(a.(*v1beta1.SecurityGroupParam), b.(*SecurityGroupParam), scope)
}); err != nil {
return err
}
@@ -1161,9 +1161,9 @@ func autoConvert_v1alpha5_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(i
// WARNING: in.FloatingIP requires manual conversion: does not exist in peer-type
if in.SecurityGroups != nil {
in, out := &in.SecurityGroups, &out.SecurityGroups
- *out = make([]v1beta1.SecurityGroupFilter, len(*in))
+ *out = make([]v1beta1.SecurityGroupParam, len(*in))
for i := range *in {
- if err := Convert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupFilter(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1209,7 +1209,7 @@ func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha5_OpenStackMachineSpec(i
in, out := &in.SecurityGroups, &out.SecurityGroups
*out = make([]SecurityGroupParam, len(*in))
for i := range *in {
- if err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha5_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1453,7 +1453,7 @@ func autoConvert_v1beta1_PortOpts_To_v1alpha5_PortOpts(in *v1beta1.PortOpts, out
in, out := &in.SecurityGroups, &out.SecurityGroups
*out = make([]string, len(*in))
for i := range *in {
- if err := v1alpha6.Convert_v1beta1_SecurityGroupFilter_To_string(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := v1alpha6.Convert_v1beta1_SecurityGroupParam_To_string(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1517,7 +1517,7 @@ func Convert_v1beta1_Router_To_v1alpha5_Router(in *v1beta1.Router, out *Router,
}
func autoConvert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in *SecurityGroupFilter, out *v1beta1.SecurityGroupFilter, s conversion.Scope) error {
- out.ID = in.ID
+ // WARNING: in.ID requires manual conversion: does not exist in peer-type
out.Name = in.Name
out.Description = in.Description
// WARNING: in.TenantID requires manual conversion: does not exist in peer-type
@@ -1534,7 +1534,6 @@ func autoConvert_v1alpha5_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in
}
func autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupFilter(in *v1beta1.SecurityGroupFilter, out *SecurityGroupFilter, s conversion.Scope) error {
- out.ID = in.ID
out.Name = in.Name
out.Description = in.Description
out.ProjectID = in.ProjectID
@@ -1542,6 +1541,19 @@ func autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha5_SecurityGroupFilter(in
return nil
}
+func autoConvert_v1alpha5_SecurityGroupParam_To_v1beta1_SecurityGroupParam(in *SecurityGroupParam, out *v1beta1.SecurityGroupParam, s conversion.Scope) error {
+ // WARNING: in.UUID requires manual conversion: does not exist in peer-type
+ // WARNING: in.Name 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.SecurityGroupFilter vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.SecurityGroupFilter)
+ return nil
+}
+
+func autoConvert_v1beta1_SecurityGroupParam_To_v1alpha5_SecurityGroupParam(in *v1beta1.SecurityGroupParam, out *SecurityGroupParam, 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.SecurityGroupFilter vs sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha5.SecurityGroupFilter)
+ return nil
+}
+
func autoConvert_v1alpha5_Subnet_To_v1beta1_Subnet(in *Subnet, out *v1beta1.Subnet, s conversion.Scope) error {
out.Name = in.Name
out.ID = in.ID
diff --git a/api/v1alpha6/conversion_test.go b/api/v1alpha6/conversion_test.go
index 1456680359..4680ed9c15 100644
--- a/api/v1alpha6/conversion_test.go
+++ b/api/v1alpha6/conversion_test.go
@@ -455,19 +455,19 @@ func TestPortOptsConvertTo(t *testing.T) {
// Variables used in the tests
uuids := []string{"abc123", "123abc"}
- securityGroupsUuids := []infrav1.SecurityGroupFilter{
- {ID: uuids[0]},
- {ID: uuids[1]},
+ securityGroupsUuids := []infrav1.SecurityGroupParam{
+ {ID: &uuids[0]},
+ {ID: &uuids[1]},
}
securityGroupFilter := []SecurityGroupParam{
{Name: "one"},
{UUID: "654cba"},
}
- securityGroupFilterMerged := []infrav1.SecurityGroupFilter{
- {Name: "one"},
- {ID: "654cba"},
- {ID: uuids[0]},
- {ID: uuids[1]},
+ securityGroupFilterMerged := []infrav1.SecurityGroupParam{
+ {Filter: &infrav1.SecurityGroupFilter{Name: "one"}},
+ {ID: pointer.String("654cba")},
+ {ID: &uuids[0]},
+ {ID: &uuids[1]},
}
legacyPortProfile := map[string]string{
"capabilities": "[\"switchdev\"]",
diff --git a/api/v1alpha6/openstackmachine_conversion.go b/api/v1alpha6/openstackmachine_conversion.go
index d13eb5c124..d8439d19f1 100644
--- a/api/v1alpha6/openstackmachine_conversion.go
+++ b/api/v1alpha6/openstackmachine_conversion.go
@@ -170,6 +170,12 @@ func restorev1beta1MachineSpec(previous *infrav1.OpenStackMachineSpec, dst *infr
dst.ServerGroup = previous.ServerGroup
dst.Image = previous.Image
dst.FloatingIPPoolRef = previous.FloatingIPPoolRef
+
+ if len(dst.SecurityGroups) == len(previous.SecurityGroups) {
+ for i := range dst.SecurityGroups {
+ restorev1beta1SecurityGroupParam(&previous.SecurityGroups[i], &dst.SecurityGroups[i])
+ }
+ }
}
func convertNetworksToPorts(networks []NetworkParam, s apiconversion.Scope) ([]infrav1.PortOpts, error) {
diff --git a/api/v1alpha6/types_conversion.go b/api/v1alpha6/types_conversion.go
index 1b2a642f34..7b99803d3f 100644
--- a/api/v1alpha6/types_conversion.go
+++ b/api/v1alpha6/types_conversion.go
@@ -41,55 +41,71 @@ func restorev1alpha6SecurityGroupFilter(previous *SecurityGroupFilter, dst *Secu
dst.NotTagsAny = previous.NotTagsAny
}
-func Convert_v1beta1_SecurityGroupFilter_To_string(in *infrav1.SecurityGroupFilter, out *string, _ apiconversion.Scope) error {
- if in.ID != "" {
- *out = in.ID
+func restorev1beta1SecurityGroupParam(previous *infrav1.SecurityGroupParam, dst *infrav1.SecurityGroupParam) {
+ if previous == nil || dst == nil {
+ return
+ }
+
+ if dst.Filter != nil && previous.Filter != nil {
+ dst.Filter.Tags = previous.Filter.Tags
+ dst.Filter.TagsAny = previous.Filter.TagsAny
+ dst.Filter.NotTags = previous.Filter.NotTags
+ dst.Filter.NotTagsAny = previous.Filter.NotTagsAny
}
- return nil
}
-func Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupFilter(in *SecurityGroupParam, out *infrav1.SecurityGroupFilter, s apiconversion.Scope) error {
- // SecurityGroupParam is replaced by its contained SecurityGroupFilter in v1beta1
- err := Convert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&in.Filter, out, s)
- if err != nil {
- return err
+func Convert_v1beta1_SecurityGroupParam_To_string(in *infrav1.SecurityGroupParam, out *string, _ apiconversion.Scope) error {
+ if in.ID != nil {
+ *out = *in.ID
}
+ return nil
+}
+func Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupParam(in *SecurityGroupParam, out *infrav1.SecurityGroupParam, s apiconversion.Scope) error {
if in.UUID != "" {
- out.ID = in.UUID
+ out.ID = &in.UUID
+ return nil
}
+
+ outFilter := &infrav1.SecurityGroupFilter{}
+
if in.Name != "" {
- out.Name = in.Name
+ outFilter.Name = in.Name
+ } else {
+ err := Convert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&in.Filter, outFilter, s)
+ if err != nil {
+ return err
+ }
+ }
+
+ if !outFilter.IsZero() {
+ out.Filter = outFilter
}
return nil
}
-func Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupParam(in *infrav1.SecurityGroupFilter, out *SecurityGroupParam, s apiconversion.Scope) error {
- // SecurityGroupParam is replaced by its contained SecurityGroupFilter in v1beta1
- err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(in, &out.Filter, s)
- if err != nil {
- return err
+func Convert_v1beta1_SecurityGroupParam_To_v1alpha6_SecurityGroupParam(in *infrav1.SecurityGroupParam, out *SecurityGroupParam, s apiconversion.Scope) error {
+ if in.ID != nil {
+ out.UUID = *in.ID
+ return nil
}
- if in.ID != "" {
- out.UUID = in.ID
- }
- if in.Name != "" {
- out.Name = in.Name
+ if in.Filter != nil {
+ err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(in.Filter, &out.Filter, s)
+ if err != nil {
+ return err
+ }
}
+
return nil
}
func Convert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in *SecurityGroupFilter, out *infrav1.SecurityGroupFilter, s apiconversion.Scope) error {
- if err := autoConvert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in, out, s); err != nil {
+ err := autoConvert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in, out, s)
+ if err != nil {
return err
}
infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &out.FilterByNeutronTags)
-
- // TenantID has been removed in v1beta1. Write it to ProjectID if ProjectID is not already set.
- if out.ProjectID == "" {
- out.ProjectID = in.TenantID
- }
return nil
}
@@ -319,24 +335,14 @@ func Convert_v1alpha6_PortOpts_To_v1beta1_PortOpts(in *PortOpts, out *infrav1.Po
}
if len(in.SecurityGroups) > 0 || len(in.SecurityGroupFilters) > 0 {
- out.SecurityGroups = make([]infrav1.SecurityGroupFilter, 0, len(in.SecurityGroups)+len(in.SecurityGroupFilters))
+ out.SecurityGroups = make([]infrav1.SecurityGroupParam, len(in.SecurityGroups)+len(in.SecurityGroupFilters))
for i := range in.SecurityGroupFilters {
- sgParam := &in.SecurityGroupFilters[i]
- switch {
- case sgParam.UUID != "":
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{ID: sgParam.UUID})
- case sgParam.Name != "":
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{Name: sgParam.Name})
- case sgParam.Filter != (SecurityGroupFilter{}):
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{})
- outSG := &out.SecurityGroups[len(out.SecurityGroups)-1]
- if err := Convert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&sgParam.Filter, outSG, s); err != nil {
- return err
- }
+ if err := Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupParam(&in.SecurityGroupFilters[i], &out.SecurityGroups[i], s); err != nil {
+ return err
}
}
- for _, id := range in.SecurityGroups {
- out.SecurityGroups = append(out.SecurityGroups, infrav1.SecurityGroupFilter{ID: id})
+ for i := range in.SecurityGroups {
+ out.SecurityGroups[i+len(in.SecurityGroupFilters)] = infrav1.SecurityGroupParam{ID: &in.SecurityGroups[i]}
}
}
@@ -373,13 +379,8 @@ func Convert_v1beta1_PortOpts_To_v1alpha6_PortOpts(in *infrav1.PortOpts, out *Po
if len(in.SecurityGroups) > 0 {
out.SecurityGroupFilters = make([]SecurityGroupParam, len(in.SecurityGroups))
for i := range in.SecurityGroups {
- securityGroupParam := &out.SecurityGroupFilters[i]
- if in.SecurityGroups[i].ID != "" {
- securityGroupParam.UUID = in.SecurityGroups[i].ID
- } else {
- if err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(&in.SecurityGroups[i], &securityGroupParam.Filter, s); err != nil {
- return err
- }
+ if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha6_SecurityGroupParam(&in.SecurityGroups[i], &out.SecurityGroupFilters[i], s); err != nil {
+ return err
}
}
}
diff --git a/api/v1alpha6/zz_generated.conversion.go b/api/v1alpha6/zz_generated.conversion.go
index 9862d40792..2b98c9a0d8 100644
--- a/api/v1alpha6/zz_generated.conversion.go
+++ b/api/v1alpha6/zz_generated.conversion.go
@@ -321,8 +321,8 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
- if err := s.AddConversionFunc((*SecurityGroupParam)(nil), (*v1beta1.SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupFilter(a.(*SecurityGroupParam), b.(*v1beta1.SecurityGroupFilter), scope)
+ if err := s.AddConversionFunc((*SecurityGroupParam)(nil), (*v1beta1.SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupParam(a.(*SecurityGroupParam), b.(*v1beta1.SecurityGroupParam), scope)
}); err != nil {
return err
}
@@ -411,18 +411,18 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
- if err := s.AddConversionFunc((*v1beta1.SecurityGroupFilter)(nil), (*string)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1beta1_SecurityGroupFilter_To_string(a.(*v1beta1.SecurityGroupFilter), b.(*string), scope)
+ if err := s.AddConversionFunc((*v1beta1.SecurityGroupFilter)(nil), (*SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(a.(*v1beta1.SecurityGroupFilter), b.(*SecurityGroupFilter), scope)
}); err != nil {
return err
}
- if err := s.AddConversionFunc((*v1beta1.SecurityGroupFilter)(nil), (*SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(a.(*v1beta1.SecurityGroupFilter), b.(*SecurityGroupFilter), scope)
+ if err := s.AddConversionFunc((*v1beta1.SecurityGroupParam)(nil), (*string)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_SecurityGroupParam_To_string(a.(*v1beta1.SecurityGroupParam), b.(*string), scope)
}); err != nil {
return err
}
- if err := s.AddConversionFunc((*v1beta1.SecurityGroupFilter)(nil), (*SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupParam(a.(*v1beta1.SecurityGroupFilter), b.(*SecurityGroupParam), scope)
+ if err := s.AddConversionFunc((*v1beta1.SecurityGroupParam)(nil), (*SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_SecurityGroupParam_To_v1alpha6_SecurityGroupParam(a.(*v1beta1.SecurityGroupParam), b.(*SecurityGroupParam), scope)
}); err != nil {
return err
}
@@ -1196,9 +1196,9 @@ func autoConvert_v1alpha6_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(i
// WARNING: in.FloatingIP requires manual conversion: does not exist in peer-type
if in.SecurityGroups != nil {
in, out := &in.SecurityGroups, &out.SecurityGroups
- *out = make([]v1beta1.SecurityGroupFilter, len(*in))
+ *out = make([]v1beta1.SecurityGroupParam, len(*in))
for i := range *in {
- if err := Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupFilter(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1244,7 +1244,7 @@ func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(i
in, out := &in.SecurityGroups, &out.SecurityGroups
*out = make([]SecurityGroupParam, len(*in))
for i := range *in {
- if err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha6_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1489,7 +1489,7 @@ func autoConvert_v1beta1_PortOpts_To_v1alpha6_PortOpts(in *v1beta1.PortOpts, out
in, out := &in.SecurityGroups, &out.SecurityGroups
*out = make([]string, len(*in))
for i := range *in {
- if err := Convert_v1beta1_SecurityGroupFilter_To_string(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1beta1_SecurityGroupParam_To_string(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1553,7 +1553,7 @@ func Convert_v1beta1_Router_To_v1alpha6_Router(in *v1beta1.Router, out *Router,
}
func autoConvert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in *SecurityGroupFilter, out *v1beta1.SecurityGroupFilter, s conversion.Scope) error {
- out.ID = in.ID
+ // WARNING: in.ID requires manual conversion: does not exist in peer-type
out.Name = in.Name
out.Description = in.Description
// WARNING: in.TenantID requires manual conversion: does not exist in peer-type
@@ -1570,7 +1570,6 @@ func autoConvert_v1alpha6_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in
}
func autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(in *v1beta1.SecurityGroupFilter, out *SecurityGroupFilter, s conversion.Scope) error {
- out.ID = in.ID
out.Name = in.Name
out.Description = in.Description
out.ProjectID = in.ProjectID
@@ -1578,6 +1577,19 @@ func autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha6_SecurityGroupFilter(in
return nil
}
+func autoConvert_v1alpha6_SecurityGroupParam_To_v1beta1_SecurityGroupParam(in *SecurityGroupParam, out *v1beta1.SecurityGroupParam, s conversion.Scope) error {
+ // WARNING: in.UUID requires manual conversion: does not exist in peer-type
+ // WARNING: in.Name 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.SecurityGroupFilter vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.SecurityGroupFilter)
+ return nil
+}
+
+func autoConvert_v1beta1_SecurityGroupParam_To_v1alpha6_SecurityGroupParam(in *v1beta1.SecurityGroupParam, out *SecurityGroupParam, 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.SecurityGroupFilter vs sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha6.SecurityGroupFilter)
+ return nil
+}
+
func autoConvert_v1alpha6_Subnet_To_v1beta1_Subnet(in *Subnet, out *v1beta1.Subnet, s conversion.Scope) error {
out.Name = in.Name
out.ID = in.ID
diff --git a/api/v1alpha7/openstackmachine_conversion.go b/api/v1alpha7/openstackmachine_conversion.go
index fa0655288c..9ce17bbbd3 100644
--- a/api/v1alpha7/openstackmachine_conversion.go
+++ b/api/v1alpha7/openstackmachine_conversion.go
@@ -137,9 +137,19 @@ func restorev1alpha7MachineSpec(previous *OpenStackMachineSpec, dst *OpenStackMa
}
func restorev1beta1MachineSpec(previous *infrav1.OpenStackMachineSpec, dst *infrav1.OpenStackMachineSpec) {
+ if previous == nil || dst == nil {
+ return
+ }
+
dst.ServerGroup = previous.ServerGroup
dst.Image = previous.Image
+ if len(dst.SecurityGroups) == len(previous.SecurityGroups) {
+ for i := range dst.SecurityGroups {
+ restorev1beta1SecurityGroupParam(&previous.SecurityGroups[i], &dst.SecurityGroups[i])
+ }
+ }
+
if len(dst.Ports) == len(previous.Ports) {
for i := range dst.Ports {
restorev1beta1Port(&previous.Ports[i], &dst.Ports[i])
diff --git a/api/v1alpha7/types_conversion.go b/api/v1alpha7/types_conversion.go
index a63cd212ed..f98207a409 100644
--- a/api/v1alpha7/types_conversion.go
+++ b/api/v1alpha7/types_conversion.go
@@ -34,6 +34,13 @@ func restorev1alpha7SecurityGroupFilter(previous *SecurityGroupFilter, dst *Secu
dst.TagsAny = previous.TagsAny
dst.NotTags = previous.NotTags
dst.NotTagsAny = previous.NotTagsAny
+
+ // If ID was set we lost all other filter params
+ if dst.ID != "" {
+ dst.Name = previous.Name
+ dst.Description = previous.Description
+ dst.ProjectID = previous.ProjectID
+ }
}
func restorev1alpha7SecurityGroup(previous *SecurityGroup, dst *SecurityGroup) {
@@ -44,19 +51,48 @@ func restorev1alpha7SecurityGroup(previous *SecurityGroup, dst *SecurityGroup) {
dst.Rules = previous.Rules
}
-func Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in *SecurityGroupFilter, out *infrav1.SecurityGroupFilter, s apiconversion.Scope) error {
- if err := autoConvert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in, out, s); err != nil {
+func restorev1beta1SecurityGroupParam(previous *infrav1.SecurityGroupParam, dst *infrav1.SecurityGroupParam) {
+ if previous == nil || dst == nil {
+ return
+ }
+
+ if dst.Filter != nil && previous.Filter != nil {
+ dst.Filter.Tags = previous.Filter.Tags
+ dst.Filter.TagsAny = previous.Filter.TagsAny
+ dst.Filter.NotTags = previous.Filter.NotTags
+ dst.Filter.NotTagsAny = previous.Filter.NotTagsAny
+ }
+}
+
+func Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(in *SecurityGroupFilter, out *infrav1.SecurityGroupParam, s apiconversion.Scope) error {
+ if in.ID != "" {
+ out.ID = &in.ID
+ return nil
+ }
+
+ filter := &infrav1.SecurityGroupFilter{}
+ if err := autoConvert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(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_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(in *infrav1.SecurityGroupFilter, out *SecurityGroupFilter, s apiconversion.Scope) error {
- if err := autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(in, out, s); err != nil {
- return err
+func Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(in *infrav1.SecurityGroupParam, out *SecurityGroupFilter, s apiconversion.Scope) error {
+ if in.ID != nil {
+ out.ID = *in.ID
+ return nil
+ }
+
+ if in.Filter != nil {
+ if err := autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(in.Filter, out, s); err != nil {
+ return err
+ }
+ infrav1.ConvertAllTagsFrom(&in.Filter.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny)
}
- infrav1.ConvertAllTagsFrom(&in.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny)
return nil
}
@@ -294,6 +330,12 @@ func restorev1beta1Port(previous *infrav1.PortOpts, dst *infrav1.PortOpts) {
dstProfile.TrustedVF = prevProfile.TrustedVF
}
}
+
+ if len(dst.SecurityGroups) == len(previous.SecurityGroups) {
+ for j := range dst.SecurityGroups {
+ restorev1beta1SecurityGroupParam(&previous.SecurityGroups[j], &dst.SecurityGroups[j])
+ }
+ }
}
func Convert_v1alpha7_PortOpts_To_v1beta1_PortOpts(in *PortOpts, out *infrav1.PortOpts, s apiconversion.Scope) error {
@@ -334,9 +376,9 @@ func Convert_v1alpha7_PortOpts_To_v1beta1_PortOpts(in *PortOpts, out *infrav1.Po
}
if len(in.SecurityGroupFilters) > 0 {
- out.SecurityGroups = make([]infrav1.SecurityGroupFilter, len(in.SecurityGroupFilters))
+ out.SecurityGroups = make([]infrav1.SecurityGroupParam, len(in.SecurityGroupFilters))
for i := range in.SecurityGroupFilters {
- if err := Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&in.SecurityGroupFilters[i], &out.SecurityGroups[i], s); err != nil {
+ if err := Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(&in.SecurityGroupFilters[i], &out.SecurityGroups[i], s); err != nil {
return err
}
}
@@ -393,7 +435,7 @@ func Convert_v1beta1_PortOpts_To_v1alpha7_PortOpts(in *infrav1.PortOpts, out *Po
if len(in.SecurityGroups) > 0 {
out.SecurityGroupFilters = make([]SecurityGroupFilter, len(in.SecurityGroups))
for i := range in.SecurityGroups {
- if err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(&in.SecurityGroups[i], &out.SecurityGroupFilters[i], s); err != nil {
+ if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(&in.SecurityGroups[i], &out.SecurityGroupFilters[i], s); err != nil {
return err
}
}
@@ -454,3 +496,11 @@ func Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkFilter(_ *NetworkFilter, _
func Convert_v1beta1_NetworkFilter_To_v1alpha7_NetworkFilter(_ *infrav1.NetworkFilter, _ *NetworkFilter, _ apiconversion.Scope) error {
return errors.New("Convert_v1beta1_NetworkFilter_To_v1alpha6_NetworkFilter should not be called")
}
+
+func Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(_ *SecurityGroupFilter, _ *infrav1.SecurityGroupFilter, _ apiconversion.Scope) error {
+ return errors.New("Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter should not be called")
+}
+
+func Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(_ *infrav1.SecurityGroupFilter, _ *SecurityGroupFilter, _ apiconversion.Scope) error {
+ return errors.New("Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter should not be called")
+}
diff --git a/api/v1alpha7/zz_generated.conversion.go b/api/v1alpha7/zz_generated.conversion.go
index e2ae6041c7..6e00e14144 100644
--- a/api/v1alpha7/zz_generated.conversion.go
+++ b/api/v1alpha7/zz_generated.conversion.go
@@ -371,6 +371,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
+ if err := s.AddConversionFunc((*SecurityGroupFilter)(nil), (*v1beta1.SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(a.(*SecurityGroupFilter), b.(*v1beta1.SecurityGroupParam), scope)
+ }); err != nil {
+ return err
+ }
if err := s.AddConversionFunc((*SecurityGroup)(nil), (*v1beta1.SecurityGroupStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha7_SecurityGroup_To_v1beta1_SecurityGroupStatus(a.(*SecurityGroup), b.(*v1beta1.SecurityGroupStatus), scope)
}); err != nil {
@@ -446,6 +451,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
+ if err := s.AddConversionFunc((*v1beta1.SecurityGroupParam)(nil), (*SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(a.(*v1beta1.SecurityGroupParam), b.(*SecurityGroupFilter), scope)
+ }); err != nil {
+ return err
+ }
if err := s.AddConversionFunc((*v1beta1.SecurityGroupStatus)(nil), (*SecurityGroup)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_SecurityGroupStatus_To_v1alpha7_SecurityGroup(a.(*v1beta1.SecurityGroupStatus), b.(*SecurityGroup), scope)
}); err != nil {
@@ -1371,9 +1381,9 @@ func autoConvert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(i
// WARNING: in.FloatingIP requires manual conversion: does not exist in peer-type
if in.SecurityGroups != nil {
in, out := &in.SecurityGroups, &out.SecurityGroups
- *out = make([]v1beta1.SecurityGroupFilter, len(*in))
+ *out = make([]v1beta1.SecurityGroupParam, len(*in))
for i := range *in {
- if err := Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1420,7 +1430,7 @@ func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(i
in, out := &in.SecurityGroups, &out.SecurityGroups
*out = make([]SecurityGroupFilter, len(*in))
for i := range *in {
- if err := Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(&(*in)[i], &(*out)[i], s); err != nil {
+ if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
@@ -1738,7 +1748,7 @@ func autoConvert_v1beta1_RouterFilter_To_v1alpha7_RouterFilter(in *v1beta1.Route
}
func autoConvert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in *SecurityGroupFilter, out *v1beta1.SecurityGroupFilter, s conversion.Scope) error {
- out.ID = in.ID
+ // WARNING: in.ID requires manual conversion: does not exist in peer-type
out.Name = in.Name
out.Description = in.Description
out.ProjectID = in.ProjectID
@@ -1750,7 +1760,6 @@ func autoConvert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in
}
func autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(in *v1beta1.SecurityGroupFilter, out *SecurityGroupFilter, s conversion.Scope) error {
- out.ID = in.ID
out.Name = in.Name
out.Description = in.Description
out.ProjectID = in.ProjectID
diff --git a/api/v1beta1/openstackmachine_types.go b/api/v1beta1/openstackmachine_types.go
index f222f71761..5a7b05c319 100644
--- a/api/v1beta1/openstackmachine_types.go
+++ b/api/v1beta1/openstackmachine_types.go
@@ -55,7 +55,7 @@ type OpenStackMachineSpec struct {
Ports []PortOpts `json:"ports,omitempty"`
// The names of the security groups to assign to the instance
- SecurityGroups []SecurityGroupFilter `json:"securityGroups,omitempty"`
+ SecurityGroups []SecurityGroupParam `json:"securityGroups,omitempty"`
// Whether the server instance is created on a trunk port or not.
Trunk bool `json:"trunk,omitempty"`
diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go
index 0fe2f4a1f7..ad67976e96 100644
--- a/api/v1beta1/types.go
+++ b/api/v1beta1/types.go
@@ -88,8 +88,23 @@ func (f *FilterByNeutronTags) IsZero() bool {
return f == nil || (len(f.Tags) == 0 && len(f.TagsAny) == 0 && len(f.NotTags) == 0 && len(f.NotTagsAny) == 0)
}
+// SecurityGroupParam specifies an OpenStack security group. It may be specified by ID or filter, but not both.
+// +kubebuilder:validation:MaxProperties:=1
+// +kubebuilder:validation:MinProperties:=1
+type SecurityGroupParam struct {
+ // ID is the ID of the security group to use. If ID is provided, the other filters cannot be provided. Must be in UUID format.
+ // +kubebuilder:validation:Format:=uuid
+ // +optional
+ ID optional.String `json:"id,omitempty"`
+
+ // Filter specifies a query to select an OpenStack security group. If provided, cannot be empty.
+ // +optional
+ Filter *SecurityGroupFilter `json:"filter,omitempty"`
+}
+
+// SecurityGroupFilter specifies a query to select an OpenStack security group. At least one property must be set.
+// +kubebuilder:validation:MinProperties:=1
type SecurityGroupFilter struct {
- ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
ProjectID string `json:"projectID,omitempty"`
@@ -97,6 +112,16 @@ type SecurityGroupFilter struct {
FilterByNeutronTags `json:",inline"`
}
+func (f *SecurityGroupFilter) IsZero() bool {
+ if f == nil {
+ return true
+ }
+ return f.Name == "" &&
+ f.Description == "" &&
+ f.ProjectID == "" &&
+ f.FilterByNeutronTags.IsZero()
+}
+
// NetworkParam specifies an OpenStack network. It may be specified by either ID or Filter, but not both.
// +kubebuilder:validation:MaxProperties:=1
// +kubebuilder:validation:MinProperties:=1
@@ -232,7 +257,7 @@ type PortOpts struct {
// SecurityGroups is a list of the names, uuids, filters or any combination these of the security groups to assign to the instance.
// +optional
// +listType=atomic
- SecurityGroups []SecurityGroupFilter `json:"securityGroups,omitempty"`
+ SecurityGroups []SecurityGroupParam `json:"securityGroups,omitempty"`
// Tags applied to the port (and corresponding trunk, if a trunk is configured.)
// These tags are applied in addition to the instance's tags, which will also be applied to the port.
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index 6255ef3438..bbaa79118a 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -925,7 +925,7 @@ func (in *OpenStackMachineSpec) DeepCopyInto(out *OpenStackMachineSpec) {
}
if in.SecurityGroups != nil {
in, out := &in.SecurityGroups, &out.SecurityGroups
- *out = make([]SecurityGroupFilter, len(*in))
+ *out = make([]SecurityGroupParam, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1153,7 +1153,7 @@ func (in *PortOpts) DeepCopyInto(out *PortOpts) {
}
if in.SecurityGroups != nil {
in, out := &in.SecurityGroups, &out.SecurityGroups
- *out = make([]SecurityGroupFilter, len(*in))
+ *out = make([]SecurityGroupParam, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1415,6 +1415,31 @@ func (in *SecurityGroupFilter) DeepCopy() *SecurityGroupFilter {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecurityGroupParam) DeepCopyInto(out *SecurityGroupParam) {
+ *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(SecurityGroupFilter)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupParam.
+func (in *SecurityGroupParam) DeepCopy() *SecurityGroupParam {
+ if in == nil {
+ return nil
+ }
+ out := new(SecurityGroupParam)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecurityGroupRuleSpec) DeepCopyInto(out *SecurityGroupRuleSpec) {
*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 2a0546bb8c..c4adc2b0b7 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml
@@ -5349,68 +5349,84 @@ spec:
uuids, filters or any combination these of the security
groups to assign to the instance.
items:
+ description: SecurityGroupParam specifies an OpenStack
+ security group. It may be specified by ID or filter,
+ but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select
+ an OpenStack security group. If provided, cannot
+ be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group
+ to use. If ID is provided, the other filters
+ cannot be provided. Must be in UUID format.
+ format: uuid
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: array
x-kubernetes-list-type: atomic
@@ -5489,68 +5505,82 @@ spec:
description: The names of the security groups to assign to
the instance
items:
+ description: SecurityGroupParam specifies an OpenStack security
+ group. It may be specified by ID or filter, but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select an OpenStack
+ security group. If provided, cannot be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group to use.
+ If ID is provided, the other filters cannot be provided.
+ Must be in UUID format.
+ format: uuid
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: array
serverGroup:
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 1eaba9daf1..a6943b023a 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml
@@ -2782,68 +2782,85 @@ spec:
names, uuids, filters or any combination these
of the security groups to assign to the instance.
items:
+ description: SecurityGroupParam specifies
+ an OpenStack security group. It may be specified
+ by ID or filter, but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query
+ to select an OpenStack security group.
+ If provided, cannot be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security
+ group to use. If ID is provided, the
+ other filters cannot be provided. Must
+ be in UUID format.
+ format: uuid
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: array
x-kubernetes-list-type: atomic
@@ -2923,68 +2940,84 @@ spec:
description: The names of the security groups to assign
to the instance
items:
+ description: SecurityGroupParam specifies an OpenStack
+ security group. It may be specified by ID or filter,
+ but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select
+ an OpenStack security group. If provided,
+ cannot be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group
+ to use. If ID is provided, the other filters
+ cannot be provided. Must be in UUID format.
+ format: uuid
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: array
serverGroup:
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 c0463608c0..40ce3c87fd 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml
@@ -2125,68 +2125,82 @@ spec:
or any combination these of the security groups to assign
to the instance.
items:
+ description: SecurityGroupParam specifies an OpenStack security
+ group. It may be specified by ID or filter, but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select an OpenStack
+ security group. If provided, cannot be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group to use.
+ If ID is provided, the other filters cannot be provided.
+ Must be in UUID format.
+ format: uuid
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: array
x-kubernetes-list-type: atomic
@@ -2263,68 +2277,82 @@ spec:
securityGroups:
description: The names of the security groups to assign to the instance
items:
+ description: SecurityGroupParam specifies an OpenStack security
+ group. It may be specified by ID or filter, but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select an OpenStack
+ security group. If provided, cannot be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group to use. If ID
+ is provided, the other filters cannot be provided. Must be
+ in UUID format.
+ format: uuid
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: array
serverGroup:
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 2407fa4a06..e2c222712a 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml
@@ -1803,68 +1803,84 @@ spec:
uuids, filters or any combination these of the security
groups to assign to the instance.
items:
+ description: SecurityGroupParam specifies an OpenStack
+ security group. It may be specified by ID or filter,
+ but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select
+ an OpenStack security group. If provided, cannot
+ be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group
+ to use. If ID is provided, the other filters
+ cannot be provided. Must be in UUID format.
+ format: uuid
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: array
x-kubernetes-list-type: atomic
@@ -1943,68 +1959,82 @@ spec:
description: The names of the security groups to assign to
the instance
items:
+ description: SecurityGroupParam specifies an OpenStack security
+ group. It may be specified by ID or filter, but not both.
+ maxProperties: 1
+ minProperties: 1
properties:
- description:
- type: string
+ filter:
+ description: Filter specifies a query to select an OpenStack
+ security group. If provided, cannot be empty.
+ minProperties: 1
+ properties:
+ description:
+ 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 ID of the security group to use.
+ If ID is provided, the other filters cannot be provided.
+ Must be in UUID format.
+ format: uuid
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: array
serverGroup:
diff --git a/controllers/openstackmachine_controller_test.go b/controllers/openstackmachine_controller_test.go
index c941f11d04..d57848f80f 100644
--- a/controllers/openstackmachine_controller_test.go
+++ b/controllers/openstackmachine_controller_test.go
@@ -91,7 +91,7 @@ func getDefaultOpenStackMachine() *infrav1.OpenStackMachine {
{Key: "test-metadata", Value: "test-value"},
},
ConfigDrive: pointer.Bool(true),
- SecurityGroups: []infrav1.SecurityGroupFilter{},
+ SecurityGroups: []infrav1.SecurityGroupParam{},
ServerGroup: &infrav1.ServerGroupFilter{ID: serverGroupUUID},
},
Status: infrav1.OpenStackMachineStatus{
diff --git a/docs/book/src/api/v1beta1/api.md b/docs/book/src/api/v1beta1/api.md
index 24c303f15e..ecc495a928 100644
--- a/docs/book/src/api/v1beta1/api.md
+++ b/docs/book/src/api/v1beta1/api.md
@@ -626,8 +626,8 @@ If not specified a default port will be added for the default cluster network.
securityGroups
-
-[]SecurityGroupFilter
+
+[]SecurityGroupParam
|
@@ -3140,8 +3140,8 @@ If not specified a default port will be added for the default cluster network.
securityGroups
-
-[]SecurityGroupFilter
+
+[]SecurityGroupParam
|
@@ -3512,8 +3512,8 @@ If not specified a default port will be added for the default cluster network.
securityGroups
-
-[]SecurityGroupFilter
+
+[]SecurityGroupParam
|
@@ -3750,8 +3750,8 @@ string
securityGroups
-
-[]SecurityGroupFilter
+
+[]SecurityGroupParam
|
@@ -4396,10 +4396,10 @@ FilterByNeutronTags
(Appears on:
-OpenStackMachineSpec,
-PortOpts)
+SecurityGroupParam)
+
SecurityGroupFilter specifies a query to select an OpenStack security group. At least one property must be set.
@@ -4411,16 +4411,6 @@ FilterByNeutronTags
-id
-
-string
-
- |
-
- |
-
-
-
name
string
@@ -4466,6 +4456,52 @@ FilterByNeutronTags
|
+SecurityGroupParam
+
+
+(Appears on:
+OpenStackMachineSpec,
+PortOpts)
+
+
+
SecurityGroupParam specifies an OpenStack security group. It may be specified by ID or filter, but not both.
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+id
+
+string
+
+ |
+
+(Optional)
+ ID is the ID of the security group to use. If ID is provided, the other filters cannot be provided. Must be in UUID format.
+ |
+
+
+
+filter
+
+
+SecurityGroupFilter
+
+
+ |
+
+(Optional)
+ Filter specifies a query to select an OpenStack security group. If provided, cannot be empty.
+ |
+
+
+
SecurityGroupRuleSpec
diff --git a/pkg/cloud/services/networking/port_test.go b/pkg/cloud/services/networking/port_test.go
index ea0b6f3816..501f5f39cc 100644
--- a/pkg/cloud/services/networking/port_test.go
+++ b/pkg/cloud/services/networking/port_test.go
@@ -685,8 +685,8 @@ func TestService_ConstructPorts(t *testing.T) {
{
name: "machine spec security groups added to defaults",
spec: infrav1.OpenStackMachineSpec{
- SecurityGroups: []infrav1.SecurityGroupFilter{
- {Name: "test-security-group"},
+ SecurityGroups: []infrav1.SecurityGroupParam{
+ {Filter: &infrav1.SecurityGroupFilter{Name: "test-security-group"}},
},
},
expectNetwork: func(m *mock.MockNetworkClientMockRecorder) {
@@ -710,11 +710,11 @@ func TestService_ConstructPorts(t *testing.T) {
{
name: "port security groups override machine spec security groups",
spec: infrav1.OpenStackMachineSpec{
- SecurityGroups: []infrav1.SecurityGroupFilter{
- {Name: "machine-security-group"},
+ SecurityGroups: []infrav1.SecurityGroupParam{
+ {Filter: &infrav1.SecurityGroupFilter{Name: "machine-security-group"}},
},
Ports: []infrav1.PortOpts{
- {SecurityGroups: []infrav1.SecurityGroupFilter{{Name: "port-security-group"}}},
+ {SecurityGroups: []infrav1.SecurityGroupParam{{Filter: &infrav1.SecurityGroupFilter{Name: "port-security-group"}}}},
},
},
expectNetwork: func(m *mock.MockNetworkClientMockRecorder) {
@@ -758,7 +758,7 @@ func TestService_ConstructPorts(t *testing.T) {
{
name: "managed security group and machine security groups added to port",
spec: infrav1.OpenStackMachineSpec{
- SecurityGroups: []infrav1.SecurityGroupFilter{{Name: "machine-security-group"}},
+ SecurityGroups: []infrav1.SecurityGroupParam{{Filter: &infrav1.SecurityGroupFilter{Name: "machine-security-group"}}},
},
managedSecurityGroup: pointer.String(securityGroupID1),
expectNetwork: func(m *mock.MockNetworkClientMockRecorder) {
diff --git a/pkg/cloud/services/networking/securitygroups.go b/pkg/cloud/services/networking/securitygroups.go
index ecde85fe84..5d159f52a5 100644
--- a/pkg/cloud/services/networking/securitygroups.go
+++ b/pkg/cloud/services/networking/securitygroups.go
@@ -17,6 +17,7 @@ limitations under the License.
package networking
import (
+ "errors"
"fmt"
"slices"
@@ -308,21 +309,26 @@ func validateRemoteManagedGroups(remoteManagedGroups map[string]string, ruleRemo
return nil
}
-func (s *Service) GetSecurityGroups(securityGroupParams []infrav1.SecurityGroupFilter) ([]string, error) {
+func (s *Service) GetSecurityGroups(securityGroupParams []infrav1.SecurityGroupParam) ([]string, error) {
var sgIDs []string
for i := range securityGroupParams {
sg := &securityGroupParams[i]
// Don't validate an explicit UUID if we were given one
- if sg.ID != "" {
- if isDuplicate(sgIDs, sg.ID) {
+ if sg.ID != nil {
+ if isDuplicate(sgIDs, *sg.ID) {
continue
}
- sgIDs = append(sgIDs, sg.ID)
+ sgIDs = append(sgIDs, *sg.ID)
continue
}
- listOpts := filterconvert.SecurityGroupFilterToListOpts(sg)
+ if sg.Filter == nil {
+ // Should have been caught by validation
+ return nil, errors.New("security group param must have id or filter")
+ }
+
+ listOpts := filterconvert.SecurityGroupFilterToListOpts(sg.Filter)
if listOpts.ProjectID == "" {
listOpts.ProjectID = s.scope.ProjectID()
}
@@ -332,7 +338,7 @@ func (s *Service) GetSecurityGroups(securityGroupParams []infrav1.SecurityGroupF
}
if len(SGList) == 0 {
- return nil, fmt.Errorf("security group %s not found", sg.Name)
+ return nil, fmt.Errorf("security group %d not found", i)
}
for _, group := range SGList {
diff --git a/pkg/utils/filterconvert/convert.go b/pkg/utils/filterconvert/convert.go
index c1194b7880..8ece362ab6 100644
--- a/pkg/utils/filterconvert/convert.go
+++ b/pkg/utils/filterconvert/convert.go
@@ -31,7 +31,6 @@ func SecurityGroupFilterToListOpts(securityGroupFilter *infrav1.SecurityGroupFil
return securitygroups.ListOpts{}
}
return securitygroups.ListOpts{
- ID: securityGroupFilter.ID,
Name: securityGroupFilter.Name,
Description: securityGroupFilter.Description,
ProjectID: securityGroupFilter.ProjectID,
diff --git a/test/e2e/suites/apivalidations/filters_test.go b/test/e2e/suites/apivalidations/filters_test.go
index ce0b38637b..a6001c3ab2 100644
--- a/test/e2e/suites/apivalidations/filters_test.go
+++ b/test/e2e/suites/apivalidations/filters_test.go
@@ -51,9 +51,9 @@ var _ = Describe("Filter API validations", func() {
// possible to specify them in, then create the
// resulting object. It should be valid.
- securityGroups := make([]infrav1.SecurityGroupFilter, len(tags))
+ securityGroups := make([]infrav1.SecurityGroupParam, len(tags))
for i := range tags {
- securityGroups[i].FilterByNeutronTags = tags[i]
+ securityGroups[i].Filter = &infrav1.SecurityGroupFilter{FilterByNeutronTags: tags[i]}
}
machine.Spec.SecurityGroups = securityGroups
@@ -64,7 +64,7 @@ var _ = Describe("Filter API validations", func() {
port.FixedIPs = []infrav1.FixedIP{{Subnet: &infrav1.SubnetParam{
Filter: &infrav1.SubnetFilter{FilterByNeutronTags: tags[i]},
}}}
- port.SecurityGroups = []infrav1.SecurityGroupFilter{{FilterByNeutronTags: tags[i]}}
+ port.SecurityGroups = []infrav1.SecurityGroupParam{{Filter: &infrav1.SecurityGroupFilter{FilterByNeutronTags: tags[i]}}}
}
Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
@@ -97,9 +97,9 @@ var _ = Describe("Filter API validations", func() {
DescribeTable("Disallow invalid neutron filter tags", func(tags []infrav1.FilterByNeutronTags) {
{
machine := machine.DeepCopy()
- securityGroups := make([]infrav1.SecurityGroupFilter, len(tags))
+ securityGroups := make([]infrav1.SecurityGroupParam, len(tags))
for i := range tags {
- securityGroups[i].FilterByNeutronTags = tags[i]
+ securityGroups[i].Filter = &infrav1.SecurityGroupFilter{FilterByNeutronTags: tags[i]}
}
machine.Spec.SecurityGroups = securityGroups
Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail with invalid security group neutron tags")
@@ -125,7 +125,7 @@ var _ = Describe("Filter API validations", func() {
{
machine := machine.DeepCopy()
machine.Spec.Ports = []infrav1.PortOpts{
- {SecurityGroups: []infrav1.SecurityGroupFilter{{FilterByNeutronTags: tags[i]}}},
+ {SecurityGroups: []infrav1.SecurityGroupParam{{Filter: &infrav1.SecurityGroupFilter{FilterByNeutronTags: tags[i]}}}},
}
Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail with invalid port security group neutron tags")
}
@@ -307,4 +307,46 @@ var _ = Describe("Filter API validations", func() {
Expect(k8sClient.Create(ctx, cluster)).NotTo(Succeed(), "OpenStackCluster creation should fail")
})
})
+
+ Context("SecurityGroupParam", func() {
+ It("should allow setting ID", func() {
+ machine.Spec.SecurityGroups = []infrav1.SecurityGroupParam{
+ {ID: pointer.String("06c32c52-f207-4f6a-a769-bbcbe5a43f5c")},
+ }
+ Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
+ })
+
+ It("should allow setting non-empty Filter", func() {
+ machine.Spec.SecurityGroups = []infrav1.SecurityGroupParam{
+ {Filter: &infrav1.SecurityGroupFilter{Name: "foo"}},
+ }
+ Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
+ })
+
+ It("should not allow setting empty param", func() {
+ machine.Spec.SecurityGroups = []infrav1.SecurityGroupParam{{}}
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
+
+ It("should not allow setting invalid id", func() {
+ machine.Spec.SecurityGroups = []infrav1.SecurityGroupParam{
+ {ID: pointer.String("foo")},
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
+
+ It("should not allow setting empty Filter", func() {
+ machine.Spec.SecurityGroups = []infrav1.SecurityGroupParam{
+ {Filter: &infrav1.SecurityGroupFilter{}},
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
+
+ It("should not allow setting both ID and Filter", func() {
+ machine.Spec.SecurityGroups = []infrav1.SecurityGroupParam{
+ {ID: pointer.String("06c32c52-f207-4f6a-a769-bbcbe5a43f5c"), Filter: &infrav1.SecurityGroupFilter{Name: "foo"}},
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
+ })
})
diff --git a/test/e2e/suites/e2e/e2e_test.go b/test/e2e/suites/e2e/e2e_test.go
index ff0cb9c7ba..fadae81131 100644
--- a/test/e2e/suites/e2e/e2e_test.go
+++ b/test/e2e/suites/e2e/e2e_test.go
@@ -379,7 +379,7 @@ var _ = Describe("e2e tests [PR-Blocking]", func() {
Trunk: pointer.Bool(true),
},
{
- SecurityGroups: []infrav1.SecurityGroupFilter{{Name: testSecurityGroupName}},
+ SecurityGroups: []infrav1.SecurityGroupParam{{Filter: &infrav1.SecurityGroupFilter{Name: testSecurityGroupName}}},
},
}
diff --git a/test/helpers/fuzzerfuncs.go b/test/helpers/fuzzerfuncs.go
index 35720fcdd1..2c3a0fe188 100644
--- a/test/helpers/fuzzerfuncs.go
+++ b/test/helpers/fuzzerfuncs.go
@@ -137,5 +137,9 @@ func InfraV1FuzzerFuncs() []interface{} {
func(param *infrav1.SubnetParam, c fuzz.Continue) {
fuzzFilterParam(¶m.ID, ¶m.Filter, c)
},
+
+ func(param *infrav1.SecurityGroupParam, c fuzz.Continue) {
+ fuzzFilterParam(¶m.ID, ¶m.Filter, c)
+ },
}
}
From 91669cf7b4348fc58e3eccecc731ccc56bb90dc5 Mon Sep 17 00:00:00 2001
From: Matthew Booth
Date: Wed, 27 Mar 2024 18:02:46 +0000
Subject: [PATCH 2/3] make generate generates templates
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index d23c75d8ba..8b905651da 100644
--- a/Makefile
+++ b/Makefile
@@ -248,7 +248,7 @@ modules: ## Runs go mod to ensure proper vendoring.
cd $(TOOLS_DIR); go mod tidy
.PHONY: generate
-generate: generate-controller-gen generate-conversion-gen generate-go generate-manifests generate-api-docs ## Generate all generated code
+generate: templates generate-controller-gen generate-conversion-gen generate-go generate-manifests generate-api-docs ## Generate all generated code
.PHONY: generate-go
generate-go: $(MOCKGEN)
From 44be48e4f9e20eb7b31eaadb5612dcf80e9fd84c Mon Sep 17 00:00:00 2001
From: Matthew Booth
Date: Mon, 25 Mar 2024 14:08:10 +0000
Subject: [PATCH 3/3] ImageFilter to ImageParam
---
api/v1alpha5/conversion.go | 16 ++--
api/v1alpha5/zz_generated.conversion.go | 4 +-
api/v1alpha6/openstackmachine_conversion.go | 16 ++--
api/v1alpha6/zz_generated.conversion.go | 4 +-
api/v1alpha7/openstackmachine_conversion.go | 16 ++--
api/v1alpha7/zz_generated.conversion.go | 4 +-
api/v1beta1/openstackmachine_types.go | 2 +-
api/v1beta1/types.go | 28 +++++-
api/v1beta1/zz_generated.deepcopy.go | 30 +++++-
...re.cluster.x-k8s.io_openstackclusters.yaml | 46 ++++++----
...er.x-k8s.io_openstackclustertemplates.yaml | 49 +++++-----
...re.cluster.x-k8s.io_openstackmachines.yaml | 43 +++++----
...er.x-k8s.io_openstackmachinetemplates.yaml | 46 ++++++----
.../openstackcluster_controller_test.go | 6 +-
.../openstackmachine_controller_test.go | 2 +-
docs/book/src/api/v1beta1/api.md | 65 ++++++++++---
.../v1beta1/default/cluster-template.yaml | 6 +-
.../v1beta1/flatcar-sysext/patch-flatcar.yaml | 6 +-
kustomize/v1beta1/flatcar/patch-flatcar.yaml | 6 +-
pkg/cloud/services/compute/instance.go | 10 +-
pkg/cloud/services/compute/instance_test.go | 38 ++++++--
.../compute/referenced_resources_test.go | 16 ++--
pkg/webhooks/openstackcluster_webhook_test.go | 24 ++++-
.../openstackmachinetemplate_webhook_test.go | 48 ++++++++--
.../cluster-template-flatcar-sysext.yaml | 6 +-
templates/cluster-template-flatcar.yaml | 6 +-
templates/cluster-template-without-lb.yaml | 6 +-
templates/cluster-template.yaml | 6 +-
templates/clusterclass-dev-test.yaml | 4 +-
.../cluster-prev1beta1/kustomization.yaml | 10 ++
.../patch-cluster.yaml | 0
.../common-patches/cluster/kustomization.yaml | 10 ++
.../common-patches/cluster/patch-cluster.yaml | 15 +++
.../common-patches/cni/kustomization.yaml | 4 -
.../data/kustomize/default/kustomization.yaml | 1 +
.../flatcar-sysext/kustomization.yaml | 1 +
.../data/kustomize/flatcar/kustomization.yaml | 1 +
.../k8s-upgrade/upgrade-from-template.yaml | 6 +-
.../k8s-upgrade/upgrade-to-template.yaml | 6 +-
.../kustomize/v1alpha6/kustomization.yaml | 1 +
.../kustomize/v1alpha7/kustomization.yaml | 1 +
.../kustomize/without-lb/kustomization.yaml | 1 +
.../e2e/suites/apivalidations/filters_test.go | 92 +++++++++++--------
.../apivalidations/openstackcluster_test.go | 18 +++-
.../apivalidations/openstackmachine_test.go | 6 +-
test/e2e/suites/e2e/e2e_test.go | 12 ++-
test/helpers/fuzzerfuncs.go | 4 +
47 files changed, 507 insertions(+), 241 deletions(-)
create mode 100644 test/e2e/data/kustomize/common-patches/cluster-prev1beta1/kustomization.yaml
rename test/e2e/data/kustomize/common-patches/{cni => cluster-prev1beta1}/patch-cluster.yaml (100%)
create mode 100644 test/e2e/data/kustomize/common-patches/cluster/kustomization.yaml
create mode 100644 test/e2e/data/kustomize/common-patches/cluster/patch-cluster.yaml
diff --git a/api/v1alpha5/conversion.go b/api/v1alpha5/conversion.go
index 50944701eb..b9439a54eb 100644
--- a/api/v1alpha5/conversion.go
+++ b/api/v1alpha5/conversion.go
@@ -356,13 +356,13 @@ func Convert_v1alpha5_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(in *O
out.ServerGroup = &infrav1.ServerGroupFilter{}
}
- imageFilter := infrav1.ImageFilter{}
+ imageParam := infrav1.ImageParam{}
if in.ImageUUID != "" {
- imageFilter.ID = &in.ImageUUID
+ imageParam.ID = &in.ImageUUID
} else if in.Image != "" { // Only add name when ID is not set, in v1beta1 it's not possible to set both.
- imageFilter.Name = &in.Image
+ imageParam.Filter = &infrav1.ImageFilter{Name: &in.Image}
}
- out.Image = imageFilter
+ out.Image = imageParam
if in.IdentityRef != nil {
out.IdentityRef = &infrav1.OpenStackIdentityReference{Name: in.IdentityRef.Name}
@@ -686,12 +686,10 @@ func Convert_v1beta1_OpenStackMachineSpec_To_v1alpha5_OpenStackMachineSpec(in *i
out.ServerGroupID = in.ServerGroup.ID
}
- if in.Image.Name != nil && *in.Image.Name != "" {
- out.Image = *in.Image.Name
- }
-
- if in.Image.ID != nil && *in.Image.ID != "" {
+ if in.Image.ID != nil {
out.ImageUUID = *in.Image.ID
+ } else if in.Image.Filter != nil && in.Image.Filter.Name != nil {
+ out.Image = *in.Image.Filter.Name
}
if in.IdentityRef != nil {
diff --git a/api/v1alpha5/zz_generated.conversion.go b/api/v1alpha5/zz_generated.conversion.go
index 2a335b80c5..2c5a688927 100644
--- a/api/v1alpha5/zz_generated.conversion.go
+++ b/api/v1alpha5/zz_generated.conversion.go
@@ -1142,7 +1142,7 @@ func autoConvert_v1alpha5_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(i
out.InstanceID = (*string)(unsafe.Pointer(in.InstanceID))
// WARNING: in.CloudName requires manual conversion: does not exist in peer-type
out.Flavor = in.Flavor
- // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageFilter)
+ // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam)
// WARNING: in.ImageUUID requires manual conversion: does not exist in peer-type
out.SSHKeyName = in.SSHKeyName
// WARNING: in.Networks requires manual conversion: does not exist in peer-type
@@ -1192,7 +1192,7 @@ func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha5_OpenStackMachineSpec(i
out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID))
out.InstanceID = (*string)(unsafe.Pointer(in.InstanceID))
out.Flavor = in.Flavor
- // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageFilter vs string)
+ // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam vs string)
out.SSHKeyName = in.SSHKeyName
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
diff --git a/api/v1alpha6/openstackmachine_conversion.go b/api/v1alpha6/openstackmachine_conversion.go
index d8439d19f1..2b5864d818 100644
--- a/api/v1alpha6/openstackmachine_conversion.go
+++ b/api/v1alpha6/openstackmachine_conversion.go
@@ -272,13 +272,13 @@ func Convert_v1alpha6_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(in *O
out.ServerGroup = nil
}
- imageFilter := infrav1.ImageFilter{}
+ imageParam := infrav1.ImageParam{}
if in.ImageUUID != "" {
- imageFilter.ID = &in.ImageUUID
+ imageParam.ID = &in.ImageUUID
} else if in.Image != "" { // Only add name when ID is not set, in v1beta1 it's not possible to set both.
- imageFilter.Name = &in.Image
+ imageParam.Filter = &infrav1.ImageFilter{Name: &in.Image}
}
- out.Image = imageFilter
+ out.Image = imageParam
if len(in.ServerMetadata) > 0 {
serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata))
@@ -320,12 +320,10 @@ func Convert_v1beta1_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(in *i
out.ServerGroupID = in.ServerGroup.ID
}
- if in.Image.Name != nil && *in.Image.Name != "" {
- out.Image = *in.Image.Name
- }
-
- if in.Image.ID != nil && *in.Image.ID != "" {
+ if in.Image.ID != nil {
out.ImageUUID = *in.Image.ID
+ } else if in.Image.Filter != nil && in.Image.Filter.Name != nil {
+ out.Image = *in.Image.Filter.Name
}
if len(in.ServerMetadata) > 0 {
diff --git a/api/v1alpha6/zz_generated.conversion.go b/api/v1alpha6/zz_generated.conversion.go
index 2b98c9a0d8..8e33e36df6 100644
--- a/api/v1alpha6/zz_generated.conversion.go
+++ b/api/v1alpha6/zz_generated.conversion.go
@@ -1177,7 +1177,7 @@ func autoConvert_v1alpha6_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(i
out.InstanceID = (*string)(unsafe.Pointer(in.InstanceID))
// WARNING: in.CloudName requires manual conversion: does not exist in peer-type
out.Flavor = in.Flavor
- // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageFilter)
+ // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam)
// WARNING: in.ImageUUID requires manual conversion: does not exist in peer-type
out.SSHKeyName = in.SSHKeyName
// WARNING: in.Networks requires manual conversion: does not exist in peer-type
@@ -1227,7 +1227,7 @@ func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(i
out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID))
out.InstanceID = (*string)(unsafe.Pointer(in.InstanceID))
out.Flavor = in.Flavor
- // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageFilter vs string)
+ // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam vs string)
out.SSHKeyName = in.SSHKeyName
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
diff --git a/api/v1alpha7/openstackmachine_conversion.go b/api/v1alpha7/openstackmachine_conversion.go
index 9ce17bbbd3..4731f7445c 100644
--- a/api/v1alpha7/openstackmachine_conversion.go
+++ b/api/v1alpha7/openstackmachine_conversion.go
@@ -170,13 +170,13 @@ func Convert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(in *O
out.ServerGroup = nil
}
- imageFilter := infrav1.ImageFilter{}
+ imageParam := infrav1.ImageParam{}
if in.ImageUUID != "" {
- imageFilter.ID = &in.ImageUUID
+ imageParam.ID = &in.ImageUUID
} else if in.Image != "" { // Only add name when ID is not set, in v1beta1 it's not possible to set both.
- imageFilter.Name = &in.Image
+ imageParam.Filter = &infrav1.ImageFilter{Name: &in.Image}
}
- out.Image = imageFilter
+ out.Image = imageParam
if len(in.ServerMetadata) > 0 {
serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata))
@@ -215,12 +215,10 @@ func Convert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in *i
out.ServerGroupID = in.ServerGroup.ID
}
- if in.Image.Name != nil && *in.Image.Name != "" {
- out.Image = *in.Image.Name
- }
-
- if in.Image.ID != nil && *in.Image.ID != "" {
+ if in.Image.ID != nil {
out.ImageUUID = *in.Image.ID
+ } else if in.Image.Filter != nil && in.Image.Filter.Name != nil {
+ out.Image = *in.Image.Filter.Name
}
if len(in.ServerMetadata) > 0 {
diff --git a/api/v1alpha7/zz_generated.conversion.go b/api/v1alpha7/zz_generated.conversion.go
index 6e00e14144..87bb5dc328 100644
--- a/api/v1alpha7/zz_generated.conversion.go
+++ b/api/v1alpha7/zz_generated.conversion.go
@@ -1364,7 +1364,7 @@ func autoConvert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(i
out.InstanceID = (*string)(unsafe.Pointer(in.InstanceID))
// WARNING: in.CloudName requires manual conversion: does not exist in peer-type
out.Flavor = in.Flavor
- // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageFilter)
+ // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam)
// WARNING: in.ImageUUID requires manual conversion: does not exist in peer-type
out.SSHKeyName = in.SSHKeyName
if in.Ports != nil {
@@ -1413,7 +1413,7 @@ func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(i
out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID))
out.InstanceID = (*string)(unsafe.Pointer(in.InstanceID))
out.Flavor = in.Flavor
- // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageFilter vs string)
+ // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam vs string)
out.SSHKeyName = in.SSHKeyName
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
diff --git a/api/v1beta1/openstackmachine_types.go b/api/v1beta1/openstackmachine_types.go
index 5a7b05c319..3f20a559ff 100644
--- a/api/v1beta1/openstackmachine_types.go
+++ b/api/v1beta1/openstackmachine_types.go
@@ -45,7 +45,7 @@ type OpenStackMachineSpec struct {
// The image to use for your server instance.
// If the rootVolume is specified, this will be used when creating the root volume.
// +required
- Image ImageFilter `json:"image"`
+ Image ImageParam `json:"image"`
// The ssh key to inject in the instance
SSHKeyName string `json:"sshKeyName,omitempty"`
diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go
index ad67976e96..e9b9bbb2f6 100644
--- a/api/v1beta1/types.go
+++ b/api/v1beta1/types.go
@@ -28,22 +28,42 @@ type OpenStackMachineTemplateResource struct {
Spec OpenStackMachineSpec `json:"spec"`
}
-// ImageFilter describes the data needed to identify which image to use. If ID is provided it is required that all other fields are unset.
-// +kubebuilder:validation:XValidation:rule="(has(self.id) && !has(self.name) && !has(self.tags)) || !has(self.id)",message="when ID is set you cannot set other options"
-type ImageFilter struct {
- // The ID of the desired image. If ID is provided, the other filters cannot be provided. Must be in UUID format.
+// ImageParam describes a glance image. It can be specified by ID or filter.
+// +kubebuilder:validation:MaxProperties:=1
+// +kubebuilder:validation:MinProperties:=1
+type ImageParam struct {
+ // ID is the uuid of the image. ID will not be validated before use.
// +kubebuilder:validation:Format:=uuid
// +optional
ID optional.String `json:"id,omitempty"`
+
+ // Filter describes a query for an image. If specified, the combination
+ // of name and tags must return a single matching image or an error will
+ // be raised.
+ // +optional
+ Filter *ImageFilter `json:"filter,omitempty"`
+}
+
+// ImageFilter describes a query for an image.
+// +kubebuilder:validation:MinProperties:=1
+type ImageFilter struct {
// The name of the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
// +optional
Name optional.String `json:"name,omitempty"`
+
// The tags associated with the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
// +listType=set
// +optional
Tags []string `json:"tags,omitempty"`
}
+func (f *ImageFilter) IsZero() bool {
+ if f == nil {
+ return true
+ }
+ return f.Name == nil && len(f.Tags) == 0
+}
+
type ExternalRouterIPParam struct {
// The FixedIP in the corresponding subnet
FixedIP string `json:"fixedIP,omitempty"`
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index bbaa79118a..9c8f75f97f 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -307,11 +307,6 @@ func (in *FixedIP) DeepCopy() *FixedIP {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageFilter) DeepCopyInto(out *ImageFilter) {
*out = *in
- if in.ID != nil {
- in, out := &in.ID, &out.ID
- *out = new(string)
- **out = **in
- }
if in.Name != nil {
in, out := &in.Name, &out.Name
*out = new(string)
@@ -334,6 +329,31 @@ func (in *ImageFilter) DeepCopy() *ImageFilter {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ImageParam) DeepCopyInto(out *ImageParam) {
+ *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(ImageFilter)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageParam.
+func (in *ImageParam) DeepCopy() *ImageParam {
+ if in == nil {
+ return nil
+ }
+ out := new(ImageParam)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) {
*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 c4adc2b0b7..1490e10a21 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml
@@ -5050,31 +5050,37 @@ spec:
description: |-
The image to use for your server instance.
If the rootVolume is specified, this will be used when creating the root volume.
+ maxProperties: 1
+ minProperties: 1
properties:
+ filter:
+ description: |-
+ Filter describes a query for an image. If specified, the combination
+ of name and tags must return a single matching image or an error will
+ be raised.
+ minProperties: 1
+ properties:
+ name:
+ description: The name of the desired image. If specified,
+ the combination of name and tags must return a single
+ matching image or an error will be raised.
+ type: string
+ tags:
+ description: The tags associated with the desired
+ image. If specified, the combination of name and
+ tags must return a single matching image or an error
+ will be raised.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: set
+ type: object
id:
- description: The ID of the desired image. If ID is provided,
- the other filters cannot be provided. Must be in UUID
- format.
+ description: ID is the uuid of the image. ID will not
+ be validated before use.
format: uuid
type: string
- name:
- description: The name of the desired image. If specified,
- the combination of name and tags must return a single
- matching image or an error will be raised.
- type: string
- tags:
- description: The tags associated with the desired image.
- If specified, the combination of name and tags must
- return a single matching image or an error will be raised.
- items:
- type: string
- type: array
- x-kubernetes-list-type: set
type: object
- x-kubernetes-validations:
- - message: when ID is set you cannot set other options
- rule: (has(self.id) && !has(self.name) && !has(self.tags))
- || !has(self.id)
instanceID:
description: InstanceID is the OpenStack instance ID for this
machine.
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 a6943b023a..c0a334ec4c 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml
@@ -2477,33 +2477,38 @@ spec:
description: |-
The image to use for your server instance.
If the rootVolume is specified, this will be used when creating the root volume.
+ maxProperties: 1
+ minProperties: 1
properties:
+ filter:
+ description: |-
+ Filter describes a query for an image. If specified, the combination
+ of name and tags must return a single matching image or an error will
+ be raised.
+ minProperties: 1
+ properties:
+ name:
+ description: The name of the desired image.
+ If specified, the combination of name and
+ tags must return a single matching image
+ or an error will be raised.
+ type: string
+ tags:
+ description: The tags associated with the
+ desired image. If specified, the combination
+ of name and tags must return a single matching
+ image or an error will be raised.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: set
+ type: object
id:
- description: The ID of the desired image. If ID
- is provided, the other filters cannot be provided.
- Must be in UUID format.
+ description: ID is the uuid of the image. ID will
+ not be validated before use.
format: uuid
type: string
- name:
- description: The name of the desired image. If
- specified, the combination of name and tags
- must return a single matching image or an error
- will be raised.
- type: string
- tags:
- description: The tags associated with the desired
- image. If specified, the combination of name
- and tags must return a single matching image
- or an error will be raised.
- items:
- type: string
- type: array
- x-kubernetes-list-type: set
type: object
- x-kubernetes-validations:
- - message: when ID is set you cannot set other options
- rule: (has(self.id) && !has(self.name) && !has(self.tags))
- || !has(self.id)
instanceID:
description: InstanceID is the OpenStack instance
ID for this machine.
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 40ce3c87fd..1ea294dcb1 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml
@@ -1831,29 +1831,36 @@ spec:
description: |-
The image to use for your server instance.
If the rootVolume is specified, this will be used when creating the root volume.
+ maxProperties: 1
+ minProperties: 1
properties:
+ filter:
+ description: |-
+ Filter describes a query for an image. If specified, the combination
+ of name and tags must return a single matching image or an error will
+ be raised.
+ minProperties: 1
+ properties:
+ name:
+ description: The name of the desired image. If specified,
+ the combination of name and tags must return a single matching
+ image or an error will be raised.
+ type: string
+ tags:
+ description: The tags associated with the desired image. If
+ specified, the combination of name and tags must return
+ a single matching image or an error will be raised.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: set
+ type: object
id:
- description: The ID of the desired image. If ID is provided, the
- other filters cannot be provided. Must be in UUID format.
+ description: ID is the uuid of the image. ID will not be validated
+ before use.
format: uuid
type: string
- name:
- description: The name of the desired image. If specified, the
- combination of name and tags must return a single matching image
- or an error will be raised.
- type: string
- tags:
- description: The tags associated with the desired image. If specified,
- the combination of name and tags must return a single matching
- image or an error will be raised.
- items:
- type: string
- type: array
- x-kubernetes-list-type: set
type: object
- x-kubernetes-validations:
- - message: when ID is set you cannot set other options
- rule: (has(self.id) && !has(self.name) && !has(self.tags)) || !has(self.id)
instanceID:
description: InstanceID is the OpenStack instance ID for this machine.
type: string
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 e2c222712a..4c1b1abb98 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml
@@ -1504,31 +1504,37 @@ spec:
description: |-
The image to use for your server instance.
If the rootVolume is specified, this will be used when creating the root volume.
+ maxProperties: 1
+ minProperties: 1
properties:
+ filter:
+ description: |-
+ Filter describes a query for an image. If specified, the combination
+ of name and tags must return a single matching image or an error will
+ be raised.
+ minProperties: 1
+ properties:
+ name:
+ description: The name of the desired image. If specified,
+ the combination of name and tags must return a single
+ matching image or an error will be raised.
+ type: string
+ tags:
+ description: The tags associated with the desired
+ image. If specified, the combination of name and
+ tags must return a single matching image or an error
+ will be raised.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: set
+ type: object
id:
- description: The ID of the desired image. If ID is provided,
- the other filters cannot be provided. Must be in UUID
- format.
+ description: ID is the uuid of the image. ID will not
+ be validated before use.
format: uuid
type: string
- name:
- description: The name of the desired image. If specified,
- the combination of name and tags must return a single
- matching image or an error will be raised.
- type: string
- tags:
- description: The tags associated with the desired image.
- If specified, the combination of name and tags must
- return a single matching image or an error will be raised.
- items:
- type: string
- type: array
- x-kubernetes-list-type: set
type: object
- x-kubernetes-validations:
- - message: when ID is set you cannot set other options
- rule: (has(self.id) && !has(self.name) && !has(self.tags))
- || !has(self.id)
instanceID:
description: InstanceID is the OpenStack instance ID for this
machine.
diff --git a/controllers/openstackcluster_controller_test.go b/controllers/openstackcluster_controller_test.go
index 0b6fe63784..c2a602ec31 100644
--- a/controllers/openstackcluster_controller_test.go
+++ b/controllers/openstackcluster_controller_test.go
@@ -62,8 +62,10 @@ var _ = Describe("OpenStackCluster controller", func() {
testClusterName := "test-cluster"
testNum := 0
bastionSpec := infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{
- Name: pointer.String("fake-name"),
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("fake-name"),
+ },
},
}
diff --git a/controllers/openstackmachine_controller_test.go b/controllers/openstackmachine_controller_test.go
index d57848f80f..53c504e05c 100644
--- a/controllers/openstackmachine_controller_test.go
+++ b/controllers/openstackmachine_controller_test.go
@@ -84,7 +84,7 @@ func getDefaultOpenStackMachine() *infrav1.OpenStackMachine {
// FloatingIP is only used by the cluster controller for the Bastion
// TODO: Test Networks, Ports, Subnet, and Trunk separately
Flavor: flavorName,
- Image: infrav1.ImageFilter{ID: pointer.String(imageUUID)},
+ Image: infrav1.ImageParam{ID: pointer.String(imageUUID)},
SSHKeyName: sshKeyName,
Tags: []string{"test-tag"},
ServerMetadata: []infrav1.ServerMetadata{
diff --git a/docs/book/src/api/v1beta1/api.md b/docs/book/src/api/v1beta1/api.md
index ecc495a928..581f7326ef 100644
--- a/docs/book/src/api/v1beta1/api.md
+++ b/docs/book/src/api/v1beta1/api.md
@@ -587,8 +587,8 @@ string
image
-
-ImageFilter
+
+ImageParam
|
@@ -1580,10 +1580,10 @@ address in any subnet of the port’s network.
(Appears on:
-OpenStackMachineSpec)
+ImageParam)
-
ImageFilter describes the data needed to identify which image to use. If ID is provided it is required that all other fields are unset.
+ImageFilter describes a query for an image.
@@ -1595,38 +1595,73 @@ address in any subnet of the port’s network.
-id
+name
string
|
(Optional)
- The ID of the desired image. If ID is provided, the other filters cannot be provided. Must be in UUID format.
+The name of the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
|
-name
+tags
+
+[]string
+
+ |
+
+(Optional)
+ The tags associated with the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
+ |
+
+
+
+ImageParam
+
+
+(Appears on:
+OpenStackMachineSpec)
+
+
+
ImageParam describes a glance image. It can be specified by ID or filter.
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+id
string
|
(Optional)
- The name of the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
+ID is the uuid of the image. ID will not be validated before use.
|
-tags
+filter
-[]string
+
+ImageFilter
+
|
(Optional)
- The tags associated with the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
+Filter describes a query for an image. If specified, the combination
+of name and tags must return a single matching image or an error will
+be raised.
|
@@ -3101,8 +3136,8 @@ string
image
-
-ImageFilter
+
+ImageParam
|
@@ -3473,8 +3508,8 @@ string
image
-
-ImageFilter
+
+ImageParam
|
diff --git a/kustomize/v1beta1/default/cluster-template.yaml b/kustomize/v1beta1/default/cluster-template.yaml
index 52ab6c2f88..ae7db083cf 100644
--- a/kustomize/v1beta1/default/cluster-template.yaml
+++ b/kustomize/v1beta1/default/cluster-template.yaml
@@ -97,7 +97,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
---
apiVersion: cluster.x-k8s.io/v1beta1
@@ -133,7 +134,8 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
diff --git a/kustomize/v1beta1/flatcar-sysext/patch-flatcar.yaml b/kustomize/v1beta1/flatcar-sysext/patch-flatcar.yaml
index 0c60d2e460..6c143c853c 100644
--- a/kustomize/v1beta1/flatcar-sysext/patch-flatcar.yaml
+++ b/kustomize/v1beta1/flatcar-sysext/patch-flatcar.yaml
@@ -170,7 +170,8 @@ spec:
template:
spec:
image:
- name: ${FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${FLATCAR_IMAGE_NAME}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: OpenStackMachineTemplate
@@ -180,4 +181,5 @@ spec:
template:
spec:
image:
- name: ${FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${FLATCAR_IMAGE_NAME}
diff --git a/kustomize/v1beta1/flatcar/patch-flatcar.yaml b/kustomize/v1beta1/flatcar/patch-flatcar.yaml
index d95991efc9..a702429646 100644
--- a/kustomize/v1beta1/flatcar/patch-flatcar.yaml
+++ b/kustomize/v1beta1/flatcar/patch-flatcar.yaml
@@ -94,7 +94,8 @@ spec:
template:
spec:
image:
- name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: OpenStackMachineTemplate
@@ -104,4 +105,5 @@ spec:
template:
spec:
image:
- name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
diff --git a/pkg/cloud/services/compute/instance.go b/pkg/cloud/services/compute/instance.go
index eebfd9278d..ac0b377bed 100644
--- a/pkg/cloud/services/compute/instance.go
+++ b/pkg/cloud/services/compute/instance.go
@@ -18,6 +18,7 @@ package compute
import (
"context"
+ "errors"
"fmt"
"os"
"strconv"
@@ -332,12 +333,17 @@ func applyServerGroupID(opts servers.CreateOptsBuilder, serverGroupID string) se
}
// Helper function for getting image ID from name, ID, or tags.
-func (s *Service) GetImageID(image infrav1.ImageFilter) (string, error) {
+func (s *Service) GetImageID(image infrav1.ImageParam) (string, error) {
if image.ID != nil {
return *image.ID, nil
}
- listOpts := filterconvert.ImageFilterToListOpts(&image)
+ if image.Filter == nil {
+ // Should have been caught by validation
+ return "", errors.New("image id and filter are both nil")
+ }
+
+ listOpts := filterconvert.ImageFilterToListOpts(image.Filter)
allImages, err := s.getImageClient().ListImages(listOpts)
if err != nil {
return "", err
diff --git a/pkg/cloud/services/compute/instance_test.go b/pkg/cloud/services/compute/instance_test.go
index af9214e8a7..b571b25021 100644
--- a/pkg/cloud/services/compute/instance_test.go
+++ b/pkg/cloud/services/compute/instance_test.go
@@ -47,22 +47,26 @@ func TestService_getImageID(t *testing.T) {
tests := []struct {
testName string
- image infrav1.ImageFilter
+ image infrav1.ImageParam
expect func(m *mock.MockImageClientMockRecorder)
want string
wantErr bool
}{
{
testName: "Return image ID when ID given",
- image: infrav1.ImageFilter{ID: &imageID},
+ image: infrav1.ImageParam{ID: &imageID},
want: imageID,
expect: func(m *mock.MockImageClientMockRecorder) {},
wantErr: false,
},
{
testName: "Return image ID when name given",
- image: infrav1.ImageFilter{Name: &imageName},
- want: imageID,
+ image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: &imageName,
+ },
+ },
+ want: imageID,
expect: func(m *mock.MockImageClientMockRecorder) {
m.ListImages(images.ListOpts{Name: imageName}).Return(
[]images.Image{{ID: imageID, Name: imageName}},
@@ -72,8 +76,12 @@ func TestService_getImageID(t *testing.T) {
},
{
testName: "Return image ID when tags given",
- image: infrav1.ImageFilter{Tags: imageTags},
- want: imageID,
+ image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Tags: imageTags,
+ },
+ },
+ want: imageID,
expect: func(m *mock.MockImageClientMockRecorder) {
m.ListImages(images.ListOpts{Tags: imageTags}).Return(
[]images.Image{{ID: imageID, Name: imageName, Tags: imageTags}},
@@ -83,7 +91,11 @@ func TestService_getImageID(t *testing.T) {
},
{
testName: "Return no results",
- image: infrav1.ImageFilter{Name: &imageName},
+ image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: &imageName,
+ },
+ },
expect: func(m *mock.MockImageClientMockRecorder) {
m.ListImages(images.ListOpts{Name: imageName}).Return(
[]images.Image{},
@@ -94,7 +106,11 @@ func TestService_getImageID(t *testing.T) {
},
{
testName: "Return multiple results",
- image: infrav1.ImageFilter{Name: &imageName},
+ image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: &imageName,
+ },
+ },
expect: func(m *mock.MockImageClientMockRecorder) {
m.ListImages(images.ListOpts{Name: "test-image"}).Return(
[]images.Image{
@@ -107,7 +123,11 @@ func TestService_getImageID(t *testing.T) {
},
{
testName: "OpenStack returns error",
- image: infrav1.ImageFilter{Name: &imageName},
+ image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: &imageName,
+ },
+ },
expect: func(m *mock.MockImageClientMockRecorder) {
m.ListImages(images.ListOpts{Name: "test-image"}).Return(
nil,
diff --git a/pkg/cloud/services/compute/referenced_resources_test.go b/pkg/cloud/services/compute/referenced_resources_test.go
index 035bdaf824..b4419b691d 100644
--- a/pkg/cloud/services/compute/referenced_resources_test.go
+++ b/pkg/cloud/services/compute/referenced_resources_test.go
@@ -68,7 +68,7 @@ func Test_ResolveMachineSpec(t *testing.T) {
testName: "Resources ID passed",
spec: infrav1.OpenStackMachineSpec{
ServerGroup: &infrav1.ServerGroupFilter{ID: serverGroupID1},
- Image: infrav1.ImageFilter{ID: pointer.String(imageID1)},
+ Image: infrav1.ImageParam{ID: pointer.String(imageID1)},
},
want: &infrav1.ResolvedMachineSpec{
ImageID: imageID1,
@@ -79,7 +79,7 @@ func Test_ResolveMachineSpec(t *testing.T) {
{
testName: "Only image ID passed: want image id and default ports",
spec: infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{ID: pointer.String(imageID1)},
+ Image: infrav1.ImageParam{ID: pointer.String(imageID1)},
},
want: &infrav1.ResolvedMachineSpec{
ImageID: imageID1,
@@ -89,7 +89,7 @@ func Test_ResolveMachineSpec(t *testing.T) {
{
testName: "Server group empty",
spec: infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{ID: pointer.String(imageID1)},
+ Image: infrav1.ImageParam{ID: pointer.String(imageID1)},
ServerGroup: &infrav1.ServerGroupFilter{},
},
want: &infrav1.ResolvedMachineSpec{
@@ -100,7 +100,7 @@ func Test_ResolveMachineSpec(t *testing.T) {
{
testName: "Server group by Name not found",
spec: infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{ID: pointer.String(imageID1)},
+ Image: infrav1.ImageParam{ID: pointer.String(imageID1)},
ServerGroup: &infrav1.ServerGroupFilter{Name: "test-server-group"},
},
expectComputeMock: func(m *mock.MockComputeClientMockRecorder) {
@@ -114,7 +114,11 @@ func Test_ResolveMachineSpec(t *testing.T) {
{
testName: "Image by Name not found",
spec: infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{Name: pointer.String("test-image")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("test-image"),
+ },
+ },
},
expectImageMock: func(m *mock.MockImageClientMockRecorder) {
m.ListImages(images.ListOpts{Name: "test-image"}).Return([]images.Image{}, nil)
@@ -125,7 +129,7 @@ func Test_ResolveMachineSpec(t *testing.T) {
{
testName: "Ports set",
spec: infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{ID: pointer.String(imageID1)},
+ Image: infrav1.ImageParam{ID: pointer.String(imageID1)},
Ports: []infrav1.PortOpts{
{
Network: &infrav1.NetworkParam{
diff --git a/pkg/webhooks/openstackcluster_webhook_test.go b/pkg/webhooks/openstackcluster_webhook_test.go
index 3d65376486..09c18dcc70 100644
--- a/pkg/webhooks/openstackcluster_webhook_test.go
+++ b/pkg/webhooks/openstackcluster_webhook_test.go
@@ -85,7 +85,11 @@ func TestOpenStackCluster_ValidateUpdate(t *testing.T) {
},
Bastion: &infrav1.Bastion{
Spec: &infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{Name: pointer.String("foobar")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("foobar"),
+ },
+ },
Flavor: "minimal",
},
Enabled: true,
@@ -105,7 +109,11 @@ func TestOpenStackCluster_ValidateUpdate(t *testing.T) {
},
Bastion: &infrav1.Bastion{
Spec: &infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{Name: pointer.String("foobarbaz")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("foobarbaz"),
+ },
+ },
Flavor: "medium",
},
Enabled: true,
@@ -454,7 +462,11 @@ func TestOpenStackCluster_ValidateUpdate(t *testing.T) {
Enabled: true,
Spec: &infrav1.OpenStackMachineSpec{
Flavor: "m1.small",
- Image: infrav1.ImageFilter{Name: pointer.String("ubuntu")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("ubuntu"),
+ },
+ },
},
},
},
@@ -481,7 +493,11 @@ func TestOpenStackCluster_ValidateUpdate(t *testing.T) {
Enabled: false,
Spec: &infrav1.OpenStackMachineSpec{
Flavor: "m1.small",
- Image: infrav1.ImageFilter{Name: pointer.String("ubuntu")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("ubuntu"),
+ },
+ },
},
},
},
diff --git a/pkg/webhooks/openstackmachinetemplate_webhook_test.go b/pkg/webhooks/openstackmachinetemplate_webhook_test.go
index 899cf509f1..6b148f3bfa 100644
--- a/pkg/webhooks/openstackmachinetemplate_webhook_test.go
+++ b/pkg/webhooks/openstackmachinetemplate_webhook_test.go
@@ -47,7 +47,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("bar")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ },
+ },
},
},
},
@@ -57,7 +61,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("NewImage")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("NewImage"),
+ },
+ },
},
},
},
@@ -72,7 +80,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("bar")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ },
+ },
},
},
},
@@ -85,7 +97,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("bar")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ },
+ },
},
},
},
@@ -102,7 +118,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("bar")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ },
+ },
},
},
},
@@ -112,7 +132,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("NewImage")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("NewImage"),
+ },
+ },
},
},
},
@@ -127,7 +151,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("bar")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ },
+ },
},
},
},
@@ -142,7 +170,11 @@ func TestOpenStackMachineTemplate_ValidateUpdate(t *testing.T) {
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: "foo",
- Image: infrav1.ImageFilter{Name: pointer.String("NewImage")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("NewImage"),
+ },
+ },
},
},
},
diff --git a/templates/cluster-template-flatcar-sysext.yaml b/templates/cluster-template-flatcar-sysext.yaml
index 9cbef933cc..ec33bdeff2 100644
--- a/templates/cluster-template-flatcar-sysext.yaml
+++ b/templates/cluster-template-flatcar-sysext.yaml
@@ -268,7 +268,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${FLATCAR_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
@@ -280,5 +281,6 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${FLATCAR_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
diff --git a/templates/cluster-template-flatcar.yaml b/templates/cluster-template-flatcar.yaml
index 3d3f92ba23..4282265943 100644
--- a/templates/cluster-template-flatcar.yaml
+++ b/templates/cluster-template-flatcar.yaml
@@ -192,7 +192,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
@@ -204,5 +205,6 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_FLATCAR_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
diff --git a/templates/cluster-template-without-lb.yaml b/templates/cluster-template-without-lb.yaml
index 35acfdbdf1..6dbf7a72d1 100644
--- a/templates/cluster-template-without-lb.yaml
+++ b/templates/cluster-template-without-lb.yaml
@@ -144,7 +144,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
@@ -156,5 +157,6 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
diff --git a/templates/cluster-template.yaml b/templates/cluster-template.yaml
index bc8c8aab8c..3508d37e26 100644
--- a/templates/cluster-template.yaml
+++ b/templates/cluster-template.yaml
@@ -146,7 +146,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
@@ -158,5 +159,6 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
diff --git a/templates/clusterclass-dev-test.yaml b/templates/clusterclass-dev-test.yaml
index 2cd3a38531..5743a6367d 100644
--- a/templates/clusterclass-dev-test.yaml
+++ b/templates/clusterclass-dev-test.yaml
@@ -43,7 +43,7 @@ spec:
controlPlane: true
jsonPatches:
- op: add
- path: /spec/template/spec/image/name
+ path: /spec/template/spec/image/filter/name
valueFrom:
template: |
ubuntu-2204-kube-{{ .builtin.controlPlane.version }}
@@ -59,7 +59,7 @@ spec:
- default-worker
jsonPatches:
- op: add
- path: /spec/template/spec/image/name
+ path: /spec/template/spec/image/filter/name
valueFrom:
template: |
ubuntu-2204-kube-{{ .builtin.machineDeployment.version }}
diff --git a/test/e2e/data/kustomize/common-patches/cluster-prev1beta1/kustomization.yaml b/test/e2e/data/kustomize/common-patches/cluster-prev1beta1/kustomization.yaml
new file mode 100644
index 0000000000..7136e9600d
--- /dev/null
+++ b/test/e2e/data/kustomize/common-patches/cluster-prev1beta1/kustomization.yaml
@@ -0,0 +1,10 @@
+# Modifications to release templates common to all e2e test scenarios
+---
+apiVersion: kustomize.config.k8s.io/v1alpha1
+kind: Component
+
+patches:
+- target:
+ kind: OpenStackCluster
+ name: \${CLUSTER_NAME}
+ path: patch-cluster.yaml
diff --git a/test/e2e/data/kustomize/common-patches/cni/patch-cluster.yaml b/test/e2e/data/kustomize/common-patches/cluster-prev1beta1/patch-cluster.yaml
similarity index 100%
rename from test/e2e/data/kustomize/common-patches/cni/patch-cluster.yaml
rename to test/e2e/data/kustomize/common-patches/cluster-prev1beta1/patch-cluster.yaml
diff --git a/test/e2e/data/kustomize/common-patches/cluster/kustomization.yaml b/test/e2e/data/kustomize/common-patches/cluster/kustomization.yaml
new file mode 100644
index 0000000000..7136e9600d
--- /dev/null
+++ b/test/e2e/data/kustomize/common-patches/cluster/kustomization.yaml
@@ -0,0 +1,10 @@
+# Modifications to release templates common to all e2e test scenarios
+---
+apiVersion: kustomize.config.k8s.io/v1alpha1
+kind: Component
+
+patches:
+- target:
+ kind: OpenStackCluster
+ name: \${CLUSTER_NAME}
+ path: patch-cluster.yaml
diff --git a/test/e2e/data/kustomize/common-patches/cluster/patch-cluster.yaml b/test/e2e/data/kustomize/common-patches/cluster/patch-cluster.yaml
new file mode 100644
index 0000000000..b6d9564506
--- /dev/null
+++ b/test/e2e/data/kustomize/common-patches/cluster/patch-cluster.yaml
@@ -0,0 +1,15 @@
+---
+- op: add
+ path: /spec/bastion
+ value:
+ enabled: true
+ spec:
+ flavor: ${OPENSTACK_BASTION_MACHINE_FLAVOR}
+ image:
+ filter:
+ name: ${OPENSTACK_BASTION_IMAGE_NAME}
+ sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
+- op: add
+ path: /spec/controlPlaneAvailabilityZones
+ value:
+ - ${OPENSTACK_FAILURE_DOMAIN}
diff --git a/test/e2e/data/kustomize/common-patches/cni/kustomization.yaml b/test/e2e/data/kustomize/common-patches/cni/kustomization.yaml
index 60fe867342..0f10084b63 100644
--- a/test/e2e/data/kustomize/common-patches/cni/kustomization.yaml
+++ b/test/e2e/data/kustomize/common-patches/cni/kustomization.yaml
@@ -7,8 +7,4 @@ resources:
- cni.yaml
patches:
-- target:
- kind: OpenStackCluster
- name: \${CLUSTER_NAME}
- path: patch-cluster.yaml
- path: patch-cni.yaml
diff --git a/test/e2e/data/kustomize/default/kustomization.yaml b/test/e2e/data/kustomize/default/kustomization.yaml
index 30f2c9d85d..e85e60a623 100644
--- a/test/e2e/data/kustomize/default/kustomization.yaml
+++ b/test/e2e/data/kustomize/default/kustomization.yaml
@@ -3,6 +3,7 @@ kind: Kustomization
resources:
- ../../../../../kustomize/v1beta1/default
components:
+- ../common-patches/cluster
- ../common-patches/cni
- ../upgrade-patches
- ../common-patches/ccm
diff --git a/test/e2e/data/kustomize/flatcar-sysext/kustomization.yaml b/test/e2e/data/kustomize/flatcar-sysext/kustomization.yaml
index 6738cde3a8..63c5035c15 100644
--- a/test/e2e/data/kustomize/flatcar-sysext/kustomization.yaml
+++ b/test/e2e/data/kustomize/flatcar-sysext/kustomization.yaml
@@ -3,6 +3,7 @@ resources:
- ../../../../../kustomize/v1beta1/flatcar-sysext
components:
+- ../common-patches/cluster
- ../common-patches/cni
- ../common-patches/ccm
- ../common-patches/externalNetworkByName
diff --git a/test/e2e/data/kustomize/flatcar/kustomization.yaml b/test/e2e/data/kustomize/flatcar/kustomization.yaml
index 2de905e98e..ca872d20cb 100644
--- a/test/e2e/data/kustomize/flatcar/kustomization.yaml
+++ b/test/e2e/data/kustomize/flatcar/kustomization.yaml
@@ -4,6 +4,7 @@ resources:
- ../../../../../kustomize/v1beta1/flatcar
components:
+- ../common-patches/cluster
- ../common-patches/cni
- ../common-patches/ccm
- ../common-patches/externalNetworkByName
diff --git a/test/e2e/data/kustomize/k8s-upgrade/upgrade-from-template.yaml b/test/e2e/data/kustomize/k8s-upgrade/upgrade-from-template.yaml
index 6e9098977b..d49208116d 100644
--- a/test/e2e/data/kustomize/k8s-upgrade/upgrade-from-template.yaml
+++ b/test/e2e/data/kustomize/k8s-upgrade/upgrade-from-template.yaml
@@ -8,7 +8,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME_UPGRADE_FROM}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME_UPGRADE_FROM}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
tags:
- control-plane
@@ -22,7 +23,8 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME_UPGRADE_FROM}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME_UPGRADE_FROM}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
tags:
- machine
diff --git a/test/e2e/data/kustomize/k8s-upgrade/upgrade-to-template.yaml b/test/e2e/data/kustomize/k8s-upgrade/upgrade-to-template.yaml
index 39272254fd..466cb7931b 100644
--- a/test/e2e/data/kustomize/k8s-upgrade/upgrade-to-template.yaml
+++ b/test/e2e/data/kustomize/k8s-upgrade/upgrade-to-template.yaml
@@ -15,7 +15,8 @@ spec:
spec:
flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
tags:
- control-plane
@@ -31,7 +32,8 @@ spec:
spec:
flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR}
image:
- name: ${OPENSTACK_IMAGE_NAME}
+ filter:
+ name: ${OPENSTACK_IMAGE_NAME}
sshKeyName: ${OPENSTACK_SSH_KEY_NAME}
tags:
- machine
diff --git a/test/e2e/data/kustomize/v1alpha6/kustomization.yaml b/test/e2e/data/kustomize/v1alpha6/kustomization.yaml
index 9f7ac4445d..f2035ba071 100644
--- a/test/e2e/data/kustomize/v1alpha6/kustomization.yaml
+++ b/test/e2e/data/kustomize/v1alpha6/kustomization.yaml
@@ -4,6 +4,7 @@ resources:
- ../../../../../kustomize/v1alpha6/external-cloud-provider
components:
+- ../common-patches/cluster-prev1beta1
- ../common-patches/cni
- ../common-patches/ccm
diff --git a/test/e2e/data/kustomize/v1alpha7/kustomization.yaml b/test/e2e/data/kustomize/v1alpha7/kustomization.yaml
index ed5685505c..9bcee09929 100644
--- a/test/e2e/data/kustomize/v1alpha7/kustomization.yaml
+++ b/test/e2e/data/kustomize/v1alpha7/kustomization.yaml
@@ -4,6 +4,7 @@ resources:
- ../../../../../kustomize/v1alpha6/external-cloud-provider
components:
+- ../common-patches/cluster-prev1beta1
- ../common-patches/cni
- ../common-patches/ccm
diff --git a/test/e2e/data/kustomize/without-lb/kustomization.yaml b/test/e2e/data/kustomize/without-lb/kustomization.yaml
index 7f3842e60c..2d88085bde 100644
--- a/test/e2e/data/kustomize/without-lb/kustomization.yaml
+++ b/test/e2e/data/kustomize/without-lb/kustomization.yaml
@@ -4,6 +4,7 @@ resources:
- ../../../../../kustomize/v1beta1/without-lb
components:
+- ../common-patches/cluster
- ../common-patches/cni
- ../common-patches/ccm
- ../common-patches/externalNetworkByName
diff --git a/test/e2e/suites/apivalidations/filters_test.go b/test/e2e/suites/apivalidations/filters_test.go
index a6001c3ab2..e2bad140a5 100644
--- a/test/e2e/suites/apivalidations/filters_test.go
+++ b/test/e2e/suites/apivalidations/filters_test.go
@@ -36,7 +36,11 @@ var _ = Describe("Filter API validations", func() {
namespace = createNamespace()
// Initialise a basic machine object in the correct namespace
- machine = &infrav1.OpenStackMachine{}
+ machine = &infrav1.OpenStackMachine{
+ Spec: infrav1.OpenStackMachineSpec{
+ Image: infrav1.ImageParam{Filter: &infrav1.ImageFilter{Name: pointer.String("test-image")}},
+ },
+ }
machine.Namespace = namespace.Name
machine.GenerateName = "machine-"
@@ -179,49 +183,59 @@ var _ = Describe("Filter API validations", func() {
}),
)
- const imageUUID = "5a78f794-cdc3-48d2-8d9f-0fd472fdd743"
+ Context("ImageParam", func() {
+ const imageUUID = "5a78f794-cdc3-48d2-8d9f-0fd472fdd743"
- It("should not allow both ID and Name of ImageFilter to be set", func() {
- By("Creating a machine")
- machine.Spec.Image = infrav1.ImageFilter{
- ID: pointer.String(imageUUID),
- Name: pointer.String("bar"),
- }
- Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
- })
+ It("should not allow both ID and Filter to be set", func() {
+ machine.Spec.Image = infrav1.ImageParam{
+ ID: pointer.String(imageUUID),
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ },
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
- It("should not allow both ID and Tags of ImageFilter to be set", func() {
- By("Creating a machine")
- machine.Spec.Image = infrav1.ImageFilter{
- ID: pointer.String(imageUUID),
- Tags: []string{"bar", "baz"},
- }
- Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
- })
+ It("should not allow both ID and Tags of ImageFilter to be set", func() {
+ machine.Spec.Image = infrav1.ImageParam{
+ ID: pointer.String(imageUUID),
+ Filter: &infrav1.ImageFilter{
+ Tags: []string{"bar", "baz"},
+ },
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
- It("should allow UUID ID of ImageFilter to be set", func() {
- By("Creating a machine")
- machine.Spec.Image = infrav1.ImageFilter{
- ID: pointer.String(imageUUID),
- }
- Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
- })
+ It("should allow UUID ID of ImageFilter to be set", func() {
+ machine.Spec.Image = infrav1.ImageParam{
+ ID: pointer.String(imageUUID),
+ }
+ Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
+ })
- It("should not allow non-UUID ID of ImageFilter to be set", func() {
- By("Creating a machine")
- machine.Spec.Image = infrav1.ImageFilter{
- ID: pointer.String("foo"),
- }
- Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
- })
+ It("should not allow non-UUID ID of ImageFilter to be set", func() {
+ machine.Spec.Image = infrav1.ImageParam{
+ ID: pointer.String("foo"),
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
- It("should allow Name and Tags of ImageFilter to be set", func() {
- By("Creating a machine")
- machine.Spec.Image = infrav1.ImageFilter{
- Name: pointer.String("bar"),
- Tags: []string{"bar", "baz"},
- }
- Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
+ It("should allow Name and Tags of ImageFilter to be set", func() {
+ machine.Spec.Image = infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("bar"),
+ Tags: []string{"bar", "baz"},
+ },
+ }
+ Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "OpenStackMachine creation should succeed")
+ })
+
+ It("should not allow a non-nil, empty image filter", func() {
+ machine.Spec.Image = infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{},
+ }
+ Expect(k8sClient.Create(ctx, machine)).NotTo(Succeed(), "OpenStackMachine creation should fail")
+ })
})
Context("NetworkParam", func() {
diff --git a/test/e2e/suites/apivalidations/openstackcluster_test.go b/test/e2e/suites/apivalidations/openstackcluster_test.go
index f84e1d13d7..947f9b7b84 100644
--- a/test/e2e/suites/apivalidations/openstackcluster_test.go
+++ b/test/e2e/suites/apivalidations/openstackcluster_test.go
@@ -92,7 +92,11 @@ var _ = Describe("OpenStackCluster API validations", func() {
cluster.Spec.Bastion = &infrav1.Bastion{
Enabled: true,
Spec: &infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{Name: pointer.String("fake-image")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("fake-image"),
+ },
+ },
},
}
Expect(k8sClient.Create(ctx, cluster)).To(Succeed(), "OpenStackCluster creation should succeed")
@@ -120,7 +124,11 @@ var _ = Describe("OpenStackCluster API validations", func() {
cluster.Spec.Bastion = &infrav1.Bastion{
Enabled: true,
Spec: &infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{Name: pointer.String("fake-image")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("fake-image"),
+ },
+ },
},
FloatingIP: pointer.String("10.0.0.0"),
}
@@ -131,7 +139,11 @@ var _ = Describe("OpenStackCluster API validations", func() {
cluster.Spec.Bastion = &infrav1.Bastion{
Enabled: true,
Spec: &infrav1.OpenStackMachineSpec{
- Image: infrav1.ImageFilter{Name: pointer.String("fake-image")},
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String("fake-image"),
+ },
+ },
},
FloatingIP: pointer.String("foobar"),
}
diff --git a/test/e2e/suites/apivalidations/openstackmachine_test.go b/test/e2e/suites/apivalidations/openstackmachine_test.go
index c984ab1e61..4e888a3a41 100644
--- a/test/e2e/suites/apivalidations/openstackmachine_test.go
+++ b/test/e2e/suites/apivalidations/openstackmachine_test.go
@@ -35,7 +35,11 @@ var _ = Describe("OpenStackMachine API validations", func() {
namespace = createNamespace()
// Initialise a basic machine object in the correct namespace
- machine = &infrav1.OpenStackMachine{}
+ machine = &infrav1.OpenStackMachine{
+ Spec: infrav1.OpenStackMachineSpec{
+ Image: infrav1.ImageParam{Filter: &infrav1.ImageFilter{Name: pointer.String("test-image")}},
+ },
+ }
machine.Namespace = namespace.Name
machine.GenerateName = "machine-"
})
diff --git a/test/e2e/suites/e2e/e2e_test.go b/test/e2e/suites/e2e/e2e_test.go
index fadae81131..37422eb33f 100644
--- a/test/e2e/suites/e2e/e2e_test.go
+++ b/test/e2e/suites/e2e/e2e_test.go
@@ -859,8 +859,10 @@ func makeOpenStackMachineTemplate(namespace, clusterName, name string) *infrav1.
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: e2eCtx.E2EConfig.GetVariable(shared.OpenStackNodeMachineFlavor),
- Image: infrav1.ImageFilter{
- Name: pointer.String(e2eCtx.E2EConfig.GetVariable(shared.OpenStackImageName)),
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String(e2eCtx.E2EConfig.GetVariable(shared.OpenStackImageName)),
+ },
},
SSHKeyName: shared.DefaultSSHKeyPairName,
IdentityRef: &infrav1.OpenStackIdentityReference{
@@ -883,8 +885,10 @@ func makeOpenStackMachineTemplateWithPortOptions(namespace, clusterName, name st
Template: infrav1.OpenStackMachineTemplateResource{
Spec: infrav1.OpenStackMachineSpec{
Flavor: e2eCtx.E2EConfig.GetVariable(shared.OpenStackNodeMachineFlavor),
- Image: infrav1.ImageFilter{
- Name: pointer.String(e2eCtx.E2EConfig.GetVariable(shared.OpenStackImageName)),
+ Image: infrav1.ImageParam{
+ Filter: &infrav1.ImageFilter{
+ Name: pointer.String(e2eCtx.E2EConfig.GetVariable(shared.OpenStackImageName)),
+ },
},
SSHKeyName: shared.DefaultSSHKeyPairName,
IdentityRef: &infrav1.OpenStackIdentityReference{
diff --git a/test/helpers/fuzzerfuncs.go b/test/helpers/fuzzerfuncs.go
index 2c3a0fe188..36ee8baa85 100644
--- a/test/helpers/fuzzerfuncs.go
+++ b/test/helpers/fuzzerfuncs.go
@@ -141,5 +141,9 @@ func InfraV1FuzzerFuncs() []interface{} {
func(param *infrav1.SecurityGroupParam, c fuzz.Continue) {
fuzzFilterParam(¶m.ID, ¶m.Filter, c)
},
+
+ func(param *infrav1.ImageParam, c fuzz.Continue) {
+ fuzzFilterParam(¶m.ID, ¶m.Filter, c)
+ },
}
}