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
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,7 @@ GET /api/hyperfleet/v1/clusters/{id}
147
147
"status": {
148
148
"conditions": [
149
149
{
150
-
"type": "Available",
150
+
"type": "LastKnownReconciled",
151
151
"status": "True",
152
152
"observed_generation": 1,
153
153
"last_transition_time": "2026-03-10T07:56:35Z"
@@ -164,7 +164,7 @@ GET /api/hyperfleet/v1/clusters/{id}
164
164
"updated_time": "2026-03-10T07:56:35Z"
165
165
}
166
166
167
-
→ API returns aggregated status with Available and Ready conditions
167
+
→ API returns aggregated status with LastKnownReconciled and Ready conditions
168
168
169
169
# 3. View adapter statuses
170
170
GET /api/hyperfleet/v1/clusters/{id}/statuses
@@ -323,7 +323,7 @@ HyperFleet API aggregates the condition values reported by adapters associated w
323
323
| Condition | Meaning | When True |
324
324
|-----------|---------|-----------|
325
325
| **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) |
326
+
| **LastKnownReconciled** | Resource is operational at any known good configuration | All registered adapters report `Available=True` (at any generation) |
327
327
328
328
**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
329
@@ -337,16 +337,16 @@ The resource `status.conditions` array contains:
337
337
- `True`: All required adapters `conditions[type=Available].status==True` at current spec generation
338
338
- `False`: Any other combination of conditions
339
339
340
-
- **Available** - The resource is reconciled at a generation of the spec, current or past
340
+
- **LastKnownReconciled** - The resource is reconciled at a generation of the spec, current or past
341
341
- This condition is stateful meaning that is computed taking into account its previous values of `status` and `observed_generation`
342
342
- This condition is "best effort", since there are cases that can not be covered correctly.
343
343
- `True`:
344
344
- All required adapters `conditions[type=Available].status==True` for the same `observed_generation`
345
345
- Current value `status==True` and required adapters `conditions[type=Available]` at mixed `observed_generation`
346
346
- `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
347
+
- e.g. `LastKnownReconciled=True` for `observed_generation==1`
348
+
- One adapter reports `Available=False` for `observed_generation=1` `LastKnownReconciled` transitions to `False`
349
+
- One adapter reports `Available=False` for `observed_generation=2` `LastKnownReconciled` keeps its `True` status
350
350
351
351
- One **per-adapter** condition for each required adapter that has reported, mirroring the adapter's `conditions[type=Available]`:
352
352
- `type`: Derived from the adapter name — PascalCase with `Successful` suffix (e.g., `adapter1` → `Adapter1Successful`, `my-adapter` → `MyAdapterSuccessful`)
@@ -392,7 +392,7 @@ These are API examples for a resource and resource statuses:
392
392
"last_transition_time": "2021-01-01T10:00:00Z"
393
393
},
394
394
{
395
-
"type": "Available",
395
+
"type": "LastKnownReconciled",
396
396
"status": "True",
397
397
"reason": "All adapters reported Available True for the same generation",
398
398
"message": "All adapters reported Available True for the same generation",
@@ -497,23 +497,23 @@ These are API examples for a resource and resource statuses:
497
497
When a resource is created:
498
498
499
499
- 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`
500
+
- `observed_generation`for `Ready` and `LastKnownReconciled` aggregated conditions is 1
501
+
- `last_updated_time`and `last_transition_time` for `Ready` and `LastKnownReconciled` aggregated conditions is `resource.last_updated_time`
502
502
503
503
When a resource is changed:
504
504
505
505
- `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.
507
+
- `status.conditions[type==LastKnownReconciled].observed_generation`changes when all required adapters `condition[type==Available].observed_generation==resource.generation` otherwise remains unchanged.
508
508
509
509
##### Computing `observed_generation`
510
510
511
511
- For `Ready` it always matches `resource.generation`
512
-
- For `Available`:
512
+
- For `LastKnownReconciled`:
513
513
- If all required adapters have a common `observed_generation` it will match the common value
514
514
- 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)`
515
+
- If `LastKnownReconciled` is `True`, `observed_generation` remains at its current value
516
+
- If `LastKnownReconciled` is `False`, `observed_generation` will get the value of the `max(condition[type==Available].observed_generation)`
@@ -526,14 +526,14 @@ The meaning of `last_updated_time` in the aggregated conditions refers to the ne
526
526
- Why do we want to keep the "oldest" value? because if it is too old, we need to trigger a reconciliation
527
527
- 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
532
- If not all required adapters have `condition[type==Available].observed_generation` at the same value:
533
533
- 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
534
- In any other case `last_updated_time` is kept unchanged
535
535
536
-
##### Computing `last_transition_time` for both `Ready` and `Available`
536
+
##### Computing `last_transition_time` for both `Ready` and `LastKnownReconciled`
537
537
538
538
- Meaning is last time this condition’s status (True / False) changed, regardless of the existing and new `observed_generation`
539
539
- 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
+7-7Lines changed: 7 additions & 7 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
@@ -1199,7 +1199,7 @@ components:
1199
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
@@ -1565,7 +1565,7 @@ components:
1565
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