Merge pull request #94728 from amorenoz/portforward_udp

kubectl: Fix TCP and UDP port forward
This commit is contained in:
Kubernetes Prow Robot 2020-09-16 16:14:46 -07:00 committed by GitHub
commit 28fc772d36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 10 deletions

View File

@ -260,35 +260,37 @@ func checkUDPPorts(udpOnlyPorts sets.Int, ports []string, obj metav1.Object) err
// checkUDPPortInService returns an error if remote port in Service is a UDP port // checkUDPPortInService returns an error if remote port in Service is a UDP port
// TODO: remove this check after #47862 is solved // TODO: remove this check after #47862 is solved
func checkUDPPortInService(ports []string, svc *corev1.Service) error { func checkUDPPortInService(ports []string, svc *corev1.Service) error {
udpOnlyPorts := sets.NewInt() udpPorts := sets.NewInt()
tcpPorts := sets.NewInt()
for _, port := range svc.Spec.Ports { for _, port := range svc.Spec.Ports {
portNum := int(port.Port) portNum := int(port.Port)
switch port.Protocol { switch port.Protocol {
case corev1.ProtocolUDP: case corev1.ProtocolUDP:
udpOnlyPorts.Insert(portNum) udpPorts.Insert(portNum)
case corev1.ProtocolTCP: case corev1.ProtocolTCP:
udpOnlyPorts.Delete(portNum) tcpPorts.Insert(portNum)
} }
} }
return checkUDPPorts(udpOnlyPorts, ports, svc) return checkUDPPorts(udpPorts.Difference(tcpPorts), ports, svc)
} }
// checkUDPPortInPod returns an error if remote port in Pod is a UDP port // checkUDPPortInPod returns an error if remote port in Pod is a UDP port
// TODO: remove this check after #47862 is solved // TODO: remove this check after #47862 is solved
func checkUDPPortInPod(ports []string, pod *corev1.Pod) error { func checkUDPPortInPod(ports []string, pod *corev1.Pod) error {
udpOnlyPorts := sets.NewInt() udpPorts := sets.NewInt()
tcpPorts := sets.NewInt()
for _, ct := range pod.Spec.Containers { for _, ct := range pod.Spec.Containers {
for _, ctPort := range ct.Ports { for _, ctPort := range ct.Ports {
portNum := int(ctPort.ContainerPort) portNum := int(ctPort.ContainerPort)
switch ctPort.Protocol { switch ctPort.Protocol {
case corev1.ProtocolUDP: case corev1.ProtocolUDP:
udpOnlyPorts.Insert(portNum) udpPorts.Insert(portNum)
case corev1.ProtocolTCP: case corev1.ProtocolTCP:
udpOnlyPorts.Delete(portNum) tcpPorts.Insert(portNum)
} }
} }
} }
return checkUDPPorts(udpOnlyPorts, ports, pod) return checkUDPPorts(udpPorts.Difference(tcpPorts), ports, pod)
} }
// Complete completes all the required options for port-forward cmd. // Complete completes all the required options for port-forward cmd.

View File

@ -880,7 +880,7 @@ func TestCheckUDPPort(t *testing.T) {
expectError: true, expectError: true,
}, },
{ {
name: "Pod has ports with both TCP and UDP protocol", name: "Pod has ports with both TCP and UDP protocol (UDP first)",
pod: &corev1.Pod{ pod: &corev1.Pod{
Spec: corev1.PodSpec{ Spec: corev1.PodSpec{
Containers: []corev1.Container{ Containers: []corev1.Container{
@ -895,6 +895,22 @@ func TestCheckUDPPort(t *testing.T) {
}, },
ports: []string{":53"}, ports: []string{":53"},
}, },
{
name: "Pod has ports with both TCP and UDP protocol (TCP first)",
pod: &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Ports: []corev1.ContainerPort{
{Protocol: corev1.ProtocolTCP, ContainerPort: 53},
{Protocol: corev1.ProtocolUDP, ContainerPort: 53},
},
},
},
},
},
ports: []string{":53"},
},
{ {
name: "forward to a UDP port in a Service", name: "forward to a UDP port in a Service",
@ -921,7 +937,7 @@ func TestCheckUDPPort(t *testing.T) {
expectError: true, expectError: true,
}, },
{ {
name: "Service has ports with both TCP and UDP protocol", name: "Service has ports with both TCP and UDP protocol (UDP first)",
service: &corev1.Service{ service: &corev1.Service{
Spec: corev1.ServiceSpec{ Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{ Ports: []corev1.ServicePort{
@ -932,6 +948,18 @@ func TestCheckUDPPort(t *testing.T) {
}, },
ports: []string{"53"}, ports: []string{"53"},
}, },
{
name: "Service has ports with both TCP and UDP protocol (TCP first)",
service: &corev1.Service{
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{Protocol: corev1.ProtocolTCP, Port: 53},
{Protocol: corev1.ProtocolUDP, Port: 53},
},
},
},
ports: []string{"53"},
},
} }
for _, tc := range tests { for _, tc := range tests {
var err error var err error