Merge pull request #84261 from oomichi/move-to-e2e-network-framework

Move funcs of networking_utils to e2e network
This commit is contained in:
Kubernetes Prow Robot 2019-10-24 00:47:08 -07:00 committed by GitHub
commit 3325cbb280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 71 deletions

View File

@ -683,25 +683,6 @@ func (config *NetworkingTestConfig) getServiceClient() coreclientset.ServiceInte
return config.f.ClientSet.CoreV1().Services(config.Namespace) return config.f.ClientSet.CoreV1().Services(config.Namespace)
} }
// CheckReachabilityFromPod checks reachability from the specified pod.
func CheckReachabilityFromPod(expectToBeReachable bool, timeout time.Duration, namespace, pod, target string) {
cmd := fmt.Sprintf("wget -T 5 -qO- %q", target)
err := wait.PollImmediate(Poll, timeout, func() (bool, error) {
_, err := RunHostCmd(namespace, pod, cmd)
if expectToBeReachable && err != nil {
Logf("Expect target to be reachable. But got err: %v. Retry until timeout", err)
return false, nil
}
if !expectToBeReachable && err == nil {
Logf("Expect target NOT to be reachable. But it is reachable. Retry until timeout")
return false, nil
}
return true, nil
})
ExpectNoError(err)
}
// HTTPPokeParams is a struct for HTTP poke parameters. // HTTPPokeParams is a struct for HTTP poke parameters.
type HTTPPokeParams struct { type HTTPPokeParams struct {
Timeout time.Duration Timeout time.Duration
@ -979,49 +960,6 @@ func PokeUDP(host string, port int, request string, params *UDPPokeParams) UDPPo
return ret return ret
} }
// TestHitNodesFromOutside checkes HTTP connectivity from outside.
func TestHitNodesFromOutside(externalIP string, httpPort int32, timeout time.Duration, expectedHosts sets.String) error {
return TestHitNodesFromOutsideWithCount(externalIP, httpPort, timeout, expectedHosts, 1)
}
// TestHitNodesFromOutsideWithCount checkes HTTP connectivity from outside with count.
func TestHitNodesFromOutsideWithCount(externalIP string, httpPort int32, timeout time.Duration, expectedHosts sets.String,
countToSucceed int) error {
Logf("Waiting up to %v for satisfying expectedHosts for %v times", timeout, countToSucceed)
hittedHosts := sets.NewString()
count := 0
condition := func() (bool, error) {
result := PokeHTTP(externalIP, int(httpPort), "/hostname", &HTTPPokeParams{Timeout: 1 * time.Second})
if result.Status != HTTPSuccess {
return false, nil
}
hittedHost := strings.TrimSpace(string(result.Body))
if !expectedHosts.Has(hittedHost) {
Logf("Error hitting unexpected host: %v, reset counter: %v", hittedHost, count)
count = 0
return false, nil
}
if !hittedHosts.Has(hittedHost) {
hittedHosts.Insert(hittedHost)
Logf("Missing %+v, got %+v", expectedHosts.Difference(hittedHosts), hittedHosts)
}
if hittedHosts.Equal(expectedHosts) {
count++
if count >= countToSucceed {
return true, nil
}
}
return false, nil
}
if err := wait.Poll(time.Second, timeout, condition); err != nil {
return fmt.Errorf("error waiting for expectedHosts: %v, hittedHosts: %v, count: %v, expected count: %v",
expectedHosts, hittedHosts, count, countToSucceed)
}
return nil
}
// TestUnderTemporaryNetworkFailure blocks outgoing network traffic on 'node'. Then runs testFunc and returns its status. // TestUnderTemporaryNetworkFailure blocks outgoing network traffic on 'node'. Then runs testFunc and returns its status.
// At the end (even in case of errors), the network traffic is brought back to normal. // At the end (even in case of errors), the network traffic is brought back to normal.
// This function executes commands on a node so it will work only for some // This function executes commands on a node so it will work only for some

View File

