fix: add getList with records wrapper + correct options format from browser capture
This commit is contained in:
@@ -21,7 +21,7 @@ func (b *BillingService) Orders(ctx context.Context) ([]provider.Order, error) {
|
|||||||
CreateDate string `json:"create_date"`
|
CreateDate string `json:"create_date"`
|
||||||
}
|
}
|
||||||
var raw []rainyunOrder
|
var raw []rainyunOrder
|
||||||
if err := b.client.getWithQuery(ctx, "/expense/orders/list", map[string]string{"options": "1"}, &raw); err != nil {
|
if err := b.client.getList(ctx, "/expense/orders/list", &raw); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
orders := make([]provider.Order, len(raw))
|
orders := make([]provider.Order, len(raw))
|
||||||
|
|||||||
@@ -44,6 +44,23 @@ func (c *client) getWithQuery(ctx context.Context, path string, query map[string
|
|||||||
return c.do(ctx, "GET", path, nil, result, query)
|
return c.do(ctx, "GET", path, nil, result, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getList sends a GET request to a Rainyun list endpoint and extracts the "records" field.
|
||||||
|
func (c *client) getList(ctx context.Context, path string, result any) error {
|
||||||
|
var wrapper listResponse
|
||||||
|
if err := c.do(ctx, "GET", path, nil, &wrapper, listOptions()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Unmarshal the records array into the result
|
||||||
|
recordsJSON, err := json.Marshal(wrapper.Records)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("marshal records: %w", err)
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(recordsJSON, result); err != nil {
|
||||||
|
return fmt.Errorf("unmarshal records: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *client) post(ctx context.Context, path string, body, result any) error {
|
func (c *client) post(ctx context.Context, path string, body, result any) error {
|
||||||
return c.do(ctx, "POST", path, body, result, nil)
|
return c.do(ctx, "POST", path, body, result, nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type rainyunDomain struct {
|
|||||||
|
|
||||||
func (d *DomainService) List(ctx context.Context) ([]provider.Domain, error) {
|
func (d *DomainService) List(ctx context.Context) ([]provider.Domain, error) {
|
||||||
var raw []rainyunDomain
|
var raw []rainyunDomain
|
||||||
if err := d.client.getWithQuery(ctx, "/product/domain/", map[string]string{"options": "1"}, &raw); err != nil {
|
if err := d.client.getList(ctx, "/product/domain/", &raw); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
domains := make([]provider.Domain, len(raw))
|
domains := make([]provider.Domain, len(raw))
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package rainyun
|
||||||
|
|
||||||
|
// listOptions returns the standard pagination query for Rainyun list endpoints.
|
||||||
|
// Format verified via browser DevTools capture of the Rainyun web console:
|
||||||
|
//
|
||||||
|
// https://api.v2.rainyun.com/product/rcs/?options={url-encoded JSON}
|
||||||
|
//
|
||||||
|
// The decoded JSON is: {"columnFilters":{},"sort":[],"page":1,"perPage":20}
|
||||||
|
func listOptions() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"options": `{"columnFilters":{},"sort":[],"page":1,"perPage":50}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// listResponse is the JSON envelope returned by Rainyun list endpoints.
|
||||||
|
// The API wraps data in {"code":0,"data":{"records":[...],"totalRecords":N}}.
|
||||||
|
// Our client extracts apiResp.Data ({"records":[...]}), then we unmarshal into this.
|
||||||
|
type listResponse struct {
|
||||||
|
Records []any `json:"records"`
|
||||||
|
TotalRecords int `json:"totalRecords"`
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ type rainyunServer struct {
|
|||||||
|
|
||||||
func (s *ServerService) List(ctx context.Context) ([]provider.Server, error) {
|
func (s *ServerService) List(ctx context.Context) ([]provider.Server, error) {
|
||||||
var raw []rainyunServer
|
var raw []rainyunServer
|
||||||
if err := s.client.getWithQuery(ctx, "/product/rcs/", map[string]string{"options": "1"}, &raw); err != nil {
|
if err := s.client.getList(ctx, "/product/rcs/", &raw); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
servers := make([]provider.Server, len(raw))
|
servers := make([]provider.Server, len(raw))
|
||||||
|
|||||||
@@ -15,18 +15,21 @@ func TestServerList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
resp := map[string]any{
|
resp := map[string]any{
|
||||||
"code": 0,
|
"code": 0,
|
||||||
"data": []map[string]any{
|
"data": map[string]any{
|
||||||
{
|
"records": []map[string]any{
|
||||||
"id": 12001,
|
{
|
||||||
"name": "web-server",
|
"id": 12001,
|
||||||
"status": "running",
|
"name": "web-server",
|
||||||
"ip": "1.2.3.4",
|
"status": "running",
|
||||||
"vcpu": 2,
|
"ip": "1.2.3.4",
|
||||||
"memory": 4096,
|
"vcpu": 2,
|
||||||
"disk": 50,
|
"memory": 4096,
|
||||||
"os": "Ubuntu 22.04",
|
"disk": 50,
|
||||||
"expire_date": "2026-08-15",
|
"os": "Ubuntu 22.04",
|
||||||
|
"expire_date": "2026-08-15",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
"totalRecords": 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
json.NewEncoder(w).Encode(resp)
|
json.NewEncoder(w).Encode(resp)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func (s *StorageService) List(ctx context.Context) ([]provider.StorageInstance,
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
if err := s.client.getWithQuery(ctx, "/product/ros/instance", map[string]string{"options": "1"}, &raw); err != nil {
|
if err := s.client.getList(ctx, "/product/ros/instance", &raw); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
instances := make([]provider.StorageInstance, len(raw))
|
instances := make([]provider.StorageInstance, len(raw))
|
||||||
|
|||||||
Reference in New Issue
Block a user