Skip to content

Commit a80cdd2

Browse files
authored
Merge pull request #1828 from shiftstack/server-metadata
⚠️ Convert ServerMetadata from a map to a list
2 parents 54d6fd0 + dfb963d commit a80cdd2

15 files changed

+304
-28
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: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,20 @@ import (
2626

2727
var _ ctrlconversion.Convertible = &OpenStackCluster{}
2828

29-
var v1alpha7OpenStackClusterRestorer = conversion.RestorerFor[*OpenStackCluster]{}
29+
func restorev1alpha7Bastion(previous **Bastion, dst **Bastion) {
30+
if *previous != nil && *dst != nil {
31+
restorev1alpha7MachineSpec(&(*previous).Instance, &(*dst).Instance)
32+
}
33+
}
34+
35+
var v1alpha7OpenStackClusterRestorer = conversion.RestorerFor[*OpenStackCluster]{
36+
"bastion": conversion.HashedFieldRestorer(
37+
func(c *OpenStackCluster) **Bastion {
38+
return &c.Spec.Bastion
39+
},
40+
restorev1alpha7Bastion,
41+
),
42+
}
3043

3144
var v1alpha8OpenStackClusterRestorer = conversion.RestorerFor[*infrav1.OpenStackCluster]{
3245
"bastion": conversion.HashedFieldRestorer(
@@ -67,6 +80,24 @@ var v1alpha8OpenStackClusterRestorer = conversion.RestorerFor[*infrav1.OpenStack
6780

6881
func restorev1alpha7MachineSpec(previous *OpenStackMachineSpec, dst *OpenStackMachineSpec) {
6982
dst.FloatingIP = previous.FloatingIP
83+
84+
// Conversion to v1alpha8 truncates keys and values to 255 characters
85+
for k, v := range previous.ServerMetadata {
86+
kd := k
87+
if len(k) > 255 {
88+
kd = k[:255]
89+
}
90+
91+
vd := v
92+
if len(v) > 255 {
93+
vd = v[:255]
94+
}
95+
96+
if kd != k || vd != v {
97+
delete(dst.ServerMetadata, kd)
98+
dst.ServerMetadata[k] = v
99+
}
100+
}
70101
}
71102

72103
func restorev1alpha8MachineSpec(previous *infrav1.OpenStackMachineSpec, dst *infrav1.OpenStackMachineSpec) {
@@ -139,12 +170,23 @@ func (r *OpenStackClusterList) ConvertFrom(srcRaw ctrlconversion.Hub) error {
139170

140171
var _ ctrlconversion.Convertible = &OpenStackClusterTemplate{}
141172

173+
func restorev1alpha7ClusterTemplateSpec(previous *OpenStackClusterTemplateSpec, dst *OpenStackClusterTemplateSpec) {
174+
restorev1alpha7Bastion(&previous.Template.Spec.Bastion, &dst.Template.Spec.Bastion)
175+
}
176+
142177
func restorev1alpha8ClusterTemplateSpec(previous *infrav1.OpenStackClusterTemplateSpec, dst *infrav1.OpenStackClusterTemplateSpec) {
143178
restorev1alpha8Bastion(&previous.Template.Spec.Bastion, &dst.Template.Spec.Bastion)
144179
restorev1alpha8ClusterSpec(&previous.Template.Spec, &dst.Template.Spec)
145180
}
146181

147-
var v1alpha7OpenStackClusterTemplateRestorer = conversion.RestorerFor[*OpenStackClusterTemplate]{}
182+
var v1alpha7OpenStackClusterTemplateRestorer = conversion.RestorerFor[*OpenStackClusterTemplate]{
183+
"spec": conversion.HashedFieldRestorer(
184+
func(c *OpenStackClusterTemplate) *OpenStackClusterTemplateSpec {
185+
return &c.Spec
186+
},
187+
restorev1alpha7ClusterTemplateSpec,
188+
),
189+
}
148190

149191
var v1alpha8OpenStackClusterTemplateRestorer = conversion.RestorerFor[*infrav1.OpenStackClusterTemplate]{
150192
"spec": conversion.HashedFieldRestorer(
@@ -308,6 +350,16 @@ func Convert_v1alpha8_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in *
308350
out.ImageUUID = in.Image.ID
309351
}
310352

353+
if len(in.ServerMetadata) > 0 {
354+
serverMetadata := make(map[string]string, len(in.ServerMetadata))
355+
for i := range in.ServerMetadata {
356+
key := in.ServerMetadata[i].Key
357+
value := in.ServerMetadata[i].Value
358+
serverMetadata[key] = value
359+
}
360+
out.ServerMetadata = serverMetadata
361+
}
362+
311363
return nil
312364
}
313365

@@ -332,6 +384,23 @@ func Convert_v1alpha7_OpenStackMachineSpec_To_v1alpha8_OpenStackMachineSpec(in *
332384
}
333385
out.Image = imageFilter
334386

387+
if len(in.ServerMetadata) > 0 {
388+
serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata))
389+
for k, v := range in.ServerMetadata {
390+
// Truncate key and value to 255 characters if required, as this
391+
// was not validated prior to v1alpha8
392+
if len(k) > 255 {
393+
k = k[:255]
394+
}
395+
if len(v) > 255 {
396+
v = v[:255]
397+
}
398+
399+
serverMetadata = append(serverMetadata, infrav1.ServerMetadata{Key: k, Value: v})
400+
}
401+
out.ServerMetadata = serverMetadata
402+
}
403+
335404
return nil
336405
}
337406

api/v1alpha7/conversion_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,37 @@ func TestFuzzyConversion(t *testing.T) {
6969
spec.Subnets = append(spec.Subnets, subnet)
7070
}
7171
},
72+
73+
func(spec *OpenStackMachineSpec, c fuzz.Continue) {
74+
c.FuzzNoCustom(spec)
75+
76+
// RandString() generates strings up to 20
77+
// characters long. To exercise truncation of
78+
// long server metadata keys and values we need
79+
// the possibility of strings > 255 chars.
80+
genLongString := func() string {
81+
var ret string
82+
for len(ret) < 255 {
83+
ret += c.RandString()
84+
}
85+
return ret
86+
}
87+
88+
// Existing server metadata keys will be short. Add a random number of long ones.
89+
for c.RandBool() {
90+
if spec.ServerMetadata == nil {
91+
spec.ServerMetadata = map[string]string{}
92+
}
93+
spec.ServerMetadata[genLongString()] = c.RandString()
94+
}
95+
96+
// Randomly make some server metadata values long.
97+
for k := range spec.ServerMetadata {
98+
if c.RandBool() {
99+
spec.ServerMetadata[k] = genLongString()
100+
}
101+
}
102+
},
72103
}
73104
}
74105

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)