package commands import ( "bytes" "encoding/json" "fmt" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/client" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/config" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/output" ) // monitorOverviewResponse matches the backend monitor overview schema. type monitorOverviewResponse struct { TotalServers int `json:"total_servers"` OnlineServers int `json:"online_servers"` } // monitorServerResponse matches the backend monitor server schema. type monitorServerResponse struct { ID int `json:"id"` Identifier string `json:"identifier"` DisplayName *string `json:"display_name"` Status string `json:"status"` LastSeen *string `json:"last_seen"` CreatedAt string `json:"created_at"` } // monitorAPIKeyResponse matches the backend monitor API key schema. type monitorAPIKeyResponse struct { Identifier string `json:"identifier"` APIKey string `json:"api_key"` } // RunMonitorOverview implements `hf monitor overview`. func RunMonitorOverview(tokenFlag string) { token := ResolveToken(tokenFlag) cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) data, err := c.Get("/monitor/overview") if err != nil { output.Errorf("failed to get monitor overview: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } var o monitorOverviewResponse if err := json.Unmarshal(data, &o); err != nil { output.Errorf("cannot parse monitor overview: %v", err) } output.PrintKeyValue( "total-servers", fmt.Sprintf("%d", o.TotalServers), "online-servers", fmt.Sprintf("%d", o.OnlineServers), ) } // RunMonitorServerList implements `hf monitor server list`. func RunMonitorServerList(tokenFlag string) { token := ResolveToken(tokenFlag) cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) data, err := c.Get("/monitor/servers") if err != nil { output.Errorf("failed to list monitor servers: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } var servers []monitorServerResponse if err := json.Unmarshal(data, &servers); err != nil { output.Errorf("cannot parse server list: %v", err) } headers := []string{"IDENTIFIER", "NAME", "STATUS", "LAST SEEN"} var rows [][]string for _, s := range servers { name := "" if s.DisplayName != nil { name = *s.DisplayName } lastSeen := "" if s.LastSeen != nil { lastSeen = *s.LastSeen } rows = append(rows, []string{s.Identifier, name, s.Status, lastSeen}) } output.PrintTable(headers, rows) } // RunMonitorServerGet implements `hf monitor server get `. func RunMonitorServerGet(identifier, tokenFlag string) { token := ResolveToken(tokenFlag) cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) data, err := c.Get("/monitor/servers/" + identifier) if err != nil { output.Errorf("failed to get server: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } var s monitorServerResponse if err := json.Unmarshal(data, &s); err != nil { output.Errorf("cannot parse server: %v", err) } name := "" if s.DisplayName != nil { name = *s.DisplayName } lastSeen := "" if s.LastSeen != nil { lastSeen = *s.LastSeen } output.PrintKeyValue( "identifier", s.Identifier, "name", name, "status", s.Status, "last-seen", lastSeen, "created", s.CreatedAt, ) } // RunMonitorServerCreate implements `hf monitor server create --identifier `. func RunMonitorServerCreate(args []string, tokenFlag string) { token := ResolveToken(tokenFlag) identifier, name := "", "" for i := 0; i < len(args); i++ { switch args[i] { case "--identifier": if i+1 >= len(args) { output.Error("--identifier requires a value") } i++ identifier = args[i] case "--name": if i+1 >= len(args) { output.Error("--name requires a value") } i++ name = args[i] default: output.Errorf("unknown flag: %s", args[i]) } } if identifier == "" { output.Error("usage: hf monitor server create --identifier ") } payload := map[string]interface{}{ "identifier": identifier, } if name != "" { payload["display_name"] = name } body, err := json.Marshal(payload) if err != nil { output.Errorf("cannot marshal payload: %v", err) } cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) data, err := c.Post("/monitor/servers", bytes.NewReader(body)) if err != nil { output.Errorf("failed to create server: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } fmt.Printf("monitor server created: %s\n", identifier) _ = data } // RunMonitorServerDelete implements `hf monitor server delete `. func RunMonitorServerDelete(identifier, tokenFlag string) { token := ResolveToken(tokenFlag) cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) _, err = c.Delete("/monitor/servers/" + identifier) if err != nil { output.Errorf("failed to delete server: %v", err) } fmt.Printf("monitor server deleted: %s\n", identifier) } // RunMonitorAPIKeyGenerate implements `hf monitor api-key generate `. func RunMonitorAPIKeyGenerate(identifier, tokenFlag string) { token := ResolveToken(tokenFlag) cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) data, err := c.Post("/monitor/servers/"+identifier+"/api-key", nil) if err != nil { output.Errorf("failed to generate API key: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } var k monitorAPIKeyResponse if err := json.Unmarshal(data, &k); err != nil { fmt.Printf("API key generated for: %s\n", identifier) return } output.PrintKeyValue( "identifier", k.Identifier, "api-key", k.APIKey, ) } // RunMonitorAPIKeyRevoke implements `hf monitor api-key revoke `. func RunMonitorAPIKeyRevoke(identifier, tokenFlag string) { token := ResolveToken(tokenFlag) cfg, err := config.Load() if err != nil { output.Errorf("config error: %v", err) } c := client.New(cfg.BaseURL, token) _, err = c.Delete("/monitor/servers/" + identifier + "/api-key") if err != nil { output.Errorf("failed to revoke API key: %v", err) } fmt.Printf("API key revoked for: %s\n", identifier) }