package client
import (
"context"
"fmt"
"net/http"
"net/url"
)
const (
createSandbox = "/api/v1/sandboxes"
listSandbox = "/api/v1/sandboxes?limit=5000"
deleteSandbox = "/api/v1/sandboxes/"
suspendSandbox = "/api/sandbox/suspend"
resumeSandbox = "/api/sandbox/resume"
checkpointSandbox = "/api/sandbox/checkpoint"
)
type SandboxCreateRequest struct {
TemplateName string `json:"template_name,omitempty"`
TemplateID string `json:"template_id,omitempty"`
VMMName string `json:"vmm_name,omitempty"`
SandboxID string `json:"sandbox_id"`
VCPUNum int64 `json:"vcpu_num,omitempty"`
VCPUMax int64 `json:"vcpu_max,omitempty"`
RAMMB int64 `json:"ram_mb,omitempty"`
}
type SandboxCreateResponse struct {
SandboxID string `json:"sandboxID"`
Domain string `json:"domain"`
}
type SandboxRecord struct {
TemplateName string `json:"templateName"`
TemplateID string `json:"templateID"`
SandboxID string `json:"sandboxID"`
StartedAt string `json:"startedAt"`
CPUCount int64 `json:"cpuCount"`
MemoryMB int64 `json:"memoryMB"`
}
type SandboxLifecycleRequest struct {
SandboxID string `json:"sandbox_id"`
}
type SandboxCheckpointRequest struct {
SandboxID string `json:"sandbox_id"`
TemplateName string `json:"template_name"`
Labels map[string]string `json:"labels,omitempty"`
}
type SandboxCheckpointResponse struct {
Status string `json:"status"`
TemplateID string `json:"template_id"`
}
func (c *Client) CreateSandbox(ctx context.Context, req SandboxCreateRequest) (SandboxCreateResponse, error) {
var resp SandboxCreateResponse
if err := c.postJSON(ctx, createSandbox, req, &resp); err != nil {
return SandboxCreateResponse{}, err
}
return resp, nil
}
func (c *Client) ListSandboxes(ctx context.Context) ([]SandboxRecord, error) {
path := listSandbox
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+path, nil)
if err != nil {
return nil, fmt.Errorf("create request %s: %w", path, err)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("GET %s: %w", path, err)
}
defer resp.Body.Close()
var records []SandboxRecord
if err := decodeResponse(resp, path, &records); err != nil {
return nil, err
}
return records, nil
}
func (c *Client) DeleteSandbox(ctx context.Context, sandboxID string) error {
path := deleteSandbox + url.PathEscape(sandboxID)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.baseURL+path, nil)
if err != nil {
return fmt.Errorf("create request %s: %w", path, err)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("DELETE %s: %w", path, err)
}
defer resp.Body.Close()
return decodeResponse(resp, path, nil)
}
func (c *Client) SuspendSandbox(ctx context.Context, req SandboxLifecycleRequest) error {
return c.postJSON(ctx, suspendSandbox, req, nil)
}
func (c *Client) ResumeSandbox(ctx context.Context, req SandboxLifecycleRequest) error {
return c.postJSON(ctx, resumeSandbox, req, nil)
}
func (c *Client) CheckpointSandbox(ctx context.Context, req SandboxCheckpointRequest) (SandboxCheckpointResponse, error) {
var resp SandboxCheckpointResponse
if err := c.postJSON(ctx, checkpointSandbox, req, &resp); err != nil {
return SandboxCheckpointResponse{}, err
}
return resp, nil
}