@@ -155,7 +155,11 @@ type AddVolumeOptions struct {
155
155
156
156
func NewCmdVolume (fullName string , f * clientcmd.Factory , out , errOut io.Writer ) * cobra.Command {
157
157
addOpts := & AddVolumeOptions {}
158
- opts := & VolumeOptions {AddOpts : addOpts }
158
+ opts := & VolumeOptions {
159
+ AddOpts : addOpts ,
160
+ Out : out ,
161
+ Err : errOut ,
162
+ }
159
163
cmd := & cobra.Command {
160
164
Use : "volumes RESOURCE/NAME --add|--remove|--list" ,
161
165
Short : "Update volumes on a pod template" ,
@@ -165,12 +169,12 @@ func NewCmdVolume(fullName string, f *clientcmd.Factory, out, errOut io.Writer)
165
169
Run : func (cmd * cobra.Command , args []string ) {
166
170
addOpts .TypeChanged = cmd .Flag ("type" ).Changed
167
171
172
+ kcmdutil .CheckErr (opts .Complete (f , cmd ))
173
+
168
174
err := opts .Validate (cmd , args )
169
175
if err != nil {
170
176
kcmdutil .CheckErr (kcmdutil .UsageErrorf (cmd , err .Error ()))
171
177
}
172
- err = opts .Complete (f , cmd , out , errOut )
173
- kcmdutil .CheckErr (err )
174
178
175
179
err = opts .RunVolume (args , f )
176
180
if err == kcmdutil .ErrExit {
@@ -228,32 +232,19 @@ func (v *VolumeOptions) Validate(cmd *cobra.Command, args []string) error {
228
232
return errors .New ("provide one or more resources to add, list, or delete volumes on as TYPE/NAME" )
229
233
}
230
234
231
- numOps := 0
232
- if v .Add {
233
- numOps ++
234
- }
235
- if v .Remove {
236
- numOps ++
237
- }
238
- if v .List {
239
- numOps ++
240
- }
241
-
242
- switch {
243
- case numOps == 0 :
244
- v .List = true
245
- case numOps > 1 :
246
- return errors .New ("you may only specify one operation at a time" )
247
- }
248
-
249
- output := kcmdutil .GetFlagString (cmd , "output" )
250
- if v .List && len (output ) > 0 {
235
+ if v .List && len (v .Output ) > 0 {
251
236
return errors .New ("--list and --output may not be specified together" )
252
237
}
253
238
254
- err := v .AddOpts .Validate (v .Add )
255
- if err != nil {
256
- return err
239
+ if v .Add {
240
+ err := v .AddOpts .Validate ()
241
+ if err != nil {
242
+ return err
243
+ }
244
+ } else if len (v .AddOpts .Source ) > 0 || len (v .AddOpts .Path ) > 0 || len (v .AddOpts .SecretName ) > 0 ||
245
+ len (v .AddOpts .ConfigMapName ) > 0 || len (v .AddOpts .ClaimName ) > 0 || len (v .AddOpts .DefaultMode ) > 0 ||
246
+ v .AddOpts .Overwrite {
247
+ return errors .New ("--type|--path|--configmap-name|--secret-name|--claim-name|--source|--default-mode|--overwrite are only valid for --add operation" )
257
248
}
258
249
// Removing all volumes for the resource type needs confirmation
259
250
if v .Remove && len (v .Name ) == 0 && ! v .Confirm {
@@ -262,111 +253,74 @@ func (v *VolumeOptions) Validate(cmd *cobra.Command, args []string) error {
262
253
return nil
263
254
}
264
255
265
- func (a * AddVolumeOptions ) Validate (isAddOp bool ) error {
266
- if isAddOp {
267
- if len (a .Type ) == 0 && (len (a .ClaimName ) > 0 || len (a .ClaimSize ) > 0 ) {
268
- a .Type = "persistentvolumeclaim"
269
- a .TypeChanged = true
270
- }
271
- if len (a .Type ) == 0 && (len (a .SecretName ) > 0 ) {
272
- a .Type = "secret"
273
- a .TypeChanged = true
274
- }
275
- if len (a .Type ) == 0 && (len (a .ConfigMapName ) > 0 ) {
276
- a .Type = "configmap"
277
- a .TypeChanged = true
278
- }
279
- if len (a .Type ) == 0 && (len (a .Path ) > 0 ) {
280
- a .Type = "hostpath"
281
- a .TypeChanged = true
282
- }
283
- if len (a .Type ) == 0 {
284
- a .Type = "emptydir"
285
- }
286
-
287
- if len (a .Type ) == 0 && len (a .Source ) == 0 {
288
- return errors .New ("must provide --type or --source for --add operation" )
289
- } else if a .TypeChanged && len (a .Source ) > 0 {
290
- return errors .New ("either specify --type or --source but not both for --add operation" )
291
- }
256
+ func (a * AddVolumeOptions ) Validate () error {
257
+ if len (a .Type ) == 0 && len (a .Source ) == 0 {
258
+ return errors .New ("must provide --type or --source for --add operation" )
259
+ } else if a .TypeChanged && len (a .Source ) > 0 {
260
+ return errors .New ("either specify --type or --source but not both for --add operation" )
261
+ }
292
262
293
- if len (a .Type ) > 0 {
294
- switch strings .ToLower (a .Type ) {
295
- case "emptydir" :
296
- if len (a .DefaultMode ) > 0 {
297
- return errors .New ("--default-mode is only available for secrets and configmaps" )
298
- }
299
- case "hostpath" :
300
- if len (a .Path ) == 0 {
301
- return errors .New ("must provide --path for --type=hostPath" )
302
- }
303
- if len (a .DefaultMode ) > 0 {
304
- return errors .New ("--default-mode is only available for secrets and configmaps" )
305
- }
306
- case "secret" :
307
- if len (a .SecretName ) == 0 {
308
- return errors .New ("must provide --secret-name for --type=secret" )
309
- }
310
- if len (a .DefaultMode ) > 0 {
311
- if ok , _ := regexp .MatchString (`\b0?[0-7]{3}\b` , a .DefaultMode ); ! ok {
312
- return errors .New ("--default-mode must be between 0000 and 0777" )
313
- }
314
- }
315
- case "configmap" :
316
- if len (a .ConfigMapName ) == 0 {
317
- return errors .New ("must provide --configmap-name for --type=configmap" )
318
- }
319
- if len (a .DefaultMode ) > 0 {
320
- if ok , _ := regexp .MatchString (`\b0?[0-7]{3}\b` , a .DefaultMode ); ! ok {
321
- return errors .New ("--default-mode must be between 0000 and 0777" )
322
- }
323
- }
324
- case "persistentvolumeclaim" , "pvc" :
325
- if len (a .ClaimName ) == 0 && len (a .ClaimSize ) == 0 {
326
- return errors .New ("must provide --claim-name or --claim-size (to create a new claim) for --type=pvc" )
327
- }
328
- if len (a .DefaultMode ) > 0 {
329
- return errors .New ("--default-mode is only available for secrets and configmaps" )
330
- }
331
- default :
332
- return errors .New ("invalid volume type. Supported types: emptyDir, hostPath, secret, persistentVolumeClaim" )
263
+ if len (a .Type ) > 0 {
264
+ switch strings .ToLower (a .Type ) {
265
+ case "emptydir" :
266
+ case "hostpath" :
267
+ if len (a .Path ) == 0 {
268
+ return errors .New ("must provide --path for --type=hostPath" )
333
269
}
334
- } else if len (a .Path ) > 0 || len (a .SecretName ) > 0 || len (a .ClaimName ) > 0 {
335
- return errors .New ("--path|--secret-name|--claim-name are only valid for --type option" )
336
- }
337
-
338
- if len (a .Source ) > 0 {
339
- var source map [string ]interface {}
340
- err := json .Unmarshal ([]byte (a .Source ), & source )
341
- if err != nil {
342
- return err
270
+ case "secret" :
271
+ if len (a .SecretName ) == 0 {
272
+ return errors .New ("must provide --secret-name for --type=secret" )
343
273
}
344
- if len ( source ) > 1 {
345
- return errors .New ("must provide only one volume for --source " )
274
+ if ok , _ := regexp . MatchString ( `\b0?[0-7]{3}\b` , a . DefaultMode ); ! ok {
275
+ return errors .New ("--default-mode must be between 0000 and 0777 " )
346
276
}
347
-
348
- var vs kapi.VolumeSource
349
- err = json .Unmarshal ([]byte (a .Source ), & vs )
350
- if err != nil {
351
- return err
277
+ case "configmap" :
278
+ if len (a .ConfigMapName ) == 0 {
279
+ return errors .New ("must provide --configmap-name for --type=configmap" )
352
280
}
353
- }
354
- if len (a .ClaimClass ) > 0 {
355
- selectedLowerType := strings .ToLower (a .Type )
356
- if selectedLowerType != "persistentvolumeclaim" && selectedLowerType != "pvc" {
357
- return errors .New ("must provide --type as persistentVolumeClaim" )
281
+ if ok , _ := regexp .MatchString (`\b0?[0-7]{3}\b` , a .DefaultMode ); ! ok {
282
+ return errors .New ("--default-mode must be between 0000 and 0777" )
358
283
}
359
- if len (a .ClaimSize ) == 0 {
360
- return errors .New ("must provide --claim-size to create new pvc with claim-class" )
284
+ case "persistentvolumeclaim" , "pvc" :
285
+ if len (a .ClaimName ) == 0 && len (a .ClaimSize ) == 0 {
286
+ return errors .New ("must provide --claim-name or --claim-size (to create a new claim) for --type=pvc" )
361
287
}
288
+ default :
289
+ return errors .New ("invalid volume type. Supported types: emptyDir, hostPath, secret, persistentVolumeClaim" )
290
+ }
291
+ } else if len (a .Path ) > 0 || len (a .SecretName ) > 0 || len (a .ClaimName ) > 0 {
292
+ return errors .New ("--path|--secret-name|--claim-name are only valid for --type option" )
293
+ }
294
+
295
+ if len (a .Source ) > 0 {
296
+ var source map [string ]interface {}
297
+ err := json .Unmarshal ([]byte (a .Source ), & source )
298
+ if err != nil {
299
+ return err
300
+ }
301
+ if len (source ) > 1 {
302
+ return errors .New ("must provide only one volume for --source" )
303
+ }
304
+
305
+ var vs kapi.VolumeSource
306
+ err = json .Unmarshal ([]byte (a .Source ), & vs )
307
+ if err != nil {
308
+ return err
309
+ }
310
+ }
311
+ if len (a .ClaimClass ) > 0 {
312
+ selectedLowerType := strings .ToLower (a .Type )
313
+ if selectedLowerType != "persistentvolumeclaim" && selectedLowerType != "pvc" {
314
+ return errors .New ("must provide --type as persistentVolumeClaim" )
315
+ }
316
+ if len (a .ClaimSize ) == 0 {
317
+ return errors .New ("must provide --claim-size to create new pvc with claim-class" )
362
318
}
363
- } else if len (a .Source ) > 0 || len (a .Path ) > 0 || len (a .SecretName ) > 0 || len (a .ConfigMapName ) > 0 || len (a .ClaimName ) > 0 || a .Overwrite {
364
- return errors .New ("--type|--path|--configmap-name|--secret-name|--claim-name|--source|--overwrite are only valid for --add operation" )
365
319
}
366
320
return nil
367
321
}
368
322
369
- func (v * VolumeOptions ) Complete (f * clientcmd.Factory , cmd * cobra.Command , out , errOut io. Writer ) error {
323
+ func (v * VolumeOptions ) Complete (f * clientcmd.Factory , cmd * cobra.Command ) error {
370
324
kc , err := f .ClientSet ()
371
325
if err != nil {
372
326
return err
@@ -379,6 +333,24 @@ func (v *VolumeOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, out,
379
333
}
380
334
mapper , typer := f .Object ()
381
335
336
+ numOps := 0
337
+ if v .Add {
338
+ numOps ++
339
+ }
340
+ if v .Remove {
341
+ numOps ++
342
+ }
343
+ if v .List {
344
+ numOps ++
345
+ }
346
+
347
+ switch {
348
+ case numOps == 0 :
349
+ v .List = true
350
+ case numOps > 1 :
351
+ return errors .New ("you may only specify one operation at a time" )
352
+ }
353
+
382
354
v .Output = kcmdutil .GetFlagString (cmd , "output" )
383
355
v .PrintObject = func (infos []* resource.Info ) error {
384
356
return f .PrintResourceInfos (cmd , v .Local , infos , v .Out )
@@ -387,44 +359,79 @@ func (v *VolumeOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, out,
387
359
v .Cmd = cmd
388
360
v .DefaultNamespace = cmdNamespace
389
361
v .ExplicitNamespace = explicit
390
- v .Out = out
391
- v .Err = errOut
392
362
v .Mapper = mapper
393
363
v .Typer = typer
394
364
v .CategoryExpander = f .CategoryExpander ()
395
365
v .RESTClientFactory = f .ClientForMapping
396
366
v .UpdatePodSpecForObject = f .UpdatePodSpecForObject
397
367
v .Encoder = kcmdutil .InternalVersionJSONEncoder ()
398
368
369
+ // Complete AddOpts
370
+ if v .Add {
371
+ err := v .AddOpts .Complete ()
372
+ if err != nil {
373
+ return err
374
+ }
375
+ }
376
+ return nil
377
+ }
378
+
379
+ func (a * AddVolumeOptions ) Complete () error {
380
+ if len (a .Type ) == 0 {
381
+ switch {
382
+ case len (a .ClaimName ) > 0 || len (a .ClaimSize ) > 0 :
383
+ a .Type = "persistentvolumeclaim"
384
+ a .TypeChanged = true
385
+ case len (a .SecretName ) > 0 :
386
+ a .Type = "secret"
387
+ a .TypeChanged = true
388
+ case len (a .ConfigMapName ) > 0 :
389
+ a .Type = "configmap"
390
+ a .TypeChanged = true
391
+ case len (a .Path ) > 0 :
392
+ a .Type = "hostpath"
393
+ a .TypeChanged = true
394
+ default :
395
+ a .Type = "emptydir"
396
+ }
397
+ }
398
+ if a .Type == "configmap" || a .Type == "secret" {
399
+ if len (a .DefaultMode ) == 0 {
400
+ a .DefaultMode = "644"
401
+ }
402
+ } else {
403
+ if len (a .DefaultMode ) != 0 {
404
+ return errors .New ("--default-mode is only available for secrets and configmaps" )
405
+ }
406
+ }
407
+
399
408
// In case of volume source ignore the default volume type
400
- if len (v . AddOpts .Source ) > 0 {
401
- v . AddOpts .Type = ""
409
+ if len (a .Source ) > 0 {
410
+ a .Type = ""
402
411
}
403
- if len (v . AddOpts .ClaimSize ) > 0 {
404
- v . AddOpts .CreateClaim = true
405
- if len (v . AddOpts .ClaimName ) == 0 {
406
- v . AddOpts .ClaimName = names .SimpleNameGenerator .GenerateName ("pvc-" )
412
+ if len (a .ClaimSize ) > 0 {
413
+ a .CreateClaim = true
414
+ if len (a .ClaimName ) == 0 {
415
+ a .ClaimName = names .SimpleNameGenerator .GenerateName ("pvc-" )
407
416
}
408
- q , err := kresource .ParseQuantity (v . AddOpts .ClaimSize )
417
+ q , err := kresource .ParseQuantity (a .ClaimSize )
409
418
if err != nil {
410
419
return fmt .Errorf ("--claim-size is not valid: %v" , err )
411
420
}
412
- v .AddOpts .ClaimSize = q .String ()
413
- }
414
- if len (v .AddOpts .DefaultMode ) == 0 {
415
- v .AddOpts .DefaultMode = "644"
421
+ a .ClaimSize = q .String ()
416
422
}
417
- switch strings .ToLower (v . AddOpts .ClaimMode ) {
423
+ switch strings .ToLower (a .ClaimMode ) {
418
424
case strings .ToLower (string (kapi .ReadOnlyMany )), "rom" :
419
- v . AddOpts .ClaimMode = string (kapi .ReadOnlyMany )
425
+ a .ClaimMode = string (kapi .ReadOnlyMany )
420
426
case strings .ToLower (string (kapi .ReadWriteOnce )), "rwo" :
421
- v . AddOpts .ClaimMode = string (kapi .ReadWriteOnce )
427
+ a .ClaimMode = string (kapi .ReadWriteOnce )
422
428
case strings .ToLower (string (kapi .ReadWriteMany )), "rwm" :
423
- v . AddOpts .ClaimMode = string (kapi .ReadWriteMany )
429
+ a .ClaimMode = string (kapi .ReadWriteMany )
424
430
case "" :
425
431
default :
426
432
return errors .New ("--claim-mode must be one of ReadWriteOnce (rwo), ReadWriteMany (rwm), or ReadOnlyMany (rom)" )
427
433
}
434
+
428
435
return nil
429
436
}
430
437
0 commit comments