Skip to content

Commit 352336c

Browse files
committed
feat(volcengine): add RDS support
1 parent f966279 commit 352336c

7 files changed

Lines changed: 624 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ CloudToolKit is intended to help defenders verify:
5858
| AWS | EC2, S3, IAM | iam-user-check, bucket-check |
5959
| Azure | Virtual Machines, Blob Storage | - |
6060
| GCP | Compute Engine, Cloud DNS, IAM | - |
61-
| Volcengine | ECS, IAM, TOS | iam-user-check, bucket-check, instance-cmd-check |
61+
| Volcengine | ECS, IAM, TOS, RDS | iam-user-check, bucket-check, instance-cmd-check |
6262
| JDCloud | VM, IAM, OSS | - |
6363

6464
## Quick Start

pkg/providers/volcengine/api/endpoint.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ var globalServices = map[string]struct{}{
1212
"iam": {},
1313
}
1414

15+
var regionalServiceHostAliases = map[string]string{
16+
"rds_mysql": "rds-mysql",
17+
"rds_postgresql": "rds-postgresql",
18+
"rds_mssql": "rds-mssql",
19+
}
20+
1521
// ResolveEndpoint returns the HTTPS base URL for a Volcengine OpenAPI service.
1622
func ResolveEndpoint(service, region, siteStack string) string {
1723
service = strings.ToLower(strings.TrimSpace(service))
@@ -30,11 +36,18 @@ func ResolveEndpoint(service, region, siteStack string) string {
3036
case isGlobalService(service):
3137
host = service + "." + stack + ".com"
3238
case region != "":
33-
host = service + "." + region + "." + stack + ".com"
39+
host = endpointHostPrefix(service) + "." + region + "." + stack + ".com"
3440
}
3541
return "https://" + host
3642
}
3743

44+
func endpointHostPrefix(service string) string {
45+
if alias, ok := regionalServiceHostAliases[service]; ok {
46+
return alias
47+
}
48+
return service
49+
}
50+
3851
func isGlobalService(service string) bool {
3952
_, ok := globalServices[strings.ToLower(strings.TrimSpace(service))]
4053
return ok

pkg/providers/volcengine/api/endpoint_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ func TestResolveEndpoint(t *testing.T) {
1313
{name: "global iam", service: "iam", region: "cn-beijing", want: "https://iam.volcengineapi.com"},
1414
{name: "global billing", service: "billing", region: "", want: "https://billing.volcengineapi.com"},
1515
{name: "regional ecs", service: "ecs", region: "cn-shanghai", want: "https://ecs.cn-shanghai.volcengineapi.com"},
16+
{name: "regional rds mysql alias", service: "rds_mysql", region: "cn-beijing", want: "https://rds-mysql.cn-beijing.volcengineapi.com"},
17+
{name: "regional rds postgresql alias", service: "rds_postgresql", region: "cn-guangzhou", want: "https://rds-postgresql.cn-guangzhou.volcengineapi.com"},
18+
{name: "regional rds mssql alias", service: "rds_mssql", region: "cn-shanghai", want: "https://rds-mssql.cn-shanghai.volcengineapi.com"},
1619
{name: "fallback open", service: "ecs", region: "", want: "https://open.volcengineapi.com"},
1720
{name: "custom stack", service: "ecs", region: "cn-beijing", siteStack: "volcengine-api", want: "https://ecs.cn-beijing.volcengine-api.com"},
1821
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package api
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"net/http"
7+
)
8+
9+
const (
10+
rdsAPIVersion = "2022-01-01"
11+
ServiceRDSMySQL = "rds_mysql"
12+
ServiceRDSPostgreSQL = "rds_postgresql"
13+
ServiceRDSMSSQL = "rds_mssql"
14+
)
15+
16+
type DescribeRDSRegionsResponse struct {
17+
ResponseMetadata ResponseMetadata `json:"ResponseMetadata"`
18+
Result struct {
19+
Regions []RDSRegion `json:"Regions"`
20+
} `json:"Result"`
21+
}
22+
23+
type RDSRegion struct {
24+
RegionID string `json:"RegionId"`
25+
RegionName string `json:"RegionName"`
26+
}
27+
28+
type DescribeRDSMySQLInstancesResponse struct {
29+
ResponseMetadata ResponseMetadata `json:"ResponseMetadata"`
30+
Result struct {
31+
Instances []RDSMySQLInstance `json:"Instances"`
32+
Total int32 `json:"Total"`
33+
} `json:"Result"`
34+
}
35+
36+
type RDSMySQLInstance struct {
37+
AddressObject []RDSAddressObject `json:"AddressObject"`
38+
DBEngineVersion string `json:"DBEngineVersion"`
39+
InstanceID string `json:"InstanceId"`
40+
InstanceName string `json:"InstanceName"`
41+
InstanceStatus string `json:"InstanceStatus"`
42+
RegionID string `json:"RegionId"`
43+
}
44+
45+
type DescribeRDSPostgreSQLInstancesResponse struct {
46+
ResponseMetadata ResponseMetadata `json:"ResponseMetadata"`
47+
Result struct {
48+
Instances []RDSPostgreSQLInstance `json:"Instances"`
49+
Total int32 `json:"Total"`
50+
} `json:"Result"`
51+
}
52+
53+
type RDSPostgreSQLInstance struct {
54+
AddressObject []RDSAddressObject `json:"AddressObject"`
55+
DBEngineVersion string `json:"DBEngineVersion"`
56+
InstanceID string `json:"InstanceId"`
57+
InstanceName string `json:"InstanceName"`
58+
InstanceStatus string `json:"InstanceStatus"`
59+
RegionID string `json:"RegionId"`
60+
}
61+
62+
type RDSAddressObject struct {
63+
Domain string `json:"Domain"`
64+
IPAddress string `json:"IPAddress"`
65+
NetworkType string `json:"NetworkType"`
66+
Port string `json:"Port"`
67+
}
68+
69+
type DescribeRDSSQLServerInstancesResponse struct {
70+
ResponseMetadata ResponseMetadata `json:"ResponseMetadata"`
71+
Result struct {
72+
InstancesInfo []RDSSQLServerInstance `json:"InstancesInfo"`
73+
Total int32 `json:"Total"`
74+
} `json:"Result"`
75+
}
76+
77+
type RDSSQLServerInstance struct {
78+
DBEngineVersion string `json:"DBEngineVersion"`
79+
InstanceID string `json:"InstanceId"`
80+
InstanceName string `json:"InstanceName"`
81+
InstanceStatus string `json:"InstanceStatus"`
82+
NodeDetailInfo []RDSSQLServerNode `json:"NodeDetailInfo"`
83+
Port string `json:"Port"`
84+
RegionID string `json:"RegionId"`
85+
}
86+
87+
type RDSSQLServerNode struct {
88+
NodeIP string `json:"NodeIP"`
89+
NodeType string `json:"NodeType"`
90+
}
91+
92+
type describeRDSInstancesInput struct {
93+
PageNumber int32 `json:"PageNumber"`
94+
PageSize int32 `json:"PageSize"`
95+
}
96+
97+
func (c *Client) DescribeRDSRegions(ctx context.Context, service, region string) (DescribeRDSRegionsResponse, error) {
98+
var out DescribeRDSRegionsResponse
99+
err := c.doRDSAction(ctx, service, "DescribeRegions", region, struct{}{}, &out)
100+
return out, err
101+
}
102+
103+
func (c *Client) DescribeRDSMySQLInstances(ctx context.Context, region string, pageNumber, pageSize int32) (DescribeRDSMySQLInstancesResponse, error) {
104+
var out DescribeRDSMySQLInstancesResponse
105+
err := c.doRDSAction(ctx, ServiceRDSMySQL, "DescribeDBInstances", region, describeRDSInstancesInput{
106+
PageNumber: pageNumber,
107+
PageSize: pageSize,
108+
}, &out)
109+
return out, err
110+
}
111+
112+
func (c *Client) DescribeRDSPostgreSQLInstances(ctx context.Context, region string, pageNumber, pageSize int32) (DescribeRDSPostgreSQLInstancesResponse, error) {
113+
var out DescribeRDSPostgreSQLInstancesResponse
114+
err := c.doRDSAction(ctx, ServiceRDSPostgreSQL, "DescribeDBInstances", region, describeRDSInstancesInput{
115+
PageNumber: pageNumber,
116+
PageSize: pageSize,
117+
}, &out)
118+
return out, err
119+
}
120+
121+
func (c *Client) DescribeRDSSQLServerInstances(ctx context.Context, region string, pageNumber, pageSize int32) (DescribeRDSSQLServerInstancesResponse, error) {
122+
var out DescribeRDSSQLServerInstancesResponse
123+
err := c.doRDSAction(ctx, ServiceRDSMSSQL, "DescribeDBInstances", region, describeRDSInstancesInput{
124+
PageNumber: pageNumber,
125+
PageSize: pageSize,
126+
}, &out)
127+
return out, err
128+
}
129+
130+
func (c *Client) doRDSAction(ctx context.Context, service, action, region string, payload any, out any) error {
131+
body, err := json.Marshal(payload)
132+
if err != nil {
133+
return err
134+
}
135+
return c.DoOpenAPI(ctx, Request{
136+
Service: service,
137+
Version: rdsAPIVersion,
138+
Action: action,
139+
Method: http.MethodPost,
140+
Region: region,
141+
Path: "/",
142+
Body: body,
143+
Idempotent: true,
144+
}, out)
145+
}

0 commit comments

Comments
 (0)