diff --git a/fuzzer/README.md b/fuzzer/README.md new file mode 100644 index 0000000000..ae6b860e73 --- /dev/null +++ b/fuzzer/README.md @@ -0,0 +1,93 @@ +# Exemplary Pod Fuzzer + +The Exemplary Pod Fuzzer is a high-fidelity synthetic pod generator designed to stress-test the Kubernetes control plane. It uses a **"Sanitize & Clone"** model: it takes a real production pod manifest as a "base", scrubs all PII/sensitive data, and preserves the exact structural complexity (volume mounts, env vars, managed fields) for benchmarking. + +## Key Features + +- **Direct Sanitization**: Automatically scrubs Names, Namespaces, UIDs, and OwnerReferences from a real pod. +- **Spec Randomization**: Randomizes all environment variable keys and values while maintaining the original count and structure. +- **ManagedFields Cloning**: Clones the exact history and field ownership of the base pod, but randomizes the internal JSON paths (supporting both `f:` and `k:` prefixes). +- **Safety by Default**: Forces pods to be unschedulable (Pending state) using non-existent nodeSelectors and schedulerNames. +- **Performance Optimized**: Uses high-performance `client-go` settings (500 QPS / 1000 Burst) and precomputes "Fuzzed Prototypes" to ensure string interning memory optimizations are correctly triggered. + +## Benchmarking with Kind + +To perform a realistic 50,000 pod stress test on a local `kind` cluster, follow these steps: + +### 1. Create a Large-Scale Kind Cluster +Standard `kind` clusters have a default `etcd` quota that is too small for 50k heavy pods. Use this configuration to increase the quota to 8GB: + +```bash +cat < kind-config.yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + kubeadmConfigPatches: + - | + kind: ClusterConfiguration + etcd: + local: + extraArgs: + quota-backend-bytes: "8589934592" +EOF + +kind create cluster --config kind-config.yaml --name fuzzer-test +``` + +### 2. Prepare the Namespace and Dependencies +Real production pods (like the templates in this repo) often have dependencies like specific **Namespaces** or **ServiceAccounts**. The fuzzer preserves these references. You must create them before injecting pods: + +```bash +# Example: Using the complex-daemonset.yaml base +kubectl create namespace fuzz-test +kubectl create serviceaccount cilium -n fuzz-test +``` + +### 3. Run the Fuzzer +Inject the pods using high concurrency. + +```bash +go run cmd/main.go \ + --base-pod templates/complex-daemonset.yaml \ + --namespace fuzz-test \ + --name-prefix representative-pod \ + --count 50000 \ + --concurrency 100 +``` + +## Usage (General) + +### Generate Pod Manifests to Disk +To generate fuzzed manifests for manual inspection: +```bash +go run cmd/main.go \ + --base-pod path/to/real-pod.yaml \ + --name-prefix representative-pod \ + --namespace my-test-ns \ + --count 1000 \ + --output-dir ./generated-pods +``` + +## Flags + +- `--base-pod`: Path to the real `v1.Pod` YAML manifest used as a structural source. +- `--name-prefix`: Prefix for the generated pod names (default: `fuzzed-pod`). +- `--namespace`: Target namespace for the generated pods (default: `fuzz-test`). +- `--count`: Number of pods to generate. +- `--offset`: Starting index for naming (useful for incremental runs). +- `--concurrency`: Number of concurrent workers (default: 50). +- `--kubeconfig`: Path to the kubeconfig file. Defaults to `$HOME/.kube/config`. +- `--output-dir`: If specified, write YAMLs to this directory instead of injecting into a cluster. + +## Verification & Metrics + +To quickly verify the number of pods in the API server storage without timing out: +```bash +kubectl get --raw /metrics | grep 'apiserver_storage_objects{resource="pods"}' +``` + +To measure control plane memory usage: +```bash +docker exec fuzzer-test-control-plane ps aux | grep -E "kube-apiserver|etcd|kube-scheduler" +``` diff --git a/fuzzer/cmd/main.go b/fuzzer/cmd/main.go new file mode 100644 index 0000000000..6178d01922 --- /dev/null +++ b/fuzzer/cmd/main.go @@ -0,0 +1,113 @@ +/* +Copyright 2026 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "flag" + "fmt" + "log" + "os" + "time" + + v1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/perf-tests/fuzzer" + "sigs.k8s.io/yaml" +) + +func main() { + // General settings + count := flag.Int("count", 1000, "Number of fuzzed pods to generate.") + offset := flag.Int("offset", 0, "Starting index for pod naming, useful for incremental runs.") + basePodPath := flag.String("base-pod", "templates/complex-daemonset.yaml", "Path to the real Pod YAML manifest used as a structural template.") + namespace := flag.String("namespace", "fuzz-test", "Target namespace for the generated pods. Ensure this exists in the cluster.") + namePrefix := flag.String("name-prefix", "fuzzed-pod", "Prefix used for naming fuzzed pods (e.g., fuzzed-pod-1, fuzzed-pod-2).") + + // Mode-specific settings + outputDir := flag.String("output-dir", "", "If specified, write Pod YAMLs to this directory instead of injecting into a cluster.") + concurrency := flag.Int("concurrency", 50, "Number of concurrent workers used for generation or injection.") + kubeconfig := flag.String("kubeconfig", "", "Path to the kubeconfig file. Defaults to $HOME/.kube/config.") + + flag.Parse() + + // Load the template pod from disk. + basePodData, err := os.ReadFile(*basePodPath) + if err != nil { + log.Fatalf("Failed to read base pod file: %v", err) + } + var basePod v1.Pod + if err := yaml.Unmarshal(basePodData, &basePod); err != nil { + log.Fatalf("Failed to unmarshal base pod: %v", err) + } + + var clientset *kubernetes.Clientset + // Operational Path 1: Cluster Injection + // If outputDir is empty, we attempt to connect to a cluster and inject pods directly. + if *outputDir == "" { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + if *kubeconfig != "" { + loadingRules.ExplicitPath = *kubeconfig + } + config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}).ClientConfig() + if err != nil { + log.Fatalf("Failed to load kubeconfig: %v", err) + } + + // Configure high-performance injection settings to stress the control plane. + // These settings allow for rapid pod creation without being throttled by client-go. + config.QPS = 500 + config.Burst = 1000 + clientset, err = kubernetes.NewForConfig(config) + if err != nil { + log.Fatalf("Failed to create clientset: %v", err) + } + } + + creator := fuzzer.NewExemplaryPodCreator(clientset, time.Now().UnixNano(), *namePrefix, *namespace) + + progress := func(current, total int) { + fmt.Printf("\rProgress: %d/%d pods (%.1f%%)", current, total, float64(current)/float64(total)*100) + if current == total { + fmt.Println() + } + } + + start := time.Now() + if *outputDir != "" { + // Operational Path 2: Manifest Generation + // Write YAMLs to disk for manual inspection or external loading. + fmt.Printf("Writing %d fuzzed pod manifests to %s (base: %s)...\n", *count, *outputDir, *basePodPath) + dir, err := creator.WriteExemplaryPodsToDir(context.Background(), &basePod, *count, *offset, *concurrency, *outputDir, progress) + if err != nil { + log.Fatalf("\nFailed to write pods: %v", err) + } + fmt.Printf("Successfully created %d pod manifests in: %s\n", *count, dir) + } else { + // Operational Path 1: Cluster Injection (Execution) + fmt.Printf("Injecting %d fuzzed pods into cluster (base: %s)...\n", *count, *basePodPath) + err := creator.CreateExemplaryPods(context.Background(), &basePod, *count, *offset, *concurrency, progress) + if err != nil { + log.Fatalf("\nFailed to inject pods: %v", err) + } + fmt.Printf("Successfully injected %d pods.\n", *count) + } + + duration := time.Since(start) + fmt.Printf("Time taken: %v\n", duration) +} diff --git a/fuzzer/examples/representative-infrastructure-pod.yaml b/fuzzer/examples/representative-infrastructure-pod.yaml new file mode 100644 index 0000000000..2c8707bbd8 --- /dev/null +++ b/fuzzer/examples/representative-infrastructure-pod.yaml @@ -0,0 +1,1242 @@ +apiVersion: v1 +kind: Pod +metadata: + name: representative-infrastructure-pod-0 + namespace: default + uid: fuzzed-uid-00000000-9pPfd2dd + annotations: + cluster-autoscaler.kubernetes.io/enable-ds-eviction: fuzzed-val-o6U5ghpJSbYGbte5 + components.gke.io/component-name: fuzzed-val-E38Wq2JBHd5rDGSS + components.gke.io/component-version: fuzzed-val-MJqGKEdNysOsEDId + prometheus.io/port: fuzzed-val-SeNieV5AUpIh2y3Z + prometheus.io/scrape: fuzzed-val-MA6FU3Qg8sNKK01S + generation: 1 + labels: + controller-revision-hash: fuzzed-label-3FP9xNIO + k8s-app: fuzzed-label-uuW3P5ia + pod-template-generation: fuzzed-label-4IqogvHL + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:fuzzed_field_EItr: + f:fuzzed_field_3xxQ: {} + f:fuzzed_field_7F1p: + .: {} + k:{"id":13,"name":"fuzzed-node-FwZt"}: + .: {} + f:fuzzed_field_LuOM: + .: {} + f:fuzzed_field_O6dW: {} + f:fuzzed_field_kUxe: + .: {} + f:fuzzed_field_7Uyf: {} + f:fuzzed_field_TW6D: {} + f:fuzzed_field_WU3O: {} + f:fuzzed_field_b5nt: + .: {} + k:{"id":40,"name":"fuzzed-node-YTv7"}: + .: {} + f:fuzzed_field_2i9o: + .: {} + f:fuzzed_field_ZdwT: {} + f:fuzzed_field_p4xF: {} + k:{"id":54,"name":"fuzzed-node-B40n"}: + .: {} + f:fuzzed_field_DMtL: {} + f:fuzzed_field_TiTb: + .: {} + f:fuzzed_field_eBfh: {} + k:{"id":91,"name":"fuzzed-node-34MX"}: + .: {} + f:fuzzed_field_j9Z0: + .: {} + f:fuzzed_field_u620: {} + f:fuzzed_field_stsf: {} + f:fuzzed_field_cdbB: + .: {} + f:fuzzed_field_8x6d: + .: {} + f:fuzzed_field_Jqyk: {} + f:fuzzed_field_oGev: {} + f:fuzzed_field_iHV8: {} + f:fuzzed_field_p2xL: {} + f:fuzzed_field_qenB: {} + f:fuzzed_field_vRvM: + .: {} + k:{"id":67,"name":"fuzzed-node-4vyu"}: + .: {} + f:fuzzed_field_6CAF: {} + f:fuzzed_field_LgRl: {} + f:fuzzed_field_a289: {} + k:{"id":86,"name":"fuzzed-node-8U9r"}: + .: {} + f:fuzzed_field_s019: {} + f:fuzzed_field_w0un: {} + f:fuzzed_field_wXfa: {} + k:{"id":51,"name":"fuzzed-node-7UDG"}: + .: {} + f:fuzzed_field_1XLH: + .: {} + f:fuzzed_field_tmZ8: + .: {} + f:fuzzed_field_LL2N: {} + f:fuzzed_field_6bCn: + .: {} + k:{"id":41,"name":"fuzzed-node-f6Tn"}: + .: {} + f:fuzzed_field_jdko: {} + f:fuzzed_field_jmgb: {} + f:fuzzed_field_25jj: {} + f:fuzzed_field_CpIH: {} + f:fuzzed_field_EjAk: + .: {} + k:{"id":29,"name":"fuzzed-node-z2Z2"}: + .: {} + f:fuzzed_field_f9L2: {} + f:fuzzed_field_oYYt: {} + f:fuzzed_field_J3Rs: {} + f:fuzzed_field_VVy3: {} + f:fuzzed_field_hTmx: {} + f:fuzzed_field_kmhu: + .: {} + f:fuzzed_field_2heo: + .: {} + f:fuzzed_field_Bbpb: {} + f:fuzzed_field_c7Zf: {} + f:fuzzed_field_o9gq: {} + k:{"id":80,"name":"fuzzed-node-YRAk"}: + .: {} + f:fuzzed_field_5KnV: + .: {} + k:{"id":0,"name":"fuzzed-node-tqpl"}: + .: {} + f:fuzzed_field_hWG9: {} + f:fuzzed_field_iYTw: {} + f:fuzzed_field_pcez: {} + k:{"id":3,"name":"fuzzed-node-O3JT"}: + .: {} + f:fuzzed_field_Hbzm: {} + f:fuzzed_field_Ziq7: {} + f:fuzzed_field_bb6T: {} + k:{"id":29,"name":"fuzzed-node-aVKZ"}: + .: {} + f:fuzzed_field_CFJ3: {} + f:fuzzed_field_Vd7A: {} + f:fuzzed_field_v0d3: {} + k:{"id":47,"name":"fuzzed-node-0EtE"}: + .: {} + f:fuzzed_field_An3m: {} + f:fuzzed_field_BCcb: {} + f:fuzzed_field_Xy2d: {} + k:{"id":53,"name":"fuzzed-node-NSVb"}: + .: {} + f:fuzzed_field_8sb8: {} + f:fuzzed_field_uiBt: {} + f:fuzzed_field_uktn: {} + k:{"id":66,"name":"fuzzed-node-VyJ5"}: + .: {} + f:fuzzed_field_Gco8: {} + f:fuzzed_field_QdJ9: {} + f:fuzzed_field_aurY: {} + k:{"id":72,"name":"fuzzed-node-qqOM"}: + .: {} + f:fuzzed_field_7Aoh: {} + f:fuzzed_field_kIqN: {} + f:fuzzed_field_qhJi: {} + k:{"id":84,"name":"fuzzed-node-BsnO"}: + .: {} + f:fuzzed_field_RUo5: {} + f:fuzzed_field_djMU: {} + f:fuzzed_field_hUwi: {} + k:{"id":89,"name":"fuzzed-node-GTMI"}: + .: {} + f:fuzzed_field_RIWT: {} + f:fuzzed_field_WWss: {} + f:fuzzed_field_8Q0X: {} + f:fuzzed_field_AEHV: {} + f:fuzzed_field_DdFk: {} + f:fuzzed_field_FmyH: + .: {} + k:{"id":27,"name":"fuzzed-node-feZz"}: + .: {} + f:fuzzed_field_1Wdd: + .: {} + f:fuzzed_field_G71g: {} + f:fuzzed_field_VIqJ: {} + f:fuzzed_field_Iop4: {} + f:fuzzed_field_OYSA: {} + f:fuzzed_field_WAES: + .: {} + f:fuzzed_field_rmJW: + .: {} + f:fuzzed_field_IB6L: {} + f:fuzzed_field_MNp4: {} + f:fuzzed_field_Zyeb: + .: {} + f:fuzzed_field_AUzI: + .: {} + f:fuzzed_field_N2CH: {} + f:fuzzed_field_Ey04: {} + f:fuzzed_field_nRXN: {} + f:fuzzed_field_uci8: {} + f:fuzzed_field_zfGJ: {} + f:fuzzed_field_C6kr: {} + f:fuzzed_field_ETdR: {} + f:fuzzed_field_N0Zg: {} + f:fuzzed_field_No07: {} + f:fuzzed_field_P7Z8: {} + f:fuzzed_field_PK3p: {} + f:fuzzed_field_TO4k: {} + f:fuzzed_field_ToZv: {} + f:fuzzed_field_bWyr: {} + f:fuzzed_field_gVZI: {} + f:fuzzed_field_j9w8: + .: {} + f:fuzzed_field_O0Br: + .: {} + f:fuzzed_field_y8jQ: {} + f:fuzzed_field_kCNo: {} + f:fuzzed_field_mkzp: + k:{"id":40,"name":"fuzzed-node-o0gi"}: + .: {} + f:fuzzed_field_0fWP: {} + f:fuzzed_field_0jjo: {} + f:fuzzed_field_5pMG: + .: {} + k:{"id":14,"name":"fuzzed-node-UwRT"}: + .: {} + f:fuzzed_field_B8aW: + .: {} + f:fuzzed_field_x2Cu: {} + f:fuzzed_field_JGzF: {} + k:{"id":22,"name":"fuzzed-node-oyYM"}: + .: {} + f:fuzzed_field_DdIL: + .: {} + f:fuzzed_field_OqIl: {} + f:fuzzed_field_Is3M: {} + k:{"id":29,"name":"fuzzed-node-OeKC"}: + .: {} + f:fuzzed_field_7yEA: {} + f:fuzzed_field_Z8oq: + .: {} + f:fuzzed_field_jJdj: {} + k:{"id":29,"name":"fuzzed-node-k4sE"}: + .: {} + f:fuzzed_field_6NjS: {} + f:fuzzed_field_s8rL: {} + k:{"id":71,"name":"fuzzed-node-XaZg"}: + .: {} + f:fuzzed_field_RmaJ: + .: {} + f:fuzzed_field_9tNP: {} + f:fuzzed_field_tBXs: {} + k:{"id":71,"name":"fuzzed-node-oW4k"}: + .: {} + f:fuzzed_field_DYLJ: {} + f:fuzzed_field_OLYn: + .: {} + f:fuzzed_field_4wdL: {} + k:{"id":81,"name":"fuzzed-node-OTEK"}: + .: {} + f:fuzzed_field_IceV: {} + f:fuzzed_field_ZqNA: + .: {} + f:fuzzed_field_Ui0z: {} + k:{"id":82,"name":"fuzzed-node-A6sR"}: + .: {} + f:fuzzed_field_2oKw: {} + f:fuzzed_field_U6kS: {} + k:{"id":84,"name":"fuzzed-node-k9iy"}: + .: {} + f:fuzzed_field_Pxvw: + .: {} + f:fuzzed_field_Ie1v: {} + f:fuzzed_field_XKtK: {} + k:{"id":89,"name":"fuzzed-node-1byw"}: + .: {} + f:fuzzed_field_HIXc: {} + f:fuzzed_field_iuvu: {} + f:fuzzed_field_7usg: + .: {} + k:{"id":14,"name":"fuzzed-node-tCjb"}: + .: {} + f:fuzzed_field_96es: {} + f:fuzzed_field_Q7Ba: {} + f:fuzzed_field_moeW: {} + k:{"id":17,"name":"fuzzed-node-60m1"}: + .: {} + f:fuzzed_field_hVtc: {} + f:fuzzed_field_o7j0: {} + f:fuzzed_field_s2rg: {} + k:{"id":18,"name":"fuzzed-node-rbvf"}: + .: {} + f:fuzzed_field_8QFB: {} + f:fuzzed_field_OYeY: {} + f:fuzzed_field_jEgs: {} + k:{"id":21,"name":"fuzzed-node-LNhG"}: + .: {} + f:fuzzed_field_ckzT: {} + f:fuzzed_field_pLe2: {} + f:fuzzed_field_zch5: {} + k:{"id":27,"name":"fuzzed-node-bGut"}: + .: {} + f:fuzzed_field_nHNB: {} + f:fuzzed_field_oBR2: {} + k:{"id":28,"name":"fuzzed-node-cDGl"}: + .: {} + f:fuzzed_field_Kci8: {} + f:fuzzed_field_T9ey: {} + f:fuzzed_field_TN98: {} + f:fuzzed_field_zLi2: {} + k:{"id":28,"name":"fuzzed-node-pa3i"}: + .: {} + f:fuzzed_field_IuBf: {} + f:fuzzed_field_YAgk: {} + f:fuzzed_field_lbNX: {} + k:{"id":40,"name":"fuzzed-node-xVgX"}: + .: {} + f:fuzzed_field_1pPj: {} + f:fuzzed_field_zgSg: {} + k:{"id":49,"name":"fuzzed-node-o5XR"}: + .: {} + f:fuzzed_field_Bd80: {} + f:fuzzed_field_hG6o: {} + f:fuzzed_field_zLNI: {} + k:{"id":52,"name":"fuzzed-node-qk3D"}: + .: {} + f:fuzzed_field_5Ls5: {} + f:fuzzed_field_iukX: {} + k:{"id":58,"name":"fuzzed-node-QZoO"}: + .: {} + f:fuzzed_field_LX09: {} + f:fuzzed_field_kUax: {} + f:fuzzed_field_nznq: {} + k:{"id":74,"name":"fuzzed-node-Tppi"}: + .: {} + f:fuzzed_field_RdKU: {} + f:fuzzed_field_aQlA: {} + f:fuzzed_field_z28E: {} + k:{"id":75,"name":"fuzzed-node-dIaU"}: + .: {} + f:fuzzed_field_rtxN: {} + f:fuzzed_field_zqL0: {} + k:{"id":93,"name":"fuzzed-node-Tnmz"}: + .: {} + f:fuzzed_field_C8oz: {} + f:fuzzed_field_uXyu: {} + k:{"id":96,"name":"fuzzed-node-62GS"}: + .: {} + f:fuzzed_field_esY8: {} + f:fuzzed_field_pvq3: {} + f:fuzzed_field_vKdt: {} + k:{"id":97,"name":"fuzzed-node-A8Fj"}: + .: {} + f:fuzzed_field_dfHJ: {} + f:fuzzed_field_ebXS: {} + f:fuzzed_field_EBxH: {} + f:fuzzed_field_Psa1: + .: {} + k:{"id":58,"name":"fuzzed-node-xZXp"}: + .: {} + f:fuzzed_field_7npr: {} + f:fuzzed_field_9IJW: {} + f:fuzzed_field_36vz: {} + f:fuzzed_field_awg2: {} + f:fuzzed_field_SkJu: {} + f:fuzzed_field_SvW0: + .: {} + f:fuzzed_field_5dPX: {} + f:fuzzed_field_EICo: {} + f:fuzzed_field_Hyv4: {} + f:fuzzed_field_JWuf: + .: {} + f:fuzzed_field_0kgk: {} + f:fuzzed_field_8do1: {} + f:fuzzed_field_G2dY: {} + f:fuzzed_field_Sn7F: {} + f:fuzzed_field_UPQl: {} + f:fuzzed_field_tqaW: {} + f:fuzzed_field_U7ti: {} + f:fuzzed_field_ijE4: {} + f:fuzzed_field_o2AT: + .: {} + f:fuzzed_field_7lpO: {} + f:fuzzed_field_A51w: {} + f:fuzzed_field_HCy2: {} + f:fuzzed_field_YVta: + .: {} + f:fuzzed_field_406c: {} + f:fuzzed_field_DlLX: {} + f:fuzzed_field_Zthr: {} + f:fuzzed_field_dS0U: {} + f:fuzzed_field_nwYu: {} + f:fuzzed_field_cSyN: {} + f:fuzzed_field_pRFR: {} + f:fuzzed_field_r2fM: + .: {} + f:fuzzed_field_MLzk: + .: {} + f:fuzzed_field_5sAL: {} + f:fuzzed_field_PDsx: {} + f:fuzzed_field_rvCA: + .: {} + f:fuzzed_field_08AM: {} + f:fuzzed_field_yAcK: + .: {} + f:fuzzed_field_Se06: {} + f:fuzzed_field_wmPa: + .: {} + f:fuzzed_field_R2wK: {} + f:fuzzed_field_XHAG: {} + f:fuzzed_field_b2rE: {} + f:fuzzed_field_bpRA: + .: {} + f:fuzzed_field_D3bG: {} + f:fuzzed_field_RQMC: {} + f:fuzzed_field_W7VZ: {} + f:fuzzed_field_aFWk: {} + f:fuzzed_field_p3Eb: {} + f:fuzzed_field_dwLK: {} + k:{"id":81,"name":"fuzzed-node-u1b7"}: + .: {} + f:fuzzed_field_0ev4: + .: {} + f:fuzzed_field_0ffO: {} + f:fuzzed_field_8gTF: + .: {} + f:fuzzed_field_QjB2: {} + f:fuzzed_field_PALX: {} + f:fuzzed_field_S0Iy: {} + f:fuzzed_field_bsyK: {} + f:fuzzed_field_hHrN: + .: {} + f:fuzzed_field_m1SU: {} + f:fuzzed_field_q18E: {} + f:fuzzed_field_HEwE: + .: {} + f:fuzzed_field_6Wsk: + .: {} + f:fuzzed_field_LoOO: {} + f:fuzzed_field_NJOY: {} + f:fuzzed_field_Yse0: + .: {} + f:fuzzed_field_eSj7: {} + f:fuzzed_field_l2hk: {} + f:fuzzed_field_JLDv: {} + f:fuzzed_field_dcAD: {} + f:fuzzed_field_fgnm: + .: {} + k:{"id":42,"name":"fuzzed-node-eerT"}: + .: {} + f:fuzzed_field_UsOi: {} + f:fuzzed_field_dPY6: {} + f:fuzzed_field_jIMD: {} + f:fuzzed_field_lqAD: {} + f:fuzzed_field_mF4F: {} + f:fuzzed_field_pgVv: + .: {} + k:{"id":38,"name":"fuzzed-node-2Kr8"}: + .: {} + f:fuzzed_field_lEJR: {} + f:fuzzed_field_lJjA: + .: {} + f:fuzzed_field_6kwz: {} + k:{"id":44,"name":"fuzzed-node-ONVK"}: + .: {} + f:fuzzed_field_9brQ: {} + f:fuzzed_field_FW8x: {} + k:{"id":46,"name":"fuzzed-node-OuF6"}: + .: {} + f:fuzzed_field_C1Iv: {} + f:fuzzed_field_Yyqt: {} + k:{"id":55,"name":"fuzzed-node-bTsj"}: + .: {} + f:fuzzed_field_I4pW: {} + f:fuzzed_field_xMvM: + .: {} + f:fuzzed_field_UR22: {} + k:{"id":57,"name":"fuzzed-node-R7n0"}: + .: {} + f:fuzzed_field_K2ZZ: {} + f:fuzzed_field_sDmJ: {} + k:{"id":58,"name":"fuzzed-node-diu5"}: + .: {} + f:fuzzed_field_LDZY: {} + f:fuzzed_field_jVLH: {} + k:{"id":65,"name":"fuzzed-node-E2CZ"}: + .: {} + f:fuzzed_field_bugy: {} + f:fuzzed_field_k90A: {} + k:{"id":74,"name":"fuzzed-node-77oe"}: + .: {} + f:fuzzed_field_Azsa: {} + f:fuzzed_field_bESh: {} + k:{"id":76,"name":"fuzzed-node-tpCx"}: + .: {} + f:fuzzed_field_Frvi: + .: {} + f:fuzzed_field_CJ5T: {} + f:fuzzed_field_fIBB: {} + k:{"id":85,"name":"fuzzed-node-5eLb"}: + .: {} + f:fuzzed_field_6DTy: {} + f:fuzzed_field_NoX6: + .: {} + f:fuzzed_field_yGuM: {} + k:{"id":94,"name":"fuzzed-node-ymMl"}: + .: {} + f:fuzzed_field_JmsN: {} + f:fuzzed_field_fyuE: + .: {} + f:fuzzed_field_dUgQ: {} + k:{"id":97,"name":"fuzzed-node-s7o8"}: + .: {} + f:fuzzed_field_g9FU: {} + f:fuzzed_field_mWeV: {} + f:fuzzed_field_n6PT: {} + f:fuzzed_field_tn7k: + .: {} + k:{"id":5,"name":"fuzzed-node-JQMs"}: + .: {} + f:fuzzed_field_B3xg: {} + f:fuzzed_field_p2t3: + .: {} + f:fuzzed_field_ACQB: {} + f:fuzzed_field_GScf: {} + k:{"id":14,"name":"fuzzed-node-9fXS"}: + .: {} + f:fuzzed_field_LkhT: + .: {} + f:fuzzed_field_3Yuj: {} + f:fuzzed_field_vlgq: {} + f:fuzzed_field_pyPX: {} + k:{"id":14,"name":"fuzzed-node-sdNJ"}: + .: {} + f:fuzzed_field_FIjM: + .: {} + f:fuzzed_field_6vRI: {} + f:fuzzed_field_XGzb: {} + f:fuzzed_field_x4Wu: {} + f:fuzzed_field_URrI: {} + k:{"id":21,"name":"fuzzed-node-p7yn"}: + .: {} + f:fuzzed_field_WQf2: + .: {} + f:fuzzed_field_02vG: {} + f:fuzzed_field_zH8R: {} + f:fuzzed_field_eNvy: {} + k:{"id":24,"name":"fuzzed-node-cqbv"}: + .: {} + f:fuzzed_field_gpMM: {} + f:fuzzed_field_zQ9e: + .: {} + f:fuzzed_field_DDeL: {} + f:fuzzed_field_pmFE: {} + k:{"id":26,"name":"fuzzed-node-PYCK"}: + .: {} + f:fuzzed_field_ck7E: {} + f:fuzzed_field_pqjZ: + .: {} + f:fuzzed_field_9axx: {} + f:fuzzed_field_CEI3: {} + k:{"id":28,"name":"fuzzed-node-vH7o"}: + .: {} + f:fuzzed_field_FQnu: {} + f:fuzzed_field_VICR: {} + k:{"id":42,"name":"fuzzed-node-RbWo"}: + .: {} + f:fuzzed_field_1YI4: {} + f:fuzzed_field_QAJP: + .: {} + f:fuzzed_field_eaIM: {} + f:fuzzed_field_maf0: {} + k:{"id":46,"name":"fuzzed-node-l4Ci"}: + .: {} + f:fuzzed_field_Fqgv: {} + f:fuzzed_field_t5uS: + .: {} + f:fuzzed_field_HODS: {} + f:fuzzed_field_iPxU: {} + f:fuzzed_field_vuQm: {} + k:{"id":50,"name":"fuzzed-node-C0hr"}: + .: {} + f:fuzzed_field_hAl2: + .: {} + f:fuzzed_field_ax7z: {} + f:fuzzed_field_pW8P: {} + f:fuzzed_field_weYQ: {} + k:{"id":55,"name":"fuzzed-node-Ntbb"}: + .: {} + f:fuzzed_field_0zvS: + .: {} + f:fuzzed_field_GWQF: {} + f:fuzzed_field_iOv3: {} + f:fuzzed_field_Q1I9: {} + k:{"id":55,"name":"fuzzed-node-s9GS"}: + .: {} + f:fuzzed_field_p2Ju: + .: {} + f:fuzzed_field_JwoE: {} + f:fuzzed_field_ecX7: {} + f:fuzzed_field_wAVA: {} + k:{"id":56,"name":"fuzzed-node-61UW"}: + .: {} + f:fuzzed_field_2Bpn: + .: {} + f:fuzzed_field_QFIZ: {} + f:fuzzed_field_Wqax: {} + f:fuzzed_field_Urfj: {} + k:{"id":61,"name":"fuzzed-node-N9tV"}: + .: {} + f:fuzzed_field_EuHt: {} + f:fuzzed_field_yjp5: + .: {} + f:fuzzed_field_cmUm: {} + f:fuzzed_field_vLE0: {} + k:{"id":64,"name":"fuzzed-node-ddC8"}: + .: {} + f:fuzzed_field_asN0: + .: {} + f:fuzzed_field_0ct2: {} + f:fuzzed_field_SYWw: {} + f:fuzzed_field_aywx: {} + f:fuzzed_field_oczB: {} + f:fuzzed_field_nzD1: {} + k:{"id":87,"name":"fuzzed-node-DGNM"}: + .: {} + f:fuzzed_field_4uJm: + .: {} + f:fuzzed_field_8WZL: {} + f:fuzzed_field_E1t5: {} + f:fuzzed_field_okcE: {} + f:fuzzed_field_wpdL: {} + f:fuzzed_field_JpM1: {} + k:{"id":90,"name":"fuzzed-node-gjbA"}: + .: {} + f:fuzzed_field_29Js: + .: {} + f:fuzzed_field_Lf8n: {} + f:fuzzed_field_r6Gg: {} + f:fuzzed_field_X7AF: {} + k:{"id":93,"name":"fuzzed-node-Zh1b"}: + .: {} + f:fuzzed_field_NnVp: {} + f:fuzzed_field_OXVf: + .: {} + f:fuzzed_field_JA8v: {} + f:fuzzed_field_bmL7: {} + k:{"id":94,"name":"fuzzed-node-pHAh"}: + .: {} + f:fuzzed_field_HnQF: {} + f:fuzzed_field_Kyws: + .: {} + f:fuzzed_field_LG6S: {} + f:fuzzed_field_xrl5: {} + k:{"id":95,"name":"fuzzed-node-dqoG"}: + .: {} + f:fuzzed_field_2PcZ: + .: {} + f:fuzzed_field_2RDF: {} + f:fuzzed_field_81cf: {} + f:fuzzed_field_T4Xg: {} + f:fuzzed_field_f3pD: + f:fuzzed_field_6zhT: + .: {} + f:fuzzed_field_87aX: {} + f:fuzzed_field_eYmQ: {} + f:fuzzed_field_jzaU: {} + f:fuzzed_field_8hUA: + .: {} + f:fuzzed_field_EYyw: {} + f:fuzzed_field_LwLm: {} + f:fuzzed_field_ZV7a: {} + f:fuzzed_field_dwuM: {} + f:fuzzed_field_fkto: {} + f:fuzzed_field_OLmM: {} + f:fuzzed_field_mVz6: + .: {} + k:{"id":22,"name":"fuzzed-node-jZau"}: {} + manager: kube-controller-manager + operation: Update + time: "2026-02-09T03:24:00Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:fuzzed_field_5ifW: + f:fuzzed_field_2Fid: + .: {} + k:{"id":85,"name":"fuzzed-node-GWnj"}: + .: {} + f:fuzzed_field_ag1f: {} + f:fuzzed_field_3RV8: {} + f:fuzzed_field_6na6: + k:{"id":13,"name":"fuzzed-node-Ww7N"}: + .: {} + f:fuzzed_field_5oVO: {} + f:fuzzed_field_MfzX: {} + f:fuzzed_field_Mjmy: {} + f:fuzzed_field_Q0r4: {} + f:fuzzed_field_aA5b: {} + k:{"id":33,"name":"fuzzed-node-D3yj"}: + .: {} + f:fuzzed_field_DYpM: {} + f:fuzzed_field_R1sP: {} + f:fuzzed_field_ZMEm: {} + f:fuzzed_field_ehob: {} + f:fuzzed_field_lH0a: {} + k:{"id":44,"name":"fuzzed-node-pGzT"}: + f:fuzzed_field_vqE3: {} + k:{"id":77,"name":"fuzzed-node-lLIu"}: + .: {} + f:fuzzed_field_25vj: {} + f:fuzzed_field_MKvC: {} + f:fuzzed_field_PGdV: {} + f:fuzzed_field_snuG: {} + f:fuzzed_field_vXlE: {} + k:{"id":92,"name":"fuzzed-node-yaZZ"}: + .: {} + f:fuzzed_field_8xrw: {} + f:fuzzed_field_A5ti: {} + f:fuzzed_field_GP6V: {} + f:fuzzed_field_Iy0Q: {} + f:fuzzed_field_jeuI: {} + f:fuzzed_field_9rmW: {} + f:fuzzed_field_EPHI: {} + f:fuzzed_field_GjPf: {} + f:fuzzed_field_K4BR: {} + f:fuzzed_field_OTYQ: {} + f:fuzzed_field_hVAr: {} + f:fuzzed_field_rGO0: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-02-09T03:29:49Z" + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: DaemonSet + name: fuzzed-owner-xh64Xk3K + uid: fuzzed-uid-vPTLPxoE +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: metadata.name + operator: In + values: + - gke-tpu-6291e798-nd5p + automountServiceAccountToken: false + containers: + - args: + - | + exec {BASH_XTRACEFD}>&1 && set -x + + if [[ -n "$${CILIUM_CONFIG_MAP}" ]] \ + && [[ ! -f "$${CILIUM_CONFIG_MAP}/mtu" ]] \ + && [[ -n "$${MTU_DEVICE_IP}" ]]; then + # Get mtu of the interface which has ip address '$${MTU_DEVICE_IP}' + mtu="$$(ip addr show to "$${MTU_DEVICE_IP}" | grep mtu | awk '{for (I=1;I Key in an associative list (e.g., container name). + // 'f:' -> A field in an object. + if strings.HasPrefix(oldKey, "k:") { + f.rngMu.Lock() + idx := f.rng.Intn(100) + f.rngMu.Unlock() + newKey = fmt.Sprintf("k:{\"id\":%d,\"name\":\"fuzzed-node-%s\"}", idx, f.randomString(4)) + } else if strings.HasPrefix(oldKey, "f:") { + newKey = "f:fuzzed_field_" + f.randomString(4) + } else if oldKey == "." { + newKey = "." + } else { + newKey = oldKey + } + + if subMap, ok := val.(map[string]interface{}); ok { + f.fuzzMapRecursive(subMap) + m[newKey] = subMap + } else { + m[newKey] = val + } + } +} + +func (f *ExemplaryPodFuzzer) randomString(length int) string { + if length <= 0 { + return "" + } + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + b := make([]byte, length) + f.rngMu.Lock() + defer f.rngMu.Unlock() + for i := range b { + b[i] = charset[f.rng.Intn(len(charset))] + } + return string(b) +} + +// ProgressCallback is called periodically during pod generation. +type ProgressCallback func(current, total int) + +// ExemplaryPodCreator handles the creation of exemplary pods in a cluster. +type ExemplaryPodCreator struct { + client clientset.Interface + fuzzer *ExemplaryPodFuzzer +} + +// NewExemplaryPodCreator creates a new creator with settings. +func NewExemplaryPodCreator(client clientset.Interface, seed int64, namePrefix, namespace string) *ExemplaryPodCreator { + return &ExemplaryPodCreator{ + client: client, + fuzzer: NewExemplaryPodFuzzer(seed, namePrefix, namespace), + } +} + +// CreateExemplaryPods creates a batch of pods concurrently based on a base pod. +func (c *ExemplaryPodCreator) CreateExemplaryPods(ctx context.Context, base *v1.Pod, count int, offset int, concurrency int, progress ProgressCallback) error { + return c.processExemplaryPods(ctx, base, count, offset, concurrency, progress, func(pod *v1.Pod) error { + return CreatePodWithRetries(c.client, pod.Namespace, pod) + }) +} + +// WriteExemplaryPodsToDir writes a batch of pod manifests to a directory. +func (c *ExemplaryPodCreator) WriteExemplaryPodsToDir(ctx context.Context, base *v1.Pod, count int, offset int, concurrency int, dirPath string, progress ProgressCallback) (string, error) { + if dirPath == "" { + var err error + dirPath, err = os.MkdirTemp("", "exemplary-pods-") + if err != nil { + return "", fmt.Errorf("failed to create temp dir: %w", err) + } + } + + if err := os.MkdirAll(dirPath, 0755); err != nil { + return "", fmt.Errorf("failed to create directory %s: %w", dirPath, err) + } + + err := c.processExemplaryPods(ctx, base, count, offset, concurrency, progress, func(pod *v1.Pod) error { + data, err := yaml.Marshal(pod) + if err != nil { + return fmt.Errorf("failed to marshal pod %s: %w", pod.Name, err) + } + filename := filepath.Join(dirPath, fmt.Sprintf("%s.yaml", pod.Name)) + if err := os.WriteFile(filename, data, 0644); err != nil { + return fmt.Errorf("failed to write pod file %s: %w", filename, err) + } + return nil + }) + + return dirPath, err +} + +func (c *ExemplaryPodCreator) processExemplaryPods(ctx context.Context, base *v1.Pod, count int, offset int, concurrency int, progress ProgressCallback, processFunc func(*v1.Pod) error) error { + g, ctx := errgroup.WithContext(ctx) + podsChan := make(chan int, count) + + // Producer + go func() { + defer close(podsChan) + for i := range count { + select { + case podsChan <- i + offset: + case <-ctx.Done(): + return + } + } + }() + + // Consumers + var processed int64 + for range concurrency { + g.Go(func() error { + for id := range podsChan { + pod := c.fuzzer.FuzzPod(base, id) + if err := processFunc(pod); err != nil { + return err + } + + if progress != nil { + val := atomic.AddInt64(&processed, 1) + if val%100 == 0 || val == int64(count) { + progress(int(val), count) + } + } + } + return nil + }) + } + + return g.Wait() +} diff --git a/fuzzer/fuzzer_test.go b/fuzzer/fuzzer_test.go new file mode 100644 index 0000000000..fcc84137c1 --- /dev/null +++ b/fuzzer/fuzzer_test.go @@ -0,0 +1,139 @@ +/* +Copyright 2026 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fuzzer + +import ( + "context" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestExemplaryPodFuzzer(t *testing.T) { + // Intent: Verify the 'Sanitize & Clone' model correctly scrubs PII + // while maintaining structural identicality across multiple generated pods. + fuzzer := NewExemplaryPodFuzzer(42, "fuzzed-pod", "fuzzed-ns") + + basePod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "original-pod", + Namespace: "original-ns", + Annotations: map[string]string{ + "sensitive-info": "secret-data", + }, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "original-owner", + UID: "original-uid", + }, + }, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "web", + Image: "nginx", + Env: []v1.EnvVar{ + {Name: "DB_PASSWORD", Value: "password123"}, + }, + }, + }, + }, + } + + pod1 := fuzzer.FuzzPod(basePod, 1) + pod2 := fuzzer.FuzzPod(basePod, 2) + + // Verify basic fields + assert.Equal(t, "fuzzed-pod-1", pod1.Name) + assert.Equal(t, "fuzzed-pod-2", pod2.Name) + assert.Equal(t, "fuzzed-ns", pod1.Namespace) + + // Verify sanitization (no original names/data) + assert.NotEqual(t, "original-pod", pod1.Name) + assert.NotEqual(t, "secret-data", pod1.Annotations["sensitive-info"]) + assert.Contains(t, pod1.Annotations["sensitive-info"], "fuzzed-val-") + + // Verify Env Vars (Keys and Values fuzzed) + assert.Len(t, pod1.Spec.Containers[0].Env, 1) + assert.NotEqual(t, "DB_PASSWORD", pod1.Spec.Containers[0].Env[0].Name) + assert.NotEqual(t, "password123", pod1.Spec.Containers[0].Env[0].Value) + assert.Contains(t, pod1.Spec.Containers[0].Env[0].Name, "FUZZED_ENV_") + + // Verify OwnerRefs + assert.Len(t, pod1.OwnerReferences, 1) + assert.Contains(t, pod1.OwnerReferences[0].Name, "fuzzed-owner-") + assert.Contains(t, string(pod1.OwnerReferences[0].UID), "fuzzed-uid-") + + // Verify stability/interning (pod1 and pod2 should share identical strings for everything except Name/UID) + assert.Equal(t, pod1.Spec.Containers[0].Env[0].Name, pod2.Spec.Containers[0].Env[0].Name) + assert.Equal(t, pod1.Annotations["sensitive-info"], pod2.Annotations["sensitive-info"]) +} + +func TestDeeplyNestedManagedFields(t *testing.T) { + // Intent: Verify that the recursive fuzzer correctly handles complex + // Server-Side Apply (SSA) JSON paths without losing data or structure. + fuzzer := NewExemplaryPodFuzzer(42, "nested-test", "default") + basePod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "base", + ManagedFields: []metav1.ManagedFieldsEntry{ + { + Manager: "kubelet", + APIVersion: "v1", + FieldsV1: &metav1.FieldsV1{ + Raw: []byte(`{"f:spec":{"f:containers":{"k:{\"name\":\"web\"}":{".":{},"f:image":{}}}}}`), + }, + }, + }, + }, + } + + pod := fuzzer.FuzzPod(basePod, 0) + assert.Len(t, pod.ManagedFields, 1) + assert.Equal(t, "kubelet", pod.ManagedFields[0].Manager) + + raw := string(pod.ManagedFields[0].FieldsV1.Raw) + // Verify it contains fuzzed field paths + assert.Contains(t, raw, "f:fuzzed_field_") + assert.Contains(t, raw, "k:{\\\"id\\\":") + // Verify it preserves nesting (count {) + assert.Equal(t, strings.Count(string(basePod.ManagedFields[0].FieldsV1.Raw), "{"), strings.Count(raw, "{")) +} + +func TestWriteExemplaryPodsToDir(t *testing.T) { + // Intent: Verify the batch generation logic and filesystem interaction. + creator := NewExemplaryPodCreator(nil, 42, "test-pod", "default") + basePod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "base"}, + } + + dir, err := creator.WriteExemplaryPodsToDir(context.TODO(), basePod, 5, 0, 2, "", nil) + require.NoError(t, err) + defer func() { + _ = os.RemoveAll(dir) + }() + + files, err := os.ReadDir(dir) + require.NoError(t, err) + assert.Len(t, files, 5) +} diff --git a/fuzzer/go.mod b/fuzzer/go.mod new file mode 100644 index 0000000000..8ae09ef194 --- /dev/null +++ b/fuzzer/go.mod @@ -0,0 +1,89 @@ +module k8s.io/perf-tests/fuzzer + +go 1.25.0 + +require ( + github.com/stretchr/testify v1.10.0 + golang.org/x/sync v0.10.0 + k8s.io/api v0.32.1 + k8s.io/apimachinery v0.32.1 + k8s.io/client-go v0.32.1 + sigs.k8s.io/yaml v1.4.0 +) + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/time v0.7.0 // indirect + google.golang.org/protobuf v1.35.1 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect +) + +replace ( + k8s.io/api => k8s.io/api v0.32.1 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.32.1 + k8s.io/apimachinery => k8s.io/apimachinery v0.32.1 + k8s.io/apiserver => k8s.io/apiserver v0.32.1 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.32.1 + k8s.io/client-go => k8s.io/client-go v0.32.1 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.32.1 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.32.1 + k8s.io/code-generator => k8s.io/code-generator v0.32.1 + k8s.io/component-base => k8s.io/component-base v0.32.1 + k8s.io/component-helpers => k8s.io/component-helpers v0.32.1 + k8s.io/controller-manager => k8s.io/controller-manager v0.32.1 + k8s.io/cri-api => k8s.io/cri-api v0.32.1 + k8s.io/cri-control-plane => k8s.io/cri-control-plane v0.32.1 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.32.1 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.32.1 + k8s.io/endpointslice => k8s.io/endpointslice v0.32.1 + k8s.io/external-connector => k8s.io/external-connector v0.32.1 + k8s.io/kms => k8s.io/kms v0.32.1 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.32.1 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.32.1 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.32.1 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.32.1 + k8s.io/kubectl => k8s.io/kubectl v0.32.1 + k8s.io/kubelet => k8s.io/kubelet v0.32.1 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.32.1 + k8s.io/metrics => k8s.io/metrics v0.32.1 + k8s.io/mount-utils => k8s.io/mount-utils v0.32.1 + k8s.io/node-api => k8s.io/node-api v0.32.1 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.32.1 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.32.1 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.32.1 + k8s.io/sample-controller => k8s.io/sample-controller v0.32.1 +) diff --git a/fuzzer/go.sum b/fuzzer/go.sum new file mode 100644 index 0000000000..35382ae303 --- /dev/null +++ b/fuzzer/go.sum @@ -0,0 +1,156 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/fuzzer/templates/complex-daemonset.yaml b/fuzzer/templates/complex-daemonset.yaml new file mode 100644 index 0000000000..cf3bce8f76 --- /dev/null +++ b/fuzzer/templates/complex-daemonset.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Pod +metadata: + name: complex-daemonset-base + namespace: default + annotations: + fuzzer.io/metadata-bloat: "will-be-fuzzed" + labels: + app: representative-agent + managedFields: + - manager: "system-controller-manager" + operation: "Update" + apiVersion: "v1" + fieldsV1: + Raw: '{"f:spec":{"f:containers":{"k:{\"name\":\"core-agent\"}":{".":{},"f:args":{},"f:image":{}}}}}' +spec: + serviceAccountName: "network-agent" + hostNetwork: true + dnsPolicy: "ClusterFirst" + restartPolicy: "Always" + schedulerName: "default-scheduler" + nodeSelector: + kubernetes.io/os: "linux" + initContainers: + - name: "init-config-writer" + image: "registry.k8s.io/pause:3.10" + command: ["/bin/setup"] + env: + - name: "NODE_NAME" + valueFrom: { fieldRef: { fieldPath: "spec.nodeName" } } + resources: { requests: { cpu: "5m", memory: "30Mi" } } + volumeMounts: + - mountPath: "/etc/agent/config" + name: "config-vol" + containers: + - name: "core-agent" + image: "registry.k8s.io/pause:3.10" + args: ["--config=/etc/agent/config", "--log-level=info"] + env: + - name: "AGENT_NAMESPACE" + valueFrom: { fieldRef: { fieldPath: "metadata.namespace" } } + resources: + requests: { cpu: "200m", memory: "200Mi" } + volumeMounts: + - mountPath: "/var/run/agent" + name: "run-path" + volumes: + - name: "config-vol" + hostPath: { path: "/var/lib/agent/config", type: "DirectoryOrCreate" } + - name: "run-path" + hostPath: { path: "/var/run/agent", type: "DirectoryOrCreate" }