package netpol import ( "net" "strings" "testing" corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) // FuzzTranslate_AndRender stitches the Translator and Renderer together // against synthetic NetworkPolicies built from fuzzed bytes. We are not // trying to produce *valid* policies — the goal is to confirm that: // // 1. Neither stage panics on weird input. // 2. Render output is balanced (every "{" has a matching "}"). // 3. Rendering twice is byte-stable. // 4. The Pods set in Output is consistent with Isolated (every isolated // PodKey has a matching entry in Pods). // // The translator's warn callback is captured to ensure it never panics // with unexpected message types either. func FuzzTranslate_AndRender(f *testing.F) { type seed struct { policyNS, policyName string podSelectorKey, podSelValue string peerSelectorKey, peerSelV string peerNS, peerName, peerIP string port uint16 ipBlockCIDR, ipBlockExcept string } for _, s := range []seed{ {policyNS: "ns1", policyName: "p1", podSelectorKey: "app", podSelValue: "web", port: 80}, {policyNS: "ns1", policyName: "p1", peerSelectorKey: "app", peerSelV: "client", peerNS: "ns1", peerName: "c1", peerIP: "2001:db8::aa", port: 443}, {policyNS: "ns1", policyName: "p1", ipBlockCIDR: "10.0.0.0/8", ipBlockExcept: "10.99.0.0/16", port: 0}, {policyNS: "", policyName: ""}, // pathological {policyNS: "ns1", policyName: "p1", podSelectorKey: "app\x00", podSelValue: "web\nnewline"}, {policyNS: "ns1", policyName: "p1", port: 65535}, {policyNS: "ns1", policyName: "p1", port: 1}, } { f.Add(s.policyNS, s.policyName, s.podSelectorKey, s.podSelValue, s.peerSelectorKey, s.peerSelV, s.peerNS, s.peerName, s.peerIP, s.port, s.ipBlockCIDR, s.ipBlockExcept) } f.Fuzz(func(t *testing.T, policyNS, policyName, podSelectorKey, podSelValue, peerSelectorKey, peerSelV, peerNS, peerName, peerIP string, port uint16, ipBlockCIDR, ipBlockExcept string, ) { // Build a synthetic policy. policy := netv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{Namespace: policyNS, Name: policyName}, Spec: netv1.NetworkPolicySpec{ PolicyTypes: []netv1.PolicyType{netv1.PolicyTypeIngress}, }, } if podSelectorKey != "" { policy.Spec.PodSelector = metav1.LabelSelector{ MatchLabels: map[string]string{podSelectorKey: podSelValue}, } } else { policy.Spec.PodSelector = metav1.LabelSelector{} } ingress := netv1.NetworkPolicyIngressRule{} if peerSelectorKey != "" { ingress.From = append(ingress.From, netv1.NetworkPolicyPeer{ PodSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{peerSelectorKey: peerSelV}, }, }) } if ipBlockCIDR != "" { peer := netv1.NetworkPolicyPeer{ IPBlock: &netv1.IPBlock{CIDR: ipBlockCIDR}, } if ipBlockExcept != "" { peer.IPBlock.Except = []string{ipBlockExcept} } ingress.From = append(ingress.From, peer) } if port != 0 { tcp := corev1.ProtocolTCP p := intstr.FromInt32(int32(port)) ingress.Ports = append(ingress.Ports, netv1.NetworkPolicyPort{ Protocol: &tcp, Port: &p, }) } policy.Spec.Ingress = append(policy.Spec.Ingress, ingress) // Local pod, possibly matching the policy. pod := Pod{ Namespace: "ns1", Name: "web", Labels: map[string]string{podSelectorKey: podSelValue, "app": "web"}, HostIface: "flock00000001", IPs: []net.IP{mustIP("2001:db8::1")}, } // Peer pod, possibly matching the peer selector. var peers []PeerPod if peerName != "" { peerIPParsed := net.ParseIP(peerIP) if peerIPParsed != nil { peers = append(peers, PeerPod{ Namespace: peerNS, Name: peerName, Labels: map[string]string{peerSelectorKey: peerSelV}, IPs: []net.IP{peerIPParsed}, }) } } out, err := Translate(Inputs{ LocalPods: []Pod{pod}, PeerPods: peers, Namespaces: []Namespace{ {Name: "ns1", Labels: map[string]string{"kubernetes.io/metadata.name": "ns1"}}, }, Policies: []netv1.NetworkPolicy{policy}, }, func(string) {}) if err != nil { return // any error is acceptable } // Property: every isolated PodKey appears in Output.Pods. for iso := range out.Isolated { if _, ok := out.Pods[iso.PodKey]; !ok { t.Fatalf("isolated %s has no Pods entry", iso.PodKey) } } script := Render(out) // Property: balanced braces. if got := strings.Count(script, "{") - strings.Count(script, "}"); got != 0 { t.Fatalf("unbalanced braces (%d):\n%s", got, script) } // Property: deterministic (run again, compare). script2 := Render(out) if script != script2 { t.Fatalf("Render not deterministic") } }) }