api

package
v0.0.0-...-3fd2519 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Overview

Package api provides HTTP request handlers for the StreamSpace API.

This file implements the core REST API endpoints for managing sessions, templates, and repositories in the StreamSpace container streaming platform.

HANDLER OVERVIEW:

The API handler provides endpoints for: - Session management (create, read, update, delete, connect) - Template management (list, search, favorites) - Template catalog (marketplace) - Repository management (sync external template sources) - Connection tracking (active user connections) - Quota enforcement (resource limits)

ARCHITECTURE:

The handler acts as a bridge between HTTP requests and: - Kubernetes API (via k8s.Client) for Session/Template CRDs - PostgreSQL database (via db.Database) for caching and metadata - Connection tracker for real-time session monitoring - Quota enforcer for resource limit validation - Sync service for external repository synchronization - WebSocket manager for real-time updates

SECURITY CONSIDERATIONS:

1. Authentication: All endpoints assume authentication middleware has run

  • User context available via c.Get("userID"), c.Get("userRole")
  • Admin-only endpoints should use auth.RequireRole("admin") middleware

2. Authorization: Session ownership validated before operations

  • Users can only manage their own sessions
  • Admins can manage all sessions

3. Input Validation: All request payloads validated with binding tags

  • Malformed JSON rejected with 400 Bad Request
  • Required fields enforced

4. Quota Enforcement: Resource limits checked before session creation

  • Prevents resource exhaustion attacks
  • Enforces fair usage policies

5. Database Caching: Sessions cached in PostgreSQL for performance

  • Cache updates are best-effort (failures logged but not blocking)
  • Kubernetes is source of truth, database is cache

DATA FLOW:

Session Creation:

  1. Client → POST /api/sessions {user, template, resources}
  2. Handler validates template exists in Kubernetes
  3. Handler checks user quota against current usage
  4. Handler creates Session CRD in Kubernetes
  5. Handler caches session in PostgreSQL (best-effort)
  6. Controller watches Session CRD and creates Deployment/Service
  7. Client polls GET /api/sessions/{id} for status updates

Session Connection:

  1. Client → POST /api/sessions/{id}/connect?user={userID}
  2. Handler verifies session exists
  3. Handler creates connection record in tracker
  4. Handler returns session URL and connection ID
  5. Client establishes WebSocket/VNC connection
  6. Client sends periodic heartbeats to keep connection alive
  7. On disconnect, client calls disconnect endpoint

Template Sync:

  1. Admin → POST /api/repositories (add GitHub repo)
  2. Handler triggers background sync in SyncService
  3. SyncService clones repo, parses templates, stores in database
  4. Templates available in catalog endpoint
  5. User → POST /api/catalog/{id}/install
  6. Handler creates Template CRD in Kubernetes from catalog manifest

ERROR HANDLING:

All endpoints follow consistent error response format:

{
  "error": "Short error code",
  "message": "Detailed error message"
}

HTTP Status Codes: - 200 OK: Successful read operation - 201 Created: Successful resource creation - 202 Accepted: Async operation started (e.g., sync) - 400 Bad Request: Invalid request format or parameters - 401 Unauthorized: Authentication required - 403 Forbidden: Insufficient permissions or quota exceeded - 404 Not Found: Resource does not exist - 500 Internal Server Error: Server-side error

Package api provides HTTP handlers and WebSocket endpoints for the StreamSpace API. This file contains stub implementations, backwards compatibility handlers, Kubernetes resource management, and compliance endpoint stubs.

STUB ENDPOINTS OVERVIEW:

This file serves multiple purposes: 1. Backwards compatibility for routes migrated to specialized handlers 2. Kubernetes resource CRUD operations (generic resource management) 3. Stub endpoints for optional plugins (compliance, etc.) 4. WebSocket upgrader configuration with origin validation

KUBERNETES RESOURCE MANAGEMENT:

