123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- /*
- Copyright 2017 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 (
- "context"
- "fmt"
- "strings"
- "time"
- v1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/fields"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/util/intstr"
- "k8s.io/apimachinery/pkg/util/uuid"
- "k8s.io/apimachinery/pkg/util/wait"
- clientset "k8s.io/client-go/kubernetes"
- "k8s.io/kubernetes/test/e2e/framework"
- e2elog "k8s.io/kubernetes/test/e2e/framework/log"
- imageutils "k8s.io/kubernetes/test/utils/image"
- "github.com/onsi/ginkgo"
- "github.com/onsi/gomega"
- )
- type dnsTestCommon struct {
- f *framework.Framework
- c clientset.Interface
- ns string
- name string
- labels []string
- dnsPod *v1.Pod
- utilPod *v1.Pod
- utilService *v1.Service
- dnsServerPod *v1.Pod
- cm *v1.ConfigMap
- }
- func newDNSTestCommon() dnsTestCommon {
- return dnsTestCommon{
- f: framework.NewDefaultFramework("dns-config-map"),
- ns: "kube-system",
- }
- }
- func (t *dnsTestCommon) init() {
- ginkgo.By("Finding a DNS pod")
- label := labels.SelectorFromSet(labels.Set(map[string]string{"k8s-app": "kube-dns"}))
- options := metav1.ListOptions{LabelSelector: label.String()}
- namespace := "kube-system"
- pods, err := t.f.ClientSet.CoreV1().Pods(namespace).List(options)
- framework.ExpectNoError(err, "failed to list pods in namespace: %s", namespace)
- gomega.Expect(len(pods.Items)).Should(gomega.BeNumerically(">=", 1))
- t.dnsPod = &pods.Items[0]
- e2elog.Logf("Using DNS pod: %v", t.dnsPod.Name)
- if strings.Contains(t.dnsPod.Name, "coredns") {
- t.name = "coredns"
- } else {
- t.name = "kube-dns"
- }
- }
- func (t *dnsTestCommon) checkDNSRecord(name string, predicate func([]string) bool, timeout time.Duration) {
- t.checkDNSRecordFrom(name, predicate, "kube-dns", timeout)
- }
- func (t *dnsTestCommon) checkDNSRecordFrom(name string, predicate func([]string) bool, target string, timeout time.Duration) {
- var actual []string
- err := wait.PollImmediate(
- time.Duration(1)*time.Second,
- timeout,
- func() (bool, error) {
- actual = t.runDig(name, target)
- if predicate(actual) {
- return true, nil
- }
- return false, nil
- })
- if err != nil {
- framework.Failf("dig result did not match: %#v after %v",
- actual, timeout)
- }
- }
- // runDig queries for `dnsName`. Returns a list of responses.
- func (t *dnsTestCommon) runDig(dnsName, target string) []string {
- cmd := []string{"/usr/bin/dig", "+short"}
- switch target {
- case "coredns":
- cmd = append(cmd, "@"+t.dnsPod.Status.PodIP)
- case "kube-dns":
- cmd = append(cmd, "@"+t.dnsPod.Status.PodIP, "-p", "10053")
- case "ptr-record":
- cmd = append(cmd, "-x")
- case "cluster-dns":
- case "cluster-dns-ipv6":
- cmd = append(cmd, "AAAA")
- break
- default:
- panic(fmt.Errorf("invalid target: " + target))
- }
- cmd = append(cmd, dnsName)
- stdout, stderr, err := t.f.ExecWithOptions(framework.ExecOptions{
- Command: cmd,
- Namespace: t.f.Namespace.Name,
- PodName: t.utilPod.Name,
- ContainerName: "util",
- CaptureStdout: true,
- CaptureStderr: true,
- })
- e2elog.Logf("Running dig: %v, stdout: %q, stderr: %q, err: %v",
- cmd, stdout, stderr, err)
- if stdout == "" {
- return []string{}
- }
- return strings.Split(stdout, "\n")
- }
- func (t *dnsTestCommon) setConfigMap(cm *v1.ConfigMap) {
- if t.cm != nil {
- t.cm = cm
- }
- cm.ObjectMeta.Namespace = t.ns
- cm.ObjectMeta.Name = t.name
- options := metav1.ListOptions{
- FieldSelector: fields.Set{
- "metadata.namespace": t.ns,
- "metadata.name": t.name,
- }.AsSelector().String(),
- }
- cmList, err := t.c.CoreV1().ConfigMaps(t.ns).List(options)
- framework.ExpectNoError(err, "failed to list ConfigMaps in namespace: %s", t.ns)
- if len(cmList.Items) == 0 {
- ginkgo.By(fmt.Sprintf("Creating the ConfigMap (%s:%s) %+v", t.ns, t.name, *cm))
- _, err := t.c.CoreV1().ConfigMaps(t.ns).Create(cm)
- framework.ExpectNoError(err, "failed to create ConfigMap (%s:%s) %+v", t.ns, t.name, *cm)
- } else {
- ginkgo.By(fmt.Sprintf("Updating the ConfigMap (%s:%s) to %+v", t.ns, t.name, *cm))
- _, err := t.c.CoreV1().ConfigMaps(t.ns).Update(cm)
- framework.ExpectNoError(err, "failed to update ConfigMap (%s:%s) to %+v", t.ns, t.name, *cm)
- }
- }
- func (t *dnsTestCommon) fetchDNSConfigMapData() map[string]string {
- if t.name == "coredns" {
- pcm, err := t.c.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(t.name, metav1.GetOptions{})
- framework.ExpectNoError(err, "failed to get DNS ConfigMap: %s", t.name)
- return pcm.Data
- }
- return nil
- }
- func (t *dnsTestCommon) restoreDNSConfigMap(configMapData map[string]string) {
- if t.name == "coredns" {
- t.setConfigMap(&v1.ConfigMap{Data: configMapData})
- t.deleteCoreDNSPods()
- } else {
- t.c.CoreV1().ConfigMaps(t.ns).Delete(t.name, nil)
- }
- }
- func (t *dnsTestCommon) deleteConfigMap() {
- ginkgo.By(fmt.Sprintf("Deleting the ConfigMap (%s:%s)", t.ns, t.name))
- t.cm = nil
- err := t.c.CoreV1().ConfigMaps(t.ns).Delete(t.name, nil)
- framework.ExpectNoError(err, "failed to delete config map: %s", t.name)
- }
- func (t *dnsTestCommon) createUtilPodLabel(baseName string) {
- // Actual port # doesn't matter, just needs to exist.
- const servicePort = 10101
- t.utilPod = &v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- },
- ObjectMeta: metav1.ObjectMeta{
- Namespace: t.f.Namespace.Name,
- Labels: map[string]string{"app": baseName},
- GenerateName: baseName + "-",
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "util",
- Image: imageutils.GetE2EImage(imageutils.Dnsutils),
- Command: []string{"sleep", "10000"},
- Ports: []v1.ContainerPort{
- {ContainerPort: servicePort, Protocol: v1.ProtocolTCP},
- },
- },
- },
- },
- }
- var err error
- t.utilPod, err = t.c.CoreV1().Pods(t.f.Namespace.Name).Create(t.utilPod)
- framework.ExpectNoError(err, "failed to create pod: %v", t.utilPod)
- e2elog.Logf("Created pod %v", t.utilPod)
- err = t.f.WaitForPodRunning(t.utilPod.Name)
- framework.ExpectNoError(err, "pod failed to start running: %v", t.utilPod)
- t.utilService = &v1.Service{
- TypeMeta: metav1.TypeMeta{
- Kind: "Service",
- },
- ObjectMeta: metav1.ObjectMeta{
- Namespace: t.f.Namespace.Name,
- Name: baseName,
- },
- Spec: v1.ServiceSpec{
- Selector: map[string]string{"app": baseName},
- Ports: []v1.ServicePort{
- {
- Protocol: v1.ProtocolTCP,
- Port: servicePort,
- TargetPort: intstr.FromInt(servicePort),
- },
- },
- },
- }
- t.utilService, err = t.c.CoreV1().Services(t.f.Namespace.Name).Create(t.utilService)
- framework.ExpectNoError(err, "failed to create service: %s/%s", t.f.Namespace.Name, t.utilService.ObjectMeta.Name)
- e2elog.Logf("Created service %v", t.utilService)
- }
- func (t *dnsTestCommon) deleteUtilPod() {
- podClient := t.c.CoreV1().Pods(t.f.Namespace.Name)
- if err := podClient.Delete(t.utilPod.Name, metav1.NewDeleteOptions(0)); err != nil {
- e2elog.Logf("Delete of pod %v/%v failed: %v",
- t.utilPod.Namespace, t.utilPod.Name, err)
- }
- }
- // deleteCoreDNSPods manually deletes the CoreDNS pods to apply the changes to the ConfigMap.
- func (t *dnsTestCommon) deleteCoreDNSPods() {
- label := labels.SelectorFromSet(labels.Set(map[string]string{"k8s-app": "kube-dns"}))
- options := metav1.ListOptions{LabelSelector: label.String()}
- pods, err := t.f.ClientSet.CoreV1().Pods("kube-system").List(options)
- podClient := t.c.CoreV1().Pods(metav1.NamespaceSystem)
- for _, pod := range pods.Items {
- err = podClient.Delete(pod.Name, metav1.NewDeleteOptions(0))
- framework.ExpectNoError(err, "failed to delete pod: %s", pod.Name)
- }
- }
- func generateDNSServerPod(aRecords map[string]string) *v1.Pod {
- pod := &v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- },
- ObjectMeta: metav1.ObjectMeta{
- GenerateName: "e2e-dns-configmap-dns-server-",
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "dns",
- Image: imageutils.GetE2EImage(imageutils.Dnsutils),
- Command: []string{
- "/usr/sbin/dnsmasq",
- "-u", "root",
- "-k",
- "--log-facility", "-",
- "-q",
- },
- },
- },
- DNSPolicy: "Default",
- },
- }
- for name, ip := range aRecords {
- pod.Spec.Containers[0].Command = append(
- pod.Spec.Containers[0].Command,
- fmt.Sprintf("-A/%v/%v", name, ip))
- }
- return pod
- }
- func (t *dnsTestCommon) createDNSPodFromObj(pod *v1.Pod) {
- t.dnsServerPod = pod
- var err error
- t.dnsServerPod, err = t.c.CoreV1().Pods(t.f.Namespace.Name).Create(t.dnsServerPod)
- framework.ExpectNoError(err, "failed to create pod: %v", t.dnsServerPod)
- e2elog.Logf("Created pod %v", t.dnsServerPod)
- err = t.f.WaitForPodRunning(t.dnsServerPod.Name)
- framework.ExpectNoError(err, "pod failed to start running: %v", t.dnsServerPod)
- t.dnsServerPod, err = t.c.CoreV1().Pods(t.f.Namespace.Name).Get(
- t.dnsServerPod.Name, metav1.GetOptions{})
- framework.ExpectNoError(err, "failed to get pod: %s", t.dnsServerPod.Name)
- }
- func (t *dnsTestCommon) createDNSServer(aRecords map[string]string) {
- t.createDNSPodFromObj(generateDNSServerPod(aRecords))
- }
- func (t *dnsTestCommon) createDNSServerWithPtrRecord(isIPv6 bool) {
- pod := &v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- },
- ObjectMeta: metav1.ObjectMeta{
- GenerateName: "e2e-dns-configmap-dns-server-",
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "dns",
- Image: imageutils.GetE2EImage(imageutils.Dnsutils),
- Command: []string{
- "/usr/sbin/dnsmasq",
- "-u", "root",
- "-k",
- "--log-facility", "-",
- "-q",
- },
- },
- },
- DNSPolicy: "Default",
- },
- }
- if isIPv6 {
- pod.Spec.Containers[0].Command = append(
- pod.Spec.Containers[0].Command,
- fmt.Sprintf("--host-record=my.test,2001:db8::29"))
- } else {
- pod.Spec.Containers[0].Command = append(
- pod.Spec.Containers[0].Command,
- fmt.Sprintf("--host-record=my.test,192.0.2.123"))
- }
- t.createDNSPodFromObj(pod)
- }
- func (t *dnsTestCommon) deleteDNSServerPod() {
- podClient := t.c.CoreV1().Pods(t.f.Namespace.Name)
- if err := podClient.Delete(t.dnsServerPod.Name, metav1.NewDeleteOptions(0)); err != nil {
- e2elog.Logf("Delete of pod %v/%v failed: %v",
- t.utilPod.Namespace, t.dnsServerPod.Name, err)
- }
- }
- func createDNSPod(namespace, wheezyProbeCmd, jessieProbeCmd, podHostName, serviceName string) *v1.Pod {
- dnsPod := &v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- APIVersion: "v1",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: "dns-test-" + string(uuid.NewUUID()),
- Namespace: namespace,
- },
- Spec: v1.PodSpec{
- Volumes: []v1.Volume{
- {
- Name: "results",
- VolumeSource: v1.VolumeSource{
- EmptyDir: &v1.EmptyDirVolumeSource{},
- },
- },
- },
- Containers: []v1.Container{
- // TODO: Consider scraping logs instead of running a webserver.
- {
- Name: "webserver",
- Image: imageutils.GetE2EImage(imageutils.TestWebserver),
- Ports: []v1.ContainerPort{
- {
- Name: "http",
- ContainerPort: 80,
- },
- },
- VolumeMounts: []v1.VolumeMount{
- {
- Name: "results",
- MountPath: "/results",
- },
- },
- },
- {
- Name: "querier",
- Image: imageutils.GetE2EImage(imageutils.Dnsutils),
- Command: []string{"sh", "-c", wheezyProbeCmd},
- VolumeMounts: []v1.VolumeMount{
- {
- Name: "results",
- MountPath: "/results",
- },
- },
- },
- {
- Name: "jessie-querier",
- Image: imageutils.GetE2EImage(imageutils.JessieDnsutils),
- Command: []string{"sh", "-c", jessieProbeCmd},
- VolumeMounts: []v1.VolumeMount{
- {
- Name: "results",
- MountPath: "/results",
- },
- },
- },
- },
- },
- }
- dnsPod.Spec.Hostname = podHostName
- dnsPod.Spec.Subdomain = serviceName
- return dnsPod
- }
- func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookupIP string, fileNamePrefix, namespace, dnsDomain string) (string, []string) {
- fileNames := make([]string, 0, len(namesToResolve)*2)
- probeCmd := "for i in `seq 1 600`; do "
- for _, name := range namesToResolve {
- // Resolve by TCP and UDP DNS. Use $$(...) because $(...) is
- // expanded by kubernetes (though this won't expand so should
- // remain a literal, safe > sorry).
- lookup := "A"
- if strings.HasPrefix(name, "_") {
- lookup = "SRV"
- }
- fileName := fmt.Sprintf("%s_udp@%s", fileNamePrefix, name)
- fileNames = append(fileNames, fileName)
- probeCmd += fmt.Sprintf(`check="$$(dig +notcp +noall +answer +search %s %s)" && test -n "$$check" && echo OK > /results/%s;`, name, lookup, fileName)
- fileName = fmt.Sprintf("%s_tcp@%s", fileNamePrefix, name)
- fileNames = append(fileNames, fileName)
- probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search %s %s)" && test -n "$$check" && echo OK > /results/%s;`, name, lookup, fileName)
- }
- for _, name := range hostEntries {
- fileName := fmt.Sprintf("%s_hosts@%s", fileNamePrefix, name)
- fileNames = append(fileNames, fileName)
- probeCmd += fmt.Sprintf(`test -n "$$(getent hosts %s)" && echo OK > /results/%s;`, name, fileName)
- }
- podARecByUDPFileName := fmt.Sprintf("%s_udp@PodARecord", fileNamePrefix)
- podARecByTCPFileName := fmt.Sprintf("%s_tcp@PodARecord", fileNamePrefix)
- probeCmd += fmt.Sprintf(`podARec=$$(hostname -i| awk -F. '{print $$1"-"$$2"-"$$3"-"$$4".%s.pod.%s"}');`, namespace, dnsDomain)
- probeCmd += fmt.Sprintf(`check="$$(dig +notcp +noall +answer +search $${podARec} A)" && test -n "$$check" && echo OK > /results/%s;`, podARecByUDPFileName)
- probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search $${podARec} A)" && test -n "$$check" && echo OK > /results/%s;`, podARecByTCPFileName)
- fileNames = append(fileNames, podARecByUDPFileName)
- fileNames = append(fileNames, podARecByTCPFileName)
- if len(ptrLookupIP) > 0 {
- ptrLookup := fmt.Sprintf("%s.in-addr.arpa.", strings.Join(reverseArray(strings.Split(ptrLookupIP, ".")), "."))
- ptrRecByUDPFileName := fmt.Sprintf("%s_udp@PTR", ptrLookupIP)
- ptrRecByTCPFileName := fmt.Sprintf("%s_tcp@PTR", ptrLookupIP)
- probeCmd += fmt.Sprintf(`check="$$(dig +notcp +noall +answer +search %s PTR)" && test -n "$$check" && echo OK > /results/%s;`, ptrLookup, ptrRecByUDPFileName)
- probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search %s PTR)" && test -n "$$check" && echo OK > /results/%s;`, ptrLookup, ptrRecByTCPFileName)
- fileNames = append(fileNames, ptrRecByUDPFileName)
- fileNames = append(fileNames, ptrRecByTCPFileName)
- }
- probeCmd += "sleep 1; done"
- return probeCmd, fileNames
- }
- // createTargetedProbeCommand returns a command line that performs a DNS lookup for a specific record type
- func createTargetedProbeCommand(nameToResolve string, lookup string, fileNamePrefix string) (string, string) {
- fileName := fmt.Sprintf("%s_udp@%s", fileNamePrefix, nameToResolve)
- probeCmd := fmt.Sprintf("for i in `seq 1 30`; do dig +short %s %s > /results/%s; sleep 1; done", nameToResolve, lookup, fileName)
- return probeCmd, fileName
- }
- func assertFilesExist(fileNames []string, fileDir string, pod *v1.Pod, client clientset.Interface) {
- assertFilesContain(fileNames, fileDir, pod, client, false, "")
- }
- func assertFilesContain(fileNames []string, fileDir string, pod *v1.Pod, client clientset.Interface, check bool, expected string) {
- var failed []string
- framework.ExpectNoError(wait.PollImmediate(time.Second*5, time.Second*600, func() (bool, error) {
- failed = []string{}
- ctx, cancel := context.WithTimeout(context.Background(), framework.SingleCallTimeout)
- defer cancel()
- for _, fileName := range fileNames {
- contents, err := client.CoreV1().RESTClient().Get().
- Context(ctx).
- Namespace(pod.Namespace).
- Resource("pods").
- SubResource("proxy").
- Name(pod.Name).
- Suffix(fileDir, fileName).
- Do().Raw()
- if err != nil {
- if ctx.Err() != nil {
- framework.Failf("Unable to read %s from pod %s/%s: %v", fileName, pod.Namespace, pod.Name, err)
- } else {
- e2elog.Logf("Unable to read %s from pod %s/%s: %v", fileName, pod.Namespace, pod.Name, err)
- }
- failed = append(failed, fileName)
- } else if check && strings.TrimSpace(string(contents)) != expected {
- e2elog.Logf("File %s from pod %s/%s contains '%s' instead of '%s'", fileName, pod.Namespace, pod.Name, string(contents), expected)
- failed = append(failed, fileName)
- }
- }
- if len(failed) == 0 {
- return true, nil
- }
- e2elog.Logf("Lookups using %s/%s failed for: %v\n", pod.Namespace, pod.Name, failed)
- return false, nil
- }))
- gomega.Expect(len(failed)).To(gomega.Equal(0))
- }
- func validateDNSResults(f *framework.Framework, pod *v1.Pod, fileNames []string) {
- ginkgo.By("submitting the pod to kubernetes")
- podClient := f.ClientSet.CoreV1().Pods(f.Namespace.Name)
- defer func() {
- ginkgo.By("deleting the pod")
- defer ginkgo.GinkgoRecover()
- podClient.Delete(pod.Name, metav1.NewDeleteOptions(0))
- }()
- if _, err := podClient.Create(pod); err != nil {
- framework.Failf("ginkgo.Failed to create pod %s/%s: %v", pod.Namespace, pod.Name, err)
- }
- framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
- ginkgo.By("retrieving the pod")
- pod, err := podClient.Get(pod.Name, metav1.GetOptions{})
- if err != nil {
- framework.Failf("ginkgo.Failed to get pod %s/%s: %v", pod.Namespace, pod.Name, err)
- }
- // Try to find results for each expected name.
- ginkgo.By("looking for the results for each expected name from probers")
- assertFilesExist(fileNames, "results", pod, f.ClientSet)
- // TODO: probe from the host, too.
- e2elog.Logf("DNS probes using %s/%s succeeded\n", pod.Namespace, pod.Name)
- }
- func validateTargetedProbeOutput(f *framework.Framework, pod *v1.Pod, fileNames []string, value string) {
- ginkgo.By("submitting the pod to kubernetes")
- podClient := f.ClientSet.CoreV1().Pods(f.Namespace.Name)
- defer func() {
- ginkgo.By("deleting the pod")
- defer ginkgo.GinkgoRecover()
- podClient.Delete(pod.Name, metav1.NewDeleteOptions(0))
- }()
- if _, err := podClient.Create(pod); err != nil {
- framework.Failf("ginkgo.Failed to create pod %s/%s: %v", pod.Namespace, pod.Name, err)
- }
- framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
- ginkgo.By("retrieving the pod")
- pod, err := podClient.Get(pod.Name, metav1.GetOptions{})
- if err != nil {
- framework.Failf("ginkgo.Failed to get pod %s/%s: %v", pod.Namespace, pod.Name, err)
- }
- // Try to find the expected value for each expected name.
- ginkgo.By("looking for the results for each expected name from probers")
- assertFilesContain(fileNames, "results", pod, f.ClientSet, true, value)
- e2elog.Logf("DNS probes using %s succeeded\n", pod.Name)
- }
- func reverseArray(arr []string) []string {
- for i := 0; i < len(arr)/2; i++ {
- j := len(arr) - i - 1
- arr[i], arr[j] = arr[j], arr[i]
- }
- return arr
- }
- func generateDNSUtilsPod() *v1.Pod {
- return &v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- },
- ObjectMeta: metav1.ObjectMeta{
- GenerateName: "e2e-dns-utils-",
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "util",
- Image: imageutils.GetE2EImage(imageutils.Dnsutils),
- Command: []string{"sleep", "10000"},
- },
- },
- },
- }
- }
|