@ -18,10 +18,12 @@ package network
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
cloudprovider "k8s.io/cloud-provider" cloudprovider "k8s.io/cloud-provider"
"k8s.io/kubernetes/pkg/master/ports" "k8s.io/kubernetes/pkg/master/ports"
@ -160,7 +162,7 @@ var _ = SIGDescribe("Firewall rule", func() {
// Send requests from outside of the cluster because internal traffic is whitelisted // Send requests from outside of the cluster because internal traffic is whitelisted
ginkgo.By("Accessing the external service ip from outside, all non-master nodes should be reached") ginkgo.By("Accessing the external service ip from outside, all non-master nodes should be reached")
err = framework.TestHitNodesFromOutside(svcExternalIP, firewallTestHTTPPort, e2eservice.LoadBalancerPropagationTimeoutDefault, nodesSet) err = testHitNodesFromOutside(svcExternalIP, firewallTestHTTPPort, e2eservice.LoadBalancerPropagationTimeoutDefault, nodesSet)
framework.ExpectNoError(err) framework.ExpectNoError(err)
// Check if there are overlapping tags on the firewall that extend beyond just the vms in our cluster // Check if there are overlapping tags on the firewall that extend beyond just the vms in our cluster
@ -181,12 +183,12 @@ var _ = SIGDescribe("Firewall rule", func() {
nodesSet.Insert(nodesNames[0]) nodesSet.Insert(nodesNames[0])
gce.SetInstanceTags(cloudConfig, nodesNames[0], zone, removedTags) gce.SetInstanceTags(cloudConfig, nodesNames[0], zone, removedTags)
// Make sure traffic is recovered before exit // Make sure traffic is recovered before exit
err = framework.TestHitNodesFromOutside(svcExternalIP, firewallTestHTTPPort, e2eservice.LoadBalancerPropagationTimeoutDefault, nodesSet) err = testHitNodesFromOutside(svcExternalIP, firewallTestHTTPPort, e2eservice.LoadBalancerPropagationTimeoutDefault, nodesSet)
framework.ExpectNoError(err) framework.ExpectNoError(err)
}() }()
ginkgo.By("Accessing serivce through the external ip and examine got no response from the node without tags") ginkgo.By("Accessing serivce through the external ip and examine got no response from the node without tags")
err = framework.TestHitNodesFromOutsideWithCount(svcExternalIP, firewallTestHTTPPort, e2eservice.LoadBalancerPropagationTimeoutDefault, nodesSet, 15) err = testHitNodesFromOutsideWithCount(svcExternalIP, firewallTestHTTPPort, e2eservice.LoadBalancerPropagationTimeoutDefault, nodesSet, 15)
framework.ExpectNoError(err) framework.ExpectNoError(err)
}) })
@ -228,3 +230,46 @@ func assertNotReachableHTTPTimeout(ip string, port int, timeout time.Duration) {
framework.Failf("Was unexpectedly able to reach %s:%d", ip, port) framework.Failf("Was unexpectedly able to reach %s:%d", ip, port)
} }
} }
// testHitNodesFromOutside checkes HTTP connectivity from outside.
func testHitNodesFromOutside(externalIP string, httpPort int32, timeout time.Duration, expectedHosts sets.String) error {
return testHitNodesFromOutsideWithCount(externalIP, httpPort, timeout, expectedHosts, 1)
}
// testHitNodesFromOutsideWithCount checkes HTTP connectivity from outside with count.
func testHitNodesFromOutsideWithCount(externalIP string, httpPort int32, timeout time.Duration, expectedHosts sets.String,
countToSucceed int) error {
framework.Logf("Waiting up to %v for satisfying expectedHosts for %v times", timeout, countToSucceed)
hittedHosts := sets.NewString()
count := 0
condition := func() (bool, error) {
result := framework.PokeHTTP(externalIP, int(httpPort), "/hostname", &framework.HTTPPokeParams{Timeout: 1 * time.Second})
if result.Status != framework.HTTPSuccess {
return false, nil
}
hittedHost := strings.TrimSpace(string(result.Body))
if !expectedHosts.Has(hittedHost) {
framework.Logf("Error hitting unexpected host: %v, reset counter: %v", hittedHost, count)
count = 0
return false, nil
}
if !hittedHosts.Has(hittedHost) {
hittedHosts.Insert(hittedHost)
framework.Logf("Missing %+v, got %+v", expectedHosts.Difference(hittedHosts), hittedHosts)
}
if hittedHosts.Equal(expectedHosts) {
count++
if count >= countToSucceed {
return true, nil
}
}
return false, nil
}
if err := wait.Poll(time.Second, timeout, condition); err != nil {
return fmt.Errorf("error waiting for expectedHosts: %v, hittedHosts: %v, count: %v, expected count: %v",
expectedHosts, hittedHosts, count, countToSucceed)
}
return nil
}

View File

