
This is the result of automatically editing source files like this: go install golang.org/x/tools/cmd/goimports@latest find ./test/e2e* -name "*.go" | xargs env PATH=$GOPATH/bin:$PATH ./e2e-framework-sed.sh with e2e-framework-sed.sh containing this: sed -i \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecCommandInContainer(/e2epod.ExecCommandInContainer(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecCommandInContainerWithFullOutput(/e2epod.ExecCommandInContainerWithFullOutput(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecShellInContainer(/e2epod.ExecShellInContainer(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecShellInPod(/e2epod.ExecShellInPod(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecShellInPodWithFullOutput(/e2epod.ExecShellInPodWithFullOutput(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecWithOptions(/e2epod.ExecWithOptions(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.MatchContainerOutput(/e2eoutput.MatchContainerOutput(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.PodClient(/e2epod.NewPodClient(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.PodClientNS(/e2epod.PodClientNS(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.TestContainerOutput(/e2eoutput.TestContainerOutput(\1, /" \ -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.TestContainerOutputRegexp(/e2eoutput.TestContainerOutputRegexp(\1, /" \ -e "s/framework.AddOrUpdateLabelOnNode\b/e2enode.AddOrUpdateLabelOnNode/" \ -e "s/framework.AllNodes\b/e2edebug.AllNodes/" \ -e "s/framework.AllNodesReady\b/e2enode.AllNodesReady/" \ -e "s/framework.ContainerResourceGatherer\b/e2edebug.ContainerResourceGatherer/" \ -e "s/framework.ContainerResourceUsage\b/e2edebug.ContainerResourceUsage/" \ -e "s/framework.CreateEmptyFileOnPod\b/e2eoutput.CreateEmptyFileOnPod/" \ -e "s/framework.DefaultPodDeletionTimeout\b/e2epod.DefaultPodDeletionTimeout/" \ -e "s/framework.DumpAllNamespaceInfo\b/e2edebug.DumpAllNamespaceInfo/" \ -e "s/framework.DumpDebugInfo\b/e2eoutput.DumpDebugInfo/" \ -e "s/framework.DumpNodeDebugInfo\b/e2edebug.DumpNodeDebugInfo/" \ -e "s/framework.EtcdUpgrade\b/e2eproviders.EtcdUpgrade/" \ -e "s/framework.EventsLister\b/e2edebug.EventsLister/" \ -e "s/framework.ExecOptions\b/e2epod.ExecOptions/" \ -e "s/framework.ExpectNodeHasLabel\b/e2enode.ExpectNodeHasLabel/" \ -e "s/framework.ExpectNodeHasTaint\b/e2enode.ExpectNodeHasTaint/" \ -e "s/framework.GCEUpgradeScript\b/e2eproviders.GCEUpgradeScript/" \ -e "s/framework.ImagePrePullList\b/e2epod.ImagePrePullList/" \ -e "s/framework.KubectlBuilder\b/e2ekubectl.KubectlBuilder/" \ -e "s/framework.LocationParamGKE\b/e2eproviders.LocationParamGKE/" \ -e "s/framework.LogSizeDataTimeseries\b/e2edebug.LogSizeDataTimeseries/" \ -e "s/framework.LogSizeGatherer\b/e2edebug.LogSizeGatherer/" \ -e "s/framework.LogsSizeData\b/e2edebug.LogsSizeData/" \ -e "s/framework.LogsSizeDataSummary\b/e2edebug.LogsSizeDataSummary/" \ -e "s/framework.LogsSizeVerifier\b/e2edebug.LogsSizeVerifier/" \ -e "s/framework.LookForStringInLog\b/e2eoutput.LookForStringInLog/" \ -e "s/framework.LookForStringInPodExec\b/e2eoutput.LookForStringInPodExec/" \ -e "s/framework.LookForStringInPodExecToContainer\b/e2eoutput.LookForStringInPodExecToContainer/" \ -e "s/framework.MasterAndDNSNodes\b/e2edebug.MasterAndDNSNodes/" \ -e "s/framework.MasterNodes\b/e2edebug.MasterNodes/" \ -e "s/framework.MasterUpgradeGKE\b/e2eproviders.MasterUpgradeGKE/" \ -e "s/framework.NewKubectlCommand\b/e2ekubectl.NewKubectlCommand/" \ -e "s/framework.NewLogsVerifier\b/e2edebug.NewLogsVerifier/" \ -e "s/framework.NewNodeKiller\b/e2enode.NewNodeKiller/" \ -e "s/framework.NewResourceUsageGatherer\b/e2edebug.NewResourceUsageGatherer/" \ -e "s/framework.NodeHasTaint\b/e2enode.NodeHasTaint/" \ -e "s/framework.NodeKiller\b/e2enode.NodeKiller/" \ -e "s/framework.NodesSet\b/e2edebug.NodesSet/" \ -e "s/framework.PodClient\b/e2epod.PodClient/" \ -e "s/framework.RemoveLabelOffNode\b/e2enode.RemoveLabelOffNode/" \ -e "s/framework.ResourceConstraint\b/e2edebug.ResourceConstraint/" \ -e "s/framework.ResourceGathererOptions\b/e2edebug.ResourceGathererOptions/" \ -e "s/framework.ResourceUsagePerContainer\b/e2edebug.ResourceUsagePerContainer/" \ -e "s/framework.ResourceUsageSummary\b/e2edebug.ResourceUsageSummary/" \ -e "s/framework.RunHostCmd\b/e2eoutput.RunHostCmd/" \ -e "s/framework.RunHostCmdOrDie\b/e2eoutput.RunHostCmdOrDie/" \ -e "s/framework.RunHostCmdWithFullOutput\b/e2eoutput.RunHostCmdWithFullOutput/" \ -e "s/framework.RunHostCmdWithRetries\b/e2eoutput.RunHostCmdWithRetries/" \ -e "s/framework.RunKubectl\b/e2ekubectl.RunKubectl/" \ -e "s/framework.RunKubectlInput\b/e2ekubectl.RunKubectlInput/" \ -e "s/framework.RunKubectlOrDie\b/e2ekubectl.RunKubectlOrDie/" \ -e "s/framework.RunKubectlOrDieInput\b/e2ekubectl.RunKubectlOrDieInput/" \ -e "s/framework.RunKubectlWithFullOutput\b/e2ekubectl.RunKubectlWithFullOutput/" \ -e "s/framework.RunKubemciCmd\b/e2ekubectl.RunKubemciCmd/" \ -e "s/framework.RunKubemciWithKubeconfig\b/e2ekubectl.RunKubemciWithKubeconfig/" \ -e "s/framework.SingleContainerSummary\b/e2edebug.SingleContainerSummary/" \ -e "s/framework.SingleLogSummary\b/e2edebug.SingleLogSummary/" \ -e "s/framework.TimestampedSize\b/e2edebug.TimestampedSize/" \ -e "s/framework.WaitForAllNodesSchedulable\b/e2enode.WaitForAllNodesSchedulable/" \ -e "s/framework.WaitForSSHTunnels\b/e2enode.WaitForSSHTunnels/" \ -e "s/framework.WorkItem\b/e2edebug.WorkItem/" \ "$@" for i in "$@"; do # Import all sub packages and let goimports figure out which of those # are redundant (= already imported) or not needed. sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2edebug "k8s.io/kubernetes/test/e2e/framework/debug"' "$i" sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"' "$i" sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2enode "k8s.io/kubernetes/test/e2e/framework/node"' "$i" sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"' "$i" sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2epod "k8s.io/kubernetes/test/e2e/framework/pod"' "$i" sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2eproviders "k8s.io/kubernetes/test/e2e/framework/providers"' "$i" goimports -w "$i" done
218 lines
7.5 KiB
Go
218 lines
7.5 KiB
Go
/*
|
|
Copyright 2014 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 network
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
v1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
"k8s.io/kubernetes/test/e2e/framework"
|
|
e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
|
|
e2enetwork "k8s.io/kubernetes/test/e2e/framework/network"
|
|
e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
|
|
"k8s.io/kubernetes/test/e2e/storage/utils"
|
|
)
|
|
|
|
// secondNodePortSvcName is the name of the secondary node port service
|
|
const secondNodePortSvcName = "second-node-port-service"
|
|
|
|
// GetHTTPContent returns the content of the given url by HTTP.
|
|
func GetHTTPContent(host string, port int, timeout time.Duration, url string) (string, error) {
|
|
var body bytes.Buffer
|
|
pollErr := wait.PollImmediate(framework.Poll, timeout, func() (bool, error) {
|
|
result := e2enetwork.PokeHTTP(host, port, url, nil)
|
|
if result.Status == e2enetwork.HTTPSuccess {
|
|
body.Write(result.Body)
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
})
|
|
if pollErr != nil {
|
|
framework.Logf("Could not reach HTTP service through %v:%v%v after %v: %v", host, port, url, timeout, pollErr)
|
|
}
|
|
return body.String(), pollErr
|
|
}
|
|
|
|
// GetHTTPContentFromTestContainer returns the content of the given url by HTTP via a test container.
|
|
func GetHTTPContentFromTestContainer(config *e2enetwork.NetworkingTestConfig, host string, port int, timeout time.Duration, dialCmd string) (string, error) {
|
|
var body string
|
|
pollFn := func() (bool, error) {
|
|
resp, err := config.GetResponseFromTestContainer("http", dialCmd, host, port)
|
|
if err != nil || len(resp.Errors) > 0 || len(resp.Responses) == 0 {
|
|
return false, nil
|
|
}
|
|
body = resp.Responses[0]
|
|
return true, nil
|
|
}
|
|
if pollErr := wait.PollImmediate(framework.Poll, timeout, pollFn); pollErr != nil {
|
|
return "", pollErr
|
|
}
|
|
return body, nil
|
|
}
|
|
|
|
// DescribeSvc logs the output of kubectl describe svc for the given namespace
|
|
func DescribeSvc(ns string) {
|
|
framework.Logf("\nOutput of kubectl describe svc:\n")
|
|
desc, _ := e2ekubectl.RunKubectl(
|
|
ns, "describe", "svc", fmt.Sprintf("--namespace=%v", ns))
|
|
framework.Logf(desc)
|
|
}
|
|
|
|
// CheckSCTPModuleLoadedOnNodes checks whether any node on the list has the
|
|
// sctp.ko module loaded
|
|
// For security reasons, and also to allow clusters to use userspace SCTP implementations,
|
|
// we require that just creating an SCTP Pod/Service/NetworkPolicy must not do anything
|
|
// that would cause the sctp kernel module to be loaded.
|
|
func CheckSCTPModuleLoadedOnNodes(f *framework.Framework, nodes *v1.NodeList) bool {
|
|
hostExec := utils.NewHostExec(f)
|
|
defer hostExec.Cleanup()
|
|
re := regexp.MustCompile(`^\s*sctp\s+`)
|
|
cmd := "lsmod | grep sctp"
|
|
for _, node := range nodes.Items {
|
|
framework.Logf("Executing cmd %q on node %v", cmd, node.Name)
|
|
result, err := hostExec.IssueCommandWithResult(cmd, &node)
|
|
if err != nil {
|
|
framework.Logf("sctp module is not loaded or error occurred while executing command %s on node: %v", cmd, err)
|
|
}
|
|
for _, line := range strings.Split(result, "\n") {
|
|
if found := re.Find([]byte(line)); found != nil {
|
|
framework.Logf("the sctp module is loaded on node: %v", node.Name)
|
|
return true
|
|
}
|
|
}
|
|
framework.Logf("the sctp module is not loaded on node: %v", node.Name)
|
|
}
|
|
return false
|
|
}
|
|
|
|
// execSourceIPTest executes curl to access "/clientip" endpoint on target address
|
|
// from given Pod to check if source ip is preserved.
|
|
func execSourceIPTest(sourcePod v1.Pod, targetAddr string) (string, string) {
|
|
var (
|
|
err error
|
|
stdout string
|
|
timeout = 2 * time.Minute
|
|
)
|
|
|
|
framework.Logf("Waiting up to %v to get response from %s", timeout, targetAddr)
|
|
cmd := fmt.Sprintf(`curl -q -s --connect-timeout 30 %s/clientip`, targetAddr)
|
|
for start := time.Now(); time.Since(start) < timeout; time.Sleep(2 * time.Second) {
|
|
stdout, err = e2eoutput.RunHostCmd(sourcePod.Namespace, sourcePod.Name, cmd)
|
|
if err != nil {
|
|
framework.Logf("got err: %v, retry until timeout", err)
|
|
continue
|
|
}
|
|
// Need to check output because it might omit in case of error.
|
|
if strings.TrimSpace(stdout) == "" {
|
|
framework.Logf("got empty stdout, retry until timeout")
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
|
|
framework.ExpectNoError(err)
|
|
|
|
// The stdout return from RunHostCmd is in this format: x.x.x.x:port or [xx:xx:xx::x]:port
|
|
host, _, err := net.SplitHostPort(stdout)
|
|
if err != nil {
|
|
// ginkgo.Fail the test if output format is unexpected.
|
|
framework.Failf("exec pod returned unexpected stdout: [%v]\n", stdout)
|
|
}
|
|
return sourcePod.Status.PodIP, host
|
|
}
|
|
|
|
// execHostnameTest executes curl to access "/hostname" endpoint on target address
|
|
// from given Pod to check the hostname of the target destination.
|
|
// It also converts FQDNs to hostnames, so if an FQDN is passed as
|
|
// targetHostname only the hostname part will be considered for comparison.
|
|
func execHostnameTest(sourcePod v1.Pod, targetAddr, targetHostname string) {
|
|
var (
|
|
err error
|
|
stdout string
|
|
timeout = 2 * time.Minute
|
|
)
|
|
|
|
framework.Logf("Waiting up to %v to get response from %s", timeout, targetAddr)
|
|
cmd := fmt.Sprintf(`curl -q -s --connect-timeout 30 %s/hostname`, targetAddr)
|
|
for start := time.Now(); time.Since(start) < timeout; time.Sleep(2 * time.Second) {
|
|
stdout, err = e2eoutput.RunHostCmd(sourcePod.Namespace, sourcePod.Name, cmd)
|
|
if err != nil {
|
|
framework.Logf("got err: %v, retry until timeout", err)
|
|
continue
|
|
}
|
|
// Need to check output because it might omit in case of error.
|
|
if strings.TrimSpace(stdout) == "" {
|
|
framework.Logf("got empty stdout, retry until timeout")
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
|
|
// Ensure we're comparing hostnames and not FQDNs
|
|
targetHostname = strings.Split(targetHostname, ".")[0]
|
|
hostname := strings.TrimSpace(strings.Split(stdout, ".")[0])
|
|
|
|
framework.ExpectNoError(err)
|
|
framework.ExpectEqual(hostname, targetHostname)
|
|
}
|
|
|
|
// createSecondNodePortService creates a service with the same selector as config.NodePortService and same HTTP Port
|
|
func createSecondNodePortService(f *framework.Framework, config *e2enetwork.NetworkingTestConfig) (*v1.Service, int) {
|
|
svc := &v1.Service{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: secondNodePortSvcName,
|
|
},
|
|
Spec: v1.ServiceSpec{
|
|
Type: v1.ServiceTypeNodePort,
|
|
Ports: []v1.ServicePort{
|
|
{
|
|
Port: e2enetwork.ClusterHTTPPort,
|
|
Name: "http",
|
|
Protocol: v1.ProtocolTCP,
|
|
TargetPort: intstr.FromInt(e2enetwork.EndpointHTTPPort),
|
|
},
|
|
},
|
|
Selector: config.NodePortService.Spec.Selector,
|
|
},
|
|
}
|
|
|
|
createdService := config.CreateService(svc)
|
|
|
|
err := framework.WaitForServiceEndpointsNum(f.ClientSet, config.Namespace, secondNodePortSvcName, len(config.EndpointPods), time.Second, wait.ForeverTestTimeout)
|
|
framework.ExpectNoError(err, "failed to validate endpoints for service %s in namespace: %s", secondNodePortSvcName, config.Namespace)
|
|
|
|
var httpPort int
|
|
for _, p := range createdService.Spec.Ports {
|
|
switch p.Protocol {
|
|
case v1.ProtocolTCP:
|
|
httpPort = int(p.NodePort)
|
|
default:
|
|
continue
|
|
}
|
|
}
|
|
|
|
return createdService, httpPort
|
|
}
|