// dialFromNode executes a tcp or udp request based on protocol via kubectl exec // in a test container running with host networking. // - 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 // at least once. // - maxTries is the maximum number of curl attempts. If this many attempts pass // and we don't see all expected endpoints, the test fails. // 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 // 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) { var cmd string if protocol == "udp" { cmd = fmt.Sprintf("echo 'hostName' | timeout -t 3 nc -w 1 -u %s %d", targetIP, targetPort) } else { cmd = fmt.Sprintf("curl -q -s --connect-timeout 1 http://%s:%d/hostName", targetIP, targetPort) } // TODO: This simply tells us that we can reach the endpoints. Check that // the probability of hitting a specific endpoint is roughly the same as // hitting any other. eps := sets.NewString() filterCmd := fmt.Sprintf("%s | grep -v '^\\s*$'", cmd) for i := 0; i < maxTries; i++ { stdout, err := framework.RunHostCmd(config.ns, config.hostTestContainerPod.Name, filterCmd) if err != nil { // 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 { eps.Insert(strings.TrimSpace(stdout)) } framework.Logf("Waiting for %+v endpoints, got endpoints %+v", expectedEps.Difference(eps), eps) // Check against i+1 so we exit if minTries == maxTries. if (eps.Equal(expectedEps) || eps.Len() == 0 && expectedEps.Len() == 0) && i+1 >= minTries { return } } config.diagnoseMissingEndpoints(eps) framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", minTries, cmd, eps, expectedEps) }
func waitForRouterOKResponseExec(ns, execPodName, url, host string, timeoutSeconds int) error { cmd := fmt.Sprintf(` set -e for i in $(seq 1 %d); do code=$( curl -s -o /dev/null -w '%%{http_code}\n' --header 'Host: %s' %q ) echo $code if [[ $code -eq 200 ]]; then exit 0 fi if [[ $code -ne 503 ]]; then exit 1 fi sleep 1 done `, timeoutSeconds, host, url) output, err := e2e.RunHostCmd(ns, execPodName, cmd) if err != nil { return fmt.Errorf("host command failed: %v\n%s", err, output) } lines := strings.Split(strings.TrimSpace(output), "\n") if lines[len(lines)-1] != "200" { return fmt.Errorf("last response from server was not 200:\n%s", output) } return nil }
func (p *petTester) execInPets(ps *apps.PetSet, cmd string) { podList := p.getPodList(ps) for _, pet := range podList.Items { stdout, err := framework.RunHostCmd(pet.Namespace, pet.Name, cmd) ExpectNoError(err) framework.Logf("stdout %v on %v: %v", cmd, pet.Name, stdout) } }
func getAuthenticatedRouteURLViaPod(ns, execPodName, url, host, user, pass string) (string, error) { cmd := fmt.Sprintf("curl -s -u %s:%s --header 'Host: %s' %q", user, pass, host, url) output, err := e2e.RunHostCmd(ns, execPodName, cmd) if err != nil { return "", fmt.Errorf("host command failed: %v\n%s", err, output) } return output, nil }
func (p *statefulSetTester) execInPets(ps *apps.StatefulSet, cmd string) error { podList := p.getPodList(ps) for _, pet := range podList.Items { stdout, err := framework.RunHostCmd(pet.Namespace, pet.Name, cmd) framework.Logf("stdout of %v on %v: %v", cmd, pet.Name, stdout) if err != nil { return err } } return nil }
func (s *statefulSetTester) execInStatefulPods(ss *apps.StatefulSet, cmd string) error { podList := s.getPodList(ss) for _, statefulPod := range podList.Items { stdout, err := framework.RunHostCmd(statefulPod.Namespace, statefulPod.Name, cmd) framework.Logf("stdout of %v on %v: %v", cmd, statefulPod.Name, stdout) if err != nil { return err } } return nil }
func expectRouteStatusCodeExec(ns, execPodName, url, host string, statusCode int) error { cmd := fmt.Sprintf("curl -s -o /dev/null -w '%%{http_code}' --header 'Host: %s' %q", host, url) output, err := e2e.RunHostCmd(ns, execPodName, cmd) if err != nil { return fmt.Errorf("host command failed: %v\n%s", err, output) } if output != strconv.Itoa(statusCode) { return fmt.Errorf("last response from server was not %d: %s", statusCode, output) } return nil }
func (p *statefulSetTester) checkHostname(ps *apps.StatefulSet) error { cmd := "printf $(hostname)" podList := p.getPodList(ps) for _, pet := range podList.Items { hostname, err := framework.RunHostCmd(pet.Namespace, pet.Name, cmd) if err != nil { return err } if hostname != pet.Name { return fmt.Errorf("unexpected hostname (%s) and stateful pod name (%s) not equal", hostname, pet.Name) } } return nil }
func expectRouteStatusCodeRepeatedExec(ns, execPodName, url, host string, statusCode int, times int) error { cmd := fmt.Sprintf(` set -e for i in $(seq 1 %d); do code=$( curl -s -o /dev/null -w '%%{http_code}\n' --header 'Host: %s' %q ) echo $code if [[ $code -ne %d ]]; then exit 1 fi done `, times, host, url, statusCode) output, err := e2e.RunHostCmd(ns, execPodName, cmd) if err != nil { return fmt.Errorf("host command failed: %v\n%s", err, output) } return nil }
// 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 // argument in the url. // - 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 // at least once. // - maxTries is the maximum number of curl attempts. If this many attempts pass // and we don't see all expected endpoints, the test fails. // - expectedEps is the set of endpointnames to wait for. Typically this is also // the hostname reported by each pod in the service through /hostName. // 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 // 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) { cmd := fmt.Sprintf("curl -q -s 'http://%s:%d/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'", containerIP, containerHttpPort, protocol, targetIP, targetPort) eps := sets.NewString() for i := 0; i < maxTries; i++ { stdout, err := framework.RunHostCmd(config.ns, config.hostTestContainerPod.Name, cmd) if err != nil { // 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", cmd, err) } else { 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) } } } framework.Logf("Waiting for endpoints: %v", expectedEps.Difference(eps)) // Check against i+1 so we exit if minTries == maxTries. if (eps.Equal(expectedEps) || eps.Len() == 0 && expectedEps.Len() == 0) && i+1 >= minTries { return } } config.diagnoseMissingEndpoints(eps) framework.Failf("Failed to find expected endpoints:\nTries %d\nCommand %v\nretrieved %v\nexpected %v\n", minTries, cmd, eps, expectedEps) }