@@ -17,6 +17,7 @@ import (
17
17
apiEquality "k8s.io/apimachinery/pkg/api/equality"
18
18
19
19
vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha1"
20
+ "github.com/vmware-tanzu/vm-operator/pkg/conditions"
20
21
"github.com/vmware-tanzu/vm-operator/pkg/context"
21
22
"github.com/vmware-tanzu/vm-operator/pkg/lib"
22
23
"github.com/vmware-tanzu/vm-operator/pkg/util"
@@ -114,17 +115,25 @@ func GetCloudInitMetadata(vm *vmopv1.VirtualMachine,
114
115
return string (metadataBytes ), nil
115
116
}
116
117
118
+ type ErrWithReason struct {
119
+ error
120
+ conditionReason string
121
+ }
122
+
117
123
func GetCloudInitPrepCustSpec (
118
124
cloudInitMetadata string ,
119
- updateArgs VMUpdateArgs ) (* vimTypes.VirtualMachineConfigSpec , * vimTypes.CustomizationSpec , error ) {
125
+ updateArgs VMUpdateArgs ) (* vimTypes.VirtualMachineConfigSpec , * vimTypes.CustomizationSpec , * ErrWithReason ) {
120
126
121
127
userdata := updateArgs .VMMetadata .Data ["user-data" ]
122
128
123
129
if userdata != "" {
124
130
// Ensure the data is normalized first to plain-text.
125
131
plainText , err := util .TryToDecodeBase64Gzip ([]byte (userdata ))
126
132
if err != nil {
127
- return nil , nil , fmt .Errorf ("decoding cloud-init prep userdata failed %v" , err )
133
+ return nil , nil , & ErrWithReason {
134
+ error : fmt .Errorf ("decoding cloud-init prep userdata failed %v" , err ),
135
+ conditionReason : vmopv1 .VirtualMachineMetadataInvalidReason ,
136
+ }
128
137
}
129
138
userdata = plainText
130
139
}
@@ -147,17 +156,27 @@ func GetCloudInitPrepCustSpec(
147
156
func GetCloudInitGuestInfoCustSpec (
148
157
cloudInitMetadata string ,
149
158
config * vimTypes.VirtualMachineConfigInfo ,
150
- updateArgs VMUpdateArgs ) (* vimTypes.VirtualMachineConfigSpec , error ) {
159
+ updateArgs VMUpdateArgs ) (* vimTypes.VirtualMachineConfigSpec , * ErrWithReason ) {
151
160
152
161
extraConfig := map [string ]string {}
153
162
154
163
encodedMetadata , err := EncodeGzipBase64 (cloudInitMetadata )
155
164
if err != nil {
156
- return nil , fmt .Errorf ("encoding cloud-init metadata failed %v" , err )
165
+ return nil , & ErrWithReason {
166
+ error : fmt .Errorf ("encoding cloud-init metadata failed %v" , err ),
167
+ conditionReason : vmopv1 .VirtualMachineMetadataInvalidReason ,
168
+ }
157
169
}
158
170
extraConfig [constants .CloudInitGuestInfoMetadata ] = encodedMetadata
159
171
extraConfig [constants .CloudInitGuestInfoMetadataEncoding ] = "gzip+base64"
160
172
173
+ if len (encodedMetadata ) > constants .CloudInitGuestInfoMaxSize {
174
+ return nil , & ErrWithReason {
175
+ error : fmt .Errorf ("size of cloud-init guest info exceeds the maximum allowed size of 64KiB" ),
176
+ conditionReason : vmopv1 .VirtualMachineGuestInfoSizeExceededReason ,
177
+ }
178
+ }
179
+
161
180
var data string
162
181
// Check for the 'user-data' key as per official contract and API documentation.
163
182
// Additionally, To support the cluster bootstrap data supplied by CAPBK's secret,
@@ -173,16 +192,30 @@ func GetCloudInitGuestInfoCustSpec(
173
192
// Ensure the data is normalized first to plain-text.
174
193
plainText , err := util .TryToDecodeBase64Gzip ([]byte (data ))
175
194
if err != nil {
176
- return nil , fmt .Errorf ("decoding cloud-init userdata failed %v" , err )
195
+ return nil , & ErrWithReason {
196
+ error : fmt .Errorf ("decoding cloud-init userdata failed %v" , err ),
197
+ conditionReason : vmopv1 .VirtualMachineMetadataInvalidReason ,
198
+ }
177
199
}
178
200
179
201
encodedUserdata , err := EncodeGzipBase64 (plainText )
180
202
if err != nil {
181
- return nil , fmt .Errorf ("encoding cloud-init userdata failed %v" , err )
203
+ return nil , & ErrWithReason {
204
+ error : fmt .Errorf ("encoding cloud-init userdata failed %v" , err ),
205
+ conditionReason : vmopv1 .VirtualMachineMetadataInvalidReason ,
206
+ }
182
207
}
183
208
184
209
extraConfig [constants .CloudInitGuestInfoUserdata ] = encodedUserdata
185
210
extraConfig [constants .CloudInitGuestInfoUserdataEncoding ] = "gzip+base64"
211
+
212
+ if len (encodedUserdata ) > constants .CloudInitGuestInfoMaxSize ||
213
+ len (encodedUserdata )+ len (encodedMetadata ) > constants .CloudInitGuestInfoMaxSize {
214
+ return nil , & ErrWithReason {
215
+ error : fmt .Errorf ("size of cloud-init guest info exceeds the maximum allowed size of 64KiB" ),
216
+ conditionReason : vmopv1 .VirtualMachineGuestInfoSizeExceededReason ,
217
+ }
218
+ }
186
219
}
187
220
188
221
configSpec := & vimTypes.VirtualMachineConfigSpec {}
@@ -245,23 +278,34 @@ func customizeCloudInit(
245
278
246
279
cloudInitMetadata , err := GetCloudInitMetadata (vmCtx .VM , netplan , updateArgs .VMMetadata .Data )
247
280
if err != nil {
281
+ conditions .MarkFalse (vmCtx .VM ,
282
+ vmopv1 .VirtualMachineMetadataReadyCondition ,
283
+ vmopv1 .VirtualMachineMetadataInvalidReason ,
284
+ vmopv1 .ConditionSeverityError ,
285
+ err .Error ())
248
286
return nil , nil , err
249
287
}
250
288
251
289
var configSpec * vimTypes.VirtualMachineConfigSpec
252
290
var custSpec * vimTypes.CustomizationSpec
291
+ var errWithReason * ErrWithReason
253
292
254
293
switch vmCtx .VM .Annotations [constants .CloudInitTypeAnnotation ] {
255
294
case constants .CloudInitTypeValueCloudInitPrep :
256
- configSpec , custSpec , err = GetCloudInitPrepCustSpec (cloudInitMetadata , updateArgs )
295
+ configSpec , custSpec , errWithReason = GetCloudInitPrepCustSpec (cloudInitMetadata , updateArgs )
257
296
case constants .CloudInitTypeValueGuestInfo , "" :
258
297
fallthrough
259
298
default :
260
- configSpec , err = GetCloudInitGuestInfoCustSpec (cloudInitMetadata , config , updateArgs )
299
+ configSpec , errWithReason = GetCloudInitGuestInfoCustSpec (cloudInitMetadata , config , updateArgs )
261
300
}
262
301
263
- if err != nil {
264
- return nil , nil , err
302
+ if errWithReason != nil {
303
+ conditions .MarkFalse (vmCtx .VM ,
304
+ vmopv1 .VirtualMachineMetadataReadyCondition ,
305
+ errWithReason .conditionReason ,
306
+ vmopv1 .ConditionSeverityError ,
307
+ errWithReason .Error ())
308
+ return nil , nil , errWithReason
265
309
}
266
310
267
311
return configSpec , custSpec , nil
@@ -307,6 +351,7 @@ func (s *Session) customize(
307
351
if err != nil {
308
352
return err
309
353
}
354
+ conditions .MarkTrue (vmCtx .VM , vmopv1 .VirtualMachineMetadataReadyCondition )
310
355
311
356
if configSpec != nil {
312
357
defaultConfigSpec := & vimTypes.VirtualMachineConfigSpec {}
0 commit comments