Commit d78b470
feat: add rollback recovery for control plane resize (#4865)
* feat(frontend): add rollback recovery for control plane resize
Add automatic rollback to /resizecontrolplane so failed master resizes restore the cluster to a healthy state with three running, schedulable control plane nodes at matching SKUs.
Key behaviors:
- Per-node snapshot captures original VM size, Machine spec, Node labels, and schedulability before mutation
- On failure, nodes roll back in reverse order and restore VM size, Machine metadata, Node labels, and schedulability
- Etcd health is checked between each node resize in forward and rollback paths
- Context detachment lets the operation complete even if the admin HTTP connection drops
- Step journaling captures forward and rollback timing details for diagnostics
Fixes ARO-27429
* fix(frontend): reduce rollback PR scope and harden rollback gate
Keep rollback-specific logic in this PR by dropping pre-validation inventory carryover and duplicated rollback matrix tests, while making rollback stop when etcd is unhealthy between nodes and documenting the behavior.
* fix(frontend): guard resize error normalization and immediate retry cancellation
Prevent nil CloudErrorBody panics when normalizing wrapped resize errors and stop zero-delay retry loops from issuing extra Azure calls after context cancellation.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(frontend): keep default-delay retry semantics
Revert the zero-delay cancellation behavior change and its extra test to keep runtime semantics aligned with the existing production retry policy.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(frontend): simplify control plane node label updates
Keep rollback label restoration on the same aligned-label path used during resize so the helper surface matches the fail-closed validation model.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(frontend): remove rollback retry policy indirection
Keep the Azure retry helper on the single production code path so tests verify the same retry semantics used during resize recovery.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(frontend): remove empty node label fallback
Fail fast when the internal node label helper is called without a VM size so resize and rollback only exercise the validated non-empty path.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(frontend): move resize inventory checks back to preflight
Reuse the live Machine/Azure VM/Node inventory validator in pre-flight so snapshot capture only records rollback state and no longer duplicates those consistency checks.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(frontend): reuse steps in resize happy path
Move the linear control plane resize flow onto pkg/util/steps while keeping rollback state, retry policy, and operator-facing journaling local to frontend.
This answers the reviewer request with a small behavioral diff and preserves the admin flow's existing error contract.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(frontend): pin etcd wait timeout in resize recovery
Cover waitForEtcdHealthy with a deadline-aware test so future refactors keep the per-check timeout boundary.
This protects the admin resize flow from accidentally broadening the etcd wait semantics through pkg/util/steps.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(frontend): normalize resize admin error messages
Keep resize admin replies readable by reusing the wrapped CloudError body text instead of duplicating status and target prefixes in the message field. Also normalize joined control plane inventory validation errors so Geneva-facing admin responses do not leak embedded newlines.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(frontend): preserve rebased resize preflight validation
Keep the rebased control plane resize branch on the validated inventory-preflight path and update the rebased tests to assert the normalized inventory errors without leaving a standalone follow-up fix commit.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent e548a0d commit d78b470
7 files changed
Lines changed: 1948 additions & 260 deletions
File tree
- pkg/frontend
Lines changed: 95 additions & 64 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| 36 | + | |
35 | 37 | | |
36 | 38 | | |
37 | 39 | | |
| |||
47 | 49 | | |
48 | 50 | | |
49 | 51 | | |
| 52 | + | |
50 | 53 | | |
51 | 54 | | |
52 | 55 | | |
53 | 56 | | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
54 | 106 | | |
55 | 107 | | |
56 | 108 | | |
| |||
110 | 162 | | |
111 | 163 | | |
112 | 164 | | |
113 | | - | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
114 | 170 | | |
115 | 171 | | |
116 | 172 | | |
117 | 173 | | |
118 | | - | |
| 174 | + | |
119 | 175 | | |
120 | 176 | | |
121 | 177 | | |
| |||
135 | 191 | | |
136 | 192 | | |
137 | 193 | | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
143 | 203 | | |
144 | 204 | | |
145 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
146 | 213 | | |
147 | 214 | | |
148 | 215 | | |
149 | 216 | | |
150 | 217 | | |
151 | 218 | | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
152 | 229 | | |
153 | | - | |
154 | | - | |
| 230 | + | |
| 231 | + | |
155 | 232 | | |
156 | 233 | | |
157 | 234 | | |
158 | 235 | | |
159 | 236 | | |
160 | 237 | | |
161 | 238 | | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | 239 | | |
215 | 240 | | |
216 | 241 | | |
| |||
368 | 393 | | |
369 | 394 | | |
370 | 395 | | |
371 | | - | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
372 | 402 | | |
373 | | - | |
| 403 | + | |
374 | 404 | | |
375 | 405 | | |
376 | 406 | | |
| |||
396 | 426 | | |
397 | 427 | | |
398 | 428 | | |
399 | | - | |
| 429 | + | |
| 430 | + | |
400 | 431 | | |
401 | 432 | | |
402 | 433 | | |
| |||
0 commit comments