Skip to content

Commit dc7687c

Browse files
Merge pull request #44 from ma-hill/HYPERFLEET-978
HYPERFLEET-978 - feat: Add PUT command for internal status endpoints (2/2)
2 parents 98cfd7e + 421b852 commit dc7687c

12 files changed

Lines changed: 76 additions & 270 deletions

File tree

CHANGELOG.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.0.13] - 2026-05-13
11+
12+
### Removed
13+
- POST endpoints from internal status API (`/clusters/{cluster_id}/statuses` and `/clusters/{cluster_id}/nodepools/{nodepool_id}/statuses`)
14+
15+
### Changed
16+
17+
- Internal status API now uses only PUT endpoints with upsert semantics for adapter status updates
18+
- Improved documentation for PUT endpoints to clarify upsert behavior by adapter name
19+
20+
## [1.0.12] - 2026-05-11
21+
22+
### Fixed
23+
24+
- Aligned condition example reason/message fields with actual aggregation code output (HYPERFLEET-1017)
25+
- Updated condition reason strings to use CamelCase format (`AllAdaptersReconciled`, `ReconciledAll`) instead of full sentences
26+
- Updated condition message strings to match actual aggregation logic output
27+
1028
## [1.0.11] - 2026-05-07
1129

1230
### Added
@@ -108,7 +126,9 @@ First official stable release of the HyperFleet API specification.
108126
- Interactive API documentation
109127

