@@ -267,6 +267,42 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
267
267
return true
268
268
})
269
269
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
+
270
306
// warn if the terminationGracePeriodSeconds is negative.
271
307
if podSpec .TerminationGracePeriodSeconds != nil && * podSpec .TerminationGracePeriodSeconds < 0 {
272
308
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