mirror of
https://github.com/tailscale/tailscale.git
synced 2026-11-08 21:16:10 +09:00
ProxyClass and other Tailscale CRDs embed corev1 types (e.g. corev1.Affinity) whose sibling fields are declared as type: object in the generated OpenAPI schema. Under server-side apply (ArgoCD, Flux), unset sibling fields are sent as null, but the API server rejects null for type: object without nullable: true. This does not affect native Kubernetes types because the API server handles those with built-in logic rather than OpenAPI schema validation. Fix this with a two-layer approach: 1. Add // +nullable markers to optional object/array/map fields in our own Go types (ProxyClass, Recorder, DNSConfig). controller-gen honours these markers and they survive schemapatch regeneration. 2. Add a post-processing step (crdnullable) that runs after controller-gen to add nullable: true to optional object/array sub-fields inside embedded corev1 type subtrees. These sub-fields are defined in Kubernetes core and cannot be annotated by us. The post-processor identifies corev1 type schemas by their field signatures (e.g. nodeAffinity + podAffinity + podAntiAffinity = corev1.Affinity) and only marks optional fields that don't already have nullable: true. The post-processor is wired into the go:generate pipeline between controller-gen and staticmanifests generation.