File size: 3,375 Bytes
6a7089a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | package apiclient
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"time"
)
func DoGet(client *http.Client, base, token, path string, params url.Values) map[string]any {
u := base + path
if len(params) > 0 {
u += "?" + params.Encode()
}
req, _ := http.NewRequest("GET", u, nil)
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
resp, err := client.Do(req)
if err != nil {
fatal("Request failed: %v", err)
}
defer func() { _ = resp.Body.Close() }()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 {
fmt.Fprintf(os.Stderr, "Error %d: %s\n", resp.StatusCode, string(body))
os.Exit(1)
}
// Pretty-print JSON if possible
var buf bytes.Buffer
if json.Indent(&buf, body, "", " ") == nil {
fmt.Println(buf.String())
} else {
fmt.Println(string(body))
}
// Parse and return result
var result map[string]any
if err := json.Unmarshal(body, &result); err != nil {
log.Printf("warning: error unmarshaling response: %v", err)
}
return result
}
func DoGetRaw(client *http.Client, base, token, path string, params url.Values) []byte {
u := base + path
if len(params) > 0 {
u += "?" + params.Encode()
}
req, _ := http.NewRequest("GET", u, nil)
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
resp, err := client.Do(req)
if err != nil {
fatal("Request failed: %v", err)
return nil
}
defer func() { _ = resp.Body.Close() }()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 {
fmt.Fprintf(os.Stderr, "Error %d: %s\n", resp.StatusCode, string(body))
os.Exit(1)
}
return body
}
func DoPost(client *http.Client, base, token, path string, body map[string]any) map[string]any {
data, _ := json.Marshal(body)
req, _ := http.NewRequest("POST", base+path, bytes.NewReader(data))
req.Header.Set("Content-Type", "application/json")
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
resp, err := client.Do(req)
if err != nil {
fatal("Request failed: %v", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 {
fmt.Fprintf(os.Stderr, "Error %d: %s\n", resp.StatusCode, string(respBody))
os.Exit(1)
}
var buf bytes.Buffer
if json.Indent(&buf, respBody, "", " ") == nil {
fmt.Println(buf.String())
} else {
fmt.Println(string(respBody))
}
// Parse and return result for suggestions
var result map[string]any
if err := json.Unmarshal(respBody, &result); err != nil {
log.Printf("warning: error unmarshaling response: %v", err)
}
return result
}
// ResolveInstanceBase fetches the named instance from the orchestrator and returns
// a base URL pointing directly at that instance's API port.
func ResolveInstanceBase(orchBase, token, instanceID, bind string) string {
c := &http.Client{Timeout: 10 * time.Second}
body := DoGetRaw(c, orchBase, token, fmt.Sprintf("/instances/%s", instanceID), nil)
var inst struct {
Port string `json:"port"`
}
if err := json.Unmarshal(body, &inst); err != nil {
fatal("failed to parse instance %q: %v", instanceID, err)
}
if inst.Port == "" {
fatal("instance %q has no port assigned (is it still starting?)", instanceID)
}
return fmt.Sprintf("http://%s:%s", bind, inst.Port)
}
func fatal(format string, args ...any) {
fmt.Fprintf(os.Stderr, format+"\n", args...)
os.Exit(1)
}
|