package api import ( "bytes" "encoding/json" "fmt" "io" "net/http" ) // Server mirrors the backend Server type. type Server struct { Name string `json:"name"` Type string `json:"type"` Image string `json:"image"` Replicas int32 `json:"replicas"` Ready int32 `json:"ready"` Status string `json:"status"` NodePort int32 `json:"nodePort,omitempty"` Port int32 `json:"port"` EnvVars map[string]string `json:"envVars"` CreatedAt string `json:"createdAt"` } type CreateServerRequest struct { Name string `json:"name"` Type string `json:"type"` Image string `json:"image"` Port int32 `json:"port"` NodePort int32 `json:"nodePort,omitempty"` EnvVars map[string]string `json:"envVars"` } type UpdateServerRequest struct { Image string `json:"image,omitempty"` EnvVars map[string]string `json:"envVars,omitempty"` } // Client is an HTTP client for the games-console backend. type Client struct { BaseURL string http *http.Client } func NewClient(baseURL string) *Client { return &Client{BaseURL: baseURL, http: &http.Client{}} } func (c *Client) ListServers() ([]Server, error) { var servers []Server return servers, c.get("/api/servers", &servers) } func (c *Client) GetServer(name string) (*Server, error) { var s Server return &s, c.get("/api/servers/"+name, &s) } func (c *Client) CreateServer(req CreateServerRequest) (*Server, error) { var s Server return &s, c.post("/api/servers", req, &s) } func (c *Client) UpdateServer(name string, req UpdateServerRequest) (*Server, error) { var s Server return &s, c.put("/api/servers/"+name, req, &s) } func (c *Client) DeleteServer(name string) error { return c.delete("/api/servers/" + name) } func (c *Client) GetLogs(name string, lines int) (string, error) { var resp struct { Logs string `json:"logs"` } return resp.Logs, c.get(fmt.Sprintf("/api/servers/%s/logs?lines=%d", name, lines), &resp) } func (c *Client) GetHealth(name string) (map[string]interface{}, error) { var resp map[string]interface{} return resp, c.get("/api/servers/"+name+"/health", &resp) } func (c *Client) Start(name string) error { return c.postAction("/api/servers/" + name + "/start") } func (c *Client) Stop(name string) error { return c.postAction("/api/servers/" + name + "/stop") } func (c *Client) Restart(name string) error { return c.postAction("/api/servers/" + name + "/restart") } // --- HTTP helpers --- func (c *Client) get(path string, out interface{}) error { resp, err := c.http.Get(c.BaseURL + path) if err != nil { return err } return decode(resp, out) } func (c *Client) post(path string, body interface{}, out interface{}) error { b, _ := json.Marshal(body) resp, err := c.http.Post(c.BaseURL+path, "application/json", bytes.NewReader(b)) if err != nil { return err } return decode(resp, out) } func (c *Client) postAction(path string) error { resp, err := c.http.Post(c.BaseURL+path, "application/json", nil) if err != nil { return err } resp.Body.Close() if resp.StatusCode >= 400 { return fmt.Errorf("server returned %d", resp.StatusCode) } return nil } func (c *Client) put(path string, body interface{}, out interface{}) error { b, _ := json.Marshal(body) req, _ := http.NewRequest(http.MethodPut, c.BaseURL+path, bytes.NewReader(b)) req.Header.Set("Content-Type", "application/json") resp, err := c.http.Do(req) if err != nil { return err } return decode(resp, out) } func (c *Client) delete(path string) error { req, _ := http.NewRequest(http.MethodDelete, c.BaseURL+path, nil) resp, err := c.http.Do(req) if err != nil { return err } resp.Body.Close() if resp.StatusCode >= 400 { return fmt.Errorf("server returned %d", resp.StatusCode) } return nil } func decode(resp *http.Response, out interface{}) error { defer resp.Body.Close() if resp.StatusCode >= 400 { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("server error %d: %s", resp.StatusCode, string(body)) } return json.NewDecoder(resp.Body).Decode(out) }