560 lines
13 KiB
Markdown
560 lines
13 KiB
Markdown
|
|
# Extension Registry API Documentation
|
||
|
|
|
||
|
|
Version: 1.0.0
|
||
|
|
Base URL: `http://localhost:8082/api/v1`
|
||
|
|
|
||
|
|
## Table of Contents
|
||
|
|
|
||
|
|
- [Authentication](#authentication)
|
||
|
|
- [Extension Endpoints](#extension-endpoints)
|
||
|
|
- [System Endpoints](#system-endpoints)
|
||
|
|
- [Error Responses](#error-responses)
|
||
|
|
- [Data Models](#data-models)
|
||
|
|
|
||
|
|
## Authentication
|
||
|
|
|
||
|
|
The Extension Registry API does not require authentication for read operations. Backend authentication (Gitea/OCI) is handled server-side via configuration.
|
||
|
|
|
||
|
|
## Extension Endpoints
|
||
|
|
|
||
|
|
### List Extensions
|
||
|
|
|
||
|
|
Retrieve a list of available extensions with optional filtering and pagination.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /extensions`
|
||
|
|
|
||
|
|
**Query Parameters**:
|
||
|
|
| Parameter | Type | Required | Description |
|
||
|
|
|-----------|------|----------|-------------|
|
||
|
|
| `type` | string | No | Filter by extension type: `provider`, `taskserv`, `cluster` |
|
||
|
|
| `source` | string | No | Filter by source: `gitea`, `oci` |
|
||
|
|
| `limit` | integer | No | Maximum results (default: 100, max: 1000) |
|
||
|
|
| `offset` | integer | No | Pagination offset (default: 0) |
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?type=provider&limit=10"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```json
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"name": "aws",
|
||
|
|
"type": "provider",
|
||
|
|
"version": "1.2.0",
|
||
|
|
"description": "AWS provider for provisioning infrastructure",
|
||
|
|
"author": "provisioning-team",
|
||
|
|
"repository": "https://gitea.example.com/org/aws_prov",
|
||
|
|
"source": "gitea",
|
||
|
|
"published_at": "2025-10-06T12:00:00Z",
|
||
|
|
"download_url": "https://gitea.example.com/org/aws_prov/releases/download/1.2.0/aws_prov.tar.gz",
|
||
|
|
"checksum": "sha256:abc123...",
|
||
|
|
"size": 1024000,
|
||
|
|
"tags": ["cloud", "aws", "infrastructure"]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "upcloud",
|
||
|
|
"type": "provider",
|
||
|
|
"version": "2.1.3",
|
||
|
|
"description": "UpCloud provider for European cloud infrastructure",
|
||
|
|
"author": "provisioning-team",
|
||
|
|
"repository": "https://gitea.example.com/org/upcloud_prov",
|
||
|
|
"source": "gitea",
|
||
|
|
"published_at": "2025-10-05T10:30:00Z",
|
||
|
|
"download_url": "https://gitea.example.com/org/upcloud_prov/releases/download/2.1.3/upcloud_prov.tar.gz",
|
||
|
|
"size": 890000
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Get Extension Metadata
|
||
|
|
|
||
|
|
Retrieve detailed metadata for a specific extension.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /extensions/{type}/{name}`
|
||
|
|
|
||
|
|
**Path Parameters**:
|
||
|
|
| Parameter | Type | Required | Description |
|
||
|
|
|-----------|------|----------|-------------|
|
||
|
|
| `type` | string | Yes | Extension type: `provider`, `taskserv`, `cluster` |
|
||
|
|
| `name` | string | Yes | Extension name |
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/extensions/provider/aws"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"name": "aws",
|
||
|
|
"type": "provider",
|
||
|
|
"version": "1.2.0",
|
||
|
|
"description": "AWS provider for provisioning infrastructure",
|
||
|
|
"author": "provisioning-team",
|
||
|
|
"repository": "https://gitea.example.com/org/aws_prov",
|
||
|
|
"source": "gitea",
|
||
|
|
"published_at": "2025-10-06T12:00:00Z",
|
||
|
|
"download_url": "https://gitea.example.com/org/aws_prov/releases/download/1.2.0/aws_prov.tar.gz",
|
||
|
|
"checksum": "sha256:abc123...",
|
||
|
|
"size": 1024000,
|
||
|
|
"tags": ["cloud", "aws", "infrastructure"]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error Response** (404 Not Found):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "not_found",
|
||
|
|
"message": "Extension provider/nonexistent not found"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### List Extension Versions
|
||
|
|
|
||
|
|
Get all available versions for a specific extension.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /extensions/{type}/{name}/versions`
|
||
|
|
|
||
|
|
**Path Parameters**:
|
||
|
|
| Parameter | Type | Required | Description |
|
||
|
|
|-----------|------|----------|-------------|
|
||
|
|
| `type` | string | Yes | Extension type: `provider`, `taskserv`, `cluster` |
|
||
|
|
| `name` | string | Yes | Extension name |
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/extensions/taskserv/kubernetes/versions"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```json
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"version": "1.28.0",
|
||
|
|
"published_at": "2025-10-06T12:00:00Z",
|
||
|
|
"download_url": "https://gitea.example.com/org/kubernetes_taskserv/releases/download/1.28.0/kubernetes_taskserv.tar.gz",
|
||
|
|
"checksum": "sha256:def456...",
|
||
|
|
"size": 2048000
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"version": "1.27.5",
|
||
|
|
"published_at": "2025-09-15T10:30:00Z",
|
||
|
|
"download_url": "https://gitea.example.com/org/kubernetes_taskserv/releases/download/1.27.5/kubernetes_taskserv.tar.gz",
|
||
|
|
"checksum": "sha256:ghi789...",
|
||
|
|
"size": 1980000
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"version": "1.27.4",
|
||
|
|
"published_at": "2025-08-20T08:15:00Z",
|
||
|
|
"download_url": "https://gitea.example.com/org/kubernetes_taskserv/releases/download/1.27.4/kubernetes_taskserv.tar.gz",
|
||
|
|
"size": 1950000
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Download Extension
|
||
|
|
|
||
|
|
Download a specific version of an extension.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /extensions/{type}/{name}/{version}`
|
||
|
|
|
||
|
|
**Path Parameters**:
|
||
|
|
| Parameter | Type | Required | Description |
|
||
|
|
|-----------|------|----------|-------------|
|
||
|
|
| `type` | string | Yes | Extension type: `provider`, `taskserv`, `cluster` |
|
||
|
|
| `name` | string | Yes | Extension name |
|
||
|
|
| `version` | string | Yes | Extension version (e.g., `1.2.0`) |
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl -OJ "http://localhost:8082/api/v1/extensions/provider/aws/1.2.0"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response**:
|
||
|
|
- **Content-Type**: `application/octet-stream`
|
||
|
|
- **Body**: Binary data (tarball or archive)
|
||
|
|
|
||
|
|
**Error Response** (404 Not Found):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "not_found",
|
||
|
|
"message": "Extension provider/aws version 1.2.0 not found"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Search Extensions
|
||
|
|
|
||
|
|
Search for extensions by name or description.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /extensions/search`
|
||
|
|
|
||
|
|
**Query Parameters**:
|
||
|
|
| Parameter | Type | Required | Description |
|
||
|
|
|-----------|------|----------|-------------|
|
||
|
|
| `q` | string | Yes | Search query (case-insensitive) |
|
||
|
|
| `type` | string | No | Filter by extension type |
|
||
|
|
| `limit` | integer | No | Maximum results (default: 50, max: 100) |
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/extensions/search?q=kubernetes&type=taskserv&limit=5"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```json
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"name": "kubernetes",
|
||
|
|
"type": "taskserv",
|
||
|
|
"version": "1.28.0",
|
||
|
|
"description": "Kubernetes container orchestration platform",
|
||
|
|
"author": "provisioning-team",
|
||
|
|
"source": "gitea",
|
||
|
|
"published_at": "2025-10-06T12:00:00Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "k3s",
|
||
|
|
"type": "taskserv",
|
||
|
|
"version": "1.27.5",
|
||
|
|
"description": "Lightweight Kubernetes distribution",
|
||
|
|
"author": "community",
|
||
|
|
"source": "oci",
|
||
|
|
"published_at": "2025-09-20T14:30:00Z"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## System Endpoints
|
||
|
|
|
||
|
|
### Health Check
|
||
|
|
|
||
|
|
Check service health and backend status.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /health`
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/health"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "healthy",
|
||
|
|
"version": "0.1.0",
|
||
|
|
"uptime": 3600,
|
||
|
|
"backends": {
|
||
|
|
"gitea": {
|
||
|
|
"enabled": true,
|
||
|
|
"healthy": true
|
||
|
|
},
|
||
|
|
"oci": {
|
||
|
|
"enabled": true,
|
||
|
|
"healthy": true,
|
||
|
|
"error": null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Degraded Status** (200 OK):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "degraded",
|
||
|
|
"version": "0.1.0",
|
||
|
|
"uptime": 7200,
|
||
|
|
"backends": {
|
||
|
|
"gitea": {
|
||
|
|
"enabled": true,
|
||
|
|
"healthy": false,
|
||
|
|
"error": "Connection timeout"
|
||
|
|
},
|
||
|
|
"oci": {
|
||
|
|
"enabled": true,
|
||
|
|
"healthy": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Metrics
|
||
|
|
|
||
|
|
Get Prometheus-formatted metrics.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /metrics`
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/metrics"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```
|
||
|
|
# HELP http_requests_total Total HTTP requests
|
||
|
|
# TYPE http_requests_total counter
|
||
|
|
http_requests_total 1234
|
||
|
|
|
||
|
|
# HELP http_request_duration_seconds HTTP request duration
|
||
|
|
# TYPE http_request_duration_seconds histogram
|
||
|
|
http_request_duration_seconds_bucket{le="0.005"} 100
|
||
|
|
http_request_duration_seconds_bucket{le="0.01"} 200
|
||
|
|
http_request_duration_seconds_bucket{le="0.025"} 300
|
||
|
|
http_request_duration_seconds_sum 50.5
|
||
|
|
http_request_duration_seconds_count 1234
|
||
|
|
|
||
|
|
# HELP cache_hits_total Total cache hits
|
||
|
|
# TYPE cache_hits_total counter
|
||
|
|
cache_hits_total 987
|
||
|
|
|
||
|
|
# HELP cache_misses_total Total cache misses
|
||
|
|
# TYPE cache_misses_total counter
|
||
|
|
cache_misses_total 247
|
||
|
|
|
||
|
|
# HELP extensions_total Total extensions
|
||
|
|
# TYPE extensions_total gauge
|
||
|
|
extensions_total 45
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Cache Statistics
|
||
|
|
|
||
|
|
Get cache performance statistics.
|
||
|
|
|
||
|
|
**Endpoint**: `GET /cache/stats`
|
||
|
|
|
||
|
|
**Example Request**:
|
||
|
|
```bash
|
||
|
|
curl "http://localhost:8082/api/v1/cache/stats"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example Response** (200 OK):
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"list_entries": 45,
|
||
|
|
"metadata_entries": 120,
|
||
|
|
"version_entries": 80,
|
||
|
|
"total_entries": 245
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Error Responses
|
||
|
|
|
||
|
|
All error responses follow this format:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "error_type",
|
||
|
|
"message": "Human-readable error message",
|
||
|
|
"details": "Optional additional details"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### HTTP Status Codes
|
||
|
|
|
||
|
|
| Status | Description |
|
||
|
|
|--------|-------------|
|
||
|
|
| 200 OK | Request successful |
|
||
|
|
| 400 Bad Request | Invalid input (e.g., invalid extension type) |
|
||
|
|
| 401 Unauthorized | Authentication failed |
|
||
|
|
| 404 Not Found | Resource not found |
|
||
|
|
| 429 Too Many Requests | Rate limit exceeded |
|
||
|
|
| 500 Internal Server Error | Server error |
|
||
|
|
| 503 Service Unavailable | Service temporarily unavailable |
|
||
|
|
|
||
|
|
### Error Types
|
||
|
|
|
||
|
|
| Error Type | HTTP Status | Description |
|
||
|
|
|------------|-------------|-------------|
|
||
|
|
| `not_found` | 404 | Extension or resource not found |
|
||
|
|
| `invalid_type` | 400 | Invalid extension type provided |
|
||
|
|
| `invalid_version` | 400 | Invalid version format |
|
||
|
|
| `auth_error` | 401 | Authentication failed |
|
||
|
|
| `rate_limit` | 429 | Too many requests |
|
||
|
|
| `config_error` | 500 | Server configuration error |
|
||
|
|
| `internal_error` | 500 | Internal server error |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Data Models
|
||
|
|
|
||
|
|
### Extension
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface Extension {
|
||
|
|
name: string; // Extension name
|
||
|
|
type: ExtensionType; // Extension type
|
||
|
|
version: string; // Current version (semver)
|
||
|
|
description: string; // Description
|
||
|
|
author?: string; // Author/organization
|
||
|
|
repository?: string; // Source repository URL
|
||
|
|
source: ExtensionSource; // Backend source
|
||
|
|
published_at: string; // ISO 8601 timestamp
|
||
|
|
download_url?: string; // Download URL
|
||
|
|
checksum?: string; // Checksum (e.g., sha256:...)
|
||
|
|
size?: number; // Size in bytes
|
||
|
|
tags?: string[]; // Tags
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### ExtensionType
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
type ExtensionType = "provider" | "taskserv" | "cluster";
|
||
|
|
```
|
||
|
|
|
||
|
|
### ExtensionSource
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
type ExtensionSource = "gitea" | "oci";
|
||
|
|
```
|
||
|
|
|
||
|
|
### ExtensionVersion
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface ExtensionVersion {
|
||
|
|
version: string; // Version string (semver)
|
||
|
|
published_at: string; // ISO 8601 timestamp
|
||
|
|
download_url?: string; // Download URL
|
||
|
|
checksum?: string; // Checksum
|
||
|
|
size?: number; // Size in bytes
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### HealthResponse
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface HealthResponse {
|
||
|
|
status: string; // "healthy" | "degraded"
|
||
|
|
version: string; // Service version
|
||
|
|
uptime: number; // Uptime in seconds
|
||
|
|
backends: BackendHealth; // Backend health status
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### BackendHealth
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface BackendHealth {
|
||
|
|
gitea: BackendStatus;
|
||
|
|
oci: BackendStatus;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### BackendStatus
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface BackendStatus {
|
||
|
|
enabled: boolean; // Backend enabled
|
||
|
|
healthy: boolean; // Backend healthy
|
||
|
|
error?: string; // Error message if unhealthy
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Rate Limiting
|
||
|
|
|
||
|
|
Currently, the API does not enforce rate limiting. This may be added in future versions.
|
||
|
|
|
||
|
|
For high-volume usage, consider:
|
||
|
|
- Implementing client-side rate limiting
|
||
|
|
- Using the cache effectively
|
||
|
|
- Batching requests when possible
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Caching Behavior
|
||
|
|
|
||
|
|
The service implements LRU caching with TTL:
|
||
|
|
|
||
|
|
- **Cache TTL**: Configurable (default: 5 minutes)
|
||
|
|
- **Cache Capacity**: Configurable (default: 1000 entries)
|
||
|
|
- **Cache Keys**:
|
||
|
|
- List: `list:{type}:{source}`
|
||
|
|
- Metadata: `{type}/{name}`
|
||
|
|
- Versions: `{type}/{name}/versions`
|
||
|
|
|
||
|
|
Cache headers are not currently exposed. Future versions may include:
|
||
|
|
- `X-Cache-Hit: true/false`
|
||
|
|
- `X-Cache-TTL: {seconds}`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Versioning
|
||
|
|
|
||
|
|
API version is specified in the URL path: `/api/v1/`
|
||
|
|
|
||
|
|
Major version changes will be introduced in new paths (e.g., `/api/v2/`).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Examples
|
||
|
|
|
||
|
|
### Complete Workflow
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Search for Kubernetes extensions
|
||
|
|
curl "http://localhost:8082/api/v1/extensions/search?q=kubernetes"
|
||
|
|
|
||
|
|
# 2. Get extension metadata
|
||
|
|
curl "http://localhost:8082/api/v1/extensions/taskserv/kubernetes"
|
||
|
|
|
||
|
|
# 3. List available versions
|
||
|
|
curl "http://localhost:8082/api/v1/extensions/taskserv/kubernetes/versions"
|
||
|
|
|
||
|
|
# 4. Download specific version
|
||
|
|
curl -OJ "http://localhost:8082/api/v1/extensions/taskserv/kubernetes/1.28.0"
|
||
|
|
|
||
|
|
# 5. Verify checksum (if provided)
|
||
|
|
sha256sum kubernetes_taskserv.tar.gz
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pagination
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Get first page
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?limit=10&offset=0"
|
||
|
|
|
||
|
|
# Get second page
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?limit=10&offset=10"
|
||
|
|
|
||
|
|
# Get third page
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?limit=10&offset=20"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Filtering
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Only providers from Gitea
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?type=provider&source=gitea"
|
||
|
|
|
||
|
|
# Only taskservs from OCI
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?type=taskserv&source=oci"
|
||
|
|
|
||
|
|
# All clusters
|
||
|
|
curl "http://localhost:8082/api/v1/extensions?type=cluster"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Support
|
||
|
|
|
||
|
|
For issues and questions, see the main README or project documentation.
|