Implements the full host ↔ control plane connection flow:
- Host CRUD endpoints (POST/GET/DELETE /v1/hosts) with role-based access:
regular hosts admin-only, BYOC hosts for admins and team owners
- One-time registration token flow: admin creates host → gets token (1hr TTL
in Redis + Postgres audit trail) → host agent registers with specs → gets
long-lived JWT (1yr)
- Host agent registration client with automatic spec detection (arch, CPU,
memory, disk) and token persistence to disk
- Periodic heartbeat (30s) via POST /v1/hosts/{id}/heartbeat with X-Host-Token
auth and host ID cross-check
- Token regeneration endpoint (POST /v1/hosts/{id}/token) for retry after
failed registration
- Tag management (add/remove/list) with team-scoped access control
- Host JWT with typ:"host" claim, cross-use prevention in both VerifyJWT and
VerifyHostJWT
- requireHostToken middleware for host agent authentication
- DB-level race protection: RegisterHost uses AND status='pending' with
rows-affected check; Redis GetDel for atomic token consume
- Migration for future mTLS support (cert_fingerprint, mtls_enabled columns)
- Host agent flags: --register (one-time token), --address (required ip:port)
- serviceErrToHTTP extended with "forbidden" → 403 mapping
- OpenAPI spec, .env.example, and README updated
122 lines
4.3 KiB
Go
122 lines
4.3 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
|
|
package db
|
|
|
|
import (
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
type AdminPermission struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"user_id"`
|
|
Permission string `json:"permission"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type Host struct {
|
|
ID string `json:"id"`
|
|
Type string `json:"type"`
|
|
TeamID pgtype.Text `json:"team_id"`
|
|
Provider pgtype.Text `json:"provider"`
|
|
AvailabilityZone pgtype.Text `json:"availability_zone"`
|
|
Arch pgtype.Text `json:"arch"`
|
|
CpuCores pgtype.Int4 `json:"cpu_cores"`
|
|
MemoryMb pgtype.Int4 `json:"memory_mb"`
|
|
DiskGb pgtype.Int4 `json:"disk_gb"`
|
|
Address pgtype.Text `json:"address"`
|
|
Status string `json:"status"`
|
|
LastHeartbeatAt pgtype.Timestamptz `json:"last_heartbeat_at"`
|
|
Metadata []byte `json:"metadata"`
|
|
CreatedBy string `json:"created_by"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
CertFingerprint pgtype.Text `json:"cert_fingerprint"`
|
|
MtlsEnabled bool `json:"mtls_enabled"`
|
|
}
|
|
|
|
type HostTag struct {
|
|
HostID string `json:"host_id"`
|
|
Tag string `json:"tag"`
|
|
}
|
|
|
|
type HostToken struct {
|
|
ID string `json:"id"`
|
|
HostID string `json:"host_id"`
|
|
CreatedBy string `json:"created_by"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
|
UsedAt pgtype.Timestamptz `json:"used_at"`
|
|
}
|
|
|
|
type OauthProvider struct {
|
|
Provider string `json:"provider"`
|
|
ProviderID string `json:"provider_id"`
|
|
UserID string `json:"user_id"`
|
|
Email string `json:"email"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type Sandbox struct {
|
|
ID string `json:"id"`
|
|
HostID string `json:"host_id"`
|
|
Template string `json:"template"`
|
|
Status string `json:"status"`
|
|
Vcpus int32 `json:"vcpus"`
|
|
MemoryMb int32 `json:"memory_mb"`
|
|
TimeoutSec int32 `json:"timeout_sec"`
|
|
GuestIp string `json:"guest_ip"`
|
|
HostIp string `json:"host_ip"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
StartedAt pgtype.Timestamptz `json:"started_at"`
|
|
LastActiveAt pgtype.Timestamptz `json:"last_active_at"`
|
|
LastUpdated pgtype.Timestamptz `json:"last_updated"`
|
|
TeamID string `json:"team_id"`
|
|
}
|
|
|
|
type Team struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
IsByoc bool `json:"is_byoc"`
|
|
}
|
|
|
|
type TeamApiKey struct {
|
|
ID string `json:"id"`
|
|
TeamID string `json:"team_id"`
|
|
Name string `json:"name"`
|
|
KeyHash string `json:"key_hash"`
|
|
KeyPrefix string `json:"key_prefix"`
|
|
CreatedBy string `json:"created_by"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
LastUsed pgtype.Timestamptz `json:"last_used"`
|
|
}
|
|
|
|
type Template struct {
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Vcpus pgtype.Int4 `json:"vcpus"`
|
|
MemoryMb pgtype.Int4 `json:"memory_mb"`
|
|
SizeBytes int64 `json:"size_bytes"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
TeamID string `json:"team_id"`
|
|
}
|
|
|
|
type User struct {
|
|
ID string `json:"id"`
|
|
Email string `json:"email"`
|
|
PasswordHash pgtype.Text `json:"password_hash"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
IsAdmin bool `json:"is_admin"`
|
|
}
|
|
|
|
type UsersTeam struct {
|
|
UserID string `json:"user_id"`
|
|
TeamID string `json:"team_id"`
|
|
IsDefault bool `json:"is_default"`
|
|
Role string `json:"role"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|