Generic endpoints for managing any Kubernetes resource: - CreateResource: Create any K8s resource (Deployment, Service, ConfigMap, etc.) - UpdateResource: Update existing K8s resources - DeleteResource: Delete K8s resources by type and name - ListNodes, ListPods, ListServices, etc.: List cluster resources - GetPodLogs: Stream or retrieve pod logs

BACKWARDS COMPATIBILITY:

Some endpoints like ListNodes() are stubs that redirect to specialized handlers: - Node management is now in handlers/nodes.go (NodeHandler) - User management is in handlers/users.go (UserHandler) - These stubs remain for API backwards compatibility during migration

COMPLIANCE STUBS:

The compliance endpoints return stub data when streamspace-compliance plugin is not installed. When the plugin is installed, it registers real handlers that override these stubs.

WEBSOCKET CONFIGURATION:

The WebSocket upgrader checks allowed origins from ALLOWED_ORIGINS environment variable to prevent CSRF attacks. Set to "*" to allow all origins (development only).

Example ALLOWED_ORIGINS: "http://localhost:3000,https://streamspace.example.com"

Index

Constants

View Source
const (
	// DefaultNamespace is the default Kubernetes namespace for resources
	// v2.0-beta: API doesn't create K8s resources, but passes namespace to agent in payloads
	DefaultNamespace = "streamspace"
)

sessionGVR defines the GroupVersionResource for Session custom resources.

This is used with Kubernetes dynamic client to directly manipulate Session CRDs when the strongly-typed client is not sufficient (e.g., updating tags field).

Format: {group}/{version}/namespaces/{namespace}/{resource} Example: stream.space/v1alpha1/namespaces/streamspace/sessions

Variables

This section is empty.

Functions

This section is empty.

Types

type CommandDispatcher

type CommandDispatcher interface {
	DispatchCommand(command *models.AgentCommand) error
}

CommandDispatcher interface for dispatching commands to agents

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler handles all API requests for StreamSpace.

This is the main request handler that routes HTTP requests to appropriate business logic and manages interactions with Kubernetes, database, and external services.

DEPENDENCIES:

- db: PostgreSQL database for caching and metadata - k8sClient: Kubernetes client for managing Session/Template CRDs - connTracker: Connection tracker for monitoring active user connections - syncService: Repository sync service for external template sources - wsManager: WebSocket manager for real-time updates - quotaEnforcer: Quota enforcement for resource limits - namespace: Kubernetes namespace where resources are created

CONCURRENCY:

Handler is safe for concurrent use by multiple goroutines (one per HTTP request). Each request gets its own Gin context with isolated state.

func NewHandler

func NewHandler(database *db.Database, publisher *events.Publisher, dispatcher CommandDispatcher, connTracker *tracker.ConnectionTracker, syncService *sync.SyncService, wsManager *websocket.Manager, quotaEnforcer *quota.Enforcer, platform string, agentHub *websocket.AgentHub, k8sClient *k8s.Client) *Handler

NewHandler creates a new API handler with injected dependencies.

PARAMETERS:

- database: PostgreSQL database connection for caching and metadata - publisher: NATS event publisher for platform-agnostic operations - dispatcher: Command dispatcher for sending commands to agents - connTracker: Connection tracker for active session monitoring - syncService: Service for syncing external template repositories - wsManager: Manager for WebSocket connections and real-time updates - quotaEnforcer: Enforcer for validating resource quotas - platform: Target platform (kubernetes, docker, hyperv, vcenter) - agentHub: Agent hub for tracking connected agents (required for multi-agent routing) - k8sClient: OPTIONAL Kubernetes client for cluster management endpoints (can be nil)

v2.0-beta ARCHITECTURE:

Session and template operations use database + agent pattern (NO K8s dependencies). The k8sClient parameter is OPTIONAL and only used for cluster management admin endpoints (ListNodes, ListPods, GetMetrics, etc.). When nil, these endpoints return stub data.

MULTI-AGENT ROUTING:

The agentHub is required to enable multi-agent routing and load balancing. AgentSelector uses agentHub to check which agents are connected and healthy before routing session creation requests.

NAMESPACE RESOLUTION:

