Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df0d51d

Browse files
committed
add some detailed message for dup container ports(steal from thockin)
1 parent 7a80d7c commit df0d51d

File tree

2 files changed

+71
-48
lines changed

2 files changed

+71
-48
lines changed

pkg/api/pod/warnings.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -255,30 +255,38 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
255255
return true
256256
})
257257

258+
type portBlock struct {
259+
field *field.Path
260+
port api.ContainerPort
261+
}
262+
258263
// Accumulate ports across all containers
259-
allPorts := map[string]portBlock{}
264+
allPorts := map[string][]portBlock{}
260265
pods.VisitContainersWithPath(podSpec, fieldPath.Child("spec"), func(c *api.Container, fldPath *field.Path) bool {
261266
for i, port := range c.Ports {
267+
if port.HostIP != "" && port.HostPort == 0 {
268+
warnings = append(warnings, fmt.Sprintf("%s: hostIP set without hostPort: %+v",
269+
fldPath.Child("ports").Index(i), port))
270+
}
262271
k := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
263-
if other, found := allPorts[k]; found {
272+
if others, found := allPorts[k]; found {
264273
// Someone else has this protcol+port, but it still might not be a conflict.
265-
conflict := false
266-
267-
// Exact matches are obvious.
268-
if port.HostIP == other.port.HostIP && port.HostPort == other.port.HostPort {
269-
conflict = true
270-
}
271-
// Unspecified fields are more subtle.
272-
if port.HostPort == 0 || other.port.HostPort == 0 || port.HostIP == "" || other.port.HostIP == "" {
273-
conflict = true
274-
}
275-
if conflict {
276-
warnings = append(warnings, fmt.Sprintf("%s: duplicate container port %d/%s, conflicts with %s",
277-
fldPath.Child("ports").Index(i), port.ContainerPort, port.Protocol, other.field))
278-
continue
274+
for _, other := range others {
275+
if port.HostIP == other.port.HostIP && port.HostPort == other.port.HostPort {
276+
// Exactly-equal is obvious. Validation should already filter for this except when these are unspecified.
277+
warnings = append(warnings, fmt.Sprintf("%s: duplicate port definition with %s", fldPath.Child("ports").Index(i), other.field))
278+
} else if port.HostPort == 0 || other.port.HostPort == 0 {
279+
// HostPort = 0 is redundant with any other value, which is odd but not really dangerous. HostIP doesn't matter here.
280+
warnings = append(warnings, fmt.Sprintf("%s: overlapping port definition with %s", fldPath.Child("ports").Index(i), other.field))
281+
} else if a, b := port.HostIP == "", other.port.HostIP == ""; port.HostPort == other.port.HostPort && ((a || b) && !(a && b)) {
282+
// If the HostPorts are the same and either HostIP is not specified while the other is not, the behavior is undefined.
283+
warnings = append(warnings, fmt.Sprintf("%s: dangerously ambiguous port definition with %s", fldPath.Child("ports").Index(i), other.field))
284+
}
279285
}
286+
allPorts[k] = append(allPorts[k], portBlock{field: fldPath.Child("ports").Index(i), port: port})
287+
} else {
288+
allPorts[k] = []portBlock{{field: fldPath.Child("ports").Index(i), port: port}}
280289
}
281-
allPorts[k] = portBlock{field: fldPath, port: port}
282290
}
283291
return true
284292
})
@@ -302,11 +310,6 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
302310
return warnings
303311
}
304312

305-
type portBlock struct {
306-
field *field.Path
307-
port api.ContainerPort
308-
}
309-
310313
func warningsForPodAffinityTerms(terms []api.PodAffinityTerm, fieldPath *field.Path) []string {
311314
var warnings []string
312315
for i, t := range terms {

pkg/api/pod/warnings_test.go

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -659,9 +659,7 @@ func TestWarnings(t *testing.T) {
659659
},
660660
}},
661661
}},
662-
expected: []string{
663-
`spec.containers[0].ports[1]: duplicate container port 80/TCP, conflicts with spec.containers[0]`,
664-
},
662+
expected: []string{},
665663
},
666664
{
667665
name: "one container, two ports, same protocol, port and hostPort, different hostIP",
@@ -725,9 +723,7 @@ func TestWarnings(t *testing.T) {
725723
},
726724
}},
727725
}},
728-
expected: []string{
729-
`spec.containers[1].ports[0]: duplicate container port 80/TCP, conflicts with spec.containers[0]`,
730-
},
726+
expected: []string{},
731727
},
732728
{
733729
name: "two containers, one port each, same protocol, port and hostPort, different hostIP",
@@ -758,7 +754,7 @@ func TestWarnings(t *testing.T) {
758754
}},
759755
}},
760756
expected: []string{
761-
`spec.containers[0].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
757+
`spec.containers[0].ports[1]: duplicate port definition with spec.containers[0].ports[0]`,
762758
},
763759
},
764760
{
@@ -773,7 +769,7 @@ func TestWarnings(t *testing.T) {
773769
}},
774770
}},
775771
expected: []string{
776-
`spec.containers[0].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
772+
`spec.containers[0].ports[1]: duplicate port definition with spec.containers[0].ports[0]`,
777773
},
778774
},
779775
{
@@ -788,7 +784,21 @@ func TestWarnings(t *testing.T) {
788784
}},
789785
}},
790786
expected: []string{
791-
`spec.containers[0].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
787+
`spec.containers[0].ports[1]: duplicate port definition with spec.containers[0].ports[0]`,
788+
},
789+
},
790+
{
791+
name: "one container port hostIP set without host port set",
792+
template: &api.PodTemplateSpec{Spec: api.PodSpec{
793+
Containers: []api.Container{{
794+
Name: "foo",
795+
Ports: []api.ContainerPort{
796+
{ContainerPort: 80, Protocol: api.ProtocolUDP, HostIP: "10.0.0.1"},
797+
},
798+
}},
799+
}},
800+
expected: []string{
801+
`spec.containers[0].ports[0]: hostIP set without hostPort: {Name: HostPort:0 ContainerPort:80 Protocol:UDP HostIP:10.0.0.1}`,
792802
},
793803
},
794804
{
@@ -803,22 +813,25 @@ func TestWarnings(t *testing.T) {
803813
}},
804814
}},
805815
expected: []string{
806-
`spec.containers[0].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
816+
`spec.containers[0].ports[1]: overlapping port definition with spec.containers[0].ports[0]`,
817+
`spec.containers[0].ports[1]: hostIP set without hostPort: {Name: HostPort:0 ContainerPort:80 Protocol:UDP HostIP:10.0.0.1}`,
807818
},
808819
},
809820
{
810-
name: "duplicate container ports without one host IP set and one with",
821+
name: "duplicate container ports without one host IP set and two with",
811822
template: &api.PodTemplateSpec{Spec: api.PodSpec{
812823
Containers: []api.Container{{
813824
Name: "foo",
814825
Ports: []api.ContainerPort{
815-
{ContainerPort: 80, HostPort: 80, Protocol: api.ProtocolUDP},
816826
{ContainerPort: 80, HostPort: 80, Protocol: api.ProtocolUDP, HostIP: "10.0.0.1"},
827+
{ContainerPort: 80, HostPort: 80, Protocol: api.ProtocolUDP},
828+
{ContainerPort: 80, HostPort: 80, Protocol: api.ProtocolUDP, HostIP: "10.0.0.2"},
817829
},
818830
}},
819831
}},
820832
expected: []string{
821-
`spec.containers[0].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
833+
`spec.containers[0].ports[1]: dangerously ambiguous port definition with spec.containers[0].ports[0]`,
834+
`spec.containers[0].ports[2]: dangerously ambiguous port definition with spec.containers[0].ports[1]`,
822835
},
823836
},
824837
{
@@ -833,7 +846,7 @@ func TestWarnings(t *testing.T) {
833846
}},
834847
}},
835848
expected: []string{
836-
`spec.containers[0].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
849+
`spec.containers[0].ports[1]: dangerously ambiguous port definition with spec.containers[0].ports[0]`,
837850
},
838851
},
839852
{
@@ -852,7 +865,7 @@ func TestWarnings(t *testing.T) {
852865
}},
853866
}},
854867
expected: []string{
855-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
868+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[0]`,
856869
},
857870
},
858871
{
@@ -871,7 +884,7 @@ func TestWarnings(t *testing.T) {
871884
}},
872885
}},
873886
expected: []string{
874-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
887+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[0]`,
875888
},
876889
},
877890
{
@@ -890,7 +903,7 @@ func TestWarnings(t *testing.T) {
890903
}},
891904
}},
892905
expected: []string{
893-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
906+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[0]`,
894907
},
895908
},
896909
{
@@ -909,7 +922,8 @@ func TestWarnings(t *testing.T) {
909922
}},
910923
}},
911924
expected: []string{
912-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
925+
`spec.containers[1].ports[0]: overlapping port definition with spec.containers[0].ports[0]`,
926+
`spec.containers[1].ports[0]: hostIP set without hostPort: {Name: HostPort:0 ContainerPort:80 Protocol:UDP HostIP:10.0.0.1}`,
913927
},
914928
},
915929
{
@@ -928,7 +942,7 @@ func TestWarnings(t *testing.T) {
928942
}},
929943
}},
930944
expected: []string{
931-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
945+
`spec.containers[1].ports[0]: dangerously ambiguous port definition with spec.containers[0].ports[0]`,
932946
},
933947
},
934948
{
@@ -947,7 +961,7 @@ func TestWarnings(t *testing.T) {
947961
}},
948962
}},
949963
expected: []string{
950-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
964+
`spec.containers[1].ports[0]: dangerously ambiguous port definition with spec.containers[0].ports[0]`,
951965
},
952966
},
953967
{
@@ -971,9 +985,12 @@ func TestWarnings(t *testing.T) {
971985
}},
972986
}},
973987
expected: []string{
974-
`spec.containers[0].ports[2]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
975-
`spec.containers[1].ports[0]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
976-
`spec.containers[1].ports[1]: duplicate container port 80/UDP, conflicts with spec.containers[0]`,
988+
`spec.containers[0].ports[2]: duplicate port definition with spec.containers[0].ports[0]`,
989+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[0]`,
990+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[2]`,
991+
`spec.containers[1].ports[1]: duplicate port definition with spec.containers[0].ports[0]`,
992+
`spec.containers[1].ports[1]: duplicate port definition with spec.containers[0].ports[2]`,
993+
`spec.containers[1].ports[1]: duplicate port definition with spec.containers[1].ports[0]`,
977994
},
978995
},
979996
{
@@ -1015,9 +1032,12 @@ func TestWarnings(t *testing.T) {
10151032
}},
10161033
}},
10171034
expected: []string{
1018-
`spec.containers[0].ports[2]: duplicate container port 80/TCP, conflicts with spec.containers[0]`,
1019-
`spec.containers[1].ports[0]: duplicate container port 80/TCP, conflicts with spec.containers[0]`,
1020-
`spec.containers[1].ports[1]: duplicate container port 80/TCP, conflicts with spec.containers[0]`,
1035+
`spec.containers[0].ports[2]: duplicate port definition with spec.containers[0].ports[0]`,
1036+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[0]`,
1037+
`spec.containers[1].ports[0]: duplicate port definition with spec.containers[0].ports[2]`,
1038+
`spec.containers[1].ports[1]: duplicate port definition with spec.containers[0].ports[0]`,
1039+
`spec.containers[1].ports[1]: duplicate port definition with spec.containers[0].ports[2]`,
1040+
`spec.containers[1].ports[1]: duplicate port definition with spec.containers[1].ports[0]`,
10211041
},
10221042
},
10231043
}

0 commit comments

Comments
 (0)