Skip to content

Commit ad64e3b

Browse files
Merge pull request #35 from kuudori/HYPERFLEET-971
HYPERFLEET-971 - feat: 409 Conflict responses + version bump + CHANGELOG
2 parents 2807639 + a78d705 commit ad64e3b

14 files changed

Lines changed: 168 additions & 95 deletions

File tree

CHANGELOG.md

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

1818
- Improved README.md structure to align with HyperFleet documentation standards
1919

20+
## [1.0.10] - 2026-05-05
21+
22+
### Added
23+
24+
- 409 Conflict response to cluster patch (PATCH `/clusters/{cluster_id}`) for soft-deleted cluster rejection
25+
- 409 Conflict response to nodepool create (POST `/clusters/{cluster_id}/nodepools`) for soft-deleted cluster rejection
26+
- 409 Conflict response to nodepool patch (PATCH `/clusters/{cluster_id}/nodepools/{nodepool_id}`) for soft-deleted cluster rejection
27+
28+
## [1.0.9] - 2026-05-04
29+
30+
### Added
31+
32+
- PUT endpoint for cluster adapter statuses (PUT `/clusters/{cluster_id}/statuses`) with upsert semantics
33+
- PUT endpoint for nodepool adapter statuses (PUT `/clusters/{cluster_id}/nodepools/{nodepool_id}/statuses`) with upsert semantics
34+
35+
## [1.0.8] - 2026-04-28
36+
37+
### Added
38+
39+
- "Reconciled" condition type to resource status conditions
40+
- "Finalized" condition type to adapter status conditions
41+
42+
### Fixed
43+
44+
- Inconsistent `observed_generation` values across examples
45+
46+
## [1.0.7] - 2026-04-20
47+
48+
### Added
49+
50+
- PATCH endpoint for clusters (PATCH `/clusters/{cluster_id}`) with `ClusterPatchRequest`
51+
- PATCH endpoint for nodepools (PATCH `/clusters/{cluster_id}/nodepools/{nodepool_id}`) with `NodePoolPatchRequest`
52+
2053
## [1.0.6] - 2026-04-13
2154

2255
### Added
@@ -63,7 +96,11 @@ First official stable release of the HyperFleet API specification.
6396
- Interactive API documentation
6497

6598
<!-- Links -->
66-
[Unreleased]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.6...HEAD
99+
[Unreleased]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.10...HEAD
100+
[1.0.10]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.9...v1.0.10
101+
[1.0.9]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.8...v1.0.9
102+
[1.0.8]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.7...v1.0.8
103+
[1.0.7]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.6...v1.0.7
67104
[1.0.6]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.2...v1.0.6
68105
[1.0.2]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.0...v1.0.2
69106
[1.0.0]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/tag/v1.0.0