The Kubernetes namespace is read from NAMESPACE environment variable. If not set, defaults to "streamspace". Only used when k8sClient is provided.

EXAMPLE USAGE:

// API running in Kubernetes with cluster management
handler := NewHandler(db, publisher, dispatcher, connTracker, syncService, wsManager, quotaEnforcer, "kubernetes", agentHub, k8sClient)

// API running standalone (no K8s dependencies)
handler := NewHandler(db, publisher, dispatcher, connTracker, syncService, wsManager, quotaEnforcer, "kubernetes", agentHub, nil)

func (*Handler) AddRepository

func (h *Handler) AddRepository(c *gin.Context)

AddRepository adds a new template repository

func (*Handler) AddTemplateFavorite

func (h *Handler) AddTemplateFavorite(c *gin.Context)

AddTemplateFavorite adds a template to the authenticated user's favorites list.

HTTP Method: POST Path: /api/templates/{id}/favorite Authentication: Required Authorization: Any authenticated user

SECURITY: User Context Validation

This handler retrieves user ID from Gin context (populated by auth middleware). The authentication middleware MUST run before this handler to ensure: - User is authenticated (valid JWT token) - User account is active (not disabled) - userID context value is set

DATABASE TRANSACTION BOUNDARY:

- Single INSERT query with ON CONFLICT DO NOTHING (idempotent) - No explicit transaction needed (single query is atomic) - Safe for concurrent calls (unique constraint prevents duplicates)

ERROR RESPONSES:

- 401 Unauthorized: User not authenticated - 404 Not Found: Template does not exist - 500 Internal Server Error: Database failure

func (*Handler) BrowseCatalog

func (h *Handler) BrowseCatalog(c *gin.Context)

BrowseCatalog returns catalog templates (alias for ListCatalogTemplates)

func (*Handler) CheckTemplateFavorite

func (h *Handler) CheckTemplateFavorite(c *gin.Context)

CheckTemplateFavorite checks if a template is in user's favorites

func (*Handler) ClusterWebSocket

func (h *Handler) ClusterWebSocket(c *gin.Context)

ClusterWebSocket handles WebSocket for real-time cluster updates Only admins and operators can view cluster-wide metrics

func (*Handler) ConnectSession

func (h *Handler) ConnectSession(c *gin.Context)

ConnectSession handles a user connecting to a session

func (*Handler) CreateComplianceFramework

func (h *Handler) CreateComplianceFramework(c *gin.Context)

CreateComplianceFramework creates a new compliance framework Stub returns not implemented - install streamspace-compliance plugin

func (*Handler) CreateCompliancePolicy

func (h *Handler) CreateCompliancePolicy(c *gin.Context)

CreateCompliancePolicy creates a new compliance policy Stub returns not implemented - install streamspace-compliance plugin

func (*Handler) CreateResource

func (h *Handler) CreateResource(c *gin.Context)

CreateResource creates a K8s resource v2.0-beta: Returns error when API runs without K8s access

func (*Handler) CreateSession

func (h *Handler) CreateSession(c *gin.Context)

CreateSession creates a new container session for a user.

HTTP Method: POST Path: /api/sessions Authentication: Required Authorization: User can create own sessions; Admin can create for any user

REQUEST BODY:

{
  "user": "user123",                  // REQUIRED: User ID
  "template": "firefox",               // REQUIRED: Template name
  "resources": {"memory": "2Gi", "cpu": "1000m"},  // OPTIONAL
  "persistentHome": true,              // OPTIONAL: Mount persistent storage
  "idleTimeout": "30m",                // OPTIONAL: Auto-hibernate timeout
  "maxSessionDuration": "8h",          // OPTIONAL: Maximum lifetime
  "tags": ["project-a", "dev"]         // OPTIONAL: Organization tags
}

SECURITY: Quota Enforcement

This handler enforces resource quotas before creating sessions to prevent: - Resource exhaustion attacks (unlimited session creation) - Fair usage violations (one user consuming all cluster resources) - Cluster instability (out of memory, CPU starvation)

