Skip to content

Commit 6b3d42b

Browse files
authored
feat(vpc): improve get private-network to show all attached resources (#3021)
1 parent ff2d186 commit 6b3d42b

7 files changed

+10240
-1228
lines changed

internal/namespaces/vpc/v1/custom_private_network.go

+287-29
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,17 @@ import (
44
"context"
55

66
"github.com/scaleway/scaleway-cli/v2/internal/core"
7+
"github.com/scaleway/scaleway-sdk-go/api/baremetal/v1"
78
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
9+
"github.com/scaleway/scaleway-sdk-go/api/lb/v1"
10+
"github.com/scaleway/scaleway-sdk-go/api/rdb/v1"
11+
"github.com/scaleway/scaleway-sdk-go/api/redis/v1"
812
"github.com/scaleway/scaleway-sdk-go/api/vpc/v1"
13+
"github.com/scaleway/scaleway-sdk-go/api/vpcgw/v1"
914
"github.com/scaleway/scaleway-sdk-go/scw"
1015
)
1116

1217
func privateNetworkGetBuilder(c *core.Command) *core.Command {
13-
type customServer struct {
14-
ID string `json:"id"`
15-
Name string `json:"name"`
16-
State instance.ServerState `json:"state"`
17-
NicID string `json:"nic_id"`
18-
MacAddress string `json:"mac"`
19-
}
20-
2118
c.Interceptor = func(ctx context.Context, argsI interface{}, runner core.CommandRunner) (interface{}, error) {
2219
getPNResp, err := runner(ctx, argsI)
2320
if err != nil {
@@ -26,43 +23,304 @@ func privateNetworkGetBuilder(c *core.Command) *core.Command {
2623
pn := getPNResp.(*vpc.PrivateNetwork)
2724

2825
client := core.ExtractClient(ctx)
29-
instanceAPI := instance.NewAPI(client)
30-
listServers, err := instanceAPI.ListServers(&instance.ListServersRequest{
31-
PrivateNetwork: &pn.ID,
32-
}, scw.WithAllPages())
26+
27+
// Instance
28+
listInstanceServers, err := listCustomInstanceServers(client, pn)
3329
if err != nil {
34-
return getPNResp, err
30+
return nil, err
3531
}
3632

37-
customServers := []customServer{}
38-
for _, server := range listServers.Servers {
39-
for _, nic := range server.PrivateNics {
40-
if nic.PrivateNetworkID == pn.ID {
41-
customServers = append(customServers, customServer{
42-
NicID: nic.ID,
43-
ID: nic.ServerID,
44-
MacAddress: nic.MacAddress,
45-
Name: server.Name,
46-
State: server.State,
47-
})
48-
}
49-
}
33+
// Baremetal
34+
listBaremetalServers, err := listCustomBaremetalServers(client, pn)
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
// LB
40+
listLBs, err := listCustomLBs(client, pn)
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
// Rdb
46+
listRdbInstances, err := listCustomRdbs(client, pn)
47+
if err != nil {
48+
return nil, err
49+
}
50+
51+
// Redis
52+
listRedisClusters, err := listCustomRedisClusters(client, pn)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
// Gateway
58+
listGateways, err := listCustomGateways(client, pn)
59+
if err != nil {
60+
return nil, err
5061
}
5162

5263
return &struct {
5364
*vpc.PrivateNetwork
54-
Servers []customServer `json:"servers"`
65+
InstanceServers []customInstanceServer `json:"instance_servers,omitempty"`
66+
BaremetalServers []customBaremetalServer `json:"baremetal_servers,omitempty"`
67+
LBs []customLB `json:"lbs,omitempty"`
68+
RdbInstances []customRdb `json:"rdb_instances,omitempty"`
69+
RedisClusters []customRedis `json:"redis_clusters,omitempty"`
70+
Gateways []customGateway `json:"gateways,omitempty"`
5571
}{
5672
pn,
57-
customServers,
73+
listInstanceServers,
74+
listBaremetalServers,
75+
listLBs,
76+
listRdbInstances,
77+
listRedisClusters,
78+
listGateways,
5879
}, nil
5980
}
6081

6182
c.View = &core.View{
6283
Sections: []*core.ViewSection{
63-
{FieldName: "Servers", Title: "Servers"},
84+
{
85+
FieldName: "InstanceServers",
86+
Title: "Instance Servers",
87+
HideIfEmpty: true,
88+
},
89+
{
90+
FieldName: "BaremetalServers",
91+
Title: "Baremetal Servers",
92+
HideIfEmpty: true,
93+
},
94+
{
95+
FieldName: "LBs",
96+
Title: "Load-Balancers",
97+
HideIfEmpty: true,
98+
},
99+
{
100+
FieldName: "RdbInstances",
101+
Title: "Rdb Instances",
102+
HideIfEmpty: true,
103+
},
104+
{
105+
FieldName: "RedisClusters",
106+
Title: "Redis Clusters",
107+
HideIfEmpty: true,
108+
},
109+
{
110+
FieldName: "Gateways",
111+
Title: "Public Gateways",
112+
HideIfEmpty: true,
113+
},
64114
},
65115
}
66116

67117
return c
68118
}
119+
120+
type customInstanceServer struct {
121+
ID string `json:"id"`
122+
Name string `json:"name"`
123+
State instance.ServerState `json:"state"`
124+
NicID string `json:"nic_id"`
125+
MacAddress string `json:"mac"`
126+
}
127+
type customBaremetalServer struct {
128+
ID string `json:"id"`
129+
Name string `json:"server_id"`
130+
State baremetal.ServerStatus `json:"state"`
131+
BaremetalNetworkID string `json:"baremetal_network_id"`
132+
Vlan *uint32 `json:"vlan"`
133+
}
134+
type customLB struct {
135+
ID string `json:"id"`
136+
Name string `json:"server_id"`
137+
State lb.LBStatus `json:"state"`
138+
}
139+
type customRdb struct {
140+
ID string `json:"id"`
141+
Name string `json:"server_id"`
142+
State rdb.InstanceStatus `json:"state"`
143+
EndpointID string `json:"endpoint_id"`
144+
}
145+
type customRedis struct {
146+
ID string `json:"id"`
147+
Name string `json:"server_id"`
148+
State redis.ClusterStatus `json:"state"`
149+
EndpointID string `json:"endpoint_id"`
150+
}
151+
type customGateway struct {
152+
ID string `json:"id"`
153+
Name string `json:"server_id"`
154+
State vpcgw.GatewayStatus `json:"state"`
155+
GatewayNetworkID string `json:"gateway_network_id"`
156+
}
157+
158+
func listCustomInstanceServers(client *scw.Client, pn *vpc.PrivateNetwork) ([]customInstanceServer, error) {
159+
instanceAPI := instance.NewAPI(client)
160+
listInstanceServers, err := instanceAPI.ListServers(&instance.ListServersRequest{
161+
PrivateNetwork: &pn.ID,
162+
}, scw.WithAllPages())
163+
if err != nil {
164+
return nil, err
165+
}
166+
var customInstanceServers []customInstanceServer
167+
for _, server := range listInstanceServers.Servers {
168+
for _, nic := range server.PrivateNics {
169+
if nic.PrivateNetworkID == pn.ID {
170+
customInstanceServers = append(customInstanceServers, customInstanceServer{
171+
NicID: nic.ID,
172+
ID: nic.ServerID,
173+
MacAddress: nic.MacAddress,
174+
Name: server.Name,
175+
State: server.State,
176+
})
177+
}
178+
}
179+
}
180+
return customInstanceServers, nil
181+
}
182+
183+
func listCustomBaremetalServers(client *scw.Client, pn *vpc.PrivateNetwork) ([]customBaremetalServer, error) {
184+
baremtalPNAPI := baremetal.NewPrivateNetworkAPI(client)
185+
baremetalAPI := baremetal.NewAPI(client)
186+
listBaremetalServers, err := baremtalPNAPI.ListServerPrivateNetworks(&baremetal.PrivateNetworkAPIListServerPrivateNetworksRequest{
187+
Zone: pn.Zone,
188+
PrivateNetworkID: &pn.ID,
189+
}, scw.WithAllPages())
190+
if err != nil {
191+
return nil, err
192+
}
193+
var customBaremetalServers []customBaremetalServer
194+
for _, server := range listBaremetalServers.ServerPrivateNetworks {
195+
if server.PrivateNetworkID == pn.ID {
196+
getBaremetalServer, err := baremetalAPI.GetServer(&baremetal.GetServerRequest{
197+
Zone: pn.Zone,
198+
ServerID: server.ServerID,
199+
})
200+
if err != nil {
201+
return nil, err
202+
}
203+
customBaremetalServers = append(customBaremetalServers, customBaremetalServer{
204+
ID: server.ServerID,
205+
State: getBaremetalServer.Status,
206+
BaremetalNetworkID: server.ID,
207+
Name: getBaremetalServer.Name,
208+
Vlan: server.Vlan,
209+
})
210+
}
211+
}
212+
return customBaremetalServers, nil
213+
}
214+
215+
func listCustomLBs(client *scw.Client, pn *vpc.PrivateNetwork) ([]customLB, error) {
216+
LBAPI := lb.NewZonedAPI(client)
217+
listLbs, err := LBAPI.ListLBs(&lb.ZonedAPIListLBsRequest{
218+
Zone: pn.Zone,
219+
})
220+
var filteredLBs []*lb.LB
221+
for _, loadbalancer := range listLbs.LBs {
222+
if loadbalancer.PrivateNetworkCount >= 1 {
223+
filteredLBs = append(filteredLBs, loadbalancer)
224+
}
225+
}
226+
if err != nil {
227+
return nil, err
228+
}
229+
230+
var customLBs []customLB
231+
for _, loadbalancer := range filteredLBs {
232+
listLBpns, err := LBAPI.ListLBPrivateNetworks(&lb.ZonedAPIListLBPrivateNetworksRequest{
233+
Zone: loadbalancer.Zone,
234+
LBID: loadbalancer.ID,
235+
}, scw.WithAllPages())
236+
if err != nil {
237+
return nil, err
238+
}
239+
for _, res := range listLBpns.PrivateNetwork {
240+
if res.PrivateNetworkID == pn.ID {
241+
customLBs = append(customLBs, customLB{
242+
ID: res.LB.ID,
243+
Name: res.LB.Name,
244+
State: res.LB.Status,
245+
})
246+
}
247+
}
248+
}
249+
return customLBs, nil
250+
}
251+
252+
func listCustomRdbs(client *scw.Client, pn *vpc.PrivateNetwork) ([]customRdb, error) {
253+
rdbAPI := rdb.NewAPI(client)
254+
region, err := scw.Zone.Region(pn.Zone)
255+
if err != nil {
256+
return nil, err
257+
}
258+
listDBs, err := rdbAPI.ListInstances(&rdb.ListInstancesRequest{
259+
Region: region,
260+
}, scw.WithAllPages())
261+
if err != nil {
262+
return nil, err
263+
}
264+
var customRdbs []customRdb
265+
for _, db := range listDBs.Instances {
266+
for _, endpoint := range db.Endpoints {
267+
if endpoint.PrivateNetwork != nil && endpoint.PrivateNetwork.PrivateNetworkID == pn.ID {
268+
customRdbs = append(customRdbs, customRdb{
269+
EndpointID: endpoint.ID,
270+
ID: db.ID,
271+
Name: db.Name,
272+
State: db.Status,
273+
})
274+
}
275+
}
276+
}
277+
return customRdbs, nil
278+
}
279+
280+
func listCustomRedisClusters(client *scw.Client, pn *vpc.PrivateNetwork) ([]customRedis, error) {
281+
redisAPI := redis.NewAPI(client)
282+
listRedisClusters, err := redisAPI.ListClusters(&redis.ListClustersRequest{
283+
Zone: pn.Zone,
284+
}, scw.WithAllPages())
285+
if err != nil {
286+
return nil, err
287+
}
288+
var customClusters []customRedis
289+
for _, cluster := range listRedisClusters.Clusters {
290+
for _, endpoint := range cluster.Endpoints {
291+
if endpoint.PrivateNetwork.ID == pn.ID {
292+
customClusters = append(customClusters, customRedis{
293+
ID: cluster.ID,
294+
Name: cluster.Name,
295+
State: cluster.Status,
296+
EndpointID: endpoint.ID,
297+
})
298+
}
299+
}
300+
}
301+
return customClusters, nil
302+
}
303+
304+
func listCustomGateways(client *scw.Client, pn *vpc.PrivateNetwork) ([]customGateway, error) {
305+
vpcgwAPI := vpcgw.NewAPI(client)
306+
listGateways, err := vpcgwAPI.ListGateways(&vpcgw.ListGatewaysRequest{
307+
Zone: pn.Zone,
308+
}, scw.WithAllPages())
309+
if err != nil {
310+
return nil, err
311+
}
312+
var customGateways []customGateway
313+
for _, gateway := range listGateways.Gateways {
314+
for _, gatewayNetwork := range gateway.GatewayNetworks {
315+
if gatewayNetwork.PrivateNetworkID == pn.ID {
316+
customGateways = append(customGateways, customGateway{
317+
ID: gateway.ID,
318+
Name: gateway.Name,
319+
State: gateway.Status,
320+
GatewayNetworkID: gatewayNetwork.GatewayID,
321+
})
322+
}
323+
}
324+
}
325+
return customGateways, nil
326+
}

internal/namespaces/vpc/v1/custom_private_network_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ import (
55

66
"github.com/scaleway/scaleway-cli/v2/internal/core"
77
"github.com/scaleway/scaleway-cli/v2/internal/namespaces/instance/v1"
8+
"github.com/scaleway/scaleway-cli/v2/internal/namespaces/lb/v1"
9+
"github.com/scaleway/scaleway-cli/v2/internal/namespaces/rdb/v1"
10+
"github.com/scaleway/scaleway-cli/v2/internal/namespaces/redis/v1"
811
)
912

1013
func Test_GetPrivateNetwork(t *testing.T) {
1114
cmds := GetCommands()
1215
cmds.Merge(instance.GetCommands())
16+
cmds.Merge(lb.GetCommands())
17+
cmds.Merge(rdb.GetCommands())
18+
cmds.Merge(redis.GetCommands())
1319

1420
t.Run("Simple", core.Test(&core.TestConfig{
1521
Commands: cmds,
@@ -25,4 +31,27 @@ func Test_GetPrivateNetwork(t *testing.T) {
2531
deletePN(),
2632
),
2733
}))
34+
35+
t.Run("Multiple", core.Test(&core.TestConfig{
36+
Commands: cmds,
37+
BeforeFunc: core.BeforeFuncCombine(
38+
createPN(),
39+
createInstance(),
40+
createNIC(),
41+
createLB(),
42+
attachLB(),
43+
createRdbInstance(),
44+
),
45+
Cmd: "scw vpc private-network get {{ .PN.ID }}",
46+
Check: core.TestCheckGolden(),
47+
AfterFunc: core.AfterFuncCombine(
48+
detachLB(),
49+
deleteLB(),
50+
deleteInstance(),
51+
detachRdbInstance(),
52+
waitRdbInstance(),
53+
deleteRdbInstance(),
54+
deletePN(),
55+
),
56+
}))
2857
}

0 commit comments

Comments
 (0)