https://github.com/openshift-hyperfleet/hyperfleet-api-spec
https://github.com/openshift-hyperfleet/hyperfleet-api-spec
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/openshift-hyperfleet/hyperfleet-api-spec
- Owner: openshift-hyperfleet
- Created: 2025-11-04T08:33:24.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-12-17T13:19:46.000Z (6 months ago)
- Last Synced: 2026-01-12T18:54:53.539Z (5 months ago)
- Language: TypeSpec
- Size: 201 KB
- Stars: 0
- Watchers: 0
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# HyperFleet OpenAPI spec
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:
- GCP:
## Consuming the API Specifications
### Source of truth (Production contract)
The OpenAPI contract that gets promoted to production is the one at:
-
**Download examples**:
```bash
curl -L -O https://github.com/openshift-hyperfleet/hyperfleet-api/releases/latest/download/openapi.yaml
```
### Latest Releases (Recommended for development)
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**:
```bash
# 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.yaml
```
**Use in code generation** (always uses latest stable version):
```bash
# 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 ./client
```
### Version-Specific Downloads
To download a specific version (e.g., v1.0.0):
```bash
# 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.yaml
```
**See all releases**:
## Repository Structure
The repository is organized with root-level configuration files and three main directories:
### Root-Level Files
- **`main.tsp`** - Main TypeSpec entry point that imports all service definitions
- **`aliases.tsp`** - Provider alias configuration file (re-linked to switch between providers)
- **`aliases-core.tsp`** - Core provider aliases (defines `ClusterSpec` as `CoreClusterSpec` which is `Record`)
- **`aliases-gcp.tsp`** - GCP provider aliases (defines `ClusterSpec` as `GCPClusterSpec`)
- **`tspconfig.yaml`** - TypeSpec compiler configuration
### `/models`
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 nodepools
- **`models/nodepools/`** - NodePool resource definitions
- **`models/common/`** - Common models and types (APIResource, Error, QueryParams, etc.)
### `/models-core`
Contains core provider-specific model definitions:
- **`models-core/cluster/model.tsp`** - Defines `CoreClusterSpec` as `Record` (generic)
### `/models-gcp`
Contains GCP provider-specific model definitions:
- **`models-gcp/cluster/model.tsp`** - Defines `GCPClusterSpec` with GCP-specific properties
### `/services`
Contains service definitions that generate the OpenAPI specifications:
- **`services/clusters.tsp`** - Cluster resource endpoints
- **`services/statuses.tsp`** - Status resource endpoints (GET only - public API)
- **`services/statuses-internal.tsp`** - Status write endpoints (POST/PUT - internal API, see below)
- **`services/nodepools.tsp`** - NodePool resource endpoints
#### Public vs Internal API Split
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) |
| `statuses-internal.tsp` | PUT (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
## Prerequisites
After cloning the repository, install all dependencies:
```bash
npm install
```
This installs the TypeSpec compiler and all required libraries into `node_modules/`. The build scripts invoke `tsp` directly from `node_modules/.bin/`, so no global install is needed.
## Building OpenAPI Specifications
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.
### Output Formats
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
### Using npm Scripts (Recommended)
The easiest way to build the OpenAPI schema is using the provided npm scripts:
```bash
# 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:all
```
### Using the Build Script Directly
You can also use the `build-schema.sh` script directly:
```bash
# 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 --openapi2
```
The script automatically:
1. Validates the provider parameter
2. Re-links `aliases.tsp` to the appropriate provider aliases file
3. Compiles the TypeSpec to generate the OpenAPI 3.0 schema
4. (If `--swagger` flag is used) Converts OpenAPI 3.0 to OpenAPI 2.0 (Swagger)
5. Outputs the results to `schemas/{provider}/`:
- `openapi.yaml` - OpenAPI 3.0 specification
- `swagger.yaml` - OpenAPI 2.0 (Swagger) specification (if `--swagger` flag is used)
**Extending to new providers**: Simply create `aliases-{provider}.tsp` and the script will automatically detect and support it.
### Manual Build (Alternative)
If you prefer to build manually:
#### Build Core API
1. Re-link `aliases.tsp` to `aliases-core.tsp`:
```bash
ln -sf aliases-core.tsp aliases.tsp
```
2. Compile the TypeSpec:
```bash
tsp compile main.tsp
```
Output: `tsp-output/schema/openapi.yaml`
3. (Optional) Convert to OpenAPI 2.0 (Swagger):
```bash
npx api-spec-converter --from=openapi_3 --to=swagger_2 --syntax=yaml \
tsp-output/schema/openapi.yaml > tsp-output/schema/swagger.yaml
```
#### Build GCP API
1. Re-link `aliases.tsp` to `aliases-gcp.tsp`:
```bash
ln -sf aliases-gcp.tsp aliases.tsp
```
2. Compile the TypeSpec:
```bash
tsp compile main.tsp
```
Output: `tsp-output/schema/openapi.yaml`
3. (Optional) Convert to OpenAPI 2.0 (Swagger):
```bash
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` spec and the GCP-specific `GCPClusterSpec`.
## Architecture
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
## Adding a New Provider
To add a new provider (e.g., AWS):
1. Create provider model directory: `models-aws/cluster/model.tsp`
```typescript
model AWSClusterSpec {
awsProperty1: string;
awsProperty2: string;
}
```
2. Create provider aliases file: `aliases-aws.tsp`
```typescript
import "./models-aws/cluster/model.tsp";
alias ClusterSpec = AWSClusterSpec;
```
3. To generate the AWS API, re-link `aliases.tsp`:
```bash
ln -sf aliases-aws.tsp aliases.tsp
tsp compile main.tsp
```
## Adding a New Service
To add a new service (e.g., with additional endpoints):
1. Create a new service file: `services/new-service.tsp`
```typescript
import "@typespec/http";
import "@typespec/openapi";
import "../models/common/model.tsp";
// ... other imports as needed
namespace HyperFleet;
@route("/new-resource")
interface NewService {
// ... endpoint definitions
}
```
2. Import the new service in `main.tsp`:
```typescript
import "./services/new-service.tsp";
```
## Dependencies
- `@typespec/compiler` - TypeSpec compiler
- `@typespec/http` - HTTP protocol support
- `@typespec/openapi` - OpenAPI decorators
- `@typespec/openapi3` - OpenAPI 3.0 emitter
- `api-spec-converter` - Converts OpenAPI 3.0 to OpenAPI 2.0 (Swagger)
## Updating the Specification
### Making an API change
1. **Edit the TypeSpec sources** in `models/`, `models-gcp/`, or `services/`.
2. **Bump the version** in `main.tsp`:
```typescript
@info(#{ version: "1.0.12", ... })
```
3. **Rebuild all four schemas**:
```bash
./build-schema.sh core
./build-schema.sh core --swagger
./build-schema.sh gcp
./build-schema.sh gcp --swagger
```
4. **Update [CHANGELOG.md](CHANGELOG.md)** — move your changes from `[Unreleased]` into a new versioned entry.
5. **Open a PR.** CI enforces three things automatically:
- Committed schemas match freshly generated output (catches manual edits or forgotten rebuilds).
- OpenAPI 3.0 schemas pass `spectral:oas` linting.
- Version in `main.tsp` is higher than the latest GitHub release tag.
6. **Merge to main.** The release workflow runs automatically: it creates an annotated tag (`vX.Y.Z`), builds all four schemas from scratch, and publishes a GitHub release with the artifacts attached.
### Consuming schemas as a Go module
Each release tag is a valid Go module version. Import the embedded schemas:
```go
import specschemas "github.com/openshift-hyperfleet/hyperfleet-api-spec/schemas"
data, err := specschemas.FS.ReadFile("gcp/openapi.yaml")
```
To update a consumer after a new release:
```bash
go get github.com/openshift-hyperfleet/hyperfleet-api-spec@v1.0.12
```
To test locally against an unreleased branch, use a `replace` directive in your `go.mod`:
```go
replace github.com/openshift-hyperfleet/hyperfleet-api-spec => /path/to/local/hyperfleet-api-spec
```
See [hyperfleet-api docs/openapi-spec.md](https://github.com/openshift-hyperfleet/hyperfleet-api/blob/main/docs/openapi-spec.md) for how the hyperfleet-api service consumes this module.
## Contributing
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for:
- Development setup and workflow
- Repository structure details
- Testing guidelines
- Commit standards
- Pull request process
## Developing with the Visual Studio Typespec extension
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.tsp` points to `aliases-core.tsp`
- When working on the GCP API, the `aliases.tsp` points to `aliases-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.