main.tsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ using OpenAPI;
2020
*
2121
*/
2222
@service(#{ title: "HyperFleet API" })
23-
@info(#{ version: "1.0.9", contact: #{ name: "HyperFleet Team" }, license: #{ name: "Apache 2.0" ,url: "https://www.apache.org/licenses/LICENSE-2.0"} })
23+
@info(#{ version: "1.0.10", contact: #{ name: "HyperFleet Team" }, license: #{ name: "Apache 2.0" ,url: "https://www.apache.org/licenses/LICENSE-2.0"} })
2424
@server("https://hyperfleet.redhat.com", "Production")
2525
@route("/api/hyperfleet/v1")
2626
namespace HyperFleet;

models-core/cluster/example_cluster.tsp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ const exampleCluster: Cluster = #{
4545
#{
4646
type: "Adapter1Successful",
4747
status: ResourceConditionStatus.True,
48-
reason: ExampleAdapter1AvaliableReason,
49-
message: ExampleAdapter1AvaliableMessage,
48+
reason: ExampleAdapter1AvailableReason,
49+
message: ExampleAdapter1AvailableMessage,
5050
observed_generation: 1,
5151
created_time: "2021-01-01T10:00:00Z",
5252
last_updated_time: "2021-01-01T10:00:00Z",
@@ -55,8 +55,8 @@ const exampleCluster: Cluster = #{
5555
#{
5656
type: "Adapter2Successful",
5757
status: ResourceConditionStatus.True,
58-
reason: ExampleAdapter2AvaliableReason,
59-
message: ExampleAdapter2AvaliableMessage,
58+
reason: ExampleAdapter2AvailableReason,
59+
message: ExampleAdapter2AvailableMessage,
6060
observed_generation: 1,
6161
created_time: "2021-01-01T10:01:00Z",
6262
last_updated_time: "2021-01-01T10:01:00Z",
@@ -113,8 +113,8 @@ const exampleDeletedCluster: Cluster = #{
113113
#{
114114
type: "Adapter1Successful",
115115
status: ResourceConditionStatus.True,
116-
reason: ExampleAdapter1AvaliableReason,
117-
message: ExampleAdapter1AvaliableMessage,
116+
reason: ExampleAdapter1AvailableReason,
117+
message: ExampleAdapter1AvailableMessage,
118118
observed_generation: 2,
119119
created_time: "2021-01-01T10:00:00Z",
120120
last_updated_time: "2021-01-01T10:00:00Z",
@@ -123,8 +123,8 @@ const exampleDeletedCluster: Cluster = #{
123123
#{
124124
type: "Adapter2Successful",
125125
status: ResourceConditionStatus.True,
126-
reason: ExampleAdapter2AvaliableReason,
127-
message: ExampleAdapter2AvaliableMessage,
126+
reason: ExampleAdapter2AvailableReason,
127+
message: ExampleAdapter2AvailableMessage,
128128
observed_generation: 2,
129129
created_time: "2021-01-01T10:01:00Z",
130130
last_updated_time: "2021-01-01T10:01:00Z",

models-core/nodepool/example_nodepool.tsp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ const exampleNodePool: NodePool = #{
5050
#{
5151
type: "Adapter1Successful",
5252
status: ResourceConditionStatus.True,
53-
reason: ExampleAdapter1AvaliableReason,
54-
message: ExampleAdapter1AvaliableMessage,
53+
reason: ExampleAdapter1AvailableReason,
54+
message: ExampleAdapter1AvailableMessage,
5555
observed_generation: 1,
5656
created_time: "2021-01-01T10:00:00Z",
5757
last_updated_time: "2021-01-01T10:00:00Z",
@@ -60,8 +60,8 @@ const exampleNodePool: NodePool = #{
6060
#{
6161
type: "Adapter2Successful",
6262
status: ResourceConditionStatus.True,
63-
reason: ExampleAdapter2AvaliableReason,
64-
message: ExampleAdapter2AvaliableMessage,
63+
reason: ExampleAdapter2AvailableReason,
64+
message: ExampleAdapter2AvailableMessage,
6565
observed_generation: 1,
6666
created_time: "2021-01-01T10:01:00Z",
6767
last_updated_time: "2021-01-01T10:01:00Z",
@@ -123,8 +123,8 @@ const exampleDeletedNodePool: NodePool = #{
123123
#{
124124
type: "Adapter1Successful",
125125
status: ResourceConditionStatus.True,
126-
reason: ExampleAdapter1AvaliableReason,
127-
message: ExampleAdapter1AvaliableMessage,
126+
reason: ExampleAdapter1AvailableReason,
127+
message: ExampleAdapter1AvailableMessage,
128128
observed_generation: 2,
129129
created_time: "2021-01-01T10:00:00Z",
130130
last_updated_time: "2021-01-01T10:00:00Z",
@@ -133,8 +133,8 @@ const exampleDeletedNodePool: NodePool = #{
133133
#{
134134
type: "Adapter2Successful",
135135
status: ResourceConditionStatus.True,
136-
reason: ExampleAdapter2AvaliableReason,
137-
message: ExampleAdapter2AvaliableMessage,
136+
reason: ExampleAdapter2AvailableReason,
137+
message: ExampleAdapter2AvailableMessage,
138138
observed_generation: 2,
139139
created_time: "2021-01-01T10:01:00Z",
140140
last_updated_time: "2021-01-01T10:01:00Z",

models-gcp/cluster/example_cluster.tsp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ const exampleCluster: Cluster = #{
6767
#{
6868
type: "Adapter1Successful",
6969
status: ResourceConditionStatus.True,
70-
reason: ExampleAdapter1AvaliableReason,
71-
message: ExampleAdapter1AvaliableMessage,
70+
reason: ExampleAdapter1AvailableReason,
71+
message: ExampleAdapter1AvailableMessage,
7272
observed_generation: 1,
7373
created_time: "2021-01-01T10:00:00Z",
7474
last_updated_time: "2021-01-01T10:00:00Z",
@@ -77,8 +77,8 @@ const exampleCluster: Cluster = #{
7777
#{
7878
type: "Adapter2Successful",
7979
status: ResourceConditionStatus.True,
80-
reason: ExampleAdapter2AvaliableReason,
81-
message: ExampleAdapter2AvaliableMessage,
80+
reason: ExampleAdapter2AvailableReason,
81+
message: ExampleAdapter2AvailableMessage,
8282
observed_generation: 1,
8383
created_time: "2021-01-01T10:01:00Z",
8484
last_updated_time: "2021-01-01T10:01:00Z",
@@ -157,8 +157,8 @@ const exampleDeletedCluster: Cluster = #{
157157
#{
158158
type: "Adapter1Successful",
159159
status: ResourceConditionStatus.True,
160-
reason: ExampleAdapter1AvaliableReason,
161-
message: ExampleAdapter1AvaliableMessage,
160+
reason: ExampleAdapter1AvailableReason,
161+
message: ExampleAdapter1AvailableMessage,
162162
observed_generation: 2,
163163
created_time: "2021-01-01T10:00:00Z",
164164
last_updated_time: "2021-01-01T10:00:00Z",
@@ -167,8 +167,8 @@ const exampleDeletedCluster: Cluster = #{
167167
#{
168168
type: "Adapter2Successful",
169169
status: ResourceConditionStatus.True,
170-
reason: ExampleAdapter2AvaliableReason,
171-
message: ExampleAdapter2AvaliableMessage,
170+
reason: ExampleAdapter2AvailableReason,
171+
message: ExampleAdapter2AvailableMessage,
172172
observed_generation: 2,
173173
created_time: "2021-01-01T10:01:00Z",
174174
last_updated_time: "2021-01-01T10:01:00Z",

models-gcp/nodepool/example_nodepool.tsp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import "../../aliases-gcp.tsp";
22
import "../../models/nodepools/model.tsp";
3+
import "../../models/common/model.tsp";
34

45
const exampleNodePool: NodePool = #{
56
kind: "NodePool",
@@ -41,8 +42,8 @@ const exampleNodePool: NodePool = #{
4142
#{
4243
type: ConditionType.Ready,
4344
status: ResourceConditionStatus.True,
44-
reason: "ResourceReady",
45-
message: "All conditions successful for current spec generation",
45+
reason: ExampleReadyReason,
46+
message: ExampleReadyMessage,
4647
observed_generation: 1,
4748
created_time: "2021-01-01T10:00:00Z",
4849
last_updated_time: "2021-01-01T10:00:00Z",
@@ -61,8 +62,8 @@ const exampleNodePool: NodePool = #{
6162
#{
6263
type: ConditionType.Available,
6364
status: ResourceConditionStatus.True,
64-
reason: "ResourceAvailable",
65-
message: "All conditions successful for observed_generation",
65+
reason: ExampleAvailableReason,
66+
message: ExampleAvailableMessage,
6667
observed_generation: 1,
6768
created_time: "2021-01-01T10:00:00Z",
6869
last_updated_time: "2021-01-01T10:00:00Z",
@@ -136,8 +137,8 @@ const exampleDeletedNodePool: NodePool = #{
136137
#{
137138
type: ConditionType.Ready,
138139
status: ResourceConditionStatus.True,
139-
reason: "ResourceReady",
140-
message: "All conditions successful for current spec generation",
140+
reason: ExampleReadyReason,
141+
message: ExampleReadyMessage,
141142
observed_generation: 2,
142143
created_time: "2021-01-01T10:00:00Z",
143144
last_updated_time: "2021-01-01T10:00:00Z",
@@ -156,8 +157,8 @@ const exampleDeletedNodePool: NodePool = #{
156157
#{
157158
type: ConditionType.Available,
158159
status: ResourceConditionStatus.True,
159-
reason: "ResourceAvailable",
160-
message: "All conditions successful for observed_generation",
160+
reason: ExampleAvailableReason,
161+
message: ExampleAvailableMessage,
161162
observed_generation: 2,
162163
created_time: "2021-01-01T10:00:00Z",
163164
last_updated_time: "2021-01-01T10:00:00Z",

models/common/model.tsp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ model ResourceCondition {
245245

246246
const ExampleAvailableReason: string = "All adapters reported Available True for the same generation";
247247
const ExampleAvailableMessage: string = "All adapters reported Available True for the same generation";
248-
const ExampleReadyReason: string = "All adapters reported Ready True for the current generation";
249-
const ExampleReadyMessage: string = "All adapters reported Ready True for the current generation";
248+
const ExampleReadyReason: string = "All adapters reported Available=True for the current generation";
249+
const ExampleReadyMessage: string = "All adapters reported Available=True for the current generation";
250250
const ExampleReconciledReason: string = "All required adapters reported Available=True or Finalized=True at the current generation";
251251
const ExampleReconciledMessage: string = "All required adapters reported Available=True or Finalized=True at the current generation";
252252
const ExampleAdapter1: string = "adapter1";
@@ -255,13 +255,13 @@ model ResourceCondition {
255255
const ExampleAdapter1AppliedMessage: string = "Adapter1 validation job applied successfully";
256256
const ExampleAdapter1HealthReason: string = "All adapter1 operations completed successfully";
257257
const ExampleAdapter1HealthMessage: string = "All adapter1 runtime operations completed successfully";
258-
const ExampleAdapter1AvaliableReason: string = "This adapter1 is available";
259-
const ExampleAdapter1AvaliableMessage: string = "This adapter1 is available";
258+
const ExampleAdapter1AvailableReason: string = "This adapter1 is available";
259+
const ExampleAdapter1AvailableMessage: string = "This adapter1 is available";
260260
const ExampleAdapter1FinalizedReason: string = "All resources deleted; cleanup confirmed";
261261
const ExampleAdapter1FinalizedMessage: string = "All resources deleted; cleanup confirmed";
262262
const ExampleAdapter2AppliedReason: string = "Validation job applied";
263263
const ExampleAdapter2AppliedMessage: string = "Adapter2 validation job applied successfully";
264264
const ExampleAdapter2HealthReason: string = "All adapter2 operations completed successfully";
265265
const ExampleAdapter2HealthMessage: string = "All adapter2 runtime operations completed successfully";
266-
const ExampleAdapter2AvaliableReason: string = "This adapter2 is available";
267-
const ExampleAdapter2AvaliableMessage: string = "This adapter2 is available";
266+
const ExampleAdapter2AvailableReason: string = "This adapter2 is available";
267+
const ExampleAdapter2AvailableMessage: string = "This adapter2 is available";

models/statuses/example_adapter_status.tsp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const exampleAdapterStatus: AdapterStatus = (#{
99
#{
1010
type: ConditionType.Available,
1111
status: AdapterConditionStatus.True,
12-
reason: ExampleAdapter1AvaliableReason,
13-
message: ExampleAdapter1AvaliableMessage,
12+
reason: ExampleAdapter1AvailableReason,
13+
message: ExampleAdapter1AvailableMessage,
1414
last_transition_time: "2021-01-01T10:00:00Z",
1515
},
1616
#{
@@ -63,8 +63,8 @@ const exampleAdapterStatusCreateRequest: AdapterStatusCreateRequest = (#{
6363
#{
6464
type: ConditionType.Available,
6565
status: AdapterConditionStatus.True,
66-
reason: ExampleAdapter1AvaliableReason,
67-
message: ExampleAdapter1AvaliableMessage,
66+
reason: ExampleAdapter1AvailableReason,
67+
message: ExampleAdapter1AvailableMessage,
6868
},
6969
#{
7070
type: "Applied",
@@ -116,8 +116,8 @@ const exampleAdapterStatusList: AdapterStatusList = (#{
116116
#{
117117
type: ConditionType.Available,
118118
status: AdapterConditionStatus.True,
119-
reason: ExampleAdapter1AvaliableReason,
120-
message: ExampleAdapter1AvaliableMessage,
119+
reason: ExampleAdapter1AvailableReason,
120+
message: ExampleAdapter1AvailableMessage,
121121
last_transition_time: "2021-01-01T10:00:00Z",
122122
},
123123
],
@@ -135,8 +135,8 @@ const exampleAdapterStatusList: AdapterStatusList = (#{
135135
#{
136136
type: ConditionType.Available,
137137
status: AdapterConditionStatus.True,
138-
reason: ExampleAdapter2AvaliableReason,
139-
message: ExampleAdapter2AvaliableMessage,
138+
reason: ExampleAdapter2AvailableReason,
139+
message: ExampleAdapter2AvailableMessage,
140140
last_transition_time: "2021-01-01T10:01:00Z",
141141
},
142142
],

schemas/core/openapi.yaml

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
openapi: 3.0.0
22
info:
33
title: HyperFleet API
4-
version: 1.0.9
4+
version: 1.0.10
55
contact:
66
name: HyperFleet Team
77
license:
@@ -125,6 +125,8 @@ paths:
125125
description: The server could not understand the request due to invalid syntax.
126126
'404':
127127
description: The server cannot find the requested resource.
128+
'409':
129+
description: The request conflicts with the current state of the server.
128130
default:
129131
description: An unexpected error response.
130132
content:
@@ -173,8 +175,8 @@ paths:
173175
conditions:
174176
- type: Ready
175177
status: 'True'
176-
reason: All adapters reported Ready True for the current generation
177-
message: All adapters reported Ready True for the current generation
178+
reason: All adapters reported Available=True for the current generation
179+
message: All adapters reported Available=True for the current generation
178180
observed_generation: 2
179181
created_time: '2021-01-01T10:00:00Z'
180182
last_updated_time: '2021-01-01T10:00:00Z'
@@ -283,6 +285,8 @@ paths:
283285
$ref: '#/components/schemas/NodePoolCreateResponse'
284286
'400':
285287
description: The server could not understand the request due to invalid syntax.
288+
'409':
289+
description: The request conflicts with the current state of the server.
286290
default:
287291
description: An unexpected error response.
288292
content:
@@ -376,8 +380,8 @@ paths:
376380
conditions:
377381
- type: Ready
378382
status: 'True'
379-
reason: All adapters reported Ready True for the current generation
380-
message: All adapters reported Ready True for the current generation
383+
reason: All adapters reported Available=True for the current generation
384+
message: All adapters reported Available=True for the current generation
381385
observed_generation: 2
382386
created_time: '2021-01-01T10:00:00Z'
383387
last_updated_time: '2021-01-01T10:00:00Z'
@@ -460,6 +464,8 @@ paths:
460464
description: The server could not understand the request due to invalid syntax.
461465
'404':
462466
description: The server cannot find the requested resource.
467+
'409':
468+
description: The request conflicts with the current state of the server.
463469
default:
464470
description: An unexpected error response.
465471
content:
@@ -1126,8 +1132,8 @@ components:
11261132
conditions:
11271133
- type: Ready
11281134
status: 'True'
1129-
reason: All adapters reported Ready True for the current generation
1130-
message: All adapters reported Ready True for the current generation
1135+
reason: All adapters reported Available=True for the current generation
1136+
message: All adapters reported Available=True for the current generation
11311137
observed_generation: 1
11321138
created_time: '2021-01-01T10:00:00Z'
11331139
last_updated_time: '2021-01-01T10:00:00Z'
@@ -1425,8 +1431,8 @@ components:
14251431
conditions:
14261432
- type: Ready
14271433
status: 'True'
1428-
reason: All adapters reported Ready True for the current generation
1429-
message: All adapters reported Ready True for the current generation
1434+
reason: All adapters reported Available=True for the current generation
1435+
message: All adapters reported Available=True for the current generation
14301436
observed_generation: 1
14311437
created_time: '2021-01-01T10:00:00Z'
14321438
last_updated_time: '2021-01-01T10:00:00Z'

0 commit comments

Comments
 (0)