You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
HYPERFLEET-1017 - refactor: rename aggregated Available condition to LastKnownReconciled
Rename the API-computed aggregated condition from Available to
LastKnownReconciled. The adapter-level Available condition remains
unchanged. Includes backward compatibility for legacy DB records,
differentiated reason/message for false conditions, minItems: 3
enforcement in OpenAPI schemas, and updated documentation.
2.**Automatic Version Tracking (generation)**: Every time you update the `spec`, the API automatically increments the `generation` counter. This allows distributed adapters to detect when they need to reconcile infrastructure changes.
110
110
111
-
3.**Observed State (status)**: Adapters report their progress and results back to the API via status endpoints. The API aggregates these reports into unified resource-level conditions (e.g., `Ready`, `Available`).
111
+
3.**Observed State (status)**: Adapters report their progress and results back to the API via status endpoints. The API aggregates these reports into unified resource-level conditions (e.g., `Ready`, `LastKnownReconciled`).
112
112
113
113
4.**Filtering (labels)**: Labels are key-value pairs you can attach to resources for organization and filtering (e.g., `environment: production`, `region: us-east-1`). E.g., Sentinel instances can define resource selectors based on labels to watch specific subsets of resources, enabling horizontal scaling across multiple Sentinel deployments.
114
114
@@ -147,7 +147,13 @@ GET /api/hyperfleet/v1/clusters/{id}
147
147
"status": {
148
148
"conditions": [
149
149
{
150
-
"type": "Available",
150
+
"type": "Reconciled",
151
+
"status": "True",
152
+
"observed_generation": 1,
153
+
"last_transition_time": "2026-03-10T07:56:35Z"
154
+
},
155
+
{
156
+
"type": "LastKnownReconciled",
151
157
"status": "True",
152
158
"observed_generation": 1,
153
159
"last_transition_time": "2026-03-10T07:56:35Z"
@@ -164,7 +170,7 @@ GET /api/hyperfleet/v1/clusters/{id}
164
170
"updated_time": "2026-03-10T07:56:35Z"
165
171
}
166
172
167
-
→ API returns aggregated status with Available and Ready conditions
173
+
→ API returns aggregated status with Reconciled, LastKnownReconciled, and Ready conditions
168
174
169
175
# 3. View adapter statuses
170
176
GET /api/hyperfleet/v1/clusters/{id}/statuses
@@ -323,7 +329,7 @@ HyperFleet API aggregates the condition values reported by adapters associated w
323
329
| Condition | Meaning | When True |
324
330
|-----------|---------|-----------|
325
331
| **Ready** | Resource is fully reconciled at current spec | All registered adapters report `Available=True` at the **current** `resource.spec.generation` |
326
-
| **Available** | Resource is operational at any known good configuration | All registered adapters report `Available=True` (at any generation) |
332
+
| **LastKnownReconciled** | Resource is operational at any known good configuration | All registered adapters report `Available=True` (at any generation) |
327
333
328
334
**Note**: The meaning of the field `last_updated_time` for the aggregated conditions has special meaning. It doesn't reflect the last time it was updated from adapters but the OLDEST time it can be considered to be valid.
329
335
@@ -337,16 +343,16 @@ The resource `status.conditions` array contains:
337
343
- `True`: All required adapters `conditions[type=Available].status==True` at current spec generation
338
344
- `False`: Any other combination of conditions
339
345
340
-
- **Available** - The resource is reconciled at a generation of the spec, current or past
346
+
- **LastKnownReconciled** - The resource is reconciled at a generation of the spec, current or past
341
347
- This condition is stateful meaning that is computed taking into account its previous values of `status` and `observed_generation`
342
348
- This condition is "best effort", since there are cases that can not be covered correctly.
343
349
- `True`:
344
350
- All required adapters `conditions[type=Available].status==True` for the same `observed_generation`
345
351
- Current value `status==True` and required adapters `conditions[type=Available]` at mixed `observed_generation`
346
352
- `False`: Any other combination of conditions
347
-
- e.g. `Available=True` for `observed_generation==1`
348
-
- One adapter reports `Available=False` for `observed_generation=1` `Available` transitions to `False`
349
-
- One adapter reports `Available=False` for `observed_generation=2` `Available` keeps its `True` status
353
+
- e.g. `LastKnownReconciled=True` for `observed_generation==1`
354
+
- One adapter reports `Available=False` for `observed_generation=1` `LastKnownReconciled` transitions to `False`
355
+
- One adapter reports `Available=False` for `observed_generation=2` `LastKnownReconciled` keeps its `True` status
350
356
351
357
- One **per-adapter** condition for each required adapter that has reported, mirroring the adapter's `conditions[type=Available]`:
352
358
- `type`: Derived from the adapter name — PascalCase with `Successful` suffix (e.g., `adapter1` → `Adapter1Successful`, `my-adapter` → `MyAdapterSuccessful`)
@@ -392,7 +398,7 @@ These are API examples for a resource and resource statuses:
392
398
"last_transition_time": "2021-01-01T10:00:00Z"
393
399
},
394
400
{
395
-
"type": "Available",
401
+
"type": "LastKnownReconciled",
396
402
"status": "True",
397
403
"reason": "All adapters reported Available True for the same generation",
398
404
"message": "All adapters reported Available True for the same generation",
@@ -497,23 +503,23 @@ These are API examples for a resource and resource statuses:
497
503
When a resource is created:
498
504
499
505
- Initial `generation` is 1 and aggregated conditions are evaluated
500
-
- `observed_generation`for `Ready` and `Available` aggregated conditions is 1
501
-
- `last_updated_time`and `last_transition_time` for `Ready` and `Available` aggregated conditions is `resource.last_updated_time`
506
+
- `observed_generation`for `Ready` and `LastKnownReconciled` aggregated conditions is 1
507
+
- `last_updated_time`and `last_transition_time` for `Ready` and `LastKnownReconciled` aggregated conditions is `resource.last_updated_time`
502
508
503
509
When a resource is changed:
504
510
505
511
- `resource.generation`gets incremented and aggregated conditions are re-evaluated
- `status.conditions[type==Available].observed_generation`changes when all required adapters `condition[type==Available].observed_generation==resource.generation` otherwise remains unchanged.
513
+
- `status.conditions[type==LastKnownReconciled].observed_generation`changes when all required adapters `condition[type==Available].observed_generation==resource.generation` otherwise remains unchanged.
508
514
509
515
##### Computing `observed_generation`
510
516
511
517
- For `Ready` it always matches `resource.generation`
512
-
- For `Available`:
518
+
- For `LastKnownReconciled`:
513
519
- If all required adapters have a common `observed_generation` it will match the common value
514
520
- If required adapters have mixed `observed_generation`
515
-
- If `Available` is `True`, `observed_generation` remains at its current value
516
-
- If `Available` is `False`, `observed_generation` will get the value of the `max(condition[type==Available].observed_generation)`
521
+
- If `LastKnownReconciled` is `True`, `observed_generation` remains at its current value
522
+
- If `LastKnownReconciled` is `False`, `observed_generation` will get the value of the `max(condition[type==Available].observed_generation)`
@@ -526,14 +532,14 @@ The meaning of `last_updated_time` in the aggregated conditions refers to the ne
526
532
- Why do we want to keep the "oldest" value? because if it is too old, we need to trigger a reconciliation
527
533
- When some required adapter conditions `condition[type==Available].observed_generation==resource.generation` then `last_updated_time=min(statuses[].conditions[type==Available && observed_generation==resource.generation].observed_time)`
- If all required adapters have `condition[type==Available].observed_generation` at the same value then `last_updated_time=min(statuses[].conditions[type==Available].observed_time)`
532
538
- If not all required adapters have `condition[type==Available].observed_generation` at the same value:
533
539
- If any adapter at current `observed_generation==X` has `conditions[type==Available].status==False` then `last_updated_time=min(adapters[type==Available && observed_generation==X].observed_time`
534
540
- In any other case `last_updated_time` is kept unchanged
535
541
536
-
##### Computing `last_transition_time` for both `Ready` and `Available`
542
+
##### Computing `last_transition_time` for both `Ready` and `LastKnownReconciled`
537
543
538
544
- Meaning is last time this condition’s status (True / False) changed, regardless of the existing and new `observed_generation`
539
545
- This property is stateful since it relies on the existing value to determine if there has been a transition
Copy file name to clipboardExpand all lines: docs/search.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -98,14 +98,14 @@ Label keys must contain only lowercase letters (a-z), digits (0-9), and undersco
98
98
99
99
Query resources by status conditions: `status.conditions.<Type>='<Status>'`
100
100
101
-
Condition types must be PascalCase (`Ready`, `Available`) and status must be `True` or `False` for resource conditions.
101
+
Condition types must be PascalCase (`Ready`, `LastKnownReconciled`) and status must be `True` or `False` for resource conditions.
102
102
103
103
**Note:** Only the `=` operator is supported for condition queries. Other operators (`!=`, `<`, `>`, `in`, etc.) will return an error. The `NOT` operator is not supported with condition queries (`status.conditions.<Type>` or `status.conditions.<Type>.<Subfield>`) and will return a `400 Bad Request` error. Use the inverse condition value instead (e.g., `status.conditions.Ready='False'` rather than `NOT status.conditions.Ready='True'`).
Copy file name to clipboardExpand all lines: openapi/openapi.yaml
+11-11Lines changed: 11 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -50,7 +50,7 @@ paths:
50
50
51
51
**Note**: The `status` object in the response is read-only and computed by the service.
52
52
It is NOT part of the request body. Initially,
53
-
status.conditions will include mandatory "Available", "Ready" and "Reconciled" conditions.
53
+
status.conditions will include mandatory "LastKnownReconciled", "Ready" and "Reconciled" conditions.
54
54
parameters: []
55
55
responses:
56
56
'201':
@@ -189,7 +189,7 @@ paths:
189
189
created_time: '2021-01-01T10:00:00Z'
190
190
last_updated_time: '2021-01-01T10:00:00Z'
191
191
last_transition_time: '2021-01-01T10:00:00Z'
192
-
- type: Available
192
+
- type: LastKnownReconciled
193
193
status: 'True'
194
194
reason: All adapters reported Available True for the same generation
195
195
message: All adapters reported Available True for the same generation
@@ -394,7 +394,7 @@ paths:
394
394
created_time: '2021-01-01T10:00:00Z'
395
395
last_updated_time: '2021-01-01T10:00:00Z'
396
396
last_transition_time: '2021-01-01T10:00:00Z'
397
-
- type: Available
397
+
- type: LastKnownReconciled
398
398
status: 'True'
399
399
reason: All adapters reported Available True for the same generation
400
400
message: All adapters reported Available True for the same generation
@@ -1075,7 +1075,7 @@ components:
1075
1075
created_time: '2021-01-01T10:00:00Z'
1076
1076
last_updated_time: '2021-01-01T10:00:00Z'
1077
1077
last_transition_time: '2021-01-01T10:00:00Z'
1078
-
- type: Available
1078
+
- type: LastKnownReconciled
1079
1079
status: 'True'
1080
1080
reason: All adapters reported Available True for the same generation
1081
1081
message: All adapters reported Available True for the same generation
@@ -1192,14 +1192,14 @@ components:
1192
1192
type: array
1193
1193
items:
1194
1194
$ref: '#/components/schemas/ResourceCondition'
1195
-
minItems: 2
1195
+
minItems: 3
1196
1196
description: |-
1197
1197
List of status conditions for the cluster.
1198
1198
1199
-
**Mandatory conditions**:
1199
+
**Mandatory conditions**:
1200
1200
- `type: "Ready"` *(deprecated — use Reconciled)*: Whether all adapters report successfully at the current generation.
1201
1201
- `type: "Reconciled"`: Whether the resource's desired state has been fully reconciled by all adapters at the current generation.
1202
-
- `type: "Available"`: Aggregated adapter result for a common observed_generation.
1202
+
- `type: "LastKnownReconciled"`: Aggregated adapter result for a common observed_generation. Sticky — stays True as long as all required adapters were reconciled at a common observed generation, even if a new generation is being processed.
1203
1203
1204
1204
These conditions are present immediately upon resource creation.
1205
1205
description: |-
@@ -1374,7 +1374,7 @@ components:
1374
1374
created_time: '2021-01-01T10:00:00Z'
1375
1375
last_updated_time: '2021-01-01T10:00:00Z'
1376
1376
last_transition_time: '2021-01-01T10:00:00Z'
1377
-
- type: Available
1377
+
- type: LastKnownReconciled
1378
1378
status: 'True'
1379
1379
reason: All adapters reported Available True for the same generation
1380
1380
message: All adapters reported Available True for the same generation
@@ -1558,14 +1558,14 @@ components:
1558
1558
type: array
1559
1559
items:
1560
1560
$ref: '#/components/schemas/ResourceCondition'
1561
-
minItems: 2
1561
+
minItems: 3
1562
1562
description: |-
1563
1563
List of status conditions for the nodepool.
1564
1564
1565
-
**Mandatory conditions**:
1565
+
**Mandatory conditions**:
1566
1566
- `type: "Ready"` *(deprecated — use Reconciled)*: Whether all adapters report successfully at the current generation.
1567
1567
- `type: "Reconciled"`: Whether the resource's desired state has been fully reconciled by all adapters at the current generation.
1568
-
- `type: "Available"`: Aggregated adapter result for a common observed_generation.
1568
+
- `type: "LastKnownReconciled"`: Aggregated adapter result for a common observed_generation. Sticky — stays True as long as all required adapters were reconciled at a common observed generation, even if a new generation is being processed.
1569
1569
1570
1570
These conditions are present immediately upon resource creation.
0 commit comments