From 4a294f522411d06f45c8141f22ba25a66eeb8b42 Mon Sep 17 00:00:00 2001 From: Ayoub Mrini Date: Thu, 9 Jul 2026 18:20:38 +0200 Subject: [PATCH 1/2] Add e2e test to detect named ports in NetworkPolicies Some network plugins (e.g. OVN-Kubernetes) do not support named ports in NetworkPolicies and may silently convert them into allow-all rules. Add a test that lists all cluster NetworkPolicies and fails if any use named ports instead of numeric ones, with a skip list for now. --- .../networking/networkpolicy_validation.go | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 test/extended/networking/networkpolicy_validation.go diff --git a/test/extended/networking/networkpolicy_validation.go b/test/extended/networking/networkpolicy_validation.go new file mode 100644 index 000000000000..372c7da1b45a --- /dev/null +++ b/test/extended/networking/networkpolicy_validation.go @@ -0,0 +1,78 @@ +package networking + +import ( + "context" + "fmt" + "slices" + + g "github.com/onsi/ginkgo/v2" + o "github.com/onsi/gomega" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + e2e "k8s.io/kubernetes/test/e2e/framework" + + exutil "github.com/openshift/origin/test/extended/util" +) + +var _ = g.Describe("[sig-network] NetworkPolicy", func() { + oc := exutil.NewCLIWithoutNamespace("networkpolicy-validation") + + // Some CNIs like OVN-Kubernetes do not support named ports in NetworkPolicies. + // When a named port is used, they may silently convert the rule + // into an allow-all, effectively bypassing the intended restriction. + g.It("should use numeric ports in all platform NetworkPolicies [apigroup:networking.k8s.io]", func() { + // Known NetworkPolicies that still use named ports. + // Each entry is "namespace/name". + // TODO: remove entries as the owning teams fix them. + networkPoliciesToSkip := []string{ + // https://redhat.atlassian.net/browse/OCPBUGS-99494 + "openshift-ingress/router-default", + // https://redhat.atlassian.net/browse/OCPBUGS-99492 + "openshift-cluster-csi-drivers/allow-to-dns", + // https://redhat.atlassian.net/browse/OCPBUGS-99492 + "openshift-cluster-storage-operator/allow-to-dns", + // https://redhat.atlassian.net/browse/OCPBUGS-99493 + "openshift-cluster-olm-operator/allow-egress-to-openshift-dns", + // https://redhat.atlassian.net/browse/OCPBUGS-99493 + "openshift-operator-lifecycle-manager/catalog-operator", + // https://redhat.atlassian.net/browse/OCPBUGS-99493 + "openshift-operator-lifecycle-manager/olm-operator", + } + + ctx := context.Background() + + nps, err := oc.AdminKubeClient().NetworkingV1().NetworkPolicies("").List(ctx, metav1.ListOptions{}) + o.Expect(err).NotTo(o.HaveOccurred(), "failed to list NetworkPolicies across all namespaces") + o.Expect(nps.Items).NotTo(o.BeEmpty(), "expected at least one NetworkPolicy on the cluster") + + var violations []string + for _, np := range nps.Items { + key := fmt.Sprintf("%s/%s", np.Namespace, np.Name) + skip := slices.Contains(networkPoliciesToSkip, key) + for _, rule := range np.Spec.Ingress { + for _, p := range rule.Ports { + if p.Port != nil && p.Port.Type != intstr.Int { + msg := fmt.Sprintf("%s ingress has named port %q (skip=%v)", key, p.Port.StrVal, skip) + e2e.Logf("%s", msg) + if !skip { + violations = append(violations, msg) + } + } + } + } + for _, rule := range np.Spec.Egress { + for _, p := range rule.Ports { + if p.Port != nil && p.Port.Type != intstr.Int { + msg := fmt.Sprintf("%s egress has named port %q (skip=%v)", key, p.Port.StrVal, skip) + e2e.Logf("%s", msg) + if !skip { + violations = append(violations, msg) + } + } + } + } + } + o.Expect(violations).To(o.BeEmpty(), "some NetworkPolicies use named ports instead of numeric") + }) +}) From 14a8058c4dfc9a0d0dc1fad266c508d626202789 Mon Sep 17 00:00:00 2001 From: Ayoub Mrini Date: Thu, 23 Jul 2026 11:29:59 +0200 Subject: [PATCH 2/2] restrict to platform namespaces for real --- test/extended/networking/networkpolicy_validation.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/extended/networking/networkpolicy_validation.go b/test/extended/networking/networkpolicy_validation.go index 372c7da1b45a..4cab715dfdb8 100644 --- a/test/extended/networking/networkpolicy_validation.go +++ b/test/extended/networking/networkpolicy_validation.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "slices" + "strings" g "github.com/onsi/ginkgo/v2" o "github.com/onsi/gomega" @@ -48,6 +49,15 @@ var _ = g.Describe("[sig-network] NetworkPolicy", func() { var violations []string for _, np := range nps.Items { + // Only check platform namespaces. This won't catch broken (on OVN-Kubernetes e.g.) NPs + // added by tests in ephemeral namespaces, but this will avoid false + // positives from tests that intentionally use named ports + // (e.g. verifying named-port flows or running on a CNI that + // supports them). + // For consistency, platform NetworkPolicies should use numeric ports across all CNIs. + if !strings.HasPrefix(np.Namespace, "openshift-") && !strings.HasPrefix(np.Namespace, "kube-") && np.Namespace != "default" { + continue + } key := fmt.Sprintf("%s/%s", np.Namespace, np.Name) skip := slices.Contains(networkPoliciesToSkip, key) for _, rule := range np.Spec.Ingress {