- Move Server/Domain/DNSRecord/Bucket/StorageInstance/CDNInstance/Order/Error structs to internal/model/ - Provider interfaces now reference model.* types - Rainyun provider implementations import model package for data types - CLI commands updated to use model.DNSRecord directly Separates pure data structures from service contract interfaces, following hexagonal architecture: models (entities) live independently from ports (provider interfaces) and adapters (rainyun/* implementations).
105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
package rainyun
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.yoresee.cc/nightstar/ry/internal/model"
|
|
)
|
|
|
|
// ServerService implements provider.ServerService for 雨云.
|
|
type ServerService struct {
|
|
client *client
|
|
}
|
|
|
|
// rainyunServer mirrors the Rainyun RCS API JSON fields (PascalCase).
|
|
type rainyunServer struct {
|
|
ID int `json:"ID"`
|
|
Name string `json:"name"`
|
|
Status string `json:"status"`
|
|
IP string `json:"ip"`
|
|
VCPU int `json:"vcpu"`
|
|
Memory int `json:"memory"`
|
|
Disk int `json:"disk"`
|
|
OS string `json:"os"`
|
|
Region string `json:"zone_name"`
|
|
ExpireDate int64 `json:"ExpDate"` // Unix timestamp
|
|
}
|
|
|
|
func (s *ServerService) List(ctx context.Context) ([]model.Server, error) {
|
|
var raw []rainyunServer
|
|
if err := s.client.getList(ctx, "/product/rcs/", &raw); err != nil {
|
|
return nil, err
|
|
}
|
|
servers := make([]model.Server, len(raw))
|
|
for i, r := range raw {
|
|
servers[i] = toServer(r)
|
|
}
|
|
return servers, nil
|
|
}
|
|
|
|
func (s *ServerService) Get(ctx context.Context, id string) (*model.Server, error) {
|
|
var raw rainyunServer
|
|
path := fmt.Sprintf("/product/rcs/%s/", id)
|
|
if err := s.client.get(ctx, path, &raw); err != nil {
|
|
return nil, err
|
|
}
|
|
sv := toServer(raw)
|
|
return &sv, nil
|
|
}
|
|
|
|
func (s *ServerService) Start(ctx context.Context, id string) error {
|
|
return s.client.post(ctx, fmt.Sprintf("/product/rcs/%s/start", id), nil, nil)
|
|
}
|
|
|
|
func (s *ServerService) Stop(ctx context.Context, id string) error {
|
|
return s.client.post(ctx, fmt.Sprintf("/product/rcs/%s/stop", id), nil, nil)
|
|
}
|
|
|
|
func (s *ServerService) Reboot(ctx context.Context, id string) error {
|
|
return s.client.post(ctx, fmt.Sprintf("/product/rcs/%s/reboot", id), nil, nil)
|
|
}
|
|
|
|
func (s *ServerService) Reinstall(ctx context.Context, id, osTemplate string) error {
|
|
body := map[string]string{"os": osTemplate}
|
|
return s.client.post(ctx, fmt.Sprintf("/product/rcs/%s/changeos", id), body, nil)
|
|
}
|
|
|
|
func (s *ServerService) ResetPassword(ctx context.Context, id string) error {
|
|
return s.client.post(ctx, fmt.Sprintf("/product/rcs/%s/reset-password", id), nil, nil)
|
|
}
|
|
|
|
func (s *ServerService) GetVNC(ctx context.Context, id string) (string, error) {
|
|
var resp struct {
|
|
VNCURL string `json:"vnc_url"`
|
|
}
|
|
if err := s.client.get(ctx, fmt.Sprintf("/product/rcs/%s/vnc", id), &resp); err != nil {
|
|
return "", err
|
|
}
|
|
return resp.VNCURL, nil
|
|
}
|
|
|
|
func (s *ServerService) Upgrade(ctx context.Context, id, plan string) error {
|
|
body := map[string]string{"plan": plan}
|
|
return s.client.post(ctx, fmt.Sprintf("/product/rcs/%s/upgrade", id), body, nil)
|
|
}
|
|
|
|
// toServer maps a rainyunServer to the model.Server model.
|
|
func toServer(r rainyunServer) model.Server {
|
|
expire := time.Unix(r.ExpireDate, 0)
|
|
return model.Server{
|
|
ID: fmt.Sprintf("%d", r.ID),
|
|
Name: r.Name,
|
|
Status: r.Status,
|
|
IP: r.IP,
|
|
CPU: r.VCPU,
|
|
Memory: r.Memory,
|
|
Disk: r.Disk,
|
|
OS: r.OS,
|
|
Region: r.Region,
|
|
ExpireAt: expire,
|
|
Raw: r,
|
|
}
|
|
}
|