Skip to content

Commit 1853742

Browse files
committed
refactor the duplicate paths warning for pods logic
1 parent 205a026 commit 1853742

File tree

2 files changed

+301
-153
lines changed

2 files changed

+301
-153
lines changed

pkg/api/pod/warnings.go

+36-43
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,8 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
172172
}
173173
}
174174

175-
overlappingPathInContainers := warningsForOverlappingVirtualPaths(podSpec.Volumes)
176-
if len(overlappingPathInContainers) > 0 {
177-
warnings = append(warnings, overlappingPathInContainers...)
175+
if overlaps := warningsForOverlappingVirtualPaths(podSpec.Volumes); len(overlaps) > 0 {
176+
warnings = append(warnings, overlaps...)
178177
}
179178

180179
// duplicate hostAliases (#91670, #58477)
@@ -379,71 +378,65 @@ func warningsForWeightedPodAffinityTerms(terms []api.WeightedPodAffinityTerm, fi
379378
//
380379
// In such cases we either get `is directory` or 'file exists' error message.
381380
func warningsForOverlappingVirtualPaths(volumes []api.Volume) []string {
382-
warnings := make([]string, 0)
381+
var warnings []string
383382

384383
for _, v := range volumes {
385384
if v.ConfigMap != nil && v.ConfigMap.Items != nil {
386-
w := checkVolumeMappingForOverlap(extractPaths(v.ConfigMap.Items), fmt.Sprintf("volume %q (ConfigMap %q): overlapping path", v.Name, v.ConfigMap.Name))
387-
if len(w) > 0 {
388-
warnings = append(warnings, w...)
389-
}
385+
warnings = append(warnings, checkVolumeMappingForOverlap(extractPaths(v.ConfigMap.Items), fmt.Sprintf("volume %q (ConfigMap %q): overlapping paths", v.Name, v.ConfigMap.Name))...)
390386
}
391387

392388
if v.Secret != nil && v.Secret.Items != nil {
393-
w := checkVolumeMappingForOverlap(extractPaths(v.Secret.Items), fmt.Sprintf("volume %q (Secret %q): overlapping path", v.Name, v.Secret.SecretName))
394-
if len(w) > 0 {
395-
warnings = append(warnings, w...)
396-
}
389+
warnings = append(warnings, checkVolumeMappingForOverlap(extractPaths(v.Secret.Items), fmt.Sprintf("volume %q (Secret %q): overlapping paths", v.Name, v.Secret.SecretName))...)
397390
}
398391

399392
if v.DownwardAPI != nil && v.DownwardAPI.Items != nil {
400-
w := checkVolumeMappingForOverlap(extractPathsDownwardAPI(v.DownwardAPI.Items), fmt.Sprintf("volume %q (DownwardAPI): overlapping path", v.Name))
401-
if len(w) > 0 {
402-
warnings = append(warnings, w...)
403-
}
393+
warnings = append(warnings, checkVolumeMappingForOverlap(extractPathsDownwardAPI(v.DownwardAPI.Items), fmt.Sprintf("volume %q (DownwardAPI): overlapping paths", v.Name))...)
404394
}
405395

406396
if v.Projected != nil {
407-
var sourcePaths, allPaths []string
397+
var sourcePaths []string
408398
var errorMessage string
399+
allPaths := sets.New[string]()
409400

410401
for _, source := range v.Projected.Sources {
402+
if source == (api.VolumeProjection{}) {
403+
warnings = append(warnings, fmt.Sprintf("volume %q (Projected) has no sources provided", v.Name))
404+
continue
405+
}
411406
switch {
412407
case source.ConfigMap != nil && source.ConfigMap.Items != nil:
413408
sourcePaths = extractPaths(source.ConfigMap.Items)
414-
errorMessage = fmt.Sprintf("volume %q (Projected ConfigMap %q): overlapping path", v.Name, source.ConfigMap.Name)
409+
errorMessage = fmt.Sprintf("volume %q (Projected ConfigMap %q): overlapping paths", v.Name, source.ConfigMap.Name)
415410
case source.Secret != nil && source.Secret.Items != nil:
416411
sourcePaths = extractPaths(source.Secret.Items)
417-
errorMessage = fmt.Sprintf("volume %q (Projected Secret %q): overlapping path", v.Name, source.Secret.Name)
412+
errorMessage = fmt.Sprintf("volume %q (Projected Secret %q): overlapping paths", v.Name, source.Secret.Name)
418413
case source.DownwardAPI != nil && source.DownwardAPI.Items != nil:
419414
sourcePaths = extractPathsDownwardAPI(source.DownwardAPI.Items)
420-
errorMessage = fmt.Sprintf("volume %q (Projected DownwardAPI): overlapping path", v.Name)
415+
errorMessage = fmt.Sprintf("volume %q (Projected DownwardAPI): overlapping paths", v.Name)
421416
case source.ServiceAccountToken != nil:
422417
sourcePaths = []string{source.ServiceAccountToken.Path}
423-
errorMessage = fmt.Sprintf("volume %q (Projected ServiceAccountToken): overlapping path", v.Name)
418+
errorMessage = fmt.Sprintf("volume %q (Projected ServiceAccountToken): overlapping paths", v.Name)
424419
case source.ClusterTrustBundle != nil:
425420
sourcePaths = []string{source.ClusterTrustBundle.Path}
426421
if source.ClusterTrustBundle.Name != nil {
427-
errorMessage = fmt.Sprintf("volume %q (Projected ClusterTrustBundle %q): overlapping path", v.Name, *source.ClusterTrustBundle.Name)
422+
errorMessage = fmt.Sprintf("volume %q (Projected ClusterTrustBundle %q): overlapping paths", v.Name, *source.ClusterTrustBundle.Name)
428423
} else {
429-
errorMessage = fmt.Sprintf("volume %q (Projected ClusterTrustBundle %q): overlapping path", v.Name, *source.ClusterTrustBundle.SignerName)
424+
errorMessage = fmt.Sprintf("volume %q (Projected ClusterTrustBundle %q): overlapping paths", v.Name, *source.ClusterTrustBundle.SignerName)
430425
}
431426
}
432427

433428
if len(sourcePaths) == 0 {
434429
continue
435430
}
436431

437-
warningsInSource := checkVolumeMappingForOverlap(sourcePaths, errorMessage)
438-
if len(warningsInSource) > 0 {
439-
warnings = append(warnings, warningsInSource...)
440-
}
432+
warnings = append(warnings, checkVolumeMappingForOverlap(sourcePaths, errorMessage)...)
441433

442-
allPaths = append(allPaths, sourcePaths...)
443-
warningsInAllPaths := checkVolumeMappingForOverlap(allPaths, errorMessage)
444-
if len(warningsInAllPaths) > 0 {
445-
warnings = append(warnings, warningsInAllPaths...)
446-
}
434+
// remove duplicates path and sort the new array, so we can get predetermined result
435+
uniqueSourcePaths := sets.New[string](sourcePaths...).UnsortedList()
436+
orderedSourcePaths := append(uniqueSourcePaths, allPaths.UnsortedList()...)
437+
sort.Strings(orderedSourcePaths)
438+
warnings = append(warnings, checkVolumeMappingForOverlap(orderedSourcePaths, errorMessage)...)
439+
allPaths.Insert(uniqueSourcePaths...)
447440
}
448441
}
449442

@@ -470,36 +463,36 @@ func extractPathsDownwardAPI(mapping []api.DownwardAPIVolumeFile) []string {
470463
}
471464

472465
func checkVolumeMappingForOverlap(paths []string, warningMessage string) []string {
466+
var warnings []string
473467
pathSeparator := string(os.PathSeparator)
474-
warnings := make([]string, 0)
475468
uniquePaths := sets.New[string]()
476469

477470
for _, path := range paths {
478471
normalizedPath := strings.TrimRight(path, pathSeparator)
479-
if collision := checkForOverlap(uniquePaths, normalizedPath); collision != nil {
480-
warnings = append(warnings, fmt.Sprintf("%s %q with %q", warningMessage, normalizedPath, *collision))
472+
if collision := checkForOverlap(uniquePaths, normalizedPath); collision != "" {
473+
warnings = append(warnings, fmt.Sprintf("%s: %q with %q", warningMessage, normalizedPath, collision))
481474
}
482475
uniquePaths.Insert(normalizedPath)
483476
}
484477

485478
return warnings
486479
}
487480

488-
func checkForOverlap(paths sets.Set[string], path string) *string {
481+
func checkForOverlap(paths sets.Set[string], path string) string {
489482
pathSeparator := string(os.PathSeparator)
490-
p := paths.UnsortedList()
491-
sort.Strings(p)
492483

493-
for _, item := range p {
484+
for item := range paths {
494485
switch {
486+
case item == "" || path == "":
487+
return ""
495488
case item == path:
496-
return &item
489+
return item
497490
case strings.HasPrefix(item+pathSeparator, path):
498-
return &item
491+
return item
499492
case strings.HasPrefix(path+pathSeparator, item):
500-
return &item
493+
return item
501494
}
502495
}
503496

504-
return nil
497+
return ""
505498
}

0 commit comments

Comments
 (0)