k8s.io/kubernetes@v1.29.3/pkg/apis/networking/fuzzer/fuzzer.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package fuzzer 18 19 import ( 20 "fmt" 21 "net/netip" 22 23 fuzz "github.com/google/gofuzz" 24 runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" 25 "k8s.io/kubernetes/pkg/apis/networking" 26 utilpointer "k8s.io/utils/pointer" 27 ) 28 29 // Funcs returns the fuzzer functions for the networking api group. 30 var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { 31 return []interface{}{ 32 func(np *networking.NetworkPolicyPeer, c fuzz.Continue) { 33 c.FuzzNoCustom(np) // fuzz self without calling this function again 34 // TODO: Implement a fuzzer to generate valid keys, values and operators for 35 // selector requirements. 36 if np.IPBlock != nil { 37 np.IPBlock = &networking.IPBlock{ 38 CIDR: "192.168.1.0/24", 39 Except: []string{"192.168.1.1/24", "192.168.1.2/24"}, 40 } 41 } 42 }, 43 func(np *networking.NetworkPolicy, c fuzz.Continue) { 44 c.FuzzNoCustom(np) // fuzz self without calling this function again 45 // TODO: Implement a fuzzer to generate valid keys, values and operators for 46 // selector requirements. 47 if len(np.Spec.PolicyTypes) == 0 { 48 np.Spec.PolicyTypes = []networking.PolicyType{networking.PolicyTypeIngress} 49 } 50 }, 51 func(path *networking.HTTPIngressPath, c fuzz.Continue) { 52 c.FuzzNoCustom(path) // fuzz self without calling this function again 53 pathTypes := []networking.PathType{networking.PathTypeExact, networking.PathTypePrefix, networking.PathTypeImplementationSpecific} 54 path.PathType = &pathTypes[c.Rand.Intn(len(pathTypes))] 55 }, 56 func(p *networking.ServiceBackendPort, c fuzz.Continue) { 57 c.FuzzNoCustom(p) 58 // clear one of the fields 59 if c.RandBool() { 60 p.Name = "" 61 if p.Number == 0 { 62 p.Number = 1 63 } 64 } else { 65 p.Number = 0 66 if p.Name == "" { 67 p.Name = "portname" 68 } 69 } 70 }, 71 func(p *networking.IngressClass, c fuzz.Continue) { 72 c.FuzzNoCustom(p) // fuzz self without calling this function again 73 // default Parameters to Cluster 74 if p.Spec.Parameters == nil || p.Spec.Parameters.Scope == nil { 75 p.Spec.Parameters = &networking.IngressClassParametersReference{ 76 Scope: utilpointer.String(networking.IngressClassParametersReferenceScopeCluster), 77 } 78 } 79 }, 80 func(obj *networking.IPAddress, c fuzz.Continue) { 81 c.FuzzNoCustom(obj) // fuzz self without calling this function again 82 // length in bytes of the IP Family: IPv4: 4 bytes IPv6: 16 bytes 83 boolean := []bool{false, true} 84 is6 := boolean[c.Rand.Intn(2)] 85 ip := generateRandomIP(is6, c) 86 obj.Name = ip 87 }, 88 func(obj *networking.ServiceCIDR, c fuzz.Continue) { 89 c.FuzzNoCustom(obj) // fuzz self without calling this function again 90 boolean := []bool{false, true} 91 92 is6 := boolean[c.Rand.Intn(2)] 93 primary := generateRandomCIDR(is6, c) 94 obj.Spec.CIDRs = []string{primary} 95 96 if boolean[c.Rand.Intn(2)] { 97 obj.Spec.CIDRs = append(obj.Spec.CIDRs, generateRandomCIDR(!is6, c)) 98 } 99 }, 100 } 101 } 102 103 func generateRandomIP(is6 bool, c fuzz.Continue) string { 104 n := 4 105 if is6 { 106 n = 16 107 } 108 bytes := make([]byte, n) 109 for i := 0; i < n; i++ { 110 bytes[i] = uint8(c.Rand.Intn(255)) 111 } 112 113 ip, ok := netip.AddrFromSlice(bytes) 114 if ok { 115 return ip.String() 116 } 117 // this should not happen 118 panic(fmt.Sprintf("invalid IP %v", bytes)) 119 } 120 121 func generateRandomCIDR(is6 bool, c fuzz.Continue) string { 122 ip, err := netip.ParseAddr(generateRandomIP(is6, c)) 123 if err != nil { 124 // generateRandomIP already panics if returns a not valid ip 125 panic(err) 126 } 127 128 n := 32 129 if is6 { 130 n = 128 131 } 132 133 bits := c.Rand.Intn(n) 134 prefix := netip.PrefixFrom(ip, bits) 135 return prefix.Masked().String() 136 }