Skip to content

Commit f19e3df

Browse files
committed
Convert ServerMetadata from a map to a list
While we're changing it, we also add validation that keys and values don't exceed 255 characters.
1 parent 47b87c8 commit f19e3df

15 files changed

+289
-26
lines changed

api/v1alpha5/zz_generated.conversion.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha6/conversion.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ func restorev1alpha6MachineSpec(previous *OpenStackMachineSpec, dst *OpenStackMa
4444
// FloatingIP is removed from v1alpha7 with no replacement, so can't be
4545
// losslessly converted. Restore the previously stored value on down-conversion.
4646
dst.FloatingIP = previous.FloatingIP
47+
48+
// Conversion to v1alpha8 truncates keys and values to 255 characters
49+
for k, v := range previous.ServerMetadata {
50+
kd := k
51+
if len(k) > 255 {
52+
kd = k[:255]
53+
}
54+
55+
vd := v
56+
if len(v) > 255 {
57+
vd = v[:255]
58+
}
59+
60+
if kd != k || vd != v {
61+
delete(dst.ServerMetadata, kd)
62+
dst.ServerMetadata[k] = v
63+
}
64+
}
4765
}
4866

4967
func restorev1alpha6ClusterStatus(previous *OpenStackClusterStatus, dst *OpenStackClusterStatus) {
@@ -407,6 +425,23 @@ func Convert_v1alpha6_OpenStackMachineSpec_To_v1alpha8_OpenStackMachineSpec(in *
407425
}
408426
out.Image = imageFilter
409427

428+
if len(in.ServerMetadata) > 0 {
429+
serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata))
430+
for k, v := range in.ServerMetadata {
431+
// Truncate key and value to 255 characters if required, as this
432+
// was not validated prior to v1alpha8
433+
if len(k) > 255 {
434+
k = k[:255]
435+
}
436+
if len(v) > 255 {
437+
v = v[:255]
438+
}
439+
440+
serverMetadata = append(serverMetadata, infrav1.ServerMetadata{Key: k, Value: v})
441+
}
442+
out.ServerMetadata = serverMetadata
443+
}
444+
410445
return nil
411446
}
412447

@@ -743,6 +778,16 @@ func Convert_v1alpha8_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(in *
743778
out.ImageUUID = in.Image.ID
744779
}
745780

781+
if len(in.ServerMetadata) > 0 {
782+
serverMetadata := make(map[string]string, len(in.ServerMetadata))
783+
for i := range in.ServerMetadata {
784+
key := in.ServerMetadata[i].Key
785+
value := in.ServerMetadata[i].Value
786+
serverMetadata[key] = value
787+
}
788+
out.ServerMetadata = serverMetadata
789+
}
790+
746791
return nil
747792
}
748793

api/v1alpha6/conversion_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,37 @@ func TestFuzzyConversion(t *testing.T) {
8888
status.ExternalNetwork.APIServerLoadBalancer = nil
8989
}
9090
},
91+
92+
func(spec *OpenStackMachineSpec, c fuzz.Continue) {
93+
c.FuzzNoCustom(spec)
94+
95+
// RandString() generates strings up to 20
96+
// characters long. To exercise truncation of
97+
// long server metadata keys and values we need
98+
// the possibility of strings > 255 chars.
99+
genLongString := func() string {
100+
var ret string
101+
for len(ret) < 255 {
102+
ret += c.RandString()
103+
}
104+
return ret
105+
}
106+
107+
// Existing server metadata keys will be short. Add a random number of long ones.
108+
for c.RandBool() {
109+
if spec.ServerMetadata == nil {
110+
spec.ServerMetadata = map[string]string{}
111+
}
112+
spec.ServerMetadata[genLongString()] = c.RandString()
113+
}
114+
115+
// Randomly make some server metadata values long.
116+
for k := range spec.ServerMetadata {
117+
if c.RandBool() {
118+
spec.ServerMetadata[k] = genLongString()
119+
}
120+
}
121+
},
91122
}
92123
}
93124

api/v1alpha6/zz_generated.conversion.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha7/conversion.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ var v1alpha8OpenStackClusterRestorer = conversion.RestorerFor[*infrav1.OpenStack
6767

6868
func restorev1alpha7MachineSpec(previous *OpenStackMachineSpec, dst *OpenStackMachineSpec) {
6969
dst.FloatingIP = previous.FloatingIP
70+
71+
// Conversion to v1alpha8 truncates keys and values to 255 characters
72+
for k, v := range previous.ServerMetadata {
73+
kd := k
74+
if len(k) > 255 {
75+
kd = k[:255]
76+
}
77+
78+
vd := v
79+
if len(v) > 255 {
80+
vd = v[:255]
81+
}
82+
83+
if kd != k || vd != v {
84+
delete(dst.ServerMetadata, kd)
85+
dst.ServerMetadata[k] = v
86+
}
87+
}
7088
}
7189

7290
func restorev1alpha8MachineSpec(previous *infrav1.OpenStackMachineSpec, dst *infrav1.OpenStackMachineSpec) {
@@ -304,6 +322,16 @@ func Convert_v1alpha8_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in *
304322
out.ImageUUID = in.Image.ID
305323
}
306324

325+
if len(in.ServerMetadata) > 0 {
326+
serverMetadata := make(map[string]string, len(in.ServerMetadata))
327+
for i := range in.ServerMetadata {
328+
key := in.ServerMetadata[i].Key
329+
value := in.ServerMetadata[i].Value
330+
serverMetadata[key] = value
331+
}
332+
out.ServerMetadata = serverMetadata
333+
}
334+
307335
return nil
308336
}
309337

