Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 107 additions & 40 deletions test/e2e/anp-domain/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,16 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
ginkgo.By("Cleaning up test resources")
ctx := context.Background()

// Clean up ANP if it exists
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些注释感觉保留应该会更好读吧?

if anpName != "" {
ginkgo.By("Deleting AdminNetworkPolicy " + anpName)
anpClient.Delete(anpName)
}

// Clean up second ANP if it exists (for multiple ANP test)
if anpName2 != "" {
ginkgo.By("Deleting second AdminNetworkPolicy " + anpName2)
anpClient.Delete(anpName2)
}

// Clean up pod if it exists
if podName != "" {
ginkgo.By("Deleting test pod " + podName)
err := cs.CoreV1().Pods(namespaceName).Delete(ctx, podName, metav1.DeleteOptions{})
Expand All @@ -69,14 +66,12 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
}
}

// Clean up namespace if it exists
if namespaceName != "" {
ginkgo.By("Deleting namespace " + namespaceName)
nsClient.Delete(namespaceName)
}
})

// testNetworkConnectivityWithRetry tests network connectivity with configurable retry mechanism
testNetworkConnectivityWithRetry := func(target string, shouldSucceed bool, description string, maxRetries int, retryInterval time.Duration) {
ginkgo.By(description)

Expand Down Expand Up @@ -115,7 +110,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
}
}

// testNetworkConnectivity tests network connectivity with default retry mechanism
testNetworkConnectivity := func(target string, shouldSucceed bool, description string) {
testNetworkConnectivityWithRetry(target, shouldSucceed, description, 20, 2*time.Second)
}
Expand All @@ -134,7 +128,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
pod := framework.MakePrivilegedPod(namespaceName, podName, nil, nil, f.KubeOVNImage, cmd, nil)
_ = podClient.CreateSync(pod)

// Test connectivity to baidu.com before applying ANP (should succeed)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com before applying ANP (should succeed)")

ginkgo.By("Creating AdminNetworkPolicy with domainName to deny baidu.com")
Expand All @@ -150,7 +143,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
egressRule := framework.MakeAdminNetworkPolicyEgressRule("deny-baidu", netpolv1alpha1.AdminNetworkPolicyRuleActionDeny, ports, domainNames)
anp := framework.MakeAdminNetworkPolicy(anpName, 55, namespaceSelector, []netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule}, nil)

// Create the ANP in the cluster
ginkgo.By("Creating AdminNetworkPolicy in the cluster")
createdANP := anpClient.CreateSync(anp)
framework.Logf("Successfully created AdminNetworkPolicy: %s", createdANP.Name)
Expand All @@ -166,21 +158,17 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
framework.ExpectEqual(anp.Spec.Priority, int32(55))
framework.ExpectEqual(anp.Spec.Subject.Namespaces.MatchLabels["kubernetes.io/metadata.name"], namespaceName)

// Test connectivity to baidu.com after applying ANP (should be blocked)
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after applying ANP (should be blocked)")

// Delete the ANP rule
ginkgo.By("Deleting AdminNetworkPolicy " + anpName)
anpClient.Delete(anpName)

// Test connectivity to baidu.com after deleting ANP (should succeed again)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com after deleting ANP (should succeed again)")
})

framework.ConformanceIt("should create multiple ANPs with domainName rules and verify they work together", func() {
f.SkipVersionPriorTo(1, 15, "AdminNetworkPolicy domainName support was introduced in v1.15")

// Create additional ANP name for the second policy
anpName2 = "anp2-" + framework.RandomSuffix()

ginkgo.By("Creating test namespace " + namespaceName)
Expand All @@ -195,7 +183,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
pod := framework.MakePrivilegedPod(namespaceName, podName, nil, nil, f.KubeOVNImage, cmd, nil)
_ = podClient.CreateSync(pod)

// Test connectivity to both domains before applying ANPs (should succeed)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com before applying ANPs (should succeed)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com before applying ANPs (should succeed)")

Expand All @@ -212,7 +199,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
egressRule1 := framework.MakeAdminNetworkPolicyEgressRule("deny-baidu", netpolv1alpha1.AdminNetworkPolicyRuleActionDeny, ports, domainNames1)
anp1 := framework.MakeAdminNetworkPolicy(anpName, 44, namespaceSelector, []netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule1}, nil)

// Create the first ANP in the cluster
ginkgo.By("Creating first AdminNetworkPolicy in the cluster")
createdANP1 := anpClient.CreateSync(anp1)
framework.Logf("Successfully created first AdminNetworkPolicy: %s", createdANP1.Name)
Expand All @@ -222,13 +208,11 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
egressRule2 := framework.MakeAdminNetworkPolicyEgressRule("allow-google", netpolv1alpha1.AdminNetworkPolicyRuleActionAllow, ports, domainNames2)
anp2 := framework.MakeAdminNetworkPolicy(anpName2, 45, namespaceSelector, []netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule2}, nil)

