This repository supports the development of the Hyperfleet OpenAPI contract, but is not the source-of-truth for the OpenAPI contract.
This project hosts the TypeSpec files to generate the HyperFleet OpenAPI specifications. Typescpec is an implementation detail providing better ergonomics than writing contracts in plain YAML, specially when dealing with contract variants that we need to keep aligned. The repository is organized to support multiple service variants (core, GCP, etc.) while sharing common models and interfaces.
Access to the OpenAPI contract source of truth in hyperfleet-api repository:
Access directly to the latest generated contract in this repository:
- core: https://openshift-hyperfleet.github.io/hyperfleet-api-spec/core.html
- GCP: https://openshift-hyperfleet.github.io/hyperfleet-api-spec/gcp.html
The OpenAPI contract that gets promoted to production is the one at:
Download examples:
curl -L -O https://github.com/openshift-hyperfleet/hyperfleet-api/releases/latest/download/openapi.yaml
Download the latest stable OpenAPI specifications directly from GitHub Releases:
Direct URLs (always get the latest stable version):
- Core:
https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/latest/download/core-openapi.yaml - GCP:
https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/latest/download/gcp-openapi.yaml
Download examples:
# Core API
curl -L -O https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/latest/download/core-openapi.yaml
# GCP API
curl -L -O https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/latest/download/gcp-openapi.yamlUse in code generation (always uses latest stable version):
# Generate Go client from Core API
openapi-generator generate -i https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/latest/download/core-openapi.yaml -g go -o ./client
# Generate Python client from GCP API
openapi-generator generate -i https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/latest/download/gcp-openapi.yaml -g python -o ./clientTo download a specific version (e.g., v1.0.0):
# Core API
curl -L -O https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/download/v1.0.0/core-openapi.yaml
# GCP API
curl -L -O https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases/download/v1.0.0/gcp-openapi.yamlSee all releases: https://github.com/openshift-hyperfleet/hyperfleet-api-spec/releases
The repository is organized with root-level configuration files and three main directories:
main.tsp- Main TypeSpec entry point that imports all service definitionsaliases.tsp- Provider alias configuration file (re-linked to switch between providers)aliases-core.tsp- Core provider aliases (definesClusterSpecasCoreClusterSpecwhich isRecord<unknown>)aliases-gcp.tsp- GCP provider aliases (definesClusterSpecasGCPClusterSpec)tspconfig.yaml- TypeSpec compiler configuration
Contains shared models used by all service variants:
models/clusters/- Cluster resource definitions (interfaces and base models)models/statuses/- Status resource definitions for clusters and nodepoolsmodels/nodepools/- NodePool resource definitionsmodels/common/- Common models and types (APIResource, Error, QueryParams, etc.)
Contains core provider-specific model definitions:
models-core/cluster/model.tsp- DefinesCoreClusterSpecasRecord<unknown>(generic)
Contains GCP provider-specific model definitions:
models-gcp/cluster/model.tsp- DefinesGCPClusterSpecwith GCP-specific properties
Contains service definitions that generate the OpenAPI specifications:
services/clusters.tsp- Cluster resource endpointsservices/statuses.tsp- Status resource endpoints (GET only - public API)services/statuses-internal.tsp- Status write endpoints (POST - internal API, see below)services/nodepools.tsp- NodePool resource endpoints
The status endpoints are split into two files to support different API consumers:
| File | Operations | Audience | Included in Build |
|---|---|---|---|
statuses.tsp |
GET (read) | External clients | ✅ Yes (default) |
statuses-internal.tsp |
POST (write) | Internal adapters | ❌ No (opt-in) |
Why the split?
- External clients (UI, CLI, monitoring) only need to read status information
- Internal adapters (validator, provisioner, dns) need to write/update status reports
- Separating these allows generating different API contracts for different audiences
First, install the TypeSpec compiler globally to get the tsp command:
npm install -g @typespec/compilerThis provides the tsp CLI tool but does not install the project-specific dependencies.
After cloning the repository, install the project's TypeSpec dependencies:
npm installThis installs all required TypeSpec libraries to the local node_modules/ directory:
@typespec/compiler- TypeSpec compiler@typespec/http- HTTP protocol support@typespec/rest- REST API support@typespec/openapi- OpenAPI decorators@typespec/openapi3- OpenAPI 3.0 emitter
Why both?
- Global install: Provides the
tspcommand-line tool - Local install: Provides the TypeSpec libraries that your
.tspfiles import
The repository uses a single main.tsp entry point. To generate either the core API or GCP API, you need to re-link the aliases.tsp file to point to the desired provider aliases file.
The build system supports two OpenAPI formats:
- OpenAPI 3.0 (default) - Modern format with full feature support
- OpenAPI 2.0 (Swagger) - Legacy format for compatibility with older tools
The easiest way to build the OpenAPI schema is using the provided npm scripts:
# Build OpenAPI 3.0 only
npm run build:core # Build Core API (OpenAPI 3.0)
npm run build:gcp # Build GCP API (OpenAPI 3.0)
# Build both OpenAPI 3.0 and OpenAPI 2.0 (Swagger)
npm run build:core:swagger # Build Core API with Swagger
npm run build:gcp:swagger # Build GCP API with Swagger
# Build all providers with both formats
npm run build:allYou can also use the build-schema.sh script directly:
# Build OpenAPI 3.0 only
./build-schema.sh core
./build-schema.sh gcp
# Build with OpenAPI 2.0 (Swagger) output
./build-schema.sh core --swagger
./build-schema.sh gcp --swagger
# or use the alias:
./build-schema.sh gcp --openapi2The script automatically:
- Validates the provider parameter
- Re-links
aliases.tspto the appropriate provider aliases file - Compiles the TypeSpec to generate the OpenAPI 3.0 schema
- (If
--swaggerflag is used) Converts OpenAPI 3.0 to OpenAPI 2.0 (Swagger) - Outputs the results to
schemas/{provider}/:openapi.yaml- OpenAPI 3.0 specificationswagger.yaml- OpenAPI 2.0 (Swagger) specification (if--swaggerflag is used)
Extending to new providers: Simply create aliases-{provider}.tsp and the script will automatically detect and support it.
If you prefer to build manually:
-
Re-link
aliases.tsptoaliases-core.tsp:ln -sf aliases-core.tsp aliases.tsp
-
Compile the TypeSpec:
tsp compile main.tsp
Output:
tsp-output/schema/openapi.yaml -
(Optional) Convert to OpenAPI 2.0 (Swagger):
npx api-spec-converter --from=openapi_3 --to=swagger_2 --syntax=yaml \ tsp-output/schema/openapi.yaml > tsp-output/schema/swagger.yaml
-
Re-link
aliases.tsptoaliases-gcp.tsp:ln -sf aliases-gcp.tsp aliases.tsp
-
Compile the TypeSpec:
tsp compile main.tsp
Output:
tsp-output/schema/openapi.yaml -
(Optional) Convert to OpenAPI 2.0 (Swagger):
npx api-spec-converter --from=openapi_3 --to=swagger_2 --syntax=yaml \ tsp-output/schema/openapi.yaml > tsp-output/schema/swagger.yaml
Note: The aliases.tsp file controls which provider-specific ClusterSpec definition is used throughout the service definitions. By re-linking it to either aliases-core.tsp or aliases-gcp.tsp, you switch between the generic Record<unknown> spec and the GCP-specific GCPClusterSpec.
The HyperFleet API provides simple CRUD operations for managing cluster resources and their status history:
- Simple CRUD only: No business logic, no event creation
- Separation of concerns: API layer focuses on data persistence; orchestration logic is handled by external components
To add a new provider (e.g., AWS):
-
Create provider model directory:
models-aws/cluster/model.tspmodel AWSClusterSpec { awsProperty1: string; awsProperty2: string; }
-
Create provider aliases file:
aliases-aws.tspimport "./models-aws/cluster/model.tsp"; alias ClusterSpec = AWSClusterSpec;
-
To generate the AWS API, re-link
aliases.tsp:ln -sf aliases-aws.tsp aliases.tsp tsp compile main.tsp
To add a new service (e.g., with additional endpoints):
-
Create a new service file:
services/new-service.tspimport "@typespec/http"; import "@typespec/openapi"; import "../models/common/model.tsp"; // ... other imports as needed namespace HyperFleet; @route("/new-resource") interface NewService { // ... endpoint definitions }
-
Import the new service in
main.tsp:import "./services/new-service.tsp";
@typespec/compiler- TypeSpec compiler@typespec/http- HTTP protocol support@typespec/openapi- OpenAPI decorators@typespec/openapi3- OpenAPI 3.0 emitterapi-spec-converter- Converts OpenAPI 3.0 to OpenAPI 2.0 (Swagger)
The repository works with different contracts (core and GCP) but a single Typespec main.tsp.
This is accomplished by maintaining an aliases.tsp file that holds the "active" concrete types to use (core or GCP).
- When working on the core API, the
aliases.tsppoints toaliases-core.tsp - When working on the GCP API, the
aliases.tsppoints toaliases-gcp.tsp
The downside of this is that it confuses the Typespec extension:
- For the "non-active" type files, the plugin may show errors as not defined types
- Since we duplicate aliases, the plugin may display an error of a type being duplicated
But, both the build-schema.sh script using the tsp CLI command as the plugin option to "Emit from Typespec" work fine.