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