// Create the second ANP in the cluster
ginkgo.By("Creating second AdminNetworkPolicy in the cluster")
createdANP2 := anpClient.CreateSync(anp2)
framework.Logf("Successfully created second AdminNetworkPolicy: %s", createdANP2.Name)

ginkgo.By("Verifying both ANPs structure is correct")
// Verify first ANP
framework.ExpectEqual(len(anp1.Spec.Egress), 1)
anp1EgressRule := anp1.Spec.Egress[0]
framework.ExpectEqual(len(anp1EgressRule.To), 1)
Expand All @@ -237,7 +221,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
framework.ExpectEqual(string(peer1.DomainNames[0]), "*.baidu.com.")
framework.ExpectEqual(anp1.Spec.Priority, int32(44))

// Verify second ANP
framework.ExpectEqual(len(anp2.Spec.Egress), 1)
anp2EgressRule := anp2.Spec.Egress[0]
framework.ExpectEqual(len(anp2EgressRule.To), 1)
Expand All @@ -246,29 +229,18 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
framework.ExpectEqual(string(peer2.DomainNames[0]), "*.google.com.")
framework.ExpectEqual(anp2.Spec.Priority, int32(45))

// Test connectivity after applying both ANPs
// baidu.com should be blocked (deny rule with higher priority)
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after applying both ANPs (should be blocked)")

// google.com should be allowed (allow rule)
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after applying both ANPs (should be allowed)")

// Delete the first ANP (baidu.com deny rule)
ginkgo.By("Deleting first AdminNetworkPolicy " + anpName)
anpClient.Delete(anpName)

// Test connectivity after deleting first ANP
// baidu.com should be allowed now (no deny rule)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com after deleting first ANP (should be allowed)")

// google.com should still be allowed
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after deleting first ANP (should still be allowed)")

// Delete the second ANP (google.com allow rule)
ginkgo.By("Deleting second AdminNetworkPolicy " + anpName2)
anpClient.Delete(anpName2)

// Test connectivity after deleting both ANPs (should succeed for both)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com after deleting both ANPs (should succeed)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after deleting both ANPs (should succeed)")
})
Expand All @@ -288,7 +260,6 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
pod := framework.MakePrivilegedPod(namespaceName, podName, nil, nil, f.KubeOVNImage, cmd, nil)
_ = podClient.CreateSync(pod)

// Test connectivity to both domains before applying any ANP (should succeed)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com before applying ANP (should succeed)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com before applying ANP (should succeed)")

Expand All @@ -302,67 +273,163 @@ var _ = framework.SerialDescribe("[group:admin-network-policy]", func() {
framework.MakeAdminNetworkPolicyPort(443, corev1.ProtocolTCP),
}

// Create ANP without any egress rules initially
anp := framework.MakeAdminNetworkPolicy(anpName, 50, namespaceSelector, nil, nil)
createdANP := anpClient.CreateSync(anp)
framework.Logf("Successfully created AdminNetworkPolicy: %s", createdANP.Name)

// Test connectivity after creating ANP without rules (should still succeed)
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com after creating ANP without rules (should succeed)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after creating ANP without rules (should succeed)")

ginkgo.By("Adding domainName deny rule for baidu.com to the existing ANP")
domainNames := []netpolv1alpha1.DomainName{"*.baidu.com."}
egressRule := framework.MakeAdminNetworkPolicyEgressRule("deny-baidu", netpolv1alpha1.AdminNetworkPolicyRuleActionDeny, ports, domainNames)

// Update the ANP to add the egress rule
createdANP.Spec.Egress = []netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule}
updatedANP := anpClient.Update(createdANP)
framework.Logf("Successfully updated AdminNetworkPolicy with baidu.com deny rule: %s", updatedANP.Name)

// Test connectivity after adding baidu.com deny rule
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after adding deny rule (should be blocked)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after adding baidu.com deny rule (should still succeed)")

ginkgo.By("Adding domainName deny rule for google.com to the existing ANP")
domainNames2 := []netpolv1alpha1.DomainName{"*.google.com."}
egressRule2 := framework.MakeAdminNetworkPolicyEgressRule("deny-google", netpolv1alpha1.AdminNetworkPolicyRuleActionDeny, ports, domainNames2)