Quota check process: 1. Parse and validate requested CPU/memory resources 2. Calculate current user resource usage from active pods 3. Check if user has quota headroom for new session 4. Reject with 403 Forbidden if quota would be exceeded

DATABASE TRANSACTION BOUNDARY:

- No database transaction (Kubernetes is source of truth) - Session cached in PostgreSQL after creation (best-effort) - Cache failures logged but do NOT block session creation

ERROR RESPONSES:

- 400 Bad Request: Invalid JSON or malformed resource specifications - 403 Forbidden: User quota exceeded - 404 Not Found: Template does not exist - 500 Internal Server Error: Kubernetes API failure

func (*Handler) CreateTemplate

func (h *Handler) CreateTemplate(c *gin.Context)

CreateTemplate creates a new template (admin only)

func (*Handler) DeleteRepository

func (h *Handler) DeleteRepository(c *gin.Context)

DeleteRepository deletes a template repository

func (*Handler) DeleteResource

func (h *Handler) DeleteResource(c *gin.Context)

DeleteResource deletes a K8s resource v2.0-beta: Returns error when API runs without K8s access

func (*Handler) DeleteSession

func (h *Handler) DeleteSession(c *gin.Context)

DeleteSession deletes a session

func (*Handler) DeleteTemplate

func (h *Handler) DeleteTemplate(c *gin.Context)

DeleteTemplate deletes a template (admin only)

func (*Handler) DisconnectSession

func (h *Handler) DisconnectSession(c *gin.Context)

DisconnectSession handles a user disconnecting from a session

func (*Handler) GetComplianceDashboard

func (h *Handler) GetComplianceDashboard(c *gin.Context)

GetComplianceDashboard returns compliance dashboard metrics Stub returns zero metrics - install streamspace-compliance plugin for real data

func (*Handler) GetConfig

func (h *Handler) GetConfig(c *gin.Context)

GetConfig returns configuration v2.0-beta: Returns default config when API runs without K8s access

func (*Handler) GetMetrics

func (h *Handler) GetMetrics(c *gin.Context)

GetMetrics returns comprehensive cluster metrics for the admin dashboard.

This endpoint aggregates data from multiple sources: - Kubernetes: Node count, resource capacity, allocatable resources, pod counts - Database: Session counts by state, user counts, active users (24hr) - Calculations: Resource utilization percentages

Returned Metrics: - cluster.nodes: Total, ready, and not-ready node counts - cluster.sessions: Total, running, hibernated, and terminated session counts - cluster.resources: CPU, memory, and pod capacity/usage/percentages - cluster.users: Total user count and active users (logged in last 24 hours)

Resource Estimates: Used CPU/memory are estimates based on running session count (1 core, 2GB per session). For accurate resource usage, deploy metrics-server and query real pod metrics.

GET /api/v1/metrics

func (*Handler) GetPodLogs

func (h *Handler) GetPodLogs(c *gin.Context)

GetPodLogs returns pod logs v2.0-beta: Returns error when API runs without K8s access

func (*Handler) GetSession

func (h *Handler) GetSession(c *gin.Context)

GetSession returns a single session by ID

func (*Handler) GetSessionConnections

func (h *Handler) GetSessionConnections(c *gin.Context)

GetSessionConnections returns active connections for a session

func (*Handler) GetTemplate

func (h *Handler) GetTemplate(c *gin.Context)

GetTemplate returns a single template

func (*Handler) Health

func (h *Handler) Health(c *gin.Context)

Health returns health status

func (*Handler) HibernateSession

func (h *Handler) HibernateSession(c *gin.Context)

HibernateSession handles hibernating a running session (scales to 0 replicas)

func (*Handler) InstallCatalogTemplate

func (h *Handler) InstallCatalogTemplate(c *gin.Context)

InstallCatalogTemplate installs a template from the catalog to the Kubernetes cluster.

HTTP Method: POST Path: /api/catalog/{id}/install Authentication: Required Authorization: Admin only (installs cluster-wide resources)

SECURITY: YAML Parsing from External Source

This handler parses YAML manifests from the catalog database, which may originate from external repositories. This introduces security risks:

