Skip to content

Commit b908e27

Browse files
authored
Merge pull request #113245 from pacoxu/dup-ports-warning
add warning for dup ports in containers[*].ports and service.ports
2 parents 8a0ea1b + df0d51d commit b908e27

File tree

2 files changed

+485
-4
lines changed

2 files changed

+485
-4
lines changed

pkg/api/pod/warnings.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,42 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
267267
return true
268268
})
269269

270+
type portBlock struct {
271+
field *field.Path
272+
port api.ContainerPort
273+
}
274+
275+
// Accumulate ports across all containers
276+
allPorts := map[string][]portBlock{}
277+
pods.VisitContainersWithPath(podSpec, fieldPath.Child("spec"), func(c *api.Container, fldPath *field.Path) bool {
278+
for i, port := range c.Ports {
279+
if port.HostIP != "" && port.HostPort == 0 {
280+
warnings = append(warnings, fmt.Sprintf("%s: hostIP set without hostPort: %+v",
281+
fldPath.Child("ports").Index(i), port))
282+
}
283+
k := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
284+
if others, found := allPorts[k]; found {
285+
// Someone else has this protcol+port, but it still might not be a conflict.
286+
for _, other := range others {
287+
if port.HostIP == other.port.HostIP && port.HostPort == other.port.HostPort {
288+
// Exactly-equal is obvious. Validation should already filter for this except when these are unspecified.
289+
warnings = append(warnings, fmt.Sprintf("%s: duplicate port definition with %s", fldPath.Child("ports").Index(i), other.field))
290+
} else if port.HostPort == 0 || other.port.HostPort == 0 {
291+
// HostPort = 0 is redundant with any other value, which is odd but not really dangerous. HostIP doesn't matter here.
292+
warnings = append(warnings, fmt.Sprintf("%s: overlapping port definition with %s", fldPath.Child("ports").Index(i), other.field))
293+
} else if a, b := port.HostIP == "", other.port.HostIP == ""; port.HostPort == other.port.HostPort && ((a || b) && !(a && b)) {
294+
// If the HostPorts are the same and either HostIP is not specified while the other is not, the behavior is undefined.
295+
warnings = append(warnings, fmt.Sprintf("%s: dangerously ambiguous port definition with %s", fldPath.Child("ports").Index(i), other.field))
296+
}
297+
}
298+
allPorts[k] = append(allPorts[k], portBlock{field: fldPath.Child("ports").Index(i), port: port})
299+
} else {
300+
allPorts[k] = []portBlock{{field: fldPath.Child("ports").Index(i), port: port}}
301+
}
302+
}
303+
return true
304+
})
305+
270306
// warn if the terminationGracePeriodSeconds is negative.
271307
if podSpec.TerminationGracePeriodSeconds != nil && *podSpec.TerminationGracePeriodSeconds < 0 {
272308
warnings = append(warnings, fmt.Sprintf("%s: must be >= 0; negative values are invalid and will be treated as 1", fieldPath.Child("spec", "terminationGracePeriodSeconds")))

0 commit comments

Comments
 (0)