-
Notifications
You must be signed in to change notification settings - Fork 39k
/
dns.go
135 lines (111 loc) · 5.28 KB
/
dns.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
Copyright 2019 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 windows
import (
"context"
"strings"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
"github.com/onsi/ginkgo"
)
var _ = SIGDescribe("[Feature:Windows] DNS", func() {
ginkgo.BeforeEach(func() {
e2eskipper.SkipUnlessNodeOSDistroIs("windows")
})
f := framework.NewDefaultFramework("dns")
ginkgo.It("should support configurable pod DNS servers", func() {
ginkgo.By("Getting the IP address of the internal Kubernetes service")
svc, err := f.ClientSet.CoreV1().Services("kube-system").Get(context.TODO(), "kube-dns", metav1.GetOptions{})
framework.ExpectNoError(err)
ginkgo.By("Preparing a test DNS service with injected DNS names...")
// the default service IP will vary from cluster to cluster, but will always be present and is a good DNS test target
testInjectedIP := svc.Spec.ClusterIP
testSearchPath := "default.svc.cluster.local"
ginkgo.By("Creating a windows pod with dnsPolicy=None and customized dnsConfig...")
testPod := e2epod.NewAgnhostPod(f.Namespace.Name, "e2e-dns-utils", nil, nil, nil)
testPod.Spec.DNSPolicy = v1.DNSNone
testPod.Spec.DNSConfig = &v1.PodDNSConfig{
Nameservers: []string{testInjectedIP, "1.1.1.1"},
Searches: []string{testSearchPath},
}
testPod.Spec.NodeSelector = map[string]string{
"kubernetes.io/os": "windows",
}
testPod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), testPod, metav1.CreateOptions{})
framework.ExpectNoError(err)
ginkgo.By("confirming that the pod has a windows label")
framework.ExpectEqual(testPod.Spec.NodeSelector["kubernetes.io/os"], "windows")
framework.Logf("Created pod %v", testPod)
defer func() {
framework.Logf("Deleting pod %s...", testPod.Name)
if err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Delete(context.TODO(), testPod.Name, *metav1.NewDeleteOptions(0)); err != nil {
framework.Failf("Failed to delete pod %s: %v", testPod.Name, err)
}
}()
framework.ExpectNoError(e2epod.WaitForPodNameRunningInNamespace(f.ClientSet, testPod.Name, f.Namespace.Name), "failed to wait for pod %s to be running", testPod.Name)
// This isn't the best 'test' but it is a great diagnostic, see later test for the 'real' test.
ginkgo.By("Calling ipconfig to get debugging info for this pod's DNS and confirm that a dns server 1.1.1.1 can be injected, along with ")
cmd := []string{"ipconfig", "/all"}
stdout, _, err := f.ExecWithOptions(framework.ExecOptions{
Command: cmd,
Namespace: f.Namespace.Name,
PodName: testPod.Name,
ContainerName: "agnhost-container",
CaptureStdout: true,
CaptureStderr: true,
})
framework.ExpectNoError(err)
framework.Logf("ipconfig /all:\n%s", stdout)
if !strings.Contains(stdout, "1.1.1.1") {
framework.Failf("One of the custom DNS options 1.1.1.1, not found in ipconfig /all")
}
// We've now verified that the DNS stuff is injected... now lets make sure that curl'ing 'wrong' endpoints fails, i.e.
// a negative control, to run before we run our final test...
ginkgo.By("Verifying that curl queries FAIL for wrong URLs")
// the below tests use curl because nslookup doesn't seem to use ndots properly
// ideally we'd use the powershell native ResolveDns but, that is not a part of agnhost images (as of k8s 1.20)
// TODO @jayunit100 add ResolveHost to agn images
cmd = []string{"curl.exe", "-k", "https://kubernetezzzzzzzz:443"}
stdout, _, err = f.ExecWithOptions(framework.ExecOptions{
Command: cmd,
Namespace: f.Namespace.Name,
PodName: testPod.Name,
ContainerName: "agnhost-container",
CaptureStdout: true,
CaptureStderr: true,
})
if err == nil {
framework.Logf("Warning: Somehow the curl command succeeded... The output was \n %v", stdout)
framework.Failf("Expected a bogus URL query to fail - something is wrong with this test harness, cannot proceed.")
}
ginkgo.By("Verifying that injected dns records for 'kubernetes' resolve to the valid ip address")
cmd = []string{"curl.exe", "-k", "https://kubernetes:443"}
stdout, _, err = f.ExecWithOptions(framework.ExecOptions{
Command: cmd,
Namespace: f.Namespace.Name,
PodName: testPod.Name,
ContainerName: "agnhost-container",
CaptureStdout: true,
CaptureStderr: true,
})
framework.Logf("Result of curling the kubernetes service... (Failure ok, only testing for the sake of DNS resolution) %v ... error = %v", stdout, err)
// curl returns an error if the host isnt resolved, otherwise, it will return a passing result.
if err != nil {
framework.ExpectNoError(err)
}
// TODO: Add more test cases for other DNSPolicies.
})
})