Revert "Revert "move pod networking tests common""

pull/6/head
Minhan Xia 2016-10-04 14:06:25 -07:00 committed by Minhan Xia
parent 617fa91264
commit df92825c33
5 changed files with 285 additions and 233 deletions

View File

@ -0,0 +1,62 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package common
import (
. "github.com/onsi/ginkgo"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/test/e2e/framework"
networking_util "k8s.io/kubernetes/test/utils"
)
var _ = framework.KubeDescribe("Networking", func() {
f := framework.NewDefaultFramework("pod-network-test")
framework.KubeDescribe("Granular Checks: Pods", func() {
// Try to hit all endpoints through a test container, retry 5 times,
// expect exactly one unique hostname. Each of these endpoints reports
// its own hostname.
It("should function for intra-pod communication: http [Conformance]", func() {
config := networking_util.NewCoreNetworkingTestConfig(f)
for _, endpointPod := range config.EndpointPods {
config.DialFromTestContainer("http", endpointPod.Status.PodIP, networking_util.EndpointHttpPort, config.MaxTries, 0, sets.NewString(endpointPod.Name))
}
})
It("should function for intra-pod communication: udp [Conformance]", func() {
config := networking_util.NewCoreNetworkingTestConfig(f)
for _, endpointPod := range config.EndpointPods {
config.DialFromTestContainer("udp", endpointPod.Status.PodIP, networking_util.EndpointUdpPort, config.MaxTries, 0, sets.NewString(endpointPod.Name))
}
})
It("should function for node-pod communication: http [Conformance]", func() {
config := networking_util.NewCoreNetworkingTestConfig(f)
for _, endpointPod := range config.EndpointPods {
config.DialFromNode("http", endpointPod.Status.PodIP, networking_util.EndpointHttpPort, config.MaxTries, 0, sets.NewString(endpointPod.Name))
}
})
It("should function for node-pod communication: udp [Conformance]", func() {
config := networking_util.NewCoreNetworkingTestConfig(f)
for _, endpointPod := range config.EndpointPods {
config.DialFromNode("udp", endpointPod.Status.PodIP, networking_util.EndpointUdpPort, config.MaxTries, 0, sets.NewString(endpointPod.Name))
}
})
})
})

View File