@ -1535,8 +1535,8 @@ var _ = SIGDescribe("Services", func() {
svcIP := e2eservice.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0]) svcIP := e2eservice.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0])
// Wait longer as this is our first request after creation. We can't check using a separate method, // Wait longer as this is our first request after creation. We can't check using a separate method,
// because the LB should only be reachable from the "accept" pod // because the LB should only be reachable from the "accept" pod
framework.CheckReachabilityFromPod(true, loadBalancerLagTimeout, namespace, acceptPod.Name, svcIP) checkReachabilityFromPod(true, loadBalancerLagTimeout, namespace, acceptPod.Name, svcIP)
framework.CheckReachabilityFromPod(false, normalReachabilityTimeout, namespace, dropPod.Name, svcIP) checkReachabilityFromPod(false, normalReachabilityTimeout, namespace, dropPod.Name, svcIP)
// Make sure dropPod is running. There are certain chances that the pod might be teminated due to unexpected reasons. dropPod, err = cs.CoreV1().Pods(namespace).Get(dropPod.Name, metav1.GetOptions{}) // Make sure dropPod is running. There are certain chances that the pod might be teminated due to unexpected reasons. dropPod, err = cs.CoreV1().Pods(namespace).Get(dropPod.Name, metav1.GetOptions{})
dropPod, err = cs.CoreV1().Pods(namespace).Get(dropPod.Name, metav1.GetOptions{}) dropPod, err = cs.CoreV1().Pods(namespace).Get(dropPod.Name, metav1.GetOptions{})
@ -1550,16 +1550,16 @@ var _ = SIGDescribe("Services", func() {
svc.Spec.LoadBalancerSourceRanges = []string{dropPod.Status.PodIP + "/32"} svc.Spec.LoadBalancerSourceRanges = []string{dropPod.Status.PodIP + "/32"}
}) })
framework.ExpectNoError(err) framework.ExpectNoError(err)
framework.CheckReachabilityFromPod(false, normalReachabilityTimeout, namespace, acceptPod.Name, svcIP) checkReachabilityFromPod(false, normalReachabilityTimeout, namespace, acceptPod.Name, svcIP)
framework.CheckReachabilityFromPod(true, normalReachabilityTimeout, namespace, dropPod.Name, svcIP) checkReachabilityFromPod(true, normalReachabilityTimeout, namespace, dropPod.Name, svcIP)
ginkgo.By("Delete LoadBalancerSourceRange field and check reachability") ginkgo.By("Delete LoadBalancerSourceRange field and check reachability")
_, err = jig.UpdateService(func(svc *v1.Service) { _, err = jig.UpdateService(func(svc *v1.Service) {
svc.Spec.LoadBalancerSourceRanges = nil svc.Spec.LoadBalancerSourceRanges = nil
}) })
framework.ExpectNoError(err) framework.ExpectNoError(err)
framework.CheckReachabilityFromPod(true, normalReachabilityTimeout, namespace, acceptPod.Name, svcIP) checkReachabilityFromPod(true, normalReachabilityTimeout, namespace, acceptPod.Name, svcIP)
framework.CheckReachabilityFromPod(true, normalReachabilityTimeout, namespace, dropPod.Name, svcIP) checkReachabilityFromPod(true, normalReachabilityTimeout, namespace, dropPod.Name, svcIP)
}) })
// TODO: Get rid of [DisabledForLargeClusters] tag when issue #56138 is fixed. // TODO: Get rid of [DisabledForLargeClusters] tag when issue #56138 is fixed.
@ -2572,3 +2572,22 @@ func launchHostExecPod(client clientset.Interface, ns, name string) *v1.Pod {
framework.ExpectNoError(err) framework.ExpectNoError(err)
return pod return pod
} }
// checkReachabilityFromPod checks reachability from the specified pod.
func checkReachabilityFromPod(expectToBeReachable bool, timeout time.Duration, namespace, pod, target string) {
cmd := fmt.Sprintf("wget -T 5 -qO- %q", target)
err := wait.PollImmediate(framework.Poll, timeout, func() (bool, error) {
_, err := framework.RunHostCmd(namespace, pod, cmd)
if expectToBeReachable && err != nil {
framework.Logf("Expect target to be reachable. But got err: %v. Retry until timeout", err)
return false, nil
}
if !expectToBeReachable && err == nil {
framework.Logf("Expect target NOT to be reachable. But it is reachable. Retry until timeout")
return false, nil
}
return true, nil
})
framework.ExpectNoError(err)
}