Jesús Pérez 09a97ac8f5
chore: update platform submodule to monorepo crates structure
Platform restructured into crates/, added AI service and detector,
       migrated control-center-ui to Leptos 0.8
2026-01-08 21:32:59 +00:00

13 KiB

Extension Registry API Documentation

Version: 1.0.0 Base URL: http://localhost:8082/api/v1

Table of Contents

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:

curl "http://localhost:8082/api/v1/extensions?type=provider&limit=10"
```plaintext

**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
  }
]
```plaintext

---

### 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"
```plaintext

**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"]
}
```plaintext

**Error Response** (404 Not Found):

```json
{
  "error": "not_found",
  "message": "Extension provider/nonexistent not found"
}
```plaintext

---

### 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"
```plaintext

**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
  }
]
```plaintext

---

### 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"
```plaintext

**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"
}
```plaintext

---

### 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"
```plaintext

**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"
  }
]
```plaintext

---

## System Endpoints

### Health Check

Check service health and backend status.

**Endpoint**: `GET /health`

**Example Request**:

```bash
curl "http://localhost:8082/api/v1/health"
```plaintext

**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
    }
  }
}
```plaintext

**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
    }
  }
}
```plaintext

---

### Metrics

Get Prometheus-formatted metrics.

**Endpoint**: `GET /metrics`

**Example Request**:

```bash
curl "http://localhost:8082/api/v1/metrics"
```plaintext

**Example Response** (200 OK):

```plaintext
# 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
```plaintext

---

### Cache Statistics

Get cache performance statistics.

**Endpoint**: `GET /cache/stats`

**Example Request**:

```bash
curl "http://localhost:8082/api/v1/cache/stats"
```plaintext

**Example Response** (200 OK):

```json
{
  "list_entries": 45,
  "metadata_entries": 120,
  "version_entries": 80,
  "total_entries": 245
}
```plaintext

---

## Error Responses

All error responses follow this format:

```json
{
  "error": "error_type",
  "message": "Human-readable error message",
  "details": "Optional additional details"
}
```plaintext

### 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
}
```plaintext

### ExtensionType

```typescript
type ExtensionType = "provider" | "taskserv" | "cluster";
```plaintext

### ExtensionSource

```typescript
type ExtensionSource = "gitea" | "oci";
```plaintext

### 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
}
```plaintext

### HealthResponse

```typescript
interface HealthResponse {
  status: string;            // "healthy" | "degraded"
  version: string;           // Service version
  uptime: number;            // Uptime in seconds
  backends: BackendHealth;   // Backend health status
}
```plaintext

### BackendHealth

```typescript
interface BackendHealth {
  gitea: BackendStatus;
  oci: BackendStatus;
}
```plaintext

### BackendStatus

```typescript
interface BackendStatus {
  enabled: boolean;          // Backend enabled
  healthy: boolean;          // Backend healthy
  error?: string;            // Error message if unhealthy
}
```plaintext

---

## 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
```plaintext

### 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"
```plaintext

### 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"
```plaintext

---

## Support

For issues and questions, see the main README or project documentation.