Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .spectral.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ extends: ["spectral:oas"]
overrides:
- files:
- "schemas/core/openapi.yaml#/components/schemas/BearerAuth"
- "schemas/gcp/openapi.yaml#/components/schemas/BearerAuth"
- "schemas/core/openapi.yaml#/components/schemas/ForbiddenResponse"
rules:
oas3-unused-component: off
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.20] - 2026-06-02

### Fixed

- Typed error response models (`BadRequestResponse`, `UnauthorizedResponse`, `NotFoundResponse`, `ConflictResponse`) now emit an `application/problem+json` body schema per RFC 9457 (HYPERFLEET-993)
- `UnauthorizedResponse` (401) added to all status and force-delete endpoints
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

nit — non-blocking suggestion

Category: Pattern

The six status upsert endpoints (createOrUpdateStatus for cluster, nodepool, and resource statuses) previously declared | ConflictResponse (409) in their return unions. This PR removes 409 from all of them — which the JIRA ticket explicitly permits ("or the ConflictResponse usage is removed if intentionally absent").

However, the CHANGELOG doesn't mention this removal. Since it changes the documented API contract, a line under ### Fixed or ### Changed noting it would help consumers who rely on the spec for error handling:

- `ConflictResponse` (409) removed from status create/update endpoints (upsert semantics — conflict is not applicable)

Also, | Error (default error response) was added to these same endpoints — a good fix, as it was previously missing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added both fixes to changelog, thanks for pointing it.

- `ConflictResponse` (409) removed from status create/update endpoints (upsert semantics make conflict impossible)
- Default `Error` response added to status create/update endpoints where it was previously missing

### Changed

- `page` and `pageSize` query parameters have `@minValue(1)` constraints (HYPERFLEET-993)
- Error models scoped to `namespace HyperFleet {}` block to avoid collision with TypeSpec.Http built-ins
- Error example constants extracted to `shared/models/common/example_errors.tsp`

## [1.0.18] - 2026-05-26

### Changed
Expand Down Expand Up @@ -179,7 +194,8 @@ First official stable release of the HyperFleet API specification.
- Interactive API documentation

<!-- Links -->
[Unreleased]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.18...HEAD
[Unreleased]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.20...HEAD
[1.0.20]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.18...v1.0.20
[1.0.18]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.17...v1.0.18
[1.0.17]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.16...v1.0.17
[1.0.16]: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/compare/v1.0.15...v1.0.16
Expand Down
6 changes: 4 additions & 2 deletions core/services/force-delete-internal.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ interface ClustersForceDelete {
): {
@statusCode statusCode: 204;
} | Error
| NotFoundResponse
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse
| ConflictResponse;
}

Expand All @@ -54,7 +55,8 @@ interface NodePoolsForceDelete {
): {
@statusCode statusCode: 204;
} | Error
| NotFoundResponse
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse
| ConflictResponse;
}
36 changes: 22 additions & 14 deletions core/services/resources-internal.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ interface Resources {
@operationId("getResources")
getResources(...QueryParams): Body<ResourceList>
| Error
| BadRequestResponse;
| BadRequestResponse
| UnauthorizedResponse;

/**
* Returns a single resource by its ID.
Expand All @@ -38,8 +39,9 @@ interface Resources {
@path resource_id: string,
): Resource
| Error
| NotFoundResponse
| BadRequestResponse;
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse;

/**
* Create a new resource. Only top-level entity types (no parent) can be created
Expand All @@ -53,7 +55,8 @@ interface Resources {
@statusCode statusCode: 201;
@body resource: Resource;
} | Error
| BadRequestResponse;
| BadRequestResponse
| UnauthorizedResponse;

/**
* Patch a resource by ID. Supports partial updates to spec, labels, and references.
Expand All @@ -67,8 +70,9 @@ interface Resources {
@body body: ResourcePatchRequest,
): Resource
| Error
| NotFoundResponse
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse
| ConflictResponse;

/**
Expand All @@ -85,10 +89,11 @@ interface Resources {
): {
@statusCode statusCode: 202;
@body resource: Resource;
} | NotFoundResponse
| ConflictResponse
| Error
| BadRequestResponse;
} | Error
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse
| ConflictResponse;

/**
* Permanently removes the resource record from the database for a resource stuck in Finalizing state.
Expand All @@ -104,8 +109,9 @@ interface Resources {
): {
@statusCode statusCode: 204;
} | Error
| NotFoundResponse
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse
| ConflictResponse;
}

Expand All @@ -125,8 +131,9 @@ interface ResourceStatuses {
...QueryParams,
): Body<AdapterStatusList>
| Error
| NotFoundResponse
| BadRequestResponse;
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse;

@route("")
@put
Expand All @@ -138,7 +145,8 @@ interface ResourceStatuses {
@body body: AdapterStatusCreateRequest,
):
| (CreatedResponse & AdapterStatus)
| Error
| BadRequestResponse
| NotFoundResponse
| ConflictResponse;
| UnauthorizedResponse
| NotFoundResponse;
}
21 changes: 13 additions & 8 deletions core/services/statuses-internal.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ interface ClusterStatuses {
...QueryParams
): Body<AdapterStatusList>
| Error
| NotFoundResponse
| BadRequestResponse;
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse;

@route("")
@put
Expand All @@ -47,9 +48,10 @@ interface ClusterStatuses {
@body body: AdapterStatusCreateRequest,
):
| (CreatedResponse & AdapterStatus)
| Error
| BadRequestResponse
| NotFoundResponse
| ConflictResponse;
| UnauthorizedResponse
| NotFoundResponse;
}

@tag("NodePool statuses")
Expand All @@ -72,8 +74,9 @@ interface NodePoolStatuses {
...QueryParams
): Body<AdapterStatusList>
| Error
| NotFoundResponse
| BadRequestResponse;
| BadRequestResponse
| UnauthorizedResponse
| NotFoundResponse;

@route("")
@put
Expand All @@ -94,7 +97,9 @@ interface NodePoolStatuses {
@body body: AdapterStatusCreateRequest,
):
| (CreatedResponse & AdapterStatus)
| Error
| BadRequestResponse
| NotFoundResponse
| ConflictResponse;
| UnauthorizedResponse
| NotFoundResponse;
}

2 changes: 1 addition & 1 deletion main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ using OpenAPI;
*/
@service(#{ title: "HyperFleet API" })
@info(#{
version: "1.0.19",
version: "1.0.20",
contact: #{
name: "HyperFleet Team",
url: "https://github.com/openshift-hyperfleet",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyperfleet",
"version": "1.0.19",
"version": "1.0.20",
"type": "module",
"exports": {
"./*": "./*"
Expand Down
Loading