diff --git a/test/e2e/network/network_policy.go b/test/e2e/network/network_policy.go index 4e8270cbce3..2af35ccd04b 100644 --- a/test/e2e/network/network_policy.go +++ b/test/e2e/network/network_policy.go @@ -1371,6 +1371,130 @@ var _ = SIGDescribe("NetworkPolicy [LinuxOnly]", func() { }) }) + ginkgo.It("should ensure an IP overlapping both IPBlock.CIDR and IPBlock.Except is allowed [Feature:NetworkPolicy]", func() { + protocolUDP := v1.ProtocolUDP + + // Getting podServer's status to get podServer's IP, to create the CIDR with except clause + podServerStatus, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(context.TODO(), podServer.Name, metav1.GetOptions{}) + if err != nil { + framework.ExpectNoError(err, "Error occurred while getting pod status.") + } + + podServerAllowCIDR := fmt.Sprintf("%s/24", podServerStatus.Status.PodIP) + podServerIP := fmt.Sprintf("%s/32", podServerStatus.Status.PodIP) + // Exclude podServer's IP with an Except clause + podServerExceptList := []string{podServerIP} + + // Create NetworkPolicy which blocks access to podServer with except clause. + policyAllowCIDRWithExceptServerPod := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: f.Namespace.Name, + Name: "deny-client-a-via-except-cidr-egress-rule", + }, + Spec: networkingv1.NetworkPolicySpec{ + // Apply this policy to the client. + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "pod-name": "client-a", + }, + }, + PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress}, + // Allow traffic to only one CIDR block except subnet which includes Server. + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + // Allow DNS look-ups + { + Protocol: &protocolUDP, + Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53}, + }, + }, + }, + { + To: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: podServerAllowCIDR, + Except: podServerExceptList, + }, + }, + }, + }, + }, + }, + } + + policyAllowCIDRWithExceptServerPodObj, err := f.ClientSet.NetworkingV1().NetworkPolicies(f.Namespace.Name).Create(context.TODO(), policyAllowCIDRWithExceptServerPod, metav1.CreateOptions{}) + framework.ExpectNoError(err, "Error occurred while creating policy: policyAllowCIDRWithExceptServerPod.") + + ginkgo.By("Creating client-a which should not be able to contact the server.", func() { + testCannotConnect(f, f.Namespace, "client-a", service, 80) + }) + + // Create NetworkPolicy which allows access to the podServer using podServer's IP in allow CIDR. + policyAllowCIDRServerPod := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: f.Namespace.Name, + Name: "allow-client-a-via-cidr-egress-rule", + }, + Spec: networkingv1.NetworkPolicySpec{ + // Apply this policy to the client. + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "pod-name": "client-a", + }, + }, + PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress}, + // Allow traffic to only one CIDR block which includes Server. + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + // Allow DNS look-ups + { + Protocol: &protocolUDP, + Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53}, + }, + }, + }, + { + To: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: podServerIP, + }, + }, + }, + }, + }, + }, + } + + policyAllowCIDRServerPod, err = f.ClientSet.NetworkingV1().NetworkPolicies(f.Namespace.Name).Create(context.TODO(), policyAllowCIDRServerPod, metav1.CreateOptions{}) + framework.ExpectNoError(err, "Error occurred while creating policy: policyAllowCIDRServerPod.") + defer cleanupNetworkPolicy(f, policyAllowCIDRServerPod) + + ginkgo.By("Creating client-a which should now be able to contact the server.", func() { + testCanConnect(f, f.Namespace, "client-a", service, 80) + }) + + ginkgo.By("Deleting the network policy with except podServer IP which disallows access to podServer.") + cleanupNetworkPolicy(f, policyAllowCIDRWithExceptServerPodObj) + + ginkgo.By("Creating client-a which should still be able to contact the server after deleting the network policy with except clause.", func() { + testCanConnect(f, f.Namespace, "client-a", service, 80) + }) + + // Recreate the NetworkPolicy which contains the podServer's IP in the except list. + policyAllowCIDRWithExceptServerPod, err = f.ClientSet.NetworkingV1().NetworkPolicies(f.Namespace.Name).Create(context.TODO(), policyAllowCIDRWithExceptServerPod, metav1.CreateOptions{}) + framework.ExpectNoError(err, "Error occurred while creating policy: policyAllowCIDRWithExceptServerPod.") + defer cleanupNetworkPolicy(f, policyAllowCIDRWithExceptServerPod) + + ginkgo.By("Creating client-a which should still be able to contact the server after recreating the network policy with except clause.", func() { + testCanConnect(f, f.Namespace, "client-a", service, 80) + }) + + }) + ginkgo.It("should enforce policies to check ingress and egress policies can be controlled independently based on PodSelector [Feature:NetworkPolicy]", func() { var serviceA, serviceB *v1.Service var podA, podB *v1.Pod