2024-05-08 08:01:48 +00:00
|
|
|
package vultr
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ListInstanceResponse is the response structure of Vultr ListInstance API.
|
|
|
|
type ListInstanceResponse struct {
|
|
|
|
Instances []Instance `json:"instances"`
|
2024-07-05 15:30:29 +00:00
|
|
|
Meta Meta `json:"meta"`
|
2024-05-08 08:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Instance represents Vultr Instance (VPS).
|
2024-07-05 15:30:29 +00:00
|
|
|
//
|
2024-05-08 08:01:48 +00:00
|
|
|
// See: https://github.com/vultr/govultr/blob/5125e02e715ae6eb3ce854f0e7116c7ce545a710/instance.go#L81
|
|
|
|
type Instance struct {
|
|
|
|
ID string `json:"id"`
|
2024-07-05 15:30:29 +00:00
|
|
|
OS string `json:"os"`
|
2024-05-08 08:01:48 +00:00
|
|
|
RAM int `json:"ram"`
|
|
|
|
Disk int `json:"disk"`
|
|
|
|
MainIP string `json:"main_ip"`
|
|
|
|
VCPUCount int `json:"vcpu_count"`
|
|
|
|
Region string `json:"region"`
|
|
|
|
ServerStatus string `json:"server_status"`
|
|
|
|
AllowedBandwidth int `json:"allowed_bandwidth"`
|
|
|
|
V6MainIP string `json:"v6_main_ip"`
|
|
|
|
Hostname string `json:"hostname"`
|
|
|
|
Label string `json:"label"`
|
|
|
|
InternalIP string `json:"internal_ip"`
|
2024-07-05 15:30:29 +00:00
|
|
|
OSID int `json:"os_id"`
|
2024-05-08 08:01:48 +00:00
|
|
|
Features []string `json:"features"`
|
|
|
|
Plan string `json:"plan"`
|
|
|
|
Tags []string `json:"tags"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Meta represents the available pagination information
|
2024-07-05 15:30:29 +00:00
|
|
|
//
|
|
|
|
// See https://www.vultr.com/api/#section/Introduction/Meta-and-Pagination
|
2024-05-08 08:01:48 +00:00
|
|
|
type Meta struct {
|
2024-07-05 15:30:29 +00:00
|
|
|
Links Links `json:"links"`
|
2024-05-08 08:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Links represent the next/previous cursor in your pagination calls
|
|
|
|
type Links struct {
|
|
|
|
Next string `json:"next"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// getInstances retrieve instance from Vultr HTTP API.
|
|
|
|
func getInstances(cfg *apiConfig) ([]Instance, error) {
|
|
|
|
var instances []Instance
|
|
|
|
|
|
|
|
// prepare GET params
|
2024-07-05 15:30:29 +00:00
|
|
|
queryParams := cfg.listQueryParams
|
2024-05-08 08:01:48 +00:00
|
|
|
|
|
|
|
// send request to vultr API
|
|
|
|
for {
|
|
|
|
// See: https://www.vultr.com/api/#tag/instances/operation/list-instances
|
2024-07-05 15:30:29 +00:00
|
|
|
path := "/v2/instances?" + queryParams + "&per_page=100"
|
|
|
|
data, err := cfg.c.GetAPIResponse(path)
|
2024-05-08 08:01:48 +00:00
|
|
|
if err != nil {
|
2024-07-05 15:30:29 +00:00
|
|
|
return nil, fmt.Errorf("cannot get Vultr response from %q: %w", path, err)
|
2024-05-08 08:01:48 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 15:30:29 +00:00
|
|
|
var resp ListInstanceResponse
|
|
|
|
if err := json.Unmarshal(data, &resp); err != nil {
|
|
|
|
return nil, fmt.Errorf("cannot unmarshal ListInstanceResponse obtained from %q: %w; response=%q", path, err, data)
|
2024-05-08 08:01:48 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 15:30:29 +00:00
|
|
|
instances = append(instances, resp.Instances...)
|
2024-05-08 08:01:48 +00:00
|
|
|
|
2024-07-05 15:30:29 +00:00
|
|
|
if resp.Meta.Links.Next == "" {
|
2024-05-08 08:01:48 +00:00
|
|
|
break
|
|
|
|
}
|
2024-07-05 15:30:29 +00:00
|
|
|
|
|
|
|
// if `next page` is available, set the cursor param and request again.
|
|
|
|
queryParams = cfg.listQueryParams + "&cursor=" + url.QueryEscape(resp.Meta.Links.Next)
|
2024-05-08 08:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return instances, nil
|
|
|
|
}
|