|
1 | 1 | package networking |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + "regexp" |
| 7 | + "time" |
| 8 | + |
4 | 9 | g "github.com/onsi/ginkgo/v2" |
5 | 10 | o "github.com/onsi/gomega" |
6 | 11 | exutil "github.com/openshift/origin/test/extended/util" |
7 | 12 | e2e "k8s.io/kubernetes/test/e2e/framework" |
| 13 | + e2epod "k8s.io/kubernetes/test/e2e/framework/pod" |
8 | 14 | admissionapi "k8s.io/pod-security-admission/api" |
9 | 15 | ) |
10 | 16 |
|
11 | 17 | var _ = g.Describe("[sig-network] external gateway address", func() { |
12 | | - oc := exutil.NewCLIWithPodSecurityLevel("ns-global", admissionapi.LevelPrivileged) |
| 18 | + oc := exutil.NewCLIWithoutNamespace("ns-global") |
13 | 19 |
|
14 | 20 | InOVNKubernetesContext(func() { |
15 | 21 | f := oc.KubeFramework() |
| 22 | + f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged |
16 | 23 |
|
17 | 24 | g.It("should match the address family of the pod", func() { |
| 25 | + labelKey, labelValue := "test", "external-gateway" |
| 26 | + labels := map[string]string{ |
| 27 | + labelKey: labelValue, |
| 28 | + } |
| 29 | + |
| 30 | + // Expected error message for APB policy sync failure |
| 31 | + errorLog := "Failed to sync APB policy %s.*gateway specified for namespace %s.*%s" |
| 32 | + |
| 33 | + // Returns true if the ovnkube-controller logs contain the expected error message |
| 34 | + checkLogs := func(ovnkubePodInfo ovnKubePodInfo, regex *regexp.Regexp) (bool, error) { |
| 35 | + logs, err := e2epod.GetPodLogs(context.TODO(), f.ClientSet, ovnNamespace, ovnkubePodInfo.podName, ovnkubePodInfo.containerName) |
| 36 | + if err != nil { |
| 37 | + return false, err |
| 38 | + } |
| 39 | + return regex.MatchString(logs), nil |
| 40 | + } |
| 41 | + |
| 42 | + g.By("creating namespace with external-gateway label") |
| 43 | + ns, err := f.CreateNamespace(context.TODO(), f.BaseName, labels) |
| 44 | + expectNoError(err) |
| 45 | + f.Namespace = ns |
| 46 | + |
| 47 | + g.By("determining cluster pod IP address family") |
18 | 48 | podIPFamily := GetIPFamilyForCluster(f) |
19 | 49 | o.Expect(podIPFamily).NotTo(o.Equal(Unknown)) |
| 50 | + |
20 | 51 | // Set external gateway address into an IPv6 address and make sure |
21 | 52 | // pod ip address matches with IPv6 address family. |
22 | | - setNamespaceExternalGateway(f, "fd00:10:244:2::6") |
23 | | - podIPs, err := createPod(f.ClientSet, f.Namespace.Name, "test-ipv6-pod") |
| 53 | + apbPolicyNameIPv6 := "static-egress-route-ipv6" |
| 54 | + g.By(fmt.Sprintf("applying IPv6 AdminPolicyBasedExternalRoute %s with gateway fd00:10:244:2::6", apbPolicyNameIPv6)) |
| 55 | + setNamespaceExternalGateway(apbPolicyNameIPv6, []string{"fd00:10:244:2::6"}, labelKey, labelValue) |
| 56 | + |
| 57 | + podNameIPv6 := "test-ipv6-pod" |
| 58 | + g.By(fmt.Sprintf("creating pod %s in namespace %s", podNameIPv6, f.Namespace.Name)) |
| 59 | + pod, err := createPod(f.ClientSet, f.Namespace.Name, podNameIPv6) |
| 60 | + expectNoError(err) |
| 61 | + podIPs := pod.Status.PodIPs |
24 | 62 | e2e.Logf("pod IPs are %v after setting external gw with IPv6 address", podIPs) |
| 63 | + |
| 64 | + g.By(fmt.Sprintf("finding ovnkube-node pod on node %s", pod.Spec.NodeName)) |
| 65 | + ovnkubePodInfo, err := ovnkubePod(oc, pod.Spec.NodeName) |
| 66 | + expectNoError(err) |
| 67 | + |
| 68 | + regexIPv6, err := regexp.Compile(fmt.Sprintf(errorLog, apbPolicyNameIPv6, f.Namespace.Name, podNameIPv6)) |
| 69 | + expectNoError(err) |
25 | 70 | switch podIPFamily { |
26 | | - case DualStack: |
27 | | - expectNoError(err) |
28 | | - o.Expect(getIPFamily(podIPs)).To(o.Equal(DualStack)) |
| 71 | + case DualStack, IPv6: |
| 72 | + g.By(fmt.Sprintf("verifying ovnkube-node logs do not report APB sync failure for IPv6 gateway on %s cluster", podIPFamily)) |
| 73 | + o.Consistently(func() bool { |
| 74 | + found, err := checkLogs(ovnkubePodInfo, regexIPv6) |
| 75 | + if err != nil { |
| 76 | + e2e.Logf("Error checking logs: %v", err) |
| 77 | + return true |
| 78 | + } |
| 79 | + return found |
| 80 | + }). |
| 81 | + WithPolling(20 * time.Second). |
| 82 | + WithTimeout(2 * time.Minute). |
| 83 | + Should(o.BeFalse()) |
29 | 84 | case IPv4: |
30 | 85 | // This is an expected failure when pod network in IPv4 address family |
31 | 86 | // whereas external gateway is set with IPv6 address |
32 | | - expectError(err) |
33 | | - case IPv6: |
34 | | - expectNoError(err) |
35 | | - o.Expect(getIPFamily(podIPs)).To(o.Equal(IPv6)) |
| 87 | + g.By("verifying ovnkube-node logs report APB sync failure for mismatched IPv6 gateway on IPv4 cluster") |
| 88 | + o.Eventually(func() bool { |
| 89 | + found, err := checkLogs(ovnkubePodInfo, regexIPv6) |
| 90 | + if err != nil { |
| 91 | + e2e.Logf("Error checking logs: %v", err) |
| 92 | + return false |
| 93 | + } |
| 94 | + return found |
| 95 | + }). |
| 96 | + WithPolling(20 * time.Second). |
| 97 | + WithTimeout(2 * time.Minute). |
| 98 | + Should(o.BeTrue()) |
36 | 99 | } |
| 100 | + |
| 101 | + g.By(fmt.Sprintf("deleting AdminPolicyBasedExternalRoute %s", apbPolicyNameIPv6)) |
| 102 | + err = oc.AsAdmin().WithoutNamespace().Run("delete").Args("adminpolicybasedexternalroute", apbPolicyNameIPv6, "--ignore-not-found").Execute() |
| 103 | + expectNoError(err) |
| 104 | + |
| 105 | + g.By(fmt.Sprintf("deleting pod %s", podNameIPv6)) |
| 106 | + err = oc.AsAdmin().WithoutNamespace().Run("delete").Args("pod", pod.Name, "-n", f.Namespace.Name, "--ignore-not-found").Execute() |
| 107 | + expectNoError(err) |
| 108 | + |
37 | 109 | // Set external gateway address into an IPv4 address and make sure |
38 | 110 | // pod ip address matches with IPv4 address family. |
39 | | - setNamespaceExternalGateway(f, "10.10.10.1") |
40 | | - podIPs, err = createPod(f.ClientSet, f.Namespace.Name, "test-ipv4-pod") |
| 111 | + apbPolicyNameIPv4 := "static-egress-route-ipv4" |
| 112 | + g.By(fmt.Sprintf("applying IPv4 AdminPolicyBasedExternalRoute %s with gateway 10.10.10.1", apbPolicyNameIPv4)) |
| 113 | + setNamespaceExternalGateway(apbPolicyNameIPv4, []string{"10.10.10.1"}, labelKey, labelValue) |
| 114 | + |
| 115 | + podNameIPv4 := "test-ipv4-pod" |
| 116 | + g.By(fmt.Sprintf("creating pod %s in namespace %s", podNameIPv4, f.Namespace.Name)) |
| 117 | + pod, err = createPod(f.ClientSet, f.Namespace.Name, podNameIPv4) |
| 118 | + expectNoError(err) |
| 119 | + podIPs = pod.Status.PodIPs |
41 | 120 | e2e.Logf("pod IPs are %v after setting external gw with IPv4 address", podIPs) |
| 121 | + |
| 122 | + g.By(fmt.Sprintf("finding ovnkube-node pod on node %s", pod.Spec.NodeName)) |
| 123 | + ovnkubePodInfo, err = ovnkubePod(oc, pod.Spec.NodeName) |
| 124 | + expectNoError(err) |
| 125 | + |
| 126 | + regexIPv4, err := regexp.Compile(fmt.Sprintf(errorLog, apbPolicyNameIPv4, f.Namespace.Name, podNameIPv4)) |
| 127 | + expectNoError(err) |
42 | 128 | switch podIPFamily { |
43 | | - case DualStack: |
44 | | - expectNoError(err) |
45 | | - o.Expect(getIPFamily(podIPs)).To(o.Equal(DualStack)) |
46 | | - case IPv4: |
47 | | - expectNoError(err) |
48 | | - o.Expect(getIPFamily(podIPs)).To(o.Equal(IPv4)) |
| 129 | + case DualStack, IPv4: |
| 130 | + g.By(fmt.Sprintf("verifying ovnkube-node logs do not report APB sync failure for IPv4 gateway on %s cluster", podIPFamily)) |
| 131 | + o.Consistently(func() bool { |
| 132 | + found, err := checkLogs(ovnkubePodInfo, regexIPv4) |
| 133 | + if err != nil { |
| 134 | + e2e.Logf("Error checking logs: %v", err) |
| 135 | + return true |
| 136 | + } |
| 137 | + return found |
| 138 | + }). |
| 139 | + WithPolling(20 * time.Second). |
| 140 | + WithTimeout(2 * time.Minute). |
| 141 | + Should(o.BeFalse()) |
49 | 142 | case IPv6: |
50 | 143 | // This is an expected failure when pod network in IPv6 address family |
51 | 144 | // whereas external gateway is set with IPv4 address |
52 | | - expectError(err) |
| 145 | + g.By("verifying ovnkube-node logs report APB sync failure for mismatched IPv4 gateway on IPv6 cluster") |
| 146 | + o.Eventually(func() bool { |
| 147 | + found, err := checkLogs(ovnkubePodInfo, regexIPv4) |
| 148 | + if err != nil { |
| 149 | + e2e.Logf("Error checking logs: %v", err) |
| 150 | + return false |
| 151 | + } |
| 152 | + return found |
| 153 | + }). |
| 154 | + WithPolling(20 * time.Second). |
| 155 | + WithTimeout(2 * time.Minute). |
| 156 | + Should(o.BeTrue()) |
53 | 157 | } |
| 158 | + |
| 159 | + g.By(fmt.Sprintf("deleting AdminPolicyBasedExternalRoute %s", apbPolicyNameIPv4)) |
| 160 | + err = oc.AsAdmin().WithoutNamespace().Run("delete").Args("adminpolicybasedexternalroute", apbPolicyNameIPv4, "--ignore-not-found").Execute() |
| 161 | + expectNoError(err) |
| 162 | + |
| 163 | + g.By(fmt.Sprintf("deleting pod %s", podNameIPv4)) |
| 164 | + err = oc.AsAdmin().WithoutNamespace().Run("delete").Args("pod", pod.Name, "-n", f.Namespace.Name, "--ignore-not-found").Execute() |
| 165 | + expectNoError(err) |
| 166 | + |
54 | 167 | // Set external gateway address supporting Dual Stack and make sure |
55 | 168 | // pod ip address(es) match with desired address family. |
56 | | - setNamespaceExternalGateway(f, "10.10.10.1,fd00:10:244:2::6") |
57 | | - podIPs, err = createPod(f.ClientSet, f.Namespace.Name, "test-dual-stack-pod") |
58 | | - o.Expect(err).NotTo(o.HaveOccurred()) |
| 169 | + apbPolicyNameDualStack := "static-egress-route-dual-stack" |
| 170 | + g.By(fmt.Sprintf("applying dual-stack AdminPolicyBasedExternalRoute %s with gateways 10.10.10.1 and fd00:10:244:2::6", apbPolicyNameDualStack)) |
| 171 | + setNamespaceExternalGateway(apbPolicyNameDualStack, []string{"10.10.10.1", "fd00:10:244:2::6"}, labelKey, labelValue) |
| 172 | + |
| 173 | + podNameDualStack := "test-dual-stack-pod" |
| 174 | + g.By(fmt.Sprintf("creating pod %s in namespace %s", podNameDualStack, f.Namespace.Name)) |
| 175 | + pod, err = createPod(f.ClientSet, f.Namespace.Name, podNameDualStack) |
| 176 | + expectNoError(err) |
| 177 | + podIPs = pod.Status.PodIPs |
59 | 178 | e2e.Logf("pod IPs are %v after setting external gw with Dual Stack address", podIPs) |
| 179 | + |
| 180 | + g.By("verifying pod IP address family matches cluster") |
60 | 181 | o.Expect(getIPFamily(podIPs)).To(o.Equal(podIPFamily)) |
| 182 | + |
| 183 | + g.By(fmt.Sprintf("finding ovnkube-node pod on node %s", pod.Spec.NodeName)) |
| 184 | + ovnkubePodInfo, err = ovnkubePod(oc, pod.Spec.NodeName) |
| 185 | + expectNoError(err) |
| 186 | + |
| 187 | + regexDualStack, err := regexp.Compile(fmt.Sprintf(errorLog, apbPolicyNameDualStack, f.Namespace.Name, podNameDualStack)) |
| 188 | + expectNoError(err) |
| 189 | + g.By("verifying ovnkube-node logs do not report APB sync failure for dual-stack gateway") |
| 190 | + o.Consistently(func() bool { |
| 191 | + found, err := checkLogs(ovnkubePodInfo, regexDualStack) |
| 192 | + if err != nil { |
| 193 | + e2e.Logf("Error checking logs: %v", err) |
| 194 | + return true |
| 195 | + } |
| 196 | + return found |
| 197 | + }). |
| 198 | + WithPolling(20 * time.Second). |
| 199 | + WithTimeout(2 * time.Minute). |
| 200 | + Should(o.BeFalse()) |
| 201 | + |
| 202 | + g.By(fmt.Sprintf("deleting AdminPolicyBasedExternalRoute %s", apbPolicyNameDualStack)) |
| 203 | + err = oc.AsAdmin().WithoutNamespace().Run("delete").Args("adminpolicybasedexternalroute", apbPolicyNameDualStack, "--ignore-not-found").Execute() |
| 204 | + expectNoError(err) |
| 205 | + |
| 206 | + g.By(fmt.Sprintf("deleting pod %s", podNameDualStack)) |
| 207 | + err = oc.AsAdmin().WithoutNamespace().Run("delete").Args("pod", pod.Name, "-n", f.Namespace.Name, "--ignore-not-found").Execute() |
| 208 | + expectNoError(err) |
61 | 209 | }) |
62 | 210 | }) |
63 | 211 | }) |
0 commit comments