| package ionet |
|
|
| import ( |
| "encoding/json" |
| "fmt" |
| "strings" |
|
|
| "github.com/samber/lo" |
| ) |
|
|
| |
| func (c *Client) GetAvailableReplicas(hardwareID int, gpuCount int) (*AvailableReplicasResponse, error) { |
| if hardwareID <= 0 { |
| return nil, fmt.Errorf("hardware_id must be greater than 0") |
| } |
| if gpuCount < 1 { |
| return nil, fmt.Errorf("gpu_count must be at least 1") |
| } |
|
|
| params := map[string]interface{}{ |
| "hardware_id": hardwareID, |
| "hardware_qty": gpuCount, |
| } |
|
|
| endpoint := "/available-replicas" + buildQueryParams(params) |
|
|
| resp, err := c.makeRequest("GET", endpoint, nil) |
| if err != nil { |
| return nil, fmt.Errorf("failed to get available replicas: %w", err) |
| } |
|
|
| type availableReplicaPayload struct { |
| ID int `json:"id"` |
| ISO2 string `json:"iso2"` |
| Name string `json:"name"` |
| AvailableReplicas int `json:"available_replicas"` |
| } |
| var payload []availableReplicaPayload |
|
|
| if err := decodeData(resp.Body, &payload); err != nil { |
| return nil, fmt.Errorf("failed to parse available replicas response: %w", err) |
| } |
|
|
| replicas := lo.Map(payload, func(item availableReplicaPayload, _ int) AvailableReplica { |
| return AvailableReplica{ |
| LocationID: item.ID, |
| LocationName: item.Name, |
| HardwareID: hardwareID, |
| HardwareName: "", |
| AvailableCount: item.AvailableReplicas, |
| MaxGPUs: gpuCount, |
| } |
| }) |
|
|
| return &AvailableReplicasResponse{Replicas: replicas}, nil |
| } |
|
|
| |
| func (c *Client) GetMaxGPUsPerContainer() (*MaxGPUResponse, error) { |
| resp, err := c.makeRequest("GET", "/hardware/max-gpus-per-container", nil) |
| if err != nil { |
| return nil, fmt.Errorf("failed to get max GPUs per container: %w", err) |
| } |
|
|
| var maxGPUResp MaxGPUResponse |
| if err := decodeData(resp.Body, &maxGPUResp); err != nil { |
| return nil, fmt.Errorf("failed to parse max GPU response: %w", err) |
| } |
|
|
| return &maxGPUResp, nil |
| } |
|
|
| |
| func (c *Client) ListHardwareTypes() ([]HardwareType, int, error) { |
| maxGPUResp, err := c.GetMaxGPUsPerContainer() |
| if err != nil { |
| return nil, 0, fmt.Errorf("failed to list hardware types: %w", err) |
| } |
|
|
| mapped := lo.Map(maxGPUResp.Hardware, func(hw MaxGPUInfo, _ int) HardwareType { |
| name := strings.TrimSpace(hw.HardwareName) |
| if name == "" { |
| name = fmt.Sprintf("Hardware %d", hw.HardwareID) |
| } |
|
|
| return HardwareType{ |
| ID: hw.HardwareID, |
| Name: name, |
| GPUType: "", |
| GPUMemory: 0, |
| MaxGPUs: hw.MaxGPUsPerContainer, |
| CPU: "", |
| Memory: 0, |
| Storage: 0, |
| HourlyRate: 0, |
| Available: hw.Available > 0, |
| BrandName: strings.TrimSpace(hw.BrandName), |
| AvailableCount: hw.Available, |
| } |
| }) |
|
|
| totalAvailable := maxGPUResp.Total |
| if totalAvailable == 0 { |
| totalAvailable = lo.SumBy(maxGPUResp.Hardware, func(hw MaxGPUInfo) int { |
| return hw.Available |
| }) |
| } |
|
|
| return mapped, totalAvailable, nil |
| } |
|
|
| |
| func (c *Client) ListLocations() (*LocationsResponse, error) { |
| resp, err := c.makeRequest("GET", "/locations", nil) |
| if err != nil { |
| return nil, fmt.Errorf("failed to list locations: %w", err) |
| } |
|
|
| var locations LocationsResponse |
| if err := decodeData(resp.Body, &locations); err != nil { |
| return nil, fmt.Errorf("failed to parse locations response: %w", err) |
| } |
|
|
| locations.Locations = lo.Map(locations.Locations, func(location Location, _ int) Location { |
| location.ISO2 = strings.ToUpper(strings.TrimSpace(location.ISO2)) |
| return location |
| }) |
|
|
| if locations.Total == 0 { |
| locations.Total = lo.SumBy(locations.Locations, func(location Location) int { |
| return location.Available |
| }) |
| } |
|
|
| return &locations, nil |
| } |
|
|
| |
| func (c *Client) GetHardwareType(hardwareID int) (*HardwareType, error) { |
| if hardwareID <= 0 { |
| return nil, fmt.Errorf("hardware ID must be greater than 0") |
| } |
|
|
| endpoint := fmt.Sprintf("/hardware/types/%d", hardwareID) |
|
|
| resp, err := c.makeRequest("GET", endpoint, nil) |
| if err != nil { |
| return nil, fmt.Errorf("failed to get hardware type: %w", err) |
| } |
|
|
| |
| var hardwareType HardwareType |
| if err := json.Unmarshal(resp.Body, &hardwareType); err != nil { |
| return nil, fmt.Errorf("failed to parse hardware type: %w", err) |
| } |
|
|
| return &hardwareType, nil |
| } |
|
|
| |
| func (c *Client) GetLocation(locationID int) (*Location, error) { |
| if locationID <= 0 { |
| return nil, fmt.Errorf("location ID must be greater than 0") |
| } |
|
|
| endpoint := fmt.Sprintf("/locations/%d", locationID) |
|
|
| resp, err := c.makeRequest("GET", endpoint, nil) |
| if err != nil { |
| return nil, fmt.Errorf("failed to get location: %w", err) |
| } |
|
|
| |
| var location Location |
| if err := json.Unmarshal(resp.Body, &location); err != nil { |
| return nil, fmt.Errorf("failed to parse location: %w", err) |
| } |
|
|
| return &location, nil |
| } |
|
|
| |
| func (c *Client) GetLocationAvailability(locationID int) (*LocationAvailability, error) { |
| if locationID <= 0 { |
| return nil, fmt.Errorf("location ID must be greater than 0") |
| } |
|
|
| endpoint := fmt.Sprintf("/locations/%d/availability", locationID) |
|
|
| resp, err := c.makeRequest("GET", endpoint, nil) |
| if err != nil { |
| return nil, fmt.Errorf("failed to get location availability: %w", err) |
| } |
|
|
| |
| var availability LocationAvailability |
| if err := json.Unmarshal(resp.Body, &availability); err != nil { |
| return nil, fmt.Errorf("failed to parse location availability: %w", err) |
| } |
|
|
| return &availability, nil |
| } |
|
|