110128
<!-- Links -->
111-
[Unreleased]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.11...HEAD
129+
[Unreleased]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.13...HEAD
130+
[1.0.13]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.12...v1.0.13
131+
[1.0.12]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.11...v1.0.12
112132
[1.0.11]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.10...v1.0.11
113133
[1.0.10]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.9...v1.0.10
114134
[1.0.9]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.8...v1.0.9

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The `aliases.tsp` symlink determines which provider types are active. The `build
4646

4747
Status endpoints are split:
4848
- `services/statuses.tsp` - GET operations (external clients)
49-
- `services/statuses-internal.tsp` - POST operations (internal adapters only)
49+
- `services/statuses-internal.tsp` - PUT operations (internal adapters only)
5050

5151
The split allows generating different API contracts per audience. Only `statuses.tsp` is imported by default.
5252

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Contains service definitions that generate the OpenAPI specifications:
110110

111111
- **`services/clusters.tsp`** - Cluster resource endpoints
112112
- **`services/statuses.tsp`** - Status resource endpoints (GET only - public API)
113-
- **`services/statuses-internal.tsp`** - Status write endpoints (POST/PUT - internal API, see below)
113+
- **`services/statuses-internal.tsp`** - Status write endpoints (PUT - internal API, see below)
114114
- **`services/nodepools.tsp`** - NodePool resource endpoints
115115

116116
#### Public vs Internal API Split
@@ -120,7 +120,6 @@ The status endpoints are split into two files to support different API consumers
120120
| File | Operations | Audience | Included in Build |
121121
|------|------------|----------|-------------------|
122122
| `statuses.tsp` | GET (read) | External clients | ✅ Yes (default) |
123-
| `statuses-internal.tsp` | POST (write) | Internal adapters | ❌ No (opt-in) |
124123
| `statuses-internal.tsp` | PUT (write) | Internal adapters | ❌ No (opt-in) |
125124

126125
**Why the split?**

main.tsp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ using OpenAPI;
2020
*
2121
*/
2222
@service(#{ title: "HyperFleet API" })
23-
@info(#{ version: "1.0.12", contact: #{ name: "HyperFleet Team" }, license: #{ name: "Apache 2.0" ,url: "https://www.apache.org/licenses/LICENSE-2.0"} })
23+
@info(#{
24+
version: "1.0.13",
25+
contact: #{
26+
name: "HyperFleet Team",
27+
url: "https://github.com/openshift-hyperfleet",
28+
},
29+
license: #{
30+
name: "Apache 2.0",
31+
url: "https://www.apache.org/licenses/LICENSE-2.0",
32+
},
33+
})
2434
@server("https://hyperfleet.redhat.com", "Production")
2535
@route("/api/hyperfleet/v1")
2636
namespace HyperFleet;
@@ -30,4 +40,3 @@ model BearerAuth {
3040
type: AuthType.http;
3141
scheme: "bearer";
3242
}
33-

models/common/model.tsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ model ResourceCondition {
238238

239239
/**
240240
* When the corresponding adapter last reported (API-managed)
241-
* Updated every time the adapter POSTs, even if condition status hasn't changed
241+
* Updated every time the adapter PUTs, even if condition status hasn't changed
242242
* Copied from AdapterStatus.last_report_time
243243
*/
244244
@format("date-time") last_updated_time: string;

models/statuses/example_adapter_status.tsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const exampleAdapterStatus: AdapterStatus = (#{
5454
last_report_time: "2021-01-01T10:02:00Z",
5555
});
5656

57-
// Example AdapterStatusCreateRequest (for POST /clusters/{id}/statuses)
57+
// Example AdapterStatusCreateRequest (for PUT /clusters/{id}/statuses)
5858
const exampleAdapterStatusCreateRequest: AdapterStatusCreateRequest = (#{
5959
adapter: "validator",
6060
observed_generation: 1,

models/statuses/model.tsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ model AdapterStatus {
8585

8686
/**
8787
* When this adapter last reported its status (API-managed)
88-
* Updated every time the adapter POSTs, even if conditions haven't changed
88+
* Updated every time the adapter PUTs, even if conditions haven't changed
8989
* Used by Sentinel to detect adapter liveness
9090
*/
9191
@format("date-time") last_report_time: string;

schemas/core/openapi.yaml

Lines changed: 9 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
openapi: 3.0.0
22
info:
33
title: HyperFleet API
4-
version: 1.0.12
4+
version: 1.0.13
55
contact:
66
name: HyperFleet Team
7+
url: https://github.com/openshift-hyperfleet
78
license:
89
name: Apache 2.0
910
url: https://www.apache.org/licenses/LICENSE-2.0
@@ -507,55 +508,10 @@ paths:
507508
security:
508509
- BearerAuth: []
509510
/api/hyperfleet/v1/clusters/{cluster_id}/nodepools/{nodepool_id}/statuses:
510-
post:
511-
operationId: postNodePoolStatuses
512-
summary: Create or update adapter status
513-
description: |-
514-
Adapter creates or updates its status report for this nodepool.
515-
If adapter already has a status, it will be updated (upsert by adapter name).
516-
517-
Response includes the full adapter status with all conditions.
518-
Adapter should call this endpoint every time it evaluates the nodepool.
519-
parameters:
520-
- name: cluster_id
521-
in: path
522-
required: true
523-
description: Cluster ID
524-
schema:
525-
type: string
526-
- name: nodepool_id
527-
in: path
528-
required: true
529-
description: Nodepool ID
530-
schema:
531-
type: string
532-
responses:
533-
'201':
534-
description: The request has succeeded and a new resource has been created as a result.
535-
content:
536-
application/json:
537-
schema:
538-
$ref: '#/components/schemas/AdapterStatus'
539-
'400':
540-
description: The server could not understand the request due to invalid syntax.
541-
'404':
542-
description: The server cannot find the requested resource.
543-
'409':
544-
description: The request conflicts with the current state of the server.
545-
tags:
546-
- NodePool statuses
547-
requestBody:
548-
required: true
549-
content:
550-
application/json:
551-
schema:
552-
$ref: '#/components/schemas/AdapterStatusCreateRequest'
553-
security:
554-
- BearerAuth: []
555511
put:
556512
operationId: putNodePoolStatuses
557-
summary: Adapter creates or updates resource nodepool status
558-
description: Idempotent upsert of an adapter status for this nodepool. Use instead of POST when the adapter name is known upfront.
513+
summary: Adapter creates or updates nodepool status
514+
description: Adapters call this endpoint to report the status for a nodepool after each evaluation. The adapter's status entry is created if it doesn't exist, or updated if it does (upserted by adapter name). This allows HyperFleet to aggregate multiple adapter perspectives into a unified nodepool status.
559515
parameters:
560516
- name: cluster_id
561517
in: path
@@ -566,7 +522,7 @@ paths:
566522
- name: nodepool_id
567523
in: path
568524
required: true
569-
description: Nodepool ID
525+
description: NodePool ID
570526
schema:
571527
type: string
572528
responses:
@@ -631,49 +587,10 @@ paths:
631587
tags:
632588
- NodePool statuses
633589
/api/hyperfleet/v1/clusters/{cluster_id}/statuses:
634-
post:
635-
operationId: postClusterStatuses
636-
summary: Create or update adapter status
637-
description: |-
638-
Adapter creates or updates its status report for this cluster.
639-
If adapter already has a status, it will be updated (upsert by adapter name).
640-
641-
Response includes the full adapter status with all conditions.
642-
Adapter should call this endpoint every time it evaluates the cluster.
643-
parameters:
644-
- name: cluster_id
645-
in: path
646-
required: true
647-
description: Cluster ID
648-
schema:
649-
type: string
650-
responses:
651-
'201':
652-
description: The request has succeeded and a new resource has been created as a result.
653-
content:
654-
application/json:
655-
schema:
656-
$ref: '#/components/schemas/AdapterStatus'
657-
'400':
658-
description: The server could not understand the request due to invalid syntax.
659-
'404':
660-
description: The server cannot find the requested resource.
661-
'409':
662-
description: The request conflicts with the current state of the server.
663-
tags:
664-
- Cluster statuses
665-
requestBody:
666-
required: true
667-
content:
668-
application/json:
669-
schema:
670-
$ref: '#/components/schemas/AdapterStatusCreateRequest'
671-
security:
672-
- BearerAuth: []
673590
put:
674591
operationId: putClusterStatuses
675-
summary: Adapter creates or updates resource cluster status
676-
description: Idempotent upsert of an adapter status for this cluster. Use instead of POST when the adapter name is known upfront.
592+
summary: Adapter creates or updates cluster status
593+
description: Adapters call this endpoint to report the status for a cluster after each evaluation. The adapter's status entry is created if it doesn't exist, or updated if it does (upserted by adapter name). This allows HyperFleet to aggregate multiple adapter perspectives into a unified cluster status.
677594
parameters:
678595
- name: cluster_id
679596
in: path
@@ -902,7 +819,7 @@ components:
902819
format: date-time
903820
description: |-
904821
When this adapter last reported its status (API-managed)
905-
Updated every time the adapter POSTs, even if conditions haven't changed
822+
Updated every time the adapter PUTs, even if conditions haven't changed
906823
Used by Sentinel to detect adapter liveness
907824
description: |-
908825
AdapterStatus represents the complete status report from an adapter
@@ -1742,7 +1659,7 @@ components:
17421659
format: date-time
17431660
description: |-
17441661
When the corresponding adapter last reported (API-managed)
1745-
Updated every time the adapter POSTs, even if condition status hasn't changed
1662+
Updated every time the adapter PUTs, even if condition status hasn't changed
17461663
Copied from AdapterStatus.last_report_time
17471664
description: |-
17481665
Condition in Cluster/NodePool status

0 commit comments

Comments
 (0)