Skip to content

Commit 5c7c95a

Browse files
dilyevskyclaude
andcommitted
[cmd] use dry-run SSA for install plan diffing
Compare the dry-run server-side apply result against the live object instead of raw desired YAML. This lets the API server handle all defaulting (clusterIP, ipFamilies, protocol, targetPort, etc.) and eliminates false diffs from server-managed fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 616c82a commit 5c7c95a

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

pkg/cmd/k8s.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ func colorizedDiff(diff string) string {
251251

252252
// --- Plan building ---
253253

254-
func buildPlan(ctx context.Context, dynClient dynamic.Interface, mapper meta.RESTMapper, yamlz []byte, ns string) ([]resourcePlan, error) {
254+
func buildPlan(ctx context.Context, dynClient dynamic.Interface, mapper meta.RESTMapper, yamlz []byte, ns string, force bool) ([]resourcePlan, error) {
255255
var plans []resourcePlan
256256
for _, y := range strings.Split(string(yamlz), "---") {
257257
if strings.TrimSpace(y) == "" {
@@ -302,7 +302,23 @@ func buildPlan(ctx context.Context, dynClient dynamic.Interface, mapper meta.RES
302302
return nil, fmt.Errorf("failed to get %s (%s): %w", obj.GetName(), gvkStr, err)
303303
}
304304

305-
diff := computeDiff(existing, obj)
305+
// Dry-run SSA apply to get the object with all server defaults applied,
306+
// then diff that against what's currently live.
307+
jsonData, err := json.Marshal(obj)
308+
if err != nil {
309+
return nil, fmt.Errorf("failed to marshal %s (%s): %w", obj.GetName(), gvkStr, err)
310+
}
311+
f := force
312+
applied, err := resource.Patch(ctx, obj.GetName(), types.ApplyPatchType, jsonData, metav1.PatchOptions{
313+
FieldManager: "apoxy-cli",
314+
Force: &f,
315+
DryRun: []string{metav1.DryRunAll},
316+
})
317+
if err != nil {
318+
return nil, fmt.Errorf("failed to dry-run apply %s (%s): %w", obj.GetName(), gvkStr, err)
319+
}
320+
321+
diff := computeDiff(existing, applied)
306322
action := actionUpdate
307323
if diff == "" {
308324
action = actionUnchanged
@@ -710,7 +726,7 @@ func installController(ctx context.Context, kc *rest.Config, yamlz []byte, ns st
710726
return installControllerDryRun(ctx, dynClient, mapper, yamlz, ns, force)
711727
}
712728

713-
plans, err := buildPlan(ctx, dynClient, mapper, yamlz, ns)
729+
plans, err := buildPlan(ctx, dynClient, mapper, yamlz, ns, force)
714730
if err != nil {
715731
return err
716732
}

0 commit comments

Comments
 (0)