// Update the ANP to add the second egress rule
updatedANP.Spec.Egress = append(updatedANP.Spec.Egress, egressRule2)
updatedANP2 := anpClient.Update(updatedANP)
framework.Logf("Successfully updated AdminNetworkPolicy with both deny rules: %s", updatedANP2.Name)

// Test connectivity after adding both deny rules
testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after adding both deny rules (should be blocked)")
testNetworkConnectivity("https://www.google.com", false, "Testing connectivity to google.com after adding both deny rules (should be blocked)")

ginkgo.By("Removing baidu.com deny rule from the ANP")
// Remove the first egress rule (baidu.com deny)
updatedANP2.Spec.Egress = []netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule2}
updatedANP3 := anpClient.Update(updatedANP2)
framework.Logf("Successfully updated AdminNetworkPolicy removing baidu.com deny rule: %s", updatedANP3.Name)

// Test connectivity after removing baidu.com deny rule
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com after removing deny rule (should succeed)")
testNetworkConnectivity("https://www.google.com", false, "Testing connectivity to google.com after removing baidu.com deny rule (should still be blocked)")

ginkgo.By("Removing all domainName deny rules from the ANP")
// Remove all egress rules
updatedANP3.Spec.Egress = nil
updatedANP4 := anpClient.Update(updatedANP3)
framework.Logf("Successfully updated AdminNetworkPolicy removing all deny rules: %s", updatedANP4.Name)

// Test connectivity after removing all deny rules
testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com after removing all deny rules (should succeed)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after removing all deny rules (should succeed)")
})

framework.ConformanceIt("should create ANP with domainName and CIDR rules and verify they work together", func() {
f.SkipVersionPriorTo(1, 15, "AdminNetworkPolicy domainName support was introduced in v1.15")

ginkgo.By("Creating test namespace " + namespaceName)
labels := map[string]string{
"kubernetes.io/metadata.name": namespaceName,
}
ns := framework.MakeNamespace(namespaceName, labels, nil)
_ = nsClient.Create(ns)

ginkgo.By("Creating test pod " + podName + " in namespace " + namespaceName)
cmd := []string{"sleep", "infinity"}
pod := framework.MakePrivilegedPod(namespaceName, podName, nil, nil, f.KubeOVNImage, cmd, nil)
_ = podClient.CreateSync(pod)

testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to baidu.com before applying ANP (should succeed)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com before applying ANP (should succeed)")
testNetworkConnectivity("https://8.8.8.8", true, "Testing connectivity to 8.8.8.8 before applying ANP (should succeed)")

ginkgo.By("Creating AdminNetworkPolicy with both domainName and CIDR rules")
namespaceSelector := &metav1.LabelSelector{
MatchLabels: map[string]string{
"kubernetes.io/metadata.name": namespaceName,
},
}
ports := []netpolv1alpha1.AdminNetworkPolicyPort{
framework.MakeAdminNetworkPolicyPort(443, corev1.ProtocolTCP),
}

domainNames := []netpolv1alpha1.DomainName{"*.baidu.com."}
egressRule1 := framework.MakeAdminNetworkPolicyEgressRule("deny-baidu", netpolv1alpha1.AdminNetworkPolicyRuleActionDeny, ports, domainNames)

egressRule2 := netpolv1alpha1.AdminNetworkPolicyEgressRule{
Name: "deny-google-dns",
Action: netpolv1alpha1.AdminNetworkPolicyRuleActionDeny,
To: []netpolv1alpha1.AdminNetworkPolicyEgressPeer{
{
Networks: []netpolv1alpha1.CIDR{"8.8.8.8/32"},
},
},
Ports: &ports,
}

anp := framework.MakeAdminNetworkPolicy(anpName, 80, namespaceSelector,
[]netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule1, egressRule2}, nil)

ginkgo.By("Creating AdminNetworkPolicy in the cluster")
createdANP := anpClient.CreateSync(anp)
framework.Logf("Successfully created AdminNetworkPolicy: %s", createdANP.Name)

ginkgo.By("Verifying ANP structure is correct")
framework.ExpectEqual(len(anp.Spec.Egress), 2)
framework.ExpectEqual(anp.Spec.Priority, int32(80))

testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to baidu.com after applying ANP (should be blocked)")
testNetworkConnectivity("https://www.google.com", true, "Testing connectivity to google.com after applying ANP (should be allowed)")
testNetworkConnectivity("https://8.8.8.8", false, "Testing connectivity to 8.8.8.8 after applying ANP (should be blocked by CIDR rule)")
})