1. Malicious YAML: Catalog templates may contain crafted YAML to:

  • Exploit YAML parser vulnerabilities (billion laughs, entity expansion)
  • Inject malicious container images
  • Request excessive resources
  • Escape pod sandboxes

2. Supply Chain Attacks: If repository is compromised, attacker can:

  • Modify templates to include backdoors
  • Inject crypto miners
  • Exfiltrate data from clusters

MITIGATIONS:

- Validate YAML structure after parsing (check for required fields) - Only allow installation by admins (not regular users) - Repository sync should validate templates before storing - Consider sandboxing template execution (not implemented) - Audit log all template installations for forensics

DATABASE TRANSACTION BOUNDARY:

- Two queries: SELECT template, UPDATE install_count - No explicit transaction (install_count update is best-effort) - Failure to increment counter does NOT fail installation

DATA FLOW:

1. Retrieve template manifest from database (YAML string) 2. Parse YAML to extract spec fields 3. Build Template CRD struct from parsed data 4. Create Template resource in Kubernetes 5. Increment install_count in database (best-effort)

ERROR RESPONSES:

- 400 Bad Request: Invalid YAML manifest structure - 404 Not Found: Catalog template not found - 500 Internal Server Error: Kubernetes API or database failure

func (*Handler) InstallTemplate

func (h *Handler) InstallTemplate(c *gin.Context)

InstallTemplate installs a template from catalog (alias for InstallCatalogTemplate)

func (*Handler) ListCatalogTemplates

func (h *Handler) ListCatalogTemplates(c *gin.Context)

ListCatalogTemplates returns templates from the marketplace catalog

func (*Handler) ListComplianceFrameworks

func (h *Handler) ListComplianceFrameworks(c *gin.Context)

ListComplianceFrameworks returns available compliance frameworks Stub returns empty list - install streamspace-compliance plugin for real data

func (*Handler) ListCompliancePolicies

func (h *Handler) ListCompliancePolicies(c *gin.Context)

ListCompliancePolicies returns all compliance policies Stub returns empty list - install streamspace-compliance plugin for real data

func (*Handler) ListDeployments

func (h *Handler) ListDeployments(c *gin.Context)

ListDeployments returns deployments v2.0-beta: Returns error when API runs without K8s access

func (*Handler) ListNamespaces

func (h *Handler) ListNamespaces(c *gin.Context)

ListNamespaces returns namespaces v2.0-beta: Returns error when API runs without K8s access

func (*Handler) ListNodes

func (h *Handler) ListNodes(c *gin.Context)

ListNodes returns cluster nodes Note: This is now implemented in handlers/nodes.go via NodeHandler This stub remains for backwards compatibility with old routes v2.0-beta: Returns stub data when API runs without K8s access

func (*Handler) ListPods

func (h *Handler) ListPods(c *gin.Context)

ListPods returns pods in namespace v2.0-beta: Returns error when API runs without K8s access

func (*Handler) ListRepositories

func (h *Handler) ListRepositories(c *gin.Context)

ListRepositories returns all template and plugin repositories

func (*Handler) ListServices

func (h *Handler) ListServices(c *gin.Context)

ListServices returns services v2.0-beta: Returns error when API runs without K8s access

func (*Handler) ListSessions

func (h *Handler) ListSessions(c *gin.Context)

ListSessions retrieves all sessions for a specific user or all sessions (admin).

HTTP Method: GET Path: /api/sessions Authentication: Required Authorization: User can list own sessions; Admin can list all sessions

QUERY PARAMETERS:

- user (optional): Filter sessions by user ID

  • If provided: Returns sessions for that specific user
  • If omitted: Returns all sessions (requires admin role)

REQUEST EXAMPLE:

GET /api/sessions?user=user123

RESPONSE FORMAT:

{
  "sessions": [
    {
      "name": "user123-firefox-abc",
      "user": "user123",
      "template": "firefox",
      "state": "running",
      "activeConnections": 2,
      ...
    }
  ],
  "total": 1
}