@ -40,6 +40,7 @@ var CommonImageWhiteList = sets.NewString(
"gcr.io/google_containers/mounttest:0.7", "gcr.io/google_containers/mounttest:0.7",
"gcr.io/google_containers/mounttest-user:0.3", "gcr.io/google_containers/mounttest-user:0.3",
"gcr.io/google_containers/netexec:1.4", "gcr.io/google_containers/netexec:1.4",
"gcr.io/google_containers/netexec:1.5",
"gcr.io/google_containers/nginx-slim:0.7", "gcr.io/google_containers/nginx-slim:0.7",
"gcr.io/google_containers/serve_hostname:v1.4", "gcr.io/google_containers/serve_hostname:v1.4",
"gcr.io/google_containers/test-webserver:e2e", "gcr.io/google_containers/test-webserver:e2e",

View File

@ -20,10 +20,10 @@ import (
"fmt" "fmt"
"net/http" "net/http"
. "github.com/onsi/ginkgo"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
networking_util "k8s.io/kubernetes/test/utils"
. "github.com/onsi/ginkgo"
) )
var _ = framework.KubeDescribe("Networking", func() { var _ = framework.KubeDescribe("Networking", func() {
@ -77,148 +77,114 @@ var _ = framework.KubeDescribe("Networking", func() {
It("should check kube-proxy urls", func() { It("should check kube-proxy urls", func() {
// TODO: this is overkill we just need the host networking pod // TODO: this is overkill we just need the host networking pod
// to hit kube-proxy urls. // to hit kube-proxy urls.
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By("checking kube-proxy URLs") By("checking kube-proxy URLs")
config.getSelfURL("/healthz", "ok") config.GetSelfURL("/healthz", "ok")
config.getSelfURL("/proxyMode", "iptables") // the default config.GetSelfURL("/proxyMode", "iptables") // the default
})
framework.KubeDescribe("Granular Checks: Pods", func() {
// Try to hit all endpoints through a test container, retry 5 times,
// expect exactly one unique hostname. Each of these endpoints reports
// its own hostname.
It("should function for intra-pod communication: http [Conformance]", func() {
config := NewNetworkingTestConfig(f)
for _, endpointPod := range config.endpointPods {
config.dialFromTestContainer("http", endpointPod.Status.PodIP, endpointHttpPort, config.maxTries, 0, sets.NewString(endpointPod.Name))
}
})
It("should function for intra-pod communication: udp [Conformance]", func() {
config := NewNetworkingTestConfig(f)
for _, endpointPod := range config.endpointPods {
config.dialFromTestContainer("udp", endpointPod.Status.PodIP, endpointUdpPort, config.maxTries, 0, sets.NewString(endpointPod.Name))
}
})
It("should function for node-pod communication: http [Conformance]", func() {
config := NewNetworkingTestConfig(f)
for _, endpointPod := range config.endpointPods {
config.dialFromNode("http", endpointPod.Status.PodIP, endpointHttpPort, config.maxTries, 0, sets.NewString(endpointPod.Name))
}
})
It("should function for node-pod communication: udp [Conformance]", func() {
config := NewNetworkingTestConfig(f)
for _, endpointPod := range config.endpointPods {
config.dialFromNode("udp", endpointPod.Status.PodIP, endpointUdpPort, config.maxTries, 0, sets.NewString(endpointPod.Name))
}
})
}) })
// TODO: Remove [Slow] when this has had enough bake time to prove presubmit worthiness. // TODO: Remove [Slow] when this has had enough bake time to prove presubmit worthiness.
framework.KubeDescribe("Granular Checks: Services [Slow]", func() { framework.KubeDescribe("Granular Checks: Services [Slow]", func() {
It("should function for pod-Service: http", func() { It("should function for pod-Service: http", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.testContainerPod.Name, config.clusterIP, clusterHttpPort)) By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, networking_util.ClusterHttpPort))
config.dialFromTestContainer("http", config.clusterIP, clusterHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromTestContainer("http", config.ClusterIP, networking_util.ClusterHttpPort, config.MaxTries, 0, config.EndpointHostnames())
By(fmt.Sprintf("dialing(http) %v --> %v:%v (nodeIP)", config.testContainerPod.Name, config.externalAddrs[0], config.nodeHttpPort)) By(fmt.Sprintf("dialing(http) %v --> %v:%v (nodeIP)", config.TestContainerPod.Name, config.ExternalAddrs[0], config.NodeHttpPort))
config.dialFromTestContainer("http", config.nodeIP, config.nodeHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromTestContainer("http", config.NodeIP, config.NodeHttpPort, config.MaxTries, 0, config.EndpointHostnames())
}) })
It("should function for pod-Service: udp", func() { It("should function for pod-Service: udp", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.testContainerPod.Name, config.clusterIP, clusterUdpPort)) By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, networking_util.ClusterUdpPort))
config.dialFromTestContainer("udp", config.clusterIP, clusterUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromTestContainer("udp", config.ClusterIP, networking_util.ClusterUdpPort, config.MaxTries, 0, config.EndpointHostnames())
By(fmt.Sprintf("dialing(udp) %v --> %v:%v (nodeIP)", config.testContainerPod.Name, config.externalAddrs[0], config.nodeUdpPort)) By(fmt.Sprintf("dialing(udp) %v --> %v:%v (nodeIP)", config.TestContainerPod.Name, config.ExternalAddrs[0], config.NodeUdpPort))
config.dialFromTestContainer("udp", config.nodeIP, config.nodeUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromTestContainer("udp", config.NodeIP, config.NodeUdpPort, config.MaxTries, 0, config.EndpointHostnames())
}) })
It("should function for node-Service: http", func() { It("should function for node-Service: http", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (config.clusterIP)", config.nodeIP, config.clusterIP, clusterHttpPort)) By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (config.clusterIP)", config.NodeIP, config.ClusterIP, networking_util.ClusterHttpPort))
config.dialFromNode("http", config.clusterIP, clusterHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromNode("http", config.ClusterIP, networking_util.ClusterHttpPort, config.MaxTries, 0, config.EndpointHostnames())
By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (nodeIP)", config.nodeIP, config.nodeIP, config.nodeHttpPort)) By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (nodeIP)", config.NodeIP, config.NodeIP, config.NodeHttpPort))
config.dialFromNode("http", config.nodeIP, config.nodeHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromNode("http", config.NodeIP, config.NodeHttpPort, config.MaxTries, 0, config.EndpointHostnames())
}) })
It("should function for node-Service: udp", func() { It("should function for node-Service: udp", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (config.clusterIP)", config.nodeIP, config.clusterIP, clusterUdpPort)) By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (config.clusterIP)", config.NodeIP, config.ClusterIP, networking_util.ClusterUdpPort))
config.dialFromNode("udp", config.clusterIP, clusterUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromNode("udp", config.ClusterIP, networking_util.ClusterUdpPort, config.MaxTries, 0, config.EndpointHostnames())
By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (nodeIP)", config.nodeIP, config.nodeIP, config.nodeUdpPort)) By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (nodeIP)", config.NodeIP, config.NodeIP, config.NodeUdpPort))
config.dialFromNode("udp", config.nodeIP, config.nodeUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromNode("udp", config.NodeIP, config.NodeUdpPort, config.MaxTries, 0, config.EndpointHostnames())
}) })
It("should function for endpoint-Service: http", func() { It("should function for endpoint-Service: http", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(http) %v (endpoint) --> %v:%v (config.clusterIP)", config.endpointPods[0].Name, config.clusterIP, clusterHttpPort)) By(fmt.Sprintf("dialing(http) %v (endpoint) --> %v:%v (config.clusterIP)", config.EndpointPods[0].Name, config.ClusterIP, networking_util.ClusterHttpPort))
config.dialFromEndpointContainer("http", config.clusterIP, clusterHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromEndpointContainer("http", config.ClusterIP, networking_util.ClusterHttpPort, config.MaxTries, 0, config.EndpointHostnames())
By(fmt.Sprintf("dialing(http) %v (endpoint) --> %v:%v (nodeIP)", config.endpointPods[0].Name, config.nodeIP, config.nodeHttpPort)) By(fmt.Sprintf("dialing(http) %v (endpoint) --> %v:%v (nodeIP)", config.EndpointPods[0].Name, config.NodeIP, config.NodeHttpPort))
config.dialFromEndpointContainer("http", config.nodeIP, config.nodeHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromEndpointContainer("http", config.NodeIP, config.NodeHttpPort, config.MaxTries, 0, config.EndpointHostnames())
}) })
It("should function for endpoint-Service: udp", func() { It("should function for endpoint-Service: udp", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(udp) %v (endpoint) --> %v:%v (config.clusterIP)", config.endpointPods[0].Name, config.clusterIP, clusterUdpPort)) By(fmt.Sprintf("dialing(udp) %v (endpoint) --> %v:%v (config.clusterIP)", config.EndpointPods[0].Name, config.ClusterIP, networking_util.ClusterUdpPort))
config.dialFromEndpointContainer("udp", config.clusterIP, clusterUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromEndpointContainer("udp", config.ClusterIP, networking_util.ClusterUdpPort, config.MaxTries, 0, config.EndpointHostnames())
By(fmt.Sprintf("dialing(udp) %v (endpoint) --> %v:%v (nodeIP)", config.endpointPods[0].Name, config.nodeIP, config.nodeUdpPort)) By(fmt.Sprintf("dialing(udp) %v (endpoint) --> %v:%v (nodeIP)", config.EndpointPods[0].Name, config.NodeIP, config.NodeUdpPort))
config.dialFromEndpointContainer("udp", config.nodeIP, config.nodeUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromEndpointContainer("udp", config.NodeIP, config.NodeUdpPort, config.MaxTries, 0, config.EndpointHostnames())
}) })
It("should update endpoints: http", func() { It("should update endpoints: http", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.testContainerPod.Name, config.clusterIP, clusterHttpPort)) By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, networking_util.ClusterHttpPort))
config.dialFromTestContainer("http", config.clusterIP, clusterHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromTestContainer("http", config.ClusterIP, networking_util.ClusterHttpPort, config.MaxTries, 0, config.EndpointHostnames())
config.deleteNetProxyPod() config.DeleteNetProxyPod()
By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.testContainerPod.Name, config.clusterIP, clusterHttpPort)) By(fmt.Sprintf("dialing(http) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, networking_util.ClusterHttpPort))
config.dialFromTestContainer("http", config.clusterIP, clusterHttpPort, config.maxTries, config.maxTries, config.endpointHostnames()) config.DialFromTestContainer("http", config.ClusterIP, networking_util.ClusterHttpPort, config.MaxTries, config.MaxTries, config.EndpointHostnames())
}) })
It("should update endpoints: udp", func() { It("should update endpoints: udp", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.testContainerPod.Name, config.clusterIP, clusterUdpPort)) By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, networking_util.ClusterUdpPort))
config.dialFromTestContainer("udp", config.clusterIP, clusterUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromTestContainer("udp", config.ClusterIP, networking_util.ClusterUdpPort, config.MaxTries, 0, config.EndpointHostnames())
config.deleteNetProxyPod() config.DeleteNetProxyPod()
By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.testContainerPod.Name, config.clusterIP, clusterUdpPort)) By(fmt.Sprintf("dialing(udp) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, networking_util.ClusterUdpPort))
config.dialFromTestContainer("udp", config.clusterIP, clusterUdpPort, config.maxTries, config.maxTries, config.endpointHostnames()) config.DialFromTestContainer("udp", config.ClusterIP, networking_util.ClusterUdpPort, config.MaxTries, config.MaxTries, config.EndpointHostnames())
}) })
// Slow because we confirm that the nodePort doesn't serve traffic, which requires a period of polling. // Slow because we confirm that the nodePort doesn't serve traffic, which requires a period of polling.
It("should update nodePort: http [Slow]", func() { It("should update nodePort: http [Slow]", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (nodeIP)", config.nodeIP, config.nodeIP, config.nodeHttpPort)) By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (nodeIP)", config.NodeIP, config.NodeIP, config.NodeHttpPort))
config.dialFromNode("http", config.nodeIP, config.nodeHttpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromNode("http", config.NodeIP, config.NodeHttpPort, config.MaxTries, 0, config.EndpointHostnames())
config.deleteNodePortService() config.DeleteNodePortService()
By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (nodeIP)", config.nodeIP, config.nodeIP, config.nodeHttpPort)) By(fmt.Sprintf("dialing(http) %v (node) --> %v:%v (nodeIP)", config.NodeIP, config.NodeIP, config.NodeHttpPort))
config.dialFromNode("http", config.nodeIP, config.nodeHttpPort, config.maxTries, config.maxTries, sets.NewString()) config.DialFromNode("http", config.NodeIP, config.NodeHttpPort, config.MaxTries, config.MaxTries, sets.NewString())
}) })
// Slow because we confirm that the nodePort doesn't serve traffic, which requires a period of polling. // Slow because we confirm that the nodePort doesn't serve traffic, which requires a period of polling.
It("should update nodePort: udp [Slow]", func() { It("should update nodePort: udp [Slow]", func() {
config := NewNetworkingTestConfig(f) config := networking_util.NewNetworkingTestConfig(f)
By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (nodeIP)", config.nodeIP, config.nodeIP, config.nodeUdpPort)) By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (nodeIP)", config.NodeIP, config.NodeIP, config.NodeUdpPort))
config.dialFromNode("udp", config.nodeIP, config.nodeUdpPort, config.maxTries, 0, config.endpointHostnames()) config.DialFromNode("udp", config.NodeIP, config.NodeUdpPort, config.MaxTries, 0, config.EndpointHostnames())
config.deleteNodePortService() config.DeleteNodePortService()
By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (nodeIP)", config.nodeIP, config.nodeIP, config.nodeUdpPort)) By(fmt.Sprintf("dialing(udp) %v (node) --> %v:%v (nodeIP)", config.NodeIP, config.NodeIP, config.NodeUdpPort))
config.dialFromNode("udp", config.nodeIP, config.nodeUdpPort, config.maxTries, config.maxTries, sets.NewString()) config.DialFromNode("udp", config.NodeIP, config.NodeUdpPort, config.MaxTries, config.MaxTries, sets.NewString())
}) })
// TODO: Test sessionAffinity #31712 // TODO: Test sessionAffinity #31712
}) })

View File

@ -165,6 +165,27 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string
return "", false, err return "", false, err
} }
// Configure iptables firewall rules
// TODO: consider calling bootstrap script to configure host based on OS
cmd := getSshCommand("&&",
`iptables -L INPUT | grep "Chain INPUT (policy DROP)"`,
"(iptables -C INPUT -w -p TCP -j ACCEPT || iptables -A INPUT -w -p TCP -j ACCEPT)",
"(iptables -C INPUT -w -p UDP -j ACCEPT || iptables -A INPUT -w -p UDP -j ACCEPT)",
"(iptables -C INPUT -w -p ICMP -j ACCEPT || iptables -A INPUT -w -p ICMP -j ACCEPT)")
output, err := RunSshCommand("ssh", GetHostnameOrIp(host), "--", "sudo", "sh", "-c", cmd)
if err != nil {
glog.Errorf("Failed to configured firewall: %v output: %v", err, output)
}
cmd = getSshCommand("&&",
`iptables -L FORWARD | grep "Chain FORWARD (policy DROP)" > /dev/null`,
"(iptables -C FORWARD -w -p TCP -j ACCEPT || iptables -A FORWARD -w -p TCP -j ACCEPT)",
"(iptables -C FORWARD -w -p UDP -j ACCEPT || iptables -A FORWARD -w -p UDP -j ACCEPT)",
"(iptables -C FORWARD -w -p ICMP -j ACCEPT || iptables -A FORWARD -w -p ICMP -j ACCEPT)")
output, err = RunSshCommand("ssh", GetHostnameOrIp(host), "--", "sudo", "sh", "-c", cmd)
if err != nil {
glog.Errorf("Failed to configured firewall: %v output: %v", err, output)
}
// Copy the archive to the staging directory // Copy the archive to the staging directory
_, err = RunSshCommand("scp", archive, fmt.Sprintf("%s:%s/", GetHostnameOrIp(host), tmp)) _, err = RunSshCommand("scp", archive, fmt.Sprintf("%s:%s/", GetHostnameOrIp(host), tmp))
if err != nil { if err != nil {
@ -173,7 +194,7 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string
} }
// Kill any running node processes // Kill any running node processes
cmd := getSshCommand(" ; ", cmd = getSshCommand(" ; ",
"sudo pkill kubelet", "sudo pkill kubelet",
"sudo pkill kube-apiserver", "sudo pkill kube-apiserver",
"sudo pkill etcd", "sudo pkill etcd",
@ -187,7 +208,7 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string
// Extract the archive // Extract the archive
cmd = getSshCommand(" && ", fmt.Sprintf("cd %s", tmp), fmt.Sprintf("tar -xzvf ./%s", archiveName)) cmd = getSshCommand(" && ", fmt.Sprintf("cd %s", tmp), fmt.Sprintf("tar -xzvf ./%s", archiveName))
glog.Infof("Extracting tar on %s", host) glog.Infof("Extracting tar on %s", host)
output, err := RunSshCommand("ssh", GetHostnameOrIp(host), "--", "sh", "-c", cmd) output, err = RunSshCommand("ssh", GetHostnameOrIp(host), "--", "sh", "-c", cmd)
if err != nil { if err != nil {
// Exit failure with the error // Exit failure with the error
return "", false, err return "", false, err

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package e2e package utils
import ( import (
"encoding/json" "encoding/json"
@ -38,13 +38,13 @@ import (
) )
const ( const (
endpointHttpPort = 8080 EndpointHttpPort = 8080
endpointUdpPort = 8081 EndpointUdpPort = 8081
testContainerHttpPort = 8080 TestContainerHttpPort = 8080
clusterHttpPort = 80 ClusterHttpPort = 80
clusterUdpPort = 90 ClusterUdpPort = 90
netexecImageName = "gcr.io/google_containers/netexec:1.7" NetexecImageName = "gcr.io/google_containers/netexec:1.7"
hostexecImageName = "gcr.io/google_containers/hostexec:1.2" HostexecImageName = "gcr.io/google_containers/hostexec:1.2"
testPodName = "test-container-pod" testPodName = "test-container-pod"
hostTestPodName = "host-test-container-pod" hostTestPodName = "host-test-container-pod"
nodePortServiceName = "node-port-service" nodePortServiceName = "node-port-service"
@ -58,61 +58,79 @@ const (
// NewNetworkingTestConfig creates and sets up a new test config helper. // NewNetworkingTestConfig creates and sets up a new test config helper.
func NewNetworkingTestConfig(f *framework.Framework) *NetworkingTestConfig { func NewNetworkingTestConfig(f *framework.Framework) *NetworkingTestConfig {
config := &NetworkingTestConfig{f: f, ns: f.Namespace.Name} config := &NetworkingTestConfig{f: f, Namespace: f.Namespace.Name}
By(fmt.Sprintf("Performing setup for networking test in namespace %v", config.ns)) By(fmt.Sprintf("Performing setup for networking test in namespace %v", config.Namespace))
config.setup() config.setup(getServiceSelector())
return config return config
} }
// NewNetworkingTestNodeE2EConfig creates and sets up a new test config helper for Node E2E.
func NewCoreNetworkingTestConfig(f *framework.Framework) *NetworkingTestConfig {
config := &NetworkingTestConfig{f: f, Namespace: f.Namespace.Name}
By(fmt.Sprintf("Performing setup for networking test in namespace %v", config.Namespace))
config.setupCore(getServiceSelector())
return config
}
func getServiceSelector() map[string]string {
By("creating a selector")
selectorName := "selector-" + string(uuid.NewUUID())
serviceSelector := map[string]string{
selectorName: "true",
}
return serviceSelector
}
// NetworkingTestConfig is a convenience class around some utility methods // NetworkingTestConfig is a convenience class around some utility methods
// for testing kubeproxy/networking/services/endpoints. // for testing kubeproxy/networking/services/endpoints.
type NetworkingTestConfig struct { type NetworkingTestConfig struct {
// testContaienrPod is a test pod running the netexec image. It is capable // TestContaienrPod is a test pod running the netexec image. It is capable
// of executing tcp/udp requests against ip:port. // of executing tcp/udp requests against ip:port.
testContainerPod *api.Pod TestContainerPod *api.Pod
// hostTestContainerPod is a pod running with hostNetworking=true, and the // HostTestContainerPod is a pod running with hostNetworking=true, and the
// hostexec image. // hostexec image.
hostTestContainerPod *api.Pod HostTestContainerPod *api.Pod
// endpointPods are the pods belonging to the Service created by this // EndpointPods are the pods belonging to the Service created by this
// test config. Each invocation of `setup` creates a service with // test config. Each invocation of `setup` creates a service with
// 1 pod per node running the netexecImage. // 1 pod per node running the netexecImage.
endpointPods []*api.Pod EndpointPods []*api.Pod
f *framework.Framework f *framework.Framework
// nodePortService is a Service with Type=NodePort spanning over all podClient *framework.PodClient
// NodePortService is a Service with Type=NodePort spanning over all
// endpointPods. // endpointPods.
nodePortService *api.Service NodePortService *api.Service
// externalAddrs is a list of external IPs of nodes in the cluster. // ExternalAddrs is a list of external IPs of nodes in the cluster.
externalAddrs []string ExternalAddrs []string
// nodes is a list of nodes in the cluster. // Nodes is a list of nodes in the cluster.
nodes []api.Node Nodes []api.Node
// maxTries is the number of retries tolerated for tests run against // MaxTries is the number of retries tolerated for tests run against
// endpoints and services created by this config. // endpoints and services created by this config.
maxTries int MaxTries int
// The clusterIP of the Service reated by this test config. // The ClusterIP of the Service reated by this test config.
clusterIP string ClusterIP string
// External ip of first node for use in nodePort testing. // External ip of first node for use in nodePort testing.
nodeIP string NodeIP string
// The http/udp nodePorts of the Service. // The http/udp nodePorts of the Service.
nodeHttpPort int NodeHttpPort int
nodeUdpPort int NodeUdpPort int
// The kubernetes namespace within which all resources for this // The kubernetes namespace within which all resources for this
// config are created // config are created
ns string Namespace string
} }
func (config *NetworkingTestConfig) dialFromEndpointContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) { func (config *NetworkingTestConfig) DialFromEndpointContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
config.dialFromContainer(protocol, config.endpointPods[0].Status.PodIP, targetIP, endpointHttpPort, targetPort, maxTries, minTries, expectedEps) config.DialFromContainer(protocol, config.EndpointPods[0].Status.PodIP, targetIP, EndpointHttpPort, targetPort, maxTries, minTries, expectedEps)
} }
func (config *NetworkingTestConfig) dialFromTestContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) { func (config *NetworkingTestConfig) DialFromTestContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
config.dialFromContainer(protocol, config.testContainerPod.Status.PodIP, targetIP, testContainerHttpPort, targetPort, maxTries, minTries, expectedEps) config.DialFromContainer(protocol, config.TestContainerPod.Status.PodIP, targetIP, TestContainerHttpPort, targetPort, maxTries, minTries, expectedEps)
} }
// diagnoseMissingEndpoints prints debug information about the endpoints that // diagnoseMissingEndpoints prints debug information about the endpoints that
// are NOT in the given list of foundEndpoints. These are the endpoints we // are NOT in the given list of foundEndpoints. These are the endpoints we
// expected a response from. // expected a response from.
func (config *NetworkingTestConfig) diagnoseMissingEndpoints(foundEndpoints sets.String) { func (config *NetworkingTestConfig) diagnoseMissingEndpoints(foundEndpoints sets.String) {
for _, e := range config.endpointPods { for _, e := range config.EndpointPods {
if foundEndpoints.Has(e.Name) { if foundEndpoints.Has(e.Name) {
continue continue
} }
@ -123,16 +141,16 @@ func (config *NetworkingTestConfig) diagnoseMissingEndpoints(foundEndpoints sets
} }
} }
// endpointHostnames returns a set of hostnames for existing endpoints. // EndpointHostnames returns a set of hostnames for existing endpoints.
func (config *NetworkingTestConfig) endpointHostnames() sets.String { func (config *NetworkingTestConfig) EndpointHostnames() sets.String {
expectedEps := sets.NewString() expectedEps := sets.NewString()
for _, p := range config.endpointPods { for _, p := range config.EndpointPods {
expectedEps.Insert(p.Name) expectedEps.Insert(p.Name)
} }
return expectedEps return expectedEps
} }
// dialFromContainers executes a curl via kubectl exec in a test container, // DialFromContainers executes a curl via kubectl exec in a test container,
// which might then translate to a tcp or udp request based on the protocol // which might then translate to a tcp or udp request based on the protocol
// argument in the url. // argument in the url.
// - minTries is the minimum number of curl attempts required before declaring // - minTries is the minimum number of curl attempts required before declaring
@ -145,7 +163,7 @@ func (config *NetworkingTestConfig) endpointHostnames() sets.String {
// maxTries == minTries will confirm that we see the expected endpoints and no // maxTries == minTries will confirm that we see the expected endpoints and no
// more for maxTries. Use this if you want to eg: fail a readiness check on a // more for maxTries. Use this if you want to eg: fail a readiness check on a
// pod and confirm it doesn't show up as an endpoint. // pod and confirm it doesn't show up as an endpoint.
func (config *NetworkingTestConfig) dialFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, maxTries, minTries int, expectedEps sets.String) { func (config *NetworkingTestConfig) DialFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, maxTries, minTries int, expectedEps sets.String) {
cmd := fmt.Sprintf("curl -q -s 'http://%s:%d/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'", cmd := fmt.Sprintf("curl -q -s 'http://%s:%d/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'",
containerIP, containerIP,
containerHttpPort, containerHttpPort,
@ -156,26 +174,19 @@ func (config *NetworkingTestConfig) dialFromContainer(protocol, containerIP, tar
eps := sets.NewString() eps := sets.NewString()
for i := 0; i < maxTries; i++ { for i := 0; i < maxTries; i++ {
stdout, err := framework.RunHostCmd(config.ns, config.hostTestContainerPod.Name, cmd) stdout := config.f.ExecShellInPod(config.HostTestContainerPod.Name, cmd)
if err != nil {
// A failure to kubectl exec counts as a try, not a hard fail. var output map[string][]string
// Also note that we will keep failing for maxTries in tests where if err := json.Unmarshal([]byte(stdout), &output); err != nil {
// we confirm unreachability. framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v",
framework.Logf("Failed to execute %v: %v", cmd, err) cmd, config.HostTestContainerPod.Name, stdout, err)
} else { continue
var output map[string][]string
if err := json.Unmarshal([]byte(stdout), &output); err != nil {
framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v",
cmd, config.hostTestContainerPod.Name, stdout, err)
continue
}
for _, hostName := range output["responses"] {
trimmed := strings.TrimSpace(hostName)
if trimmed != "" {
eps.Insert(trimmed)
}
}
} }
for _, hostName := range output["responses"] {
eps.Insert(hostName)
}
framework.Logf("Waiting for endpoints: %v", expectedEps.Difference(eps)) framework.Logf("Waiting for endpoints: %v", expectedEps.Difference(eps))
// Check against i+1 so we exit if minTries == maxTries. // Check against i+1 so we exit if minTries == maxTries.
@ -188,7 +199,7 @@ func (config *NetworkingTestConfig) dialFromContainer(protocol, containerIP, tar
framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", minTries, cmd, eps, expectedEps) framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", minTries, cmd, eps, expectedEps)
} }
// dialFromNode executes a tcp or udp request based on protocol via kubectl exec // DialFromNode executes a tcp or udp request based on protocol via kubectl exec
// in a test container running with host networking. // in a test container running with host networking.
// - minTries is the minimum number of curl attempts required before declaring // - minTries is the minimum number of curl attempts required before declaring
// success. Set to 0 if you'd like to return as soon as all endpoints respond // success. Set to 0 if you'd like to return as soon as all endpoints respond
@ -198,7 +209,7 @@ func (config *NetworkingTestConfig) dialFromContainer(protocol, containerIP, tar
// maxTries == minTries will confirm that we see the expected endpoints and no // maxTries == minTries will confirm that we see the expected endpoints and no
// more for maxTries. Use this if you want to eg: fail a readiness check on a // more for maxTries. Use this if you want to eg: fail a readiness check on a
// pod and confirm it doesn't show up as an endpoint. // pod and confirm it doesn't show up as an endpoint.
func (config *NetworkingTestConfig) dialFromNode(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) { func (config *NetworkingTestConfig) DialFromNode(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
var cmd string var cmd string
if protocol == "udp" { if protocol == "udp" {
cmd = fmt.Sprintf("echo 'hostName' | timeout -t 3 nc -w 1 -u %s %d", targetIP, targetPort) cmd = fmt.Sprintf("echo 'hostName' | timeout -t 3 nc -w 1 -u %s %d", targetIP, targetPort)
@ -213,18 +224,8 @@ func (config *NetworkingTestConfig) dialFromNode(protocol, targetIP string, targ
filterCmd := fmt.Sprintf("%s | grep -v '^\\s*$'", cmd) filterCmd := fmt.Sprintf("%s | grep -v '^\\s*$'", cmd)
for i := 0; i < maxTries; i++ { for i := 0; i < maxTries; i++ {
stdout, err := framework.RunHostCmd(config.ns, config.hostTestContainerPod.Name, filterCmd) stdout := config.f.ExecShellInPod(config.HostTestContainerPod.Name, filterCmd)
if err != nil { eps.Insert(strings.TrimSpace(stdout))
// A failure to kubectl exec counts as a try, not a hard fail.
// Also note that we will keep failing for maxTries in tests where
// we confirm unreachability.
framework.Logf("Failed to execute %v: %v", filterCmd, err)
} else {
trimmed := strings.TrimSpace(stdout)
if trimmed != "" {
eps.Insert(trimmed)
}
}
framework.Logf("Waiting for %+v endpoints, got endpoints %+v", expectedEps.Difference(eps), eps) framework.Logf("Waiting for %+v endpoints, got endpoints %+v", expectedEps.Difference(eps), eps)
// Check against i+1 so we exit if minTries == maxTries. // Check against i+1 so we exit if minTries == maxTries.
@ -237,13 +238,13 @@ func (config *NetworkingTestConfig) dialFromNode(protocol, targetIP string, targ
framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", minTries, cmd, eps, expectedEps) framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", minTries, cmd, eps, expectedEps)
} }
// getSelfURL executes a curl against the given path via kubectl exec into a // GetSelfURL executes a curl against the given path via kubectl exec into a
// test container running with host networking, and fails if the output // test container running with host networking, and fails if the output
// doesn't match the expected string. // doesn't match the expected string.
func (config *NetworkingTestConfig) getSelfURL(path string, expected string) { func (config *NetworkingTestConfig) GetSelfURL(path string, expected string) {
cmd := fmt.Sprintf("curl -q -s --connect-timeout 1 http://localhost:10249%s", path) cmd := fmt.Sprintf("curl -q -s --connect-timeout 1 http://localhost:10249%s", path)
By(fmt.Sprintf("Getting kube-proxy self URL %s", path)) By(fmt.Sprintf("Getting kube-proxy self URL %s", path))
stdout := framework.RunHostCmdOrDie(config.ns, config.hostTestContainerPod.Name, cmd) stdout := framework.RunHostCmdOrDie(config.Namespace, config.HostTestContainerPod.Name, cmd)
Expect(strings.Contains(stdout, expected)).To(BeTrue()) Expect(strings.Contains(stdout, expected)).To(BeTrue())
} }
@ -257,7 +258,7 @@ func (config *NetworkingTestConfig) createNetShellPodSpec(podName string, node s
Handler: api.Handler{ Handler: api.Handler{
HTTPGet: &api.HTTPGetAction{ HTTPGet: &api.HTTPGetAction{
Path: "/healthz", Path: "/healthz",
Port: intstr.IntOrString{IntVal: endpointHttpPort}, Port: intstr.IntOrString{IntVal: EndpointHttpPort},
}, },
}, },
} }
@ -268,27 +269,27 @@ func (config *NetworkingTestConfig) createNetShellPodSpec(podName string, node s
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: podName, Name: podName,
Namespace: config.ns, Namespace: config.Namespace,
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "webserver", Name: "webserver",
Image: netexecImageName, Image: NetexecImageName,
ImagePullPolicy: api.PullIfNotPresent, ImagePullPolicy: api.PullIfNotPresent,
Command: []string{ Command: []string{
"/netexec", "/netexec",
fmt.Sprintf("--http-port=%d", endpointHttpPort), fmt.Sprintf("--http-port=%d", EndpointHttpPort),
fmt.Sprintf("--udp-port=%d", endpointUdpPort), fmt.Sprintf("--udp-port=%d", EndpointUdpPort),
}, },
Ports: []api.ContainerPort{ Ports: []api.ContainerPort{
{ {
Name: "http", Name: "http",
ContainerPort: endpointHttpPort, ContainerPort: EndpointHttpPort,
}, },
{ {
Name: "udp", Name: "udp",
ContainerPort: endpointUdpPort, ContainerPort: EndpointUdpPort,
Protocol: api.ProtocolUDP, Protocol: api.ProtocolUDP,
}, },
}, },
@ -310,23 +311,23 @@ func (config *NetworkingTestConfig) createTestPodSpec() *api.Pod {
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: testPodName, Name: testPodName,
Namespace: config.ns, Namespace: config.Namespace,
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "webserver", Name: "webserver",
Image: netexecImageName, Image: NetexecImageName,
ImagePullPolicy: api.PullIfNotPresent, ImagePullPolicy: api.PullIfNotPresent,
Command: []string{ Command: []string{
"/netexec", "/netexec",
fmt.Sprintf("--http-port=%d", endpointHttpPort), fmt.Sprintf("--http-port=%d", EndpointHttpPort),
fmt.Sprintf("--udp-port=%d", endpointUdpPort), fmt.Sprintf("--udp-port=%d", EndpointUdpPort),
}, },
Ports: []api.ContainerPort{ Ports: []api.ContainerPort{
{ {
Name: "http", Name: "http",
ContainerPort: testContainerHttpPort, ContainerPort: TestContainerHttpPort,
}, },
}, },
}, },
@ -344,24 +345,24 @@ func (config *NetworkingTestConfig) createNodePortService(selector map[string]st
Spec: api.ServiceSpec{ Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort, Type: api.ServiceTypeNodePort,
Ports: []api.ServicePort{ Ports: []api.ServicePort{
{Port: clusterHttpPort, Name: "http", Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(endpointHttpPort)}, {Port: ClusterHttpPort, Name: "http", Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(EndpointHttpPort)},
{Port: clusterUdpPort, Name: "udp", Protocol: api.ProtocolUDP, TargetPort: intstr.FromInt(endpointUdpPort)}, {Port: ClusterUdpPort, Name: "udp", Protocol: api.ProtocolUDP, TargetPort: intstr.FromInt(EndpointUdpPort)},
}, },
Selector: selector, Selector: selector,
}, },
} }
config.nodePortService = config.createService(serviceSpec) config.NodePortService = config.createService(serviceSpec)
} }
func (config *NetworkingTestConfig) deleteNodePortService() { func (config *NetworkingTestConfig) DeleteNodePortService() {
err := config.getServiceClient().Delete(config.nodePortService.Name) err := config.getServiceClient().Delete(config.NodePortService.Name)
Expect(err).NotTo(HaveOccurred(), "error while deleting NodePortService. err:%v)", err) Expect(err).NotTo(HaveOccurred(), "error while deleting NodePortService. err:%v)", err)
time.Sleep(15 * time.Second) // wait for kube-proxy to catch up with the service being deleted. time.Sleep(15 * time.Second) // wait for kube-proxy to catch up with the service being deleted.
} }
func (config *NetworkingTestConfig) createTestPods() { func (config *NetworkingTestConfig) createTestPods() {
testContainerPod := config.createTestPodSpec() testContainerPod := config.createTestPodSpec()
hostTestContainerPod := framework.NewHostExecPodSpec(config.ns, hostTestPodName) hostTestContainerPod := framework.NewHostExecPodSpec(config.Namespace, hostTestPodName)
config.createPod(testContainerPod) config.createPod(testContainerPod)
config.createPod(hostTestContainerPod) config.createPod(hostTestContainerPod)
@ -370,12 +371,12 @@ func (config *NetworkingTestConfig) createTestPods() {
framework.ExpectNoError(config.f.WaitForPodRunning(hostTestContainerPod.Name)) framework.ExpectNoError(config.f.WaitForPodRunning(hostTestContainerPod.Name))
var err error var err error
config.testContainerPod, err = config.getPodClient().Get(testContainerPod.Name) config.TestContainerPod, err = config.getPodClient().Get(testContainerPod.Name)
if err != nil { if err != nil {
framework.Failf("Failed to retrieve %s pod: %v", testContainerPod.Name, err) framework.Failf("Failed to retrieve %s pod: %v", testContainerPod.Name, err)
} }
config.hostTestContainerPod, err = config.getPodClient().Get(hostTestContainerPod.Name) config.HostTestContainerPod, err = config.getPodClient().Get(hostTestContainerPod.Name)
if err != nil { if err != nil {
framework.Failf("Failed to retrieve %s pod: %v", hostTestContainerPod.Name, err) framework.Failf("Failed to retrieve %s pod: %v", hostTestContainerPod.Name, err)
} }
@ -385,7 +386,7 @@ func (config *NetworkingTestConfig) createService(serviceSpec *api.Service) *api
_, err := config.getServiceClient().Create(serviceSpec) _, err := config.getServiceClient().Create(serviceSpec)
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to create %s service: %v", serviceSpec.Name, err)) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to create %s service: %v", serviceSpec.Name, err))
err = framework.WaitForService(config.f.Client, config.ns, serviceSpec.Name, true, 5*time.Second, 45*time.Second) err = framework.WaitForService(config.f.Client, config.Namespace, serviceSpec.Name, true, 5*time.Second, 45*time.Second)
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("error while waiting for service:%s err: %v", serviceSpec.Name, err)) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("error while waiting for service:%s err: %v", serviceSpec.Name, err))
createdService, err := config.getServiceClient().Get(serviceSpec.Name) createdService, err := config.getServiceClient().Get(serviceSpec.Name)
@ -394,48 +395,50 @@ func (config *NetworkingTestConfig) createService(serviceSpec *api.Service) *api
return createdService return createdService
} }
func (config *NetworkingTestConfig) setup() { // setupCore sets up the pods and core test config
By("creating a selector") // mainly for simplified node e2e setup
selectorName := "selector-" + string(uuid.NewUUID()) func (config *NetworkingTestConfig) setupCore(selector map[string]string) {
serviceSelector := map[string]string{ By("Creating the service pods in kubernetes")
selectorName: "true", podName := "netserver"
} config.EndpointPods = config.createNetProxyPods(podName, selector)
By("Creating test pods")
config.createTestPods()
epCount := len(config.EndpointPods)
config.MaxTries = epCount*epCount + testTries
}
// setup includes setupCore and also sets up services
func (config *NetworkingTestConfig) setup(selector map[string]string) {
config.setupCore(selector)
By("Getting node addresses") By("Getting node addresses")
framework.ExpectNoError(framework.WaitForAllNodesSchedulable(config.f.Client)) framework.ExpectNoError(framework.WaitForAllNodesSchedulable(config.f.Client))
nodeList := framework.GetReadySchedulableNodesOrDie(config.f.Client) nodeList := framework.GetReadySchedulableNodesOrDie(config.f.Client)
config.externalAddrs = framework.NodeAddresses(nodeList, api.NodeExternalIP) config.ExternalAddrs = framework.NodeAddresses(nodeList, api.NodeExternalIP)
if len(config.externalAddrs) < 2 { if len(config.ExternalAddrs) < 2 {
// fall back to legacy IPs // fall back to legacy IPs
config.externalAddrs = framework.NodeAddresses(nodeList, api.NodeLegacyHostIP) config.ExternalAddrs = framework.NodeAddresses(nodeList, api.NodeLegacyHostIP)
} }
Expect(len(config.externalAddrs)).To(BeNumerically(">=", 2), fmt.Sprintf("At least two nodes necessary with an external or LegacyHostIP")) Expect(len(config.ExternalAddrs)).To(BeNumerically(">=", 2), fmt.Sprintf("At least two nodes necessary with an external or LegacyHostIP"))
config.nodes = nodeList.Items config.Nodes = nodeList.Items
By("Creating the service pods in kubernetes")
podName := "netserver"
config.endpointPods = config.createNetProxyPods(podName, serviceSelector)
By("Creating the service on top of the pods in kubernetes") By("Creating the service on top of the pods in kubernetes")
config.createNodePortService(serviceSelector) config.createNodePortService(selector)
By("Creating test pods") for _, p := range config.NodePortService.Spec.Ports {
config.createTestPods()
for _, p := range config.nodePortService.Spec.Ports {
switch p.Protocol { switch p.Protocol {
case api.ProtocolUDP: case api.ProtocolUDP:
config.nodeUdpPort = int(p.NodePort) config.NodeUdpPort = int(p.NodePort)
case api.ProtocolTCP: case api.ProtocolTCP:
config.nodeHttpPort = int(p.NodePort) config.NodeHttpPort = int(p.NodePort)
default: default:
continue continue
} }
} }
config.ClusterIP = config.NodePortService.Spec.ClusterIP
epCount := len(config.endpointPods) config.NodeIP = config.ExternalAddrs[0]
config.maxTries = epCount*epCount + testTries
config.clusterIP = config.nodePortService.Spec.ClusterIP
config.nodeIP = config.externalAddrs[0]
} }
func (config *NetworkingTestConfig) cleanup() { func (config *NetworkingTestConfig) cleanup() {
@ -443,7 +446,7 @@ func (config *NetworkingTestConfig) cleanup() {
nsList, err := nsClient.List(api.ListOptions{}) nsList, err := nsClient.List(api.ListOptions{})
if err == nil { if err == nil {
for _, ns := range nsList.Items { for _, ns := range nsList.Items {
if strings.Contains(ns.Name, config.f.BaseName) && ns.Name != config.ns { if strings.Contains(ns.Name, config.f.BaseName) && ns.Name != config.Namespace {
nsClient.Delete(ns.Name) nsClient.Delete(ns.Name)
} }
} }
@ -495,17 +498,17 @@ func (config *NetworkingTestConfig) createNetProxyPods(podName string, selector
return runningPods return runningPods
} }
func (config *NetworkingTestConfig) deleteNetProxyPod() { func (config *NetworkingTestConfig) DeleteNetProxyPod() {
pod := config.endpointPods[0] pod := config.EndpointPods[0]
config.getPodClient().Delete(pod.Name, api.NewDeleteOptions(0)) config.getPodClient().Delete(pod.Name, api.NewDeleteOptions(0))
config.endpointPods = config.endpointPods[1:] config.EndpointPods = config.EndpointPods[1:]
// wait for pod being deleted. // wait for pod being deleted.
err := framework.WaitForPodToDisappear(config.f.Client, config.ns, pod.Name, labels.Everything(), time.Second, wait.ForeverTestTimeout) err := framework.WaitForPodToDisappear(config.f.Client, config.Namespace, pod.Name, labels.Everything(), time.Second, wait.ForeverTestTimeout)
if err != nil { if err != nil {
framework.Failf("Failed to delete %s pod: %v", pod.Name, err) framework.Failf("Failed to delete %s pod: %v", pod.Name, err)
} }
// wait for endpoint being removed. // wait for endpoint being removed.
err = framework.WaitForServiceEndpointsNum(config.f.Client, config.ns, nodePortServiceName, len(config.endpointPods), time.Second, wait.ForeverTestTimeout) err = framework.WaitForServiceEndpointsNum(config.f.Client, config.Namespace, nodePortServiceName, len(config.EndpointPods), time.Second, wait.ForeverTestTimeout)
if err != nil { if err != nil {
framework.Failf("Failed to remove endpoint from service: %s", nodePortServiceName) framework.Failf("Failed to remove endpoint from service: %s", nodePortServiceName)
} }
@ -514,19 +517,18 @@ func (config *NetworkingTestConfig) deleteNetProxyPod() {
} }
func (config *NetworkingTestConfig) createPod(pod *api.Pod) *api.Pod { func (config *NetworkingTestConfig) createPod(pod *api.Pod) *api.Pod {
createdPod, err := config.getPodClient().Create(pod) return config.getPodClient().Create(pod)
if err != nil {
framework.Failf("Failed to create %s pod: %v", pod.Name, err)
}
return createdPod
} }
func (config *NetworkingTestConfig) getPodClient() client.PodInterface { func (config *NetworkingTestConfig) getPodClient() *framework.PodClient {
return config.f.Client.Pods(config.ns) if config.podClient == nil {
config.podClient = config.f.PodClient()
}
return config.podClient
} }
func (config *NetworkingTestConfig) getServiceClient() client.ServiceInterface { func (config *NetworkingTestConfig) getServiceClient() client.ServiceInterface {
return config.f.Client.Services(config.ns) return config.f.Client.Services(config.Namespace)
} }
func (config *NetworkingTestConfig) getNamespacesClient() client.NamespaceInterface { func (config *NetworkingTestConfig) getNamespacesClient() client.NamespaceInterface {