@@ -328,6 +356,23 @@ func Convert_v1alpha7_OpenStackMachineSpec_To_v1alpha8_OpenStackMachineSpec(in *
328356
}
329357
out.Image = imageFilter
330358

359+
if len(in.ServerMetadata) > 0 {
360+
serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata))
361+
for k, v := range in.ServerMetadata {
362+
// Truncate key and value to 255 characters if required, as this
363+
// was not validated prior to v1alpha8
364+
if len(k) > 255 {
365+
k = k[:255]
366+
}
367+
if len(v) > 255 {
368+
v = v[:255]
369+
}
370+
371+
serverMetadata = append(serverMetadata, infrav1.ServerMetadata{Key: k, Value: v})
372+
}
373+
out.ServerMetadata = serverMetadata
374+
}
375+
331376
return nil
332377
}
333378

api/v1alpha7/conversion_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ package v1alpha7
1919
import (
2020
"testing"
2121

22+
fuzz "github.com/google/gofuzz"
2223
"github.com/onsi/gomega"
24+
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
2325
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2426
runtime "k8s.io/apimachinery/pkg/runtime"
27+
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
2528
"k8s.io/utils/pointer"
2629
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
2730
"sigs.k8s.io/controller-runtime/pkg/conversion"
@@ -80,31 +83,70 @@ func TestFuzzyConversion(t *testing.T) {
8083
},
8184
})))
8285

86+
fuzzerFuncs := func(_ runtimeserializer.CodecFactory) []interface{} {
87+
return []interface{}{
88+
func(spec *OpenStackMachineSpec, c fuzz.Continue) {
89+
c.FuzzNoCustom(spec)
90+
91+
// RandString() generates strings up to 20
92+
// characters long. To exercise truncation of
93+
// long server metadata keys and values we need
94+
// the possibility of strings > 255 chars.
95+
genLongString := func() string {
96+
var ret string
97+
for len(ret) < 255 {
98+
ret += c.RandString()
99+
}
100+
return ret
101+
}
102+
103+
// Existing server metadata keys will be short. Add a random number of long ones.
104+
for c.RandBool() {
105+
if spec.ServerMetadata == nil {
106+
spec.ServerMetadata = map[string]string{}
107+
}
108+
spec.ServerMetadata[genLongString()] = c.RandString()
109+
}
110+
111+
// Randomly make some server metadata values long.
112+
for k := range spec.ServerMetadata {
113+
if c.RandBool() {
114+
spec.ServerMetadata[k] = genLongString()
115+
}
116+
}
117+
},
118+
}
119+
}
120+
83121
t.Run("for OpenStackMachine", runParallel(utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
84122
Hub: &infrav1.OpenStackMachine{},
85123
Spoke: &OpenStackMachine{},
86124
HubAfterMutation: ignoreDataAnnotation,
125+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
87126
})))
88127

89128
t.Run("for OpenStackMachine with mutate", runParallel(testhelpers.FuzzMutateTestFunc(testhelpers.FuzzMutateTestFuncInput{
90129
FuzzTestFuncInput: utilconversion.FuzzTestFuncInput{
91130
Hub: &infrav1.OpenStackMachine{},
92131
Spoke: &OpenStackMachine{},
93132
HubAfterMutation: ignoreDataAnnotation,
133+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
94134
},
95135
})))
96136

97137
t.Run("for OpenStackMachineTemplate", runParallel(utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
98138
Hub: &infrav1.OpenStackMachineTemplate{},
99139
Spoke: &OpenStackMachineTemplate{},
100140
HubAfterMutation: ignoreDataAnnotation,
141+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
101142
})))
102143

103144
t.Run("for OpenStackMachineTemplate with mutate", runParallel(testhelpers.FuzzMutateTestFunc(testhelpers.FuzzMutateTestFuncInput{
104145
FuzzTestFuncInput: utilconversion.FuzzTestFuncInput{
105146
Hub: &infrav1.OpenStackMachineTemplate{},
106147
Spoke: &OpenStackMachineTemplate{},
107148
HubAfterMutation: ignoreDataAnnotation,
149+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
108150
},
109151
})))
110152
}

api/v1alpha7/zz_generated.conversion.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha8/openstackmachine_types.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ type OpenStackMachineSpec struct {
6868
Tags []string `json:"tags,omitempty"`
6969

7070
// Metadata mapping. Allows you to create a map of key value pairs to add to the server instance.
71-
ServerMetadata map[string]string `json:"serverMetadata,omitempty"`
71+
// +listType=map
72+
// +listMapKey=key
73+
ServerMetadata []ServerMetadata `json:"serverMetadata,omitempty"`
7274

7375
// Config Drive support
7476
ConfigDrive *bool `json:"configDrive,omitempty"`
@@ -91,6 +93,16 @@ type OpenStackMachineSpec struct {
9193
IdentityRef *OpenStackIdentityReference `json:"identityRef,omitempty"`
9294
}
9395

96+
type ServerMetadata struct {
97+
// Key is the server metadata key
98+
// kubebuilder:validation:MaxLength:=255
99+
Key string `json:"key"`
100+
101+
// Value is the server metadata value
102+
// kubebuilder:validation:MaxLength:=255
103+
Value string `json:"value"`
104+
}
105+
94106
// OpenStackMachineStatus defines the observed state of OpenStackMachine.
95107
type OpenStackMachineStatus struct {
96108
// Ready is true when the provider resource is ready.

api/v1alpha8/zz_generated.deepcopy.go

Lines changed: 17 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)