framework.ConformanceIt("should create ANP with wildcard domainName rules and verify they work correctly", func() {
f.SkipVersionPriorTo(1, 15, "AdminNetworkPolicy domainName support was introduced in v1.15")

ginkgo.By("Creating test namespace " + namespaceName)
labels := map[string]string{
"kubernetes.io/metadata.name": namespaceName,
}
ns := framework.MakeNamespace(namespaceName, labels, nil)
_ = nsClient.Create(ns)

ginkgo.By("Creating test pod " + podName + " in namespace " + namespaceName)
cmd := []string{"sleep", "infinity"}
pod := framework.MakePrivilegedPod(namespaceName, podName, nil, nil, f.KubeOVNImage, cmd, nil)
_ = podClient.CreateSync(pod)

testNetworkConnectivity("https://www.baidu.com", true, "Testing connectivity to www.baidu.com before applying ANP (should succeed)")
testNetworkConnectivity("https://api.baidu.com", true, "Testing connectivity to api.baidu.com before applying ANP (should succeed)")
testNetworkConnectivity("https://news.baidu.com", true, "Testing connectivity to news.baidu.com before applying ANP (should succeed)")

ginkgo.By("Creating AdminNetworkPolicy with wildcard domainName rules")
namespaceSelector := &metav1.LabelSelector{
MatchLabels: map[string]string{
"kubernetes.io/metadata.name": namespaceName,
},
}
ports := []netpolv1alpha1.AdminNetworkPolicyPort{
framework.MakeAdminNetworkPolicyPort(443, corev1.ProtocolTCP),
}

domainNames1 := []netpolv1alpha1.DomainName{"*.baidu.com."}
egressRule1 := framework.MakeAdminNetworkPolicyEgressRule("deny-baidu-wildcard", netpolv1alpha1.AdminNetworkPolicyRuleActionDeny, ports, domainNames1)

anp := framework.MakeAdminNetworkPolicy(anpName, 85, namespaceSelector,
[]netpolv1alpha1.AdminNetworkPolicyEgressRule{egressRule1}, nil)

ginkgo.By("Creating AdminNetworkPolicy in the cluster")
createdANP := anpClient.CreateSync(anp)
framework.Logf("Successfully created AdminNetworkPolicy: %s", createdANP.Name)

ginkgo.By("Verifying ANP structure is correct")
framework.ExpectEqual(len(anp.Spec.Egress), 1)
framework.ExpectEqual(anp.Spec.Priority, int32(85))

testNetworkConnectivity("https://www.baidu.com", false, "Testing connectivity to www.baidu.com after applying ANP (should be blocked by wildcard)")
testNetworkConnectivity("https://api.baidu.com", false, "Testing connectivity to api.baidu.com after applying ANP (should be blocked by wildcard)")
testNetworkConnectivity("https://news.baidu.com", false, "Testing connectivity to news.baidu.com after applying ANP (should be blocked by wildcard)")
})
})

func init() {
klog.SetOutput(ginkgo.GinkgoWriter)

// Register flags.
config.CopyFlags(config.Flags, flag.CommandLine)
k8sframework.RegisterCommonFlags(flag.CommandLine)
k8sframework.RegisterClusterFlags(flag.CommandLine)
Expand Down
12 changes: 10 additions & 2 deletions test/e2e/kube-ovn/subnet/subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math/rand/v2"
"net"
"os/exec"
"regexp"
"slices"
"strconv"
"strings"
Expand Down Expand Up @@ -1455,11 +1456,18 @@ var _ = framework.Describe("[group:subnet]", func() {
output, err := exec.Command("kubectl", "ko", "nbctl", "--data=bare", "--no-heading", "--columns=mac", "find", "logical_router_port", fmt.Sprintf("name=%s", routerPortName)).CombinedOutput()
framework.Logf("Command output: %s", string(output))

if err != nil || strings.TrimSpace(string(output)) == "" {
if err != nil {
ginkgo.Skip("Could not get gateway MAC, skipping test")
}

gatewayMAC := strings.TrimSpace(string(output))
// Extract MAC address from the output string
macRegex := regexp.MustCompile(`([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}`)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For performance and maintainability, it's better to compile this regular expression once at the package level instead of inside the test function. This avoids recompiling the regex on every test execution. You can define macRegex as a package-level variable.

gatewayMAC := macRegex.FindString(string(output))

if gatewayMAC == "" {
ginkgo.Skip("Could not find valid gateway MAC in output, skipping test")
}

framework.Logf("Gateway MAC: %s", gatewayMAC)

ginkgo.By("Creating pod with static MAC that conflicts with gateway MAC")
Expand Down