kubernetes: SSA via CustomObjectsApi needs apply-patch+yaml client

Document the kubernetes-py v35 gotcha that bit M22 Phase 8: patch with
force=True against the default merge-patch Content-Type returns 422
silently in mocks but breaks at the apiserver. Workaround is a
dedicated ApiClient with the apply-patch header.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul O'Reilly
2026-05-03 14:08:23 +12:00
parent 8aa04f256c
commit b1aa40b043

View File

@@ -177,3 +177,7 @@ A reconciliation controller should touch only resources explicitly declared in i
## Webhook-Triggered Reconciliation with Token Auth
Pair periodic reconciliation with an authenticated POST `/reconcile` endpoint so push events can trigger immediate sync. Use a 32+ char Bearer token with constant-time comparison, fail-closed (return 501) if the token is not configured. Avoids worst-case polling latency when a human just committed.
## kubernetes-py CustomObjectsApi: SSA Requires a Dedicated ApiClient
`CustomObjectsApi.patch_namespaced_custom_object(force=True)` fails with HTTP 422 on kubernetes-py v35 (`PatchOptions.meta.k8s.io is invalid: force: Forbidden: may not be specified for non-apply patch`). The default Content-Type is `application/merge-patch+json`; `force` is only valid on real server-side applies (`application/apply-patch+yaml`). The `_content_type` kwarg that older docs reference is not exposed in v35. Workaround: build a dedicated `ApiClient` and `set_default_header("Content-Type", "application/apply-patch+yaml")` on it; pass that client to a separate `CustomObjectsApi` used only for SSA patches. Reads/deletes use the default client (no body, default Content-Type harmless). The bug is silent in tests because mocks accept any kwargs — only a real apiserver round-trip surfaces it.