SECURITY:

- Uses request context for proper timeout and cancellation handling - Database enrichment failures are non-fatal (logged but don't block response) - Should be paired with authorization middleware to restrict access

ERROR RESPONSES:

- 500 Internal Server Error: Kubernetes API failure

func (*Handler) ListSessionsByTags

func (h *Handler) ListSessionsByTags(c *gin.Context)

ListSessionsByTags returns sessions filtered by tags

func (*Handler) ListTemplates

func (h *Handler) ListTemplates(c *gin.Context)

ListTemplates returns all templates with advanced filtering, search, and sorting

func (*Handler) ListUserFavoriteTemplates

func (h *Handler) ListUserFavoriteTemplates(c *gin.Context)

ListUserFavoriteTemplates returns user's favorite templates

func (*Handler) ListViolations

func (h *Handler) ListViolations(c *gin.Context)

ListViolations returns all compliance violations Stub returns empty list - install streamspace-compliance plugin for real data

func (*Handler) LogsWebSocket

func (h *Handler) LogsWebSocket(c *gin.Context)

LogsWebSocket handles WebSocket for streaming pod logs Only admins and operators can view pod logs

func (*Handler) RecordViolation

func (h *Handler) RecordViolation(c *gin.Context)

RecordViolation records a new compliance violation Stub returns not implemented - install streamspace-compliance plugin

func (*Handler) RemoveRepository

func (h *Handler) RemoveRepository(c *gin.Context)

RemoveRepository removes a repository (alias for DeleteRepository)

func (*Handler) RemoveTemplateFavorite

func (h *Handler) RemoveTemplateFavorite(c *gin.Context)

RemoveTemplateFavorite removes a template from user's favorites

func (*Handler) ResolveViolation

func (h *Handler) ResolveViolation(c *gin.Context)

ResolveViolation marks a violation as resolved Stub returns not implemented - install streamspace-compliance plugin

func (*Handler) SessionHeartbeat

func (h *Handler) SessionHeartbeat(c *gin.Context)

SessionHeartbeat handles heartbeat pings from active connections

func (*Handler) SessionsWebSocket

func (h *Handler) SessionsWebSocket(c *gin.Context)

SessionsWebSocket handles WebSocket for real-time session updates Supports query parameters: - ?user_id=<userID> - Subscribe to events for a specific user (defaults to authenticated user) - ?session_id=<sessionID> - Subscribe to events for a specific session

func (*Handler) SyncCatalog

func (h *Handler) SyncCatalog(c *gin.Context)

SyncCatalog triggers sync for all repositories

func (*Handler) SyncRepository

func (h *Handler) SyncRepository(c *gin.Context)

SyncRepository triggers a sync for a repository

func (*Handler) UpdateConfig

func (h *Handler) UpdateConfig(c *gin.Context)

UpdateConfig updates configuration v2.0-beta: Returns error when API runs without K8s access

func (*Handler) UpdateResource

func (h *Handler) UpdateResource(c *gin.Context)

UpdateResource updates a K8s resource v2.0-beta: Returns error when API runs without K8s access

func (*Handler) UpdateSession

func (h *Handler) UpdateSession(c *gin.Context)

UpdateSession updates a session (typically state changes)

func (*Handler) UpdateSessionTags

func (h *Handler) UpdateSessionTags(c *gin.Context)

UpdateSessionTags updates tags for a session

func (*Handler) UpdateTemplate

func (h *Handler) UpdateTemplate(c *gin.Context)

UpdateTemplate updates a template (admin only) v2.0-beta: Updates database only (catalog_templates), not Kubernetes CRDs

func (*Handler) Version

func (h *Handler) Version(c *gin.Context)

Version returns API version

func (*Handler) WakeSession

func (h *Handler) WakeSession(c *gin.Context)

WakeSession handles waking a hibernated session (scales to 1 replica)

func (*Handler) WebhookRepositorySync

func (h *Handler) WebhookRepositorySync(c *gin.Context)

WebhookRepositorySync handles webhooks from Git providers for auto-sync

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL