Skip to content

Commit 80c3282

Browse files
askyrieSongZhen0704
authored andcommitted
feat: cloud tencent support rds and redis
1 parent 3856fc2 commit 80c3282

6 files changed

Lines changed: 465 additions & 17 deletions

File tree

server/controller/cloud/tencent/az.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package tencent
1818

1919
import (
20+
"strconv"
21+
2022
"github.com/deepflowio/deepflow/server/controller/cloud/model"
2123
"github.com/deepflowio/deepflow/server/controller/common"
2224
"github.com/deepflowio/deepflow/server/libs/logger"
@@ -26,8 +28,13 @@ func (t *Tencent) getAZs(region string) ([]model.AZ, error) {
2628
log.Debug("get azs starting", logger.NewORGPrefix(t.orgID))
2729
var azs []model.AZ
2830

31+
// 由于 cvm.DescribeZones 不再返回已售罄的 az,导致部分资源无法关联
32+
// 尝试使用 cdb.DescribeZones 接口获取所有 az
2933
attrs := []string{"Zone", "ZoneName"}
30-
resp, err := t.getResponse("cvm", "2017-03-12", "DescribeZones", region, "ZoneSet", false, map[string]interface{}{})
34+
params := map[string]interface{}{
35+
"Product": "cdb",
36+
}
37+
resp, err := t.getResponse("region", "2022-06-27", "DescribeZones", region, "ZoneSet", false, params)
3138
if err != nil {
3239
log.Errorf("az request tencent api error: (%s)", err.Error(), logger.NewORGPrefix(t.orgID))
3340
return []model.AZ{}, err
@@ -36,19 +43,27 @@ func (t *Tencent) getAZs(region string) ([]model.AZ, error) {
3643
if !t.checkRequiredAttributes(aData, attrs) {
3744
continue
3845
}
46+
state := aData.Get("ZoneState").MustString()
47+
if state != "AVAILABLE" {
48+
log.Infof("invalid az state (%s)", state, logger.NewORGPrefix(t.orgID))
49+
continue
50+
}
3951
zone := aData.Get("Zone").MustString()
4052
name := aData.Get("ZoneName").MustString()
4153
lcuuid := common.GetUUIDByOrgID(t.orgID, t.uuidGenerate+"_"+zone)
42-
if _, ok := t.azLcuuidMap[lcuuid]; !ok {
43-
log.Debugf("az (%s) has no resource", name, logger.NewORGPrefix(t.orgID))
44-
continue
45-
}
4654
azs = append(azs, model.AZ{
4755
Lcuuid: lcuuid,
4856
Label: zone,
4957
Name: name,
5058
RegionLcuuid: t.regionLcuuid,
5159
})
60+
t.zoneToLcuuid[zone] = lcuuid
61+
zoneID, err := strconv.Atoi(aData.Get("ZoneId").MustString())
62+
if err != nil {
63+
log.Errorf("convert zone id to int failed: (%s)", err.Error(), logger.NewORGPrefix(t.orgID))
64+
continue
65+
}
66+
t.azIDToLcuuid[zoneID] = lcuuid
5267
}
5368
log.Debug("get azs complete", logger.NewORGPrefix(t.orgID))
5469
return azs, nil

server/controller/cloud/tencent/network.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,15 @@ func (t *Tencent) getNetworks(region string) ([]model.Network, []model.Subnet, [
4040
}
4141
vpcID := nData.Get("VpcId").MustString()
4242
subnetID := nData.Get("SubnetId").MustString()
43-
azID := nData.Get("Zone").MustString()
43+
zone := nData.Get("Zone").MustString()
4444
networkLcuuid := common.GetUUIDByOrgID(t.orgID, subnetID)
4545
vpcLcuuid := common.GetUUIDByOrgID(t.orgID, vpcID)
46-
azLcuuid := common.GetUUIDByOrgID(t.orgID, t.uuidGenerate+"_"+azID)
4746
networkName := nData.Get("SubnetName").MustString()
47+
azLcuuid, ok := t.zoneToLcuuid[zone]
48+
if !ok {
49+
log.Infof("subnet (%s) az (id:%s) not in available zones", networkName, zone, logger.NewORGPrefix(t.orgID))
50+
continue
51+
}
4852
networks = append(networks, model.Network{
4953
Lcuuid: networkLcuuid,
5054
Name: networkName,
@@ -61,7 +65,7 @@ func (t *Tencent) getNetworks(region string) ([]model.Network, []model.Subnet, [
6165
cidr4 := nData.Get("CidrBlock").MustString()
6266
if cidr4 != "" {
6367
subnets = append(subnets, model.Subnet{
64-
Lcuuid: common.GetUUIDByOrgID(t.orgID, networkLcuuid+cidr4),
68+
Lcuuid: common.GetUUIDByOrgID(t.orgID, networkLcuuid+"_v4"),
6569
Name: networkName + "_v4",
6670
CIDR: cidr4,
6771
NetworkLcuuid: networkLcuuid,
@@ -71,7 +75,7 @@ func (t *Tencent) getNetworks(region string) ([]model.Network, []model.Subnet, [
7175
cidr6 := nData.Get("Ipv6CidrBlock").MustString()
7276
if cidr6 != "" {
7377
subnets = append(subnets, model.Subnet{
74-
Lcuuid: common.GetUUIDByOrgID(t.orgID, networkLcuuid+cidr6),
78+
Lcuuid: common.GetUUIDByOrgID(t.orgID, networkLcuuid+"_v6"),
7579
Name: networkName + "_v6",
7680
CIDR: cidr6,
7781
NetworkLcuuid: networkLcuuid,
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
/*
2+
* Copyright (c) 2024 Yunshan Networks
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package tencent
18+
19+
import (
20+
"strings"
21+
22+
"github.com/deepflowio/deepflow/server/controller/cloud/model"
23+
"github.com/deepflowio/deepflow/server/controller/common"
24+
"github.com/deepflowio/deepflow/server/libs/logger"
25+
)
26+
27+
func (t *Tencent) getRDSInstances(region string) ([]model.RDSInstance, []model.VInterface, []model.IP, error) {
28+
log.Debug("get rds instances starting", logger.NewORGPrefix(t.orgID))
29+
var rdss []model.RDSInstance
30+
var vinterfaces []model.VInterface
31+
var ips []model.IP
32+
33+
// rds MySQL
34+
mInstances, mVInterfaces, mIPs, err := t.getRDSMySQL(region)
35+
if err != nil {
36+
return []model.RDSInstance{}, []model.VInterface{}, []model.IP{}, err
37+
}
38+
rdss = append(rdss, mInstances...)
39+
vinterfaces = append(vinterfaces, mVInterfaces...)
40+
ips = append(ips, mIPs...)
41+
42+
// rds SQLServer
43+
sInstances, sVInterfaces, sIPs, err := t.getRDSSQLServer(region)
44+
if err != nil {
45+
return []model.RDSInstance{}, []model.VInterface{}, []model.IP{}, err
46+
}
47+
rdss = append(rdss, sInstances...)
48+
vinterfaces = append(vinterfaces, sVInterfaces...)
49+
ips = append(ips, sIPs...)
50+
51+
// rds postgreSQL
52+
pInstances, pVInterfaces, pIPs, err := t.getRDSPostgreSQL(region)
53+
if err != nil {
54+
return []model.RDSInstance{}, []model.VInterface{}, []model.IP{}, err
55+
}
56+
rdss = append(rdss, pInstances...)
57+
vinterfaces = append(vinterfaces, pVInterfaces...)
58+
ips = append(ips, pIPs...)
59+
60+
log.Debug("get rds instances complete", logger.NewORGPrefix(t.orgID))
61+
return rdss, vinterfaces, ips, nil
62+
}
63+
64+
func (t *Tencent) getRDSMySQL(region string) ([]model.RDSInstance, []model.VInterface, []model.IP, error) {
65+
var rdss []model.RDSInstance
66+
var vinterfaces []model.VInterface
67+
var ips []model.IP
68+
69+
resp, err := t.getResponse("cdb", "2017-03-20", "DescribeDBInstances", region, "Items", true, map[string]interface{}{})
70+
if err != nil {
71+
log.Errorf("rds mysql request tencent api error: (%s)", err.Error(), logger.NewORGPrefix(t.orgID))
72+
return []model.RDSInstance{}, []model.VInterface{}, []model.IP{}, err
73+
}
74+
for _, rData := range resp {
75+
rdsID := rData.Get("InstanceId").MustString()
76+
rdsLcuuid := common.GetUUIDByOrgID(t.orgID, rdsID)
77+
rdsName := rData.Get("InstanceName").MustString()
78+
zoneID := rData.Get("ZoneId").MustInt()
79+
azLcuuid, ok := t.azIDToLcuuid[zoneID]
80+
if !ok {
81+
log.Infof("rds mysql (%s) az (id:%d) not in available zones", rdsName, zoneID, logger.NewORGPrefix(t.orgID))
82+
continue
83+
}
84+
vpcLcuuid := common.GetUUIDByOrgID(t.orgID, rData.Get("UniqVpcId").MustString())
85+
var rdsModel = common.RDS_MODEL_PRIMARY
86+
if rData.Get("InstanceType").MustInt() != 1 {
87+
rdsModel = common.RDS_MODEL_SHARE
88+
}
89+
var rdsState = common.RDS_STATE_RUNNING
90+
if rData.Get("Status").MustInt() != 1 {
91+
rdsState = common.RDS_STATE_RESTORING
92+
}
93+
rdss = append(rdss, model.RDSInstance{
94+
Lcuuid: rdsLcuuid,
95+
Name: rdsName,
96+
Label: rdsID,
97+
State: rdsState,
98+
Type: common.RDS_TYPE_MYSQL,
99+
Series: common.RDS_SERIES_HA,
100+
Version: rData.Get("EngineVersion").MustString(),
101+
Model: rdsModel,
102+
VPCLcuuid: vpcLcuuid,
103+
AZLcuuid: azLcuuid,
104+
RegionLcuuid: t.regionLcuuid,
105+
})
106+
t.azLcuuidMap[azLcuuid] = 0
107+
108+
address := rData.Get("Vip").MustString()
109+
vinterfaceLcuuid := common.GetUUIDByOrgID(t.orgID, rdsID+address)
110+
networkLcuuid := common.NETWORK_ISP_LCUUID
111+
subnetLcuuid := common.SUBNET_ISP_LCUUID
112+
subnetID := rData.Get("UniqSubnetId").MustString()
113+
if subnetID != "" {
114+
networkLcuuid = common.GetUUIDByOrgID(t.orgID, subnetID)
115+
subnetLcuuid = common.GetUUIDByOrgID(t.orgID, networkLcuuid+"_v4")
116+
}
117+
vinterfaces = append(vinterfaces, model.VInterface{
118+
Lcuuid: vinterfaceLcuuid,
119+
Type: common.VIF_TYPE_LAN,
120+
Mac: common.VIF_DEFAULT_MAC,
121+
DeviceLcuuid: rdsLcuuid,
122+
DeviceType: common.VIF_DEVICE_TYPE_RDS_INSTANCE,
123+
VPCLcuuid: vpcLcuuid,
124+
NetworkLcuuid: networkLcuuid,
125+
RegionLcuuid: t.regionLcuuid,
126+
})
127+
128+
ips = append(ips, model.IP{
129+
Lcuuid: common.GetUUIDByOrgID(t.orgID, vinterfaceLcuuid+address),
130+
VInterfaceLcuuid: vinterfaceLcuuid,
131+
IP: address,
132+
SubnetLcuuid: subnetLcuuid,
133+
RegionLcuuid: t.regionLcuuid,
134+
})
135+
}
136+
return rdss, vinterfaces, ips, nil
137+
}
138+
139+
func (t *Tencent) getRDSSQLServer(region string) ([]model.RDSInstance, []model.VInterface, []model.IP, error) {
140+
var rdss []model.RDSInstance
141+
var vinterfaces []model.VInterface
142+
var ips []model.IP
143+
144+
resp, err := t.getResponse("sqlserver", "2018-03-28", "DescribeDBInstances", region, "DBInstances", true, map[string]interface{}{})
145+
if err != nil {
146+
log.Errorf("rds sql server request tencent api error: (%s)", err.Error(), logger.NewORGPrefix(t.orgID))
147+
return []model.RDSInstance{}, []model.VInterface{}, []model.IP{}, err
148+
}
149+
for _, rData := range resp {
150+
rdsID := rData.Get("InstanceId").MustString()
151+
rdsLcuuid := common.GetUUIDByOrgID(t.orgID, rdsID)
152+
rdsName := rData.Get("Name").MustString()
153+
zoneID := rData.Get("ZoneId").MustInt()
154+
azLcuuid, ok := t.azIDToLcuuid[zoneID]
155+
if !ok {
156+
log.Infof("rds sql server (%s) az (id:%d) not in available zones", rdsName, zoneID, logger.NewORGPrefix(t.orgID))
157+
continue
158+
}
159+
vpcLcuuid := common.GetUUIDByOrgID(t.orgID, rData.Get("UniqVpcId").MustString())
160+
var rdsModel = common.RDS_MODEL_PRIMARY
161+
if rData.Get("InstanceType").MustInt() != 2 {
162+
rdsModel = common.RDS_MODEL_SHARE
163+
}
164+
var rdsSeries = common.RDS_SERIES_HA
165+
if !strings.HasPrefix(rData.Get("InstanceType").MustString(), "HA") {
166+
rdsSeries = common.RDS_SERIES_BASIC
167+
}
168+
var rdsState = common.RDS_STATE_RUNNING
169+
if rData.Get("Status").MustInt() != 2 {
170+
rdsState = common.RDS_STATE_RESTORING
171+
}
172+
rdss = append(rdss, model.RDSInstance{
173+
Lcuuid: rdsLcuuid,
174+
Name: rdsName,
175+
Label: rdsID,
176+
State: rdsState,
177+
Type: common.RDS_TYPE_SQL_SERVER,
178+
Series: rdsSeries,
179+
Version: rData.Get("VersionName").MustString(),
180+
Model: rdsModel,
181+
VPCLcuuid: vpcLcuuid,
182+
AZLcuuid: azLcuuid,
183+
RegionLcuuid: t.regionLcuuid,
184+
})
185+
t.azLcuuidMap[azLcuuid] = 0
186+
187+
address := rData.Get("Vip").MustString()
188+
vinterfaceLcuuid := common.GetUUIDByOrgID(t.orgID, rdsID+address)
189+
networkLcuuid := common.NETWORK_ISP_LCUUID
190+
subnetLcuuid := common.SUBNET_ISP_LCUUID
191+
subnetID := rData.Get("UniqSubnetId").MustString()
192+
if subnetID != "" {
193+
networkLcuuid = common.GetUUIDByOrgID(t.orgID, subnetID)
194+
subnetLcuuid = common.GetUUIDByOrgID(t.orgID, networkLcuuid+"_v4")
195+
}
196+
vinterfaces = append(vinterfaces, model.VInterface{
197+
Lcuuid: vinterfaceLcuuid,
198+
Type: common.VIF_TYPE_LAN,
199+
Mac: common.VIF_DEFAULT_MAC,
200+
DeviceLcuuid: rdsLcuuid,
201+
DeviceType: common.VIF_DEVICE_TYPE_RDS_INSTANCE,
202+
VPCLcuuid: vpcLcuuid,
203+
NetworkLcuuid: networkLcuuid,
204+
RegionLcuuid: t.regionLcuuid,
205+
})
206+
207+
ips = append(ips, model.IP{
208+
Lcuuid: common.GetUUIDByOrgID(t.orgID, vinterfaceLcuuid+address),
209+
VInterfaceLcuuid: vinterfaceLcuuid,
210+
IP: address,
211+
SubnetLcuuid: subnetLcuuid,
212+
RegionLcuuid: t.regionLcuuid,
213+
})
214+
}
215+
return rdss, vinterfaces, ips, nil
216+
}
217+
218+
func (t *Tencent) getRDSPostgreSQL(region string) ([]model.RDSInstance, []model.VInterface, []model.IP, error) {
219+
var rdss []model.RDSInstance
220+
var vinterfaces []model.VInterface
221+
var ips []model.IP
222+
223+
resp, err := t.getResponse("postgres", "2017-03-12", "DescribeDBInstances", region, "DBInstanceSet", true, map[string]interface{}{})
224+
if err != nil {
225+
log.Errorf("rds postgresql request tencent api error: (%s)", err.Error(), logger.NewORGPrefix(t.orgID))
226+
return []model.RDSInstance{}, []model.VInterface{}, []model.IP{}, err
227+
}
228+
for _, rData := range resp {
229+
rdsID := rData.Get("DBInstanceId").MustString()
230+
rdsLcuuid := common.GetUUIDByOrgID(t.orgID, rdsID)
231+
rdsName := rData.Get("DBInstanceName").MustString()
232+
zone := rData.Get("Zone").MustString()
233+
azLcuuid, ok := t.zoneToLcuuid[zone]
234+
if !ok {
235+
log.Infof("rds postgresql (%s) az (zone:%s) not in available zones", rdsName, zone, logger.NewORGPrefix(t.orgID))
236+
continue
237+
}
238+
vpcLcuuid := common.GetUUIDByOrgID(t.orgID, rData.Get("VpcId").MustString())
239+
var rdsModel = common.RDS_MODEL_PRIMARY
240+
if rData.Get("DBInstanceType").MustString() != "primary" {
241+
rdsModel = common.RDS_MODEL_SHARE
242+
}
243+
var rdsState = common.RDS_STATE_RUNNING
244+
if rData.Get("DBInstanceStatus").MustString() != "running" {
245+
rdsState = common.RDS_STATE_RESTORING
246+
}
247+
rdss = append(rdss, model.RDSInstance{
248+
Lcuuid: rdsLcuuid,
249+
Name: rdsName,
250+
Label: rdsID,
251+
State: rdsState,
252+
Type: common.RDS_TYPE_PSQL,
253+
Series: common.RDS_SERIES_HA,
254+
Version: rData.Get("DBVersion").MustString(),
255+
Model: rdsModel,
256+
VPCLcuuid: vpcLcuuid,
257+
AZLcuuid: azLcuuid,
258+
RegionLcuuid: t.regionLcuuid,
259+
})
260+
t.azLcuuidMap[azLcuuid] = 0
261+
262+
nets := rData.Get("DBInstanceNetInfo")
263+
for i := range nets.MustArray() {
264+
net := nets.GetIndex(i)
265+
if net.Get("Status").MustString() != "opened" {
266+
continue
267+
}
268+
vpcLcuuid = common.GetUUIDByOrgID(t.orgID, net.Get("VpcId").MustString())
269+
address := net.Get("Ip").MustString()
270+
vinterfaceLcuuid := common.GetUUIDByOrgID(t.orgID, rdsID+address)
271+
networkLcuuid := common.NETWORK_ISP_LCUUID
272+
subnetLcuuid := common.SUBNET_ISP_LCUUID
273+
subnetID := net.Get("SubnetId").MustString()
274+
if subnetID != "" {
275+
networkLcuuid = common.GetUUIDByOrgID(t.orgID, subnetID)
276+
subnetLcuuid = common.GetUUIDByOrgID(t.orgID, networkLcuuid+"_v4")
277+
}
278+
var netType = common.NETWORK_TYPE_LAN
279+
if net.Get("NetType").MustString() == "public" {
280+
netType = common.NETWORK_TYPE_WAN
281+
}
282+
vinterfaces = append(vinterfaces, model.VInterface{
283+
Lcuuid: vinterfaceLcuuid,
284+
Type: netType,
285+
Mac: common.VIF_DEFAULT_MAC,
286+
DeviceLcuuid: rdsLcuuid,
287+
DeviceType: common.VIF_DEVICE_TYPE_RDS_INSTANCE,
288+
VPCLcuuid: vpcLcuuid,
289+
NetworkLcuuid: networkLcuuid,
290+
RegionLcuuid: t.regionLcuuid,
291+
})
292+
293+
ips = append(ips, model.IP{
294+
Lcuuid: common.GetUUIDByOrgID(t.orgID, vinterfaceLcuuid+address),
295+
VInterfaceLcuuid: vinterfaceLcuuid,
296+
IP: address,
297+
SubnetLcuuid: subnetLcuuid,
298+
RegionLcuuid: t.regionLcuuid,
299+
})
300+
}
301+
}
302+
return rdss, vinterfaces, ips, nil
303+
}

0 commit comments

Comments
 (0)