feat(rcs): migrate all RCS APIs from rainyun-go-sdk

- 35 endpoints across 14 files, response structs split for reuse
- Reuse RcsRecord/Node/Plan/OsInfo/UsageData across list/detail/create
- Fix source bugs: {id} path placeholders, missing / in firewall pos path,
  missing body in ChargeRcsTrafic, resp vs &resp
- Add HTTPMethod_PATCH, common.BasicOperationResponse, VncConnectionInfo
This commit is contained in:
2026-08-05 22:35:28 +08:00
parent 0cd1a28f84
commit b8490ef422
20 changed files with 779 additions and 8 deletions
+5
View File
@@ -6,3 +6,8 @@ type StandQueryParameters struct {
Page int `json:"page"`
PerPage int `json:"perPage"`
}
type BasicOperationResponse struct {
Code int `json:"code"`
Data string `json:"data"`
}
+6 -6
View File
@@ -6,12 +6,12 @@ import (
)
type queryParamsSample struct {
IsRGpu *bool `json:"is_rgpu"`
Limit int `json:"limit"`
Name string `json:"name"`
Options StandQueryParameters `json:"options"`
Tags []string `json:"tags"`
Skip string `json:"-"`
IsRGpu *bool `json:"is_rgpu"`
Limit int `json:"limit"`
Name string `json:"name"`
Options StandQueryParameters `json:"options"`
Tags []string `json:"tags"`
Skip string `json:"-"`
NoTag string
}
+19
View File
@@ -0,0 +1,19 @@
package common
import "strconv"
type VncConnectionInfo struct {
Code int `json:"code"`
Data VncConnectionData `json:"data"`
}
type VncConnectionData struct {
RequestURL string `json:"RequestURL"` // 空
RedirectURL string `json:"RedirectURL"` // 空
PVEAuth string `json:"PVEAuth"` // 空
VNCProxyURL string `json:"VNCProxyURL"` // PVE代理地址(连接地址),里面会有一个unicode码(\u0026)(&),转码后就是可以直接在浏览器上使用的VNC连接地址
}
func GetVncConnectURL(v *VncConnectionInfo) (string, error) {
return strconv.Unquote(v.Data.VNCProxyURL)
}
+58
View File
@@ -0,0 +1,58 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type CreateRcsBackupRequest struct {
Label string `json:"label"` // 备份名称
}
type RcsSetBackupOptionsRequest struct {
AutoBackupHour int `json:"auto_backup_hour"` // 自动备份时间的小时
AutoBackupMinute int `json:"auto_backup_minute"` // 自动备份时间的分钟
KeepLast int `json:"keep_last"` // 保留份数(1/3/7)
}
func (s *RcsService) CreateRcsBackup(id int, label string) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/backup", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, CreateRcsBackupRequest{Label: label}, &resp)
return &resp, err
}
func (s *RcsService) DeleteRcsBackup(id, bid int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/backup/%d", id, bid)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_DELETE, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) CancelRcsBackup(id, bid int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/backup/%d/cancel", id, bid)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) RestoreRcsBackup(id, bid int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/backup/%d/restore", id, bid)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) EnableRcsAutoBackup(id int, req *RcsSetBackupOptionsRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/backup/setting", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_PATCH, path, nil, req, &resp)
return &resp, err
}
+26
View File
@@ -0,0 +1,26 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type ReinstallRcsRequest struct {
AppVars []struct {
AppID int `json:"app_id"`
Retry bool `json:"retry"` // 重发之前的任务,此项存在时,无需传入参数
Vars any `json:"vars"`
} `json:"app_vars"` // 当空数组时,进行单次任务下发
OsID int `json:"os_id"` // 系统ID
ResetOsd bool `json:"reset_osd"` // 重置系统盘容量
}
func (s *RcsService) ReinstallRcs(id int, req *ReinstallRcsRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/changeos", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
+36
View File
@@ -0,0 +1,36 @@
package rcs
import (
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type CreateRcsRequest struct {
AddDiskSize int `json:"add_disk_size"` // 额外硬盘容量GB
PlanID int `json:"plan_id"` // 套餐ID
Duration int `json:"duration"` // 创建时长(月)
OsID int `json:"os_id"` // 系统ID
WithEipNum int `json:"with_eip_num"` // 创建IP数量
WithEipFlags string `json:"with_eip_flags"` // 是否开启高防,us_ddosip -> 美国高防,nb_ddosip -> 宁波高防
WithEipType string `json:"with_eip_type"` // ipv4(默认)/ipv6
WithCouponID int `json:"with_coupon_id"` // 优惠券ID
Try bool `json:"try"` // 是否为试用
NodeUUID string `json:"node_uuid"` // 指定节点(管理员可用,用户不可用)
AppVars []struct {
AppID int `json:"app_id"`
Vars any `json:"vars,omitempty"`
} `json:"app_vars"` // 预装应用
Zone string `json:"zone"` // 内网可用区
}
type CreateRcsResponse struct {
Code int `json:"code"`
Data RcsRecord `json:"data"`
}
func (s *RcsService) CreateRcs(req *CreateRcsRequest) (*CreateRcsResponse, error) {
path := "/product/rcs"
var resp CreateRcsResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
+36
View File
@@ -0,0 +1,36 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type RcsManagesElasticCloudDisksRequest struct {
Actions []struct {
Type string `json:"type"` // 操作类型: expand: 扩容, create: 创建
Action any `json:"action"` // 操作参数, RcsManagesElasticCloudDisksExpand或RcsManagesElasticCloudDisksCreate
} `json:"actions"`
}
type RcsManagesElasticCloudDisksExpand struct {
EdiskID int `json:"edisk_id"` // 弹性云盘ID
SizeInGb int `json:"size_in_gb"` // 操作容量
Backup bool `json:"backup"` // 支持备份
}
type RcsManagesElasticCloudDisksCreate struct {
SizeInGb int `json:"size_in_gb"` // 操作容量
DiskType string `json:"disk_type"` // 磁盘类型(ssd/hdd)
Backup bool `json:"backup"` // 支持备份
Tag string `json:"tag"` // 标签
}
func (s *RcsService) RcsManagesElasticCloudDisks(id int, req *RcsManagesElasticCloudDisksRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/edisk", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
+61
View File
@@ -0,0 +1,61 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type SetRcsEipDescriptionRequest struct {
IP string `json:"ip"`
Description string `json:"description"`
}
type CreateAndBindIpToRcsRequest struct {
WithFlags string `json:"with_flags"` // IP特征(可选): 应该是高防: us_ddosip -> 美国高防,nb_ddosip -> 宁波高防
WithIPNum int `json:"with_ip_num"` // IP数量
WithIPType string `json:"with_ip_type"` // ipv4/ipv6
}
type ChangeRcsIPRequest struct {
DisableOldIPReason string `json:"disable_old_ip_reason"` // 可选
IP string `json:"ip"` // IP地址
ToIP string `json:"to_ip"` // 可选
}
type DisCardRcsIPRequest struct {
IP string `json:"ip"`
}
func (s *RcsService) SetRcsEipDescription(id int, ip, desc string) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/eip/description", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, SetRcsEipDescriptionRequest{IP: ip, Description: desc}, &resp)
return &resp, err
}
func (s *RcsService) CreateAndBindElasticIpToRcs(id int, req *CreateAndBindIpToRcsRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/eip", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
func (s *RcsService) ChangeRcsIP(id int, req *ChangeRcsIPRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/eip/change", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
func (s *RcsService) DisCardRcsIP(id int, req DisCardRcsIPRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/eip/discard", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
+86
View File
@@ -0,0 +1,86 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type GetRcsFirewallRulesRequest struct {
Options common.StandQueryParameters `json:"options"`
}
type GetRcsFirewallRulesResponse struct {
Code int `json:"code"`
Data RcsFirewallRuleList `json:"data"`
}
type RcsFirewallRuleList struct {
TotalRecords int `json:"TotalRecords"`
Records []RcsFirewallRule `json:"Records"`
}
type RcsFirewallRule struct {
ID int `json:"ID"`
VID int `json:"v_id"`
IsEnable bool `json:"is_enable"`
Pos int `json:"pos"`
SourceAddress string `json:"source_address"`
DestPort string `json:"dest_port"`
SourcePort string `json:"source_port"`
Protocol string `json:"protocol"`
Action string `json:"action"`
Description string `json:"description"`
}
type SetRcsFirewallRuleRequest struct {
Action string `json:"action"` // 动作,accept/drop,接受或者丢弃
Description string `json:"description"` // 备注(可选)
DestPort string `json:"dest_port"` // 代表本机的目的端口,可以用-来链接,空白代表所有端口(可选)
ID int `json:"id"` // 规则ID(可选)
IsEnable bool `json:"is_enable"` // 是否启用该规则(可选)
Protocol string `json:"protocol"` // 协议,udp/tcp/icmp,空白代表所有(可选)
SourceAddress string `json:"source_address"` // 代表来源的地址,可以用-链接范围,或者用逗号来分割多个地址,可以使用网络,CIDR格式,空则代表所有地址(可选)
SourcePort string `json:"source_port"` // 一般不填(防反射)(可选)
}
type MobileRcsFirewallRulePriorityRequest struct {
NewPos int `json:"newPos"`
}
func (s *RcsService) GetRcsFirewallRules(id int, req *GetRcsFirewallRulesRequest) (*GetRcsFirewallRulesResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/firewall/rule", id)
var resp GetRcsFirewallRulesResponse
querys, err := common.MarshalQueryParams(req)
if err != nil {
return nil, err
}
err = s.client.Do(constant.HTTPMethod_GET, path, querys, nil, &resp)
return &resp, err
}
func (s *RcsService) SetRcsFirewallRule(id int, req *SetRcsFirewallRuleRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/firewall/rule", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
func (s *RcsService) DeleteRcsFirewallRule(id, ruleID int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/firewall/rule/%d", id, ruleID)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_DELETE, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) MobileRcsFirewallRulePriority(id, ruleID int, req MobileRcsFirewallRulePriorityRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/firewall/rule/%d/pos", id, ruleID)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_PUT, path, nil, req, &resp)
return &resp, err
}
+124
View File
@@ -0,0 +1,124 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type GetRcsDetailResponse struct {
Code int `json:"code"`
Data RcsDetail `json:"data"`
}
type RcsDetail struct {
Data RcsRecord `json:"Data"`
UpgradeablePlans []UpgradeablePlan `json:"UpgradeablePlans"`
RBSList []RBSItem `json:"RBSList"`
NatList []any `json:"NatList"`
EDiskList []EDiskItem `json:"EDiskList"`
EIPList []EIPItem `json:"EIPList"`
RenewPointPrice RenewPointPrice `json:"RenewPointPrice"`
FastInstallAppTask []any `json:"FastInstallAppTask"`
VNets []any `json:"VNets"`
}
type UpgradeablePlan struct {
ID int `json:"id"`
Region string `json:"region"`
Subtype string `json:"subtype"`
PlanName string `json:"plan_name"`
Machine string `json:"machine"`
ChargeType string `json:"charge_type"`
Chinese string `json:"chinese"`
IsFree bool `json:"is_free"`
PointRenewPrice any `json:"point_renew_price"`
IsSelling bool `json:"is_selling"`
Price int `json:"price"`
TrafficBaseGb int `json:"traffic_base_gb"`
TrafficPrice any `json:"traffic_price"`
CPU int `json:"cpu"`
Memory int `json:"memory"`
NetIn int `json:"net_in"`
NetOut int `json:"net_out"`
IPPrices any `json:"ip_prices"`
IPSelling any `json:"ip_selling"`
AutoRestock int `json:"auto_restock"`
AvailableStock int `json:"available_stock"`
GpuMemorySize int `json:"gpu_memory_size"`
DgpuDevType string `json:"dgpu_dev_type"`
WebbarConfig any `json:"webbar_config"`
NoBackup bool `json:"no_backup"`
DiskPrice DiskPrice `json:"disk_price"`
}
type RBSItem struct {
ID int `json:"ID"`
UID int `json:"UID"`
ProductID int `json:"ProductID"`
NodeUUID string `json:"NodeUUID"`
Node Node `json:"Node"`
Label string `json:"Label"`
FileName string `json:"FileName"`
PackSize int64 `json:"PackSize"`
CreateTime int `json:"CreateTime"`
FinishTime int `json:"FinishTime"`
Retry int `json:"Retry"`
AdditionalInfo RBSAdditionalInfo `json:"AdditionalInfo"`
Status string `json:"Status"`
}
type RBSAdditionalInfo struct {
Osid int `json:"OSID"`
OSName string `json:"OSName"`
OSBaseDiskSize int `json:"OSBaseDiskSize"`
OSDataDiskSize int `json:"OSDataDiskSize"`
Slots map[string]RBSSlot `json:"Slots"`
}
type RBSSlot struct {
DiskType string `json:"DiskType"`
Backup bool `json:"Backup"`
Size int `json:"Size"`
}
type EDiskItem struct {
ID int `json:"ID"`
Slot int `json:"Slot"`
UID int `json:"UID"`
DiskType string `json:"DiskType"`
Tag string `json:"Tag"`
OSName string `json:"OSName"`
Vid int `json:"VID"`
Size int `json:"Size"`
Backup bool `json:"Backup"`
}
type EIPItem struct {
ID int `json:"ID"`
IPRegion string `json:"IpRegion"`
Region string `json:"Region"`
Type string `json:"Type"`
IP string `json:"IP"`
Gateway string `json:"Gateway"`
Block string `json:"Block"`
UID int `json:"UID"`
Vid int `json:"VID"`
CreateDate int `json:"CreateDate"`
Flags string `json:"Flags"`
VlanID int `json:"VlanID"`
Description string `json:"Description"`
}
type RenewPointPrice struct {
Num7 int `json:"7"`
Num31 int `json:"31"`
}
func (s *RcsService) GetRcsDetail(id int) (*GetRcsDetailResponse, error) {
path := fmt.Sprintf("/product/rcs/%d", id)
var resp GetRcsDetailResponse
err := s.client.Do(constant.HTTPMethod_GET, path, nil, nil, &resp)
return &resp, err
}
+2 -2
View File
@@ -47,9 +47,9 @@ type UsageData struct {
UsedMem int `json:"UsedMem"`
Disks DiskUsageData `json:"Disks"`
DiskRead int `json:"DiskRead"`
DiskWrite int `json:"DiskWrite"`
DiskWrite float64 `json:"DiskWrite"`
NetOut float64 `json:"NetOut"`
NetIn int `json:"NetIn"`
NetIn float64 `json:"NetIn"`
SmartHealth any `json:"SmartHealth"`
SmartTemp int `json:"SmartTemp"`
UpdateTime int `json:"UpdateTime"`
+64
View File
@@ -0,0 +1,64 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type ResetRcsPasswordRequest struct {
Password string `json:"password"` // 新密码,留空则自动生成
}
type SetRcsTagRequest struct {
TagName string `json:"tag_name"`
}
func (s *RcsService) FreeRcs(id int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/free", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) RebootRcs(id int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/reboot", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) ResetRcsPassword(id int, newPass string) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/reset-password", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, ResetRcsPasswordRequest{Password: newPass}, &resp)
return &resp, err
}
func (s *RcsService) StartRcs(id int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/start", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) StopRcs(id int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/stop", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, nil, &resp)
return &resp, err
}
func (s *RcsService) SetRcsTag(id int, tag string) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/tag", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, SetRcsTagRequest{TagName: tag}, &resp)
return &resp, err
}
+36
View File
@@ -0,0 +1,36 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type GetRcsMonitorDataRequest struct {
StartDate int `json:"start_date"` // 开始时间(时间戳)
EndDate int `json:"end_date"` // 结束时间(时间戳)
}
type GetRcsMonitorDataResponse struct {
Code int `json:"code"`
Data RcsMonitorData `json:"data"`
}
// RcsMonitorData 监控数据, Columns 与 Values 一一对应
type RcsMonitorData struct {
Columns []string `json:"Columns"`
Values [][]float64 `json:"Values"`
}
func (s *RcsService) GetRcsMonitorData(id int, req *GetRcsMonitorDataRequest) (*GetRcsMonitorDataResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/monitor", id)
var resp GetRcsMonitorDataResponse
querys, err := common.MarshalQueryParams(req)
if err != nil {
return nil, err
}
err = s.client.Do(constant.HTTPMethod_GET, path, querys, nil, &resp)
return &resp, err
}
+39
View File
@@ -0,0 +1,39 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type AddRcsNatPortMappingRequest struct {
PortIn int `json:"port_in"` // >= 1 <= 65535
PortOut int `json:"port_out"` // >= 10000 <= 60000
PortType string `json:"port_type"` // tcp/udp/tcp_udp
Tag string `json:"tag"` // 可选
}
type DeleteRcsNatPortMappingRequest struct {
NatID int `json:"nat_id"`
}
func (s *RcsService) AddRcsNatPortMapping(id int, req *AddRcsNatPortMappingRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/nat", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
func (s *RcsService) DeleteRcsNatPortMapping(id int, req *DeleteRcsNatPortMappingRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/nat", id)
var resp common.BasicOperationResponse
querys, err := common.MarshalQueryParams(req)
if err != nil {
return nil, err
}
err = s.client.Do(constant.HTTPMethod_DELETE, path, querys, nil, &resp)
return &resp, err
}
+82
View File
@@ -0,0 +1,82 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type GetRcsRenewPriceRequest struct {
ProductID int `json:"product_id"`
Duration int `json:"duration"`
WithCouponID int `json:"with_coupon_id"`
}
type GetRcsRenewPriceResponse struct {
Code int `json:"code"`
Data RcsRenewPrice `json:"data"`
}
type RcsRenewPrice struct {
Detail RcsRenewPriceDetail `json:"detail"`
Price float64 `json:"price"`
}
type RcsRenewPriceDetail struct {
Price float64 `json:"price"`
AgentPrice float64 `json:"agent_price"`
StockPrice float64 `json:"stock_price"`
DefaultPrice int `json:"default_price"`
CouponValue int `json:"coupon_value"`
SaleReward int `json:"sale_reward"`
AgentReward int `json:"agent_reward"`
AgentID int `json:"agent_id"`
IgnoreAgent bool `json:"ignore_agent"`
PerScene RcsRenewPerScene `json:"per_scene"`
}
type RcsRenewPerScene struct {
Eip int `json:"eip"`
Renew float64 `json:"renew"` // 配置价格
RenewEip float64 `json:"renew_eip"` // IP价格
}
type RenewRcsRequest struct {
Duration int `json:"duration"` // 续费时长(月)
WithCouponID int `json:"with_coupon_id"` // 优惠券ID
}
type EnableRcsAutoRenewRequest struct {
AutoRenewOption bool `json:"auto_renew_option"`
}
func (s *RcsService) GetRcsRenewPrice(req *GetRcsRenewPriceRequest) (*GetRcsRenewPriceResponse, error) {
path := "/product/rcs/price"
var resp GetRcsRenewPriceResponse
querys, err := common.MarshalQueryParams(req)
if err != nil {
return nil, err
}
querys["scene"] = "renew"
querys["is_old"] = "true"
err = s.client.Do(constant.HTTPMethod_GET, path, querys, nil, &resp)
return &resp, err
}
func (s *RcsService) RenewRcs(id int, req RenewRcsRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/renew", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
func (s *RcsService) EnableRcsAutoRenew(id int, req EnableRcsAutoRenewRequest) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/renew/option", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, req, &resp)
return &resp, err
}
+33
View File
@@ -0,0 +1,33 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type ChargeRcsTraficRequest struct {
TrafficInGb int `json:"traffic_in_gb"` // 充多少G
}
type LimitRcsTrafficRequest struct {
DayTrafficInGb int `json:"day_traffic_in_gb"` // 日流量阈值(G)
TrafficLimit int `json:"traffic_limit"` // 限制带宽(M)
}
func (s *RcsService) ChargeRcsTrafic(id, count int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/traffic/charge", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, ChargeRcsTraficRequest{TrafficInGb: count}, &resp)
return &resp, err
}
func (s *RcsService) LimitRcsTrafic(id, threshold, limit int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/traffic/limit", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, LimitRcsTrafficRequest{DayTrafficInGb: threshold, TrafficLimit: limit}, &resp)
return &resp, err
}
+21
View File
@@ -0,0 +1,21 @@
package rcs
import (
"fmt"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
type UpgradeRcsRequest struct {
DestPlan int `json:"dest_plan"` // 升级到的套餐ID
WithCouponID int `json:"with_coupon_id"` // 优惠券ID,默认为0
}
func (s *RcsService) UpgradeRcs(id, plan, coupon int) (*common.BasicOperationResponse, error) {
path := fmt.Sprintf("/product/rcs/%d/upgrade", id)
var resp common.BasicOperationResponse
err := s.client.Do(constant.HTTPMethod_POST, path, nil, UpgradeRcsRequest{DestPlan: plan, WithCouponID: coupon}, &resp)
return &resp, err
}
+36
View File
@@ -0,0 +1,36 @@
package rcs
import (
"fmt"
"net/url"
"github.com/XingfenD/rainyun_api_go_sdk/apis/common"
"github.com/XingfenD/rainyun_api_go_sdk/constant"
)
// GetRcsVnc 连接VNC
//
// consoleType: 控制台类型,可选值: novnc,xtermjs
func (s *RcsService) GetRcsVnc(id int, consoleType string) (*common.VncConnectionInfo, error) {
path := fmt.Sprintf("/product/rcs/%d/vnc", id)
var resp common.VncConnectionInfo
querys := map[string]string{"console_type": consoleType}
err := s.client.Do(constant.HTTPMethod_GET, path, querys, nil, &resp)
return &resp, err
}
// GetRcsPveAddress 获取RCS对应的PVE地址
func (s *RcsService) GetRcsPveAddress(id int) (string, error) {
v, err := s.GetRcsVnc(id, "novnc")
if err != nil {
return "", err
}
parsedURL, err := url.Parse(v.Data.RequestURL)
if err != nil {
return "", err
}
return parsedURL.Hostname(), nil
}
+1
View File
@@ -7,4 +7,5 @@ const (
HTTPMethod_POST HTTPMethod = "POST"
HTTPMethod_DELETE HTTPMethod = "DELETE"
HTTPMethod_PUT HTTPMethod = "PUT"
HTTPMethod_PATCH HTTPMethod = "PATCH"
)
+8
View File
@@ -6,6 +6,14 @@ All notable changes to this template should be documented in this file.
The format loosely follows Keep a Changelog and can be adapted to the team's habits.
本文档参考了 Keep a Changelog 的思路,也可以根据团队习惯调整。
## [0.1.0] - 2026-08-05
### Added / 新增
- 从 `rainyun-go-sdk` 迁移 RCS 全部 35 个接口(列表/详情/创建/备份/防火墙/监控/NAT/续费/升降级等),响应结构体嵌套已拆分复用(`RcsRecord`、`Node`、`Plan`、`OsInfo`、`UsageData` 等)。
- 新增 `apis/common` 基础类型:`BasicOperationResponse`、`VncConnectionInfo`。
- `constant` 新增 `HTTPMethod_PATCH`。
## [0.0.0] - 2026-08-02
### Notes / 说明