Skip to content

Commit 980b91b

Browse files
mdboothEmilienM
authored andcommitted
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 f90ddda commit 980b91b

16 files changed

+300
-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) {
@@ -425,6 +443,23 @@ func Convert_v1alpha6_OpenStackMachineSpec_To_v1alpha8_OpenStackMachineSpec(in *
425443
}
426444
out.Image = imageFilter
427445

446+
if len(in.ServerMetadata) > 0 {
447+
serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata))
448+
for k, v := range in.ServerMetadata {
449+
// Truncate key and value to 255 characters if required, as this
450+
// was not validated prior to v1alpha8
451+
if len(k) > 255 {
452+
k = k[:255]
453+
}
454+
if len(v) > 255 {
455+
v = v[:255]
456+
}
457+
458+
serverMetadata = append(serverMetadata, infrav1.ServerMetadata{Key: k, Value: v})
459+
}
460+
out.ServerMetadata = serverMetadata
461+
}
462+
428463
return nil
429464
}
430465

@@ -776,6 +811,16 @@ func Convert_v1alpha8_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(in *
776811
out.ImageUUID = in.Image.ID
777812
}
778813

814+
if len(in.ServerMetadata) > 0 {
815+
serverMetadata := make(map[string]string, len(in.ServerMetadata))
816+
for i := range in.ServerMetadata {
817+
key := in.ServerMetadata[i].Key
818+
value := in.ServerMetadata[i].Value
819+
serverMetadata[key] = value
820+
}
821+
out.ServerMetadata = serverMetadata
822+
}
823+
779824
return nil
780825
}
781826

api/v1alpha6/conversion_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,37 @@ func TestFuzzyConversion(t *testing.T) {
101101
spec.Subnets = append(spec.Subnets, subnet)
102102
}
103103
},
104+
105+
func(spec *OpenStackMachineSpec, c fuzz.Continue) {
106+
c.FuzzNoCustom(spec)
107+
108+
// RandString() generates strings up to 20
109+
// characters long. To exercise truncation of
110+
// long server metadata keys and values we need
111+
// the possibility of strings > 255 chars.
112+
genLongString := func() string {
113+
var ret string
114+
for len(ret) < 255 {
115+
ret += c.RandString()
116+
}
117+
return ret
118+
}
119+
120+
// Existing server metadata keys will be short. Add a random number of long ones.
121+
for c.RandBool() {
122+
if spec.ServerMetadata == nil {
123+
spec.ServerMetadata = map[string]string{}
124+
}
125+
spec.ServerMetadata[genLongString()] = c.RandString()
126+
}
127+
128+
// Randomly make some server metadata values long.
129+
for k := range spec.ServerMetadata {
130+
if c.RandBool() {
131+
spec.ServerMetadata[k] = genLongString()
132+
}
133+
}
134+
},
104135
}
105136
}
106137

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) {
@@ -308,6 +326,16 @@ func Convert_v1alpha8_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in *
308326
out.ImageUUID = in.Image.ID
309327
}
310328

329+
if len(in.ServerMetadata) > 0 {
330+
serverMetadata := make(map[string]string, len(in.ServerMetadata))
331+
for i := range in.ServerMetadata {
332+
key := in.ServerMetadata[i].Key
333+
value := in.ServerMetadata[i].Value
334+
serverMetadata[key] = value
335+
}
336+
out.ServerMetadata = serverMetadata
337+
}
338+
311339
return nil
312340
}
313341

@@ -332,6 +360,23 @@ func Convert_v1alpha7_OpenStackMachineSpec_To_v1alpha8_OpenStackMachineSpec(in *
332360
}
333361
out.Image = imageFilter
334362

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

api/v1alpha7/conversion_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,37 @@ func TestFuzzyConversion(t *testing.T) {
5757

5858
fuzzerFuncs := func(_ runtimeserializer.CodecFactory) []interface{} {
5959
return []interface{}{
60+
func(spec *OpenStackMachineSpec, c fuzz.Continue) {
61+
c.FuzzNoCustom(spec)
62+
63+
// RandString() generates strings up to 20
64+
// characters long. To exercise truncation of
65+
// long server metadata keys and values we need
66+
// the possibility of strings > 255 chars.
67+
genLongString := func() string {
68+
var ret string
69+
for len(ret) < 255 {
70+
ret += c.RandString()
71+
}
72+
return ret
73+
}
74+
75+
// Existing server metadata keys will be short. Add a random number of long ones.
76+
for c.RandBool() {
77+
if spec.ServerMetadata == nil {
78+
spec.ServerMetadata = map[string]string{}
79+
}
80+
spec.ServerMetadata[genLongString()] = c.RandString()
81+
}
82+
83+
// Randomly make some server metadata values long.
84+
for k := range spec.ServerMetadata {
85+
if c.RandBool() {
86+
spec.ServerMetadata[k] = genLongString()
87+
}
88+
}
89+
},
90+
6091
func(spec *infrav1.OpenStackClusterSpec, c fuzz.Continue) {
6192
c.FuzzNoCustom(spec)
6293

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.

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5269,11 +5269,28 @@ spec:
52695269
type: string
52705270
type: object
52715271
serverMetadata:
5272-
additionalProperties:
5273-
type: string
52745272
description: Metadata mapping. Allows you to create a map
52755273
of key value pairs to add to the server instance.
5276-
type: object
5274+
items:
5275+
properties:
5276+
key:
5277+
description: |-
5278+
Key is the server metadata key
5279+
kubebuilder:validation:MaxLength:=255
5280+
type: string
5281+
value:
5282+
description: |-
5283+
Value is the server metadata value
5284+
kubebuilder:validation:MaxLength:=255
5285+
type: string
5286+
required:
5287+
- key
5288+
- value
5289+
type: object
5290+
type: array
5291+
x-kubernetes-list-map-keys:
5292+
- key
5293+
x-kubernetes-list-type: map
52775294
sshKeyName:
52785295
description: The ssh key to inject in the instance
52795296
type: string

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,11 +2703,28 @@ spec:
27032703
type: string
27042704
type: object
27052705
serverMetadata:
2706-
additionalProperties:
2707-
type: string
27082706
description: Metadata mapping. Allows you to create
27092707
a map of key value pairs to add to the server instance.
2710-
type: object
2708+
items:
2709+
properties:
2710+
key:
2711+
description: |-
2712+
Key is the server metadata key
2713+
kubebuilder:validation:MaxLength:=255
2714+
type: string
2715+
value:
2716+
description: |-
2717+
Value is the server metadata value
2718+
kubebuilder:validation:MaxLength:=255
2719+
type: string
2720+
required:
2721+
- key
2722+
- value
2723+
type: object
2724+
type: array
2725+
x-kubernetes-list-map-keys:
2726+
- key
2727+
x-kubernetes-list-type: map
27112728
sshKeyName:
27122729
description: The ssh key to inject in the instance
27132730
type: string

0 commit comments

Comments
 (0)