Skip to content

Commit fe331a3

Browse files
tetra12tamplerdavidjumani
authored
Fix listVPCs unmarshall error when a VPC has network tiers attached (#26)
* Started to impl VPC list test * * Upd list VPCs test for both simple and network cases * Bump go version * Add listVPCs success and fail responses for test * Upd VPC schema * Updated generator to output valid network type for VPC Service * Minor fixes Co-authored-by: tampler <socnetfpga@gmail.com> Co-authored-by: davidjumani <dj.davidjumani1994@gmail.com>
1 parent 58b869d commit fe331a3

5 files changed

Lines changed: 342 additions & 5 deletions

File tree

cloudstack/VPCService.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ type CreateVPCResponse struct {
718718
JobID string `json:"jobid"`
719719
Jobstatus int `json:"jobstatus"`
720720
Name string `json:"name"`
721-
Network []string `json:"network"`
721+
Network []*Network `json:"network"`
722722
Networkdomain string `json:"networkdomain"`
723723
Project string `json:"project"`
724724
Projectid string `json:"projectid"`
@@ -2855,7 +2855,7 @@ type VPC struct {
28552855
JobID string `json:"jobid"`
28562856
Jobstatus int `json:"jobstatus"`
28572857
Name string `json:"name"`
2858-
Network []string `json:"network"`
2858+
Network []*Network `json:"network"`
28592859
Networkdomain string `json:"networkdomain"`
28602860
Project string `json:"project"`
28612861
Projectid string `json:"projectid"`
@@ -3169,7 +3169,7 @@ type UpdateVPCResponse struct {
31693169
JobID string `json:"jobid"`
31703170
Jobstatus int `json:"jobstatus"`
31713171
Name string `json:"name"`
3172-
Network []string `json:"network"`
3172+
Network []*Network `json:"network"`
31733173
Networkdomain string `json:"networkdomain"`
31743174
Project string `json:"project"`
31753175
Projectid string `json:"projectid"`

cloudstack/VPCService_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func TestVPCService_RestartVPC(t *testing.T) {
3838
defer server.Close()
3939
client := NewAsyncClient(server.URL, "APIKEY", "SECRETKEY", false)
4040
params := client.VPC.NewRestartVPCParams("f9ec95f3-70be-448a-8ba2-cb6388dce55a")
41+
4142
resp, err := client.VPC.RestartVPC(params)
4243
if err != nil {
4344
t.Errorf("Failed to restart VPC network due to: %v", err)
@@ -46,3 +47,27 @@ func TestVPCService_RestartVPC(t *testing.T) {
4647
t.Errorf("Failed to restart VPC network")
4748
}
4849
}
50+
51+
func TestVPCService_ListVPCs(t *testing.T) {
52+
53+
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
54+
apiName := "listVPCs"
55+
response, err := ParseAsyncResponse(apiName, "VPCService", *request)
56+
if err != nil {
57+
t.Errorf("Failed to parse response, due to: %v", err)
58+
}
59+
fmt.Fprintln(writer, response)
60+
}))
61+
defer server.Close()
62+
63+
client := NewAsyncClient(server.URL, "APIKEY", "SECRETKEY", false)
64+
params := client.VPC.NewListVPCsParams()
65+
resp, err := client.VPC.ListVPCs(params)
66+
67+
if err != nil {
68+
t.Errorf("Failed to list VPCs due to: %v", err)
69+
}
70+
if resp == nil {
71+
t.Errorf("Failed to list VPCs")
72+
}
73+
}

cloudstack/testdata/VPCServiceData.json

Lines changed: 311 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,315 @@
2222
"jobid": "98272f42-917c-4286-8c05-4e38d85d32e0"
2323
}
2424
}
25+
},
26+
"listVPCs": {
27+
"listVPCs": {
28+
"listvpcresponse": {
29+
"count": 2,
30+
"vpc": [
31+
{
32+
"id": "49b5fa29-e98f-4078-b407-7e7928105ec0",
33+
"name": "my-vpc",
34+
"displaytext": "my-vpc-text",
35+
"state": "Enabled",
36+
"zoneid": "04ccc336-d730-42fe-8ff6-5ae36e141e81",
37+
"zonename": "SimZone1",
38+
"service": [
39+
{ "name": "Dns", "provider": [{ "name": "VpcVirtualRouter" }] },
40+
{ "name": "Dhcp", "provider": [{ "name": "VpcVirtualRouter" }] },
41+
{
42+
"name": "PortForwarding",
43+
"provider": [{ "name": "VpcVirtualRouter" }]
44+
},
45+
{
46+
"name": "StaticNat",
47+
"provider": [{ "name": "VpcVirtualRouter" }]
48+
},
49+
{ "name": "Vpn", "provider": [{ "name": "VpcVirtualRouter" }] },
50+
{
51+
"name": "SourceNat",
52+
"provider": [{ "name": "VpcVirtualRouter" }]
53+
},
54+
{
55+
"name": "NetworkACL",
56+
"provider": [{ "name": "VpcVirtualRouter" }]
57+
},
58+
{
59+
"name": "UserData",
60+
"provider": [{ "name": "VpcVirtualRouter" }]
61+
},
62+
{
63+
"name": "Lb",
64+
"provider": [
65+
{ "name": "VpcVirtualRouter" },
66+
{ "name": "InternalLbVm" }
67+
]
68+
}
69+
],
70+
"cidr": "10.0.0.0/8",
71+
"vpcofferingid": "8142b164-0fa2-40c6-9067-2a90ae526df5",
72+
"vpcofferingname": "Default VPC offering",
73+
"created": "2021-12-26T22:26:18+0000",
74+
"account": "admin",
75+
"domainid": "bbae9696-627f-11ec-8fb6-0242ac110002",
76+
"domain": "ROOT",
77+
"network": [],
78+
"restartrequired": false,
79+
"networkdomain": "my-domain",
80+
"tags": [{ "key": "my-tag", "value": "true" }],
81+
"fordisplay": true,
82+
"distributedvpcrouter": false,
83+
"regionlevelvpc": false,
84+
"redundantvpcrouter": false,
85+
"hasannotations": false
86+
},
87+
{
88+
"id": "78d49100-e4af-4692-9a49-284fa2444eb9",
89+
"name": "my-vpc",
90+
"displaytext": "my-vpc",
91+
"state": "Enabled",
92+
"zoneid": "04ccc336-d730-42fe-8ff6-5ae36e141e81",
93+
"zonename": "SimZone1",
94+
"service": [
95+
{ "name": "Dns", "provider": [{ "name": "VpcVirtualRouter" }] },
96+
{ "name": "Dhcp", "provider": [{ "name": "VpcVirtualRouter" }] },
97+
{
98+
"name": "PortForwarding",
99+
"provider": [{ "name": "VpcVirtualRouter" }]
100+
},
101+
{
102+
"name": "StaticNat",
103+
"provider": [{ "name": "VpcVirtualRouter" }]
104+
},
105+
{ "name": "Vpn", "provider": [{ "name": "VpcVirtualRouter" }] },
106+
{
107+
"name": "SourceNat",
108+
"provider": [{ "name": "VpcVirtualRouter" }]
109+
},
110+
{
111+
"name": "NetworkACL",
112+
"provider": [{ "name": "VpcVirtualRouter" }]
113+
},
114+
{
115+
"name": "UserData",
116+
"provider": [{ "name": "VpcVirtualRouter" }]
117+
},
118+
{
119+
"name": "Lb",
120+
"provider": [
121+
{ "name": "VpcVirtualRouter" },
122+
{ "name": "InternalLbVm" }
123+
]
124+
}
125+
],
126+
"cidr": "10.0.0.0/8",
127+
"vpcofferingid": "8142b164-0fa2-40c6-9067-2a90ae526df5",
128+
"vpcofferingname": "Default VPC offering",
129+
"created": "2021-12-26T22:28:44+0000",
130+
"account": "admin",
131+
"domainid": "bbae9696-627f-11ec-8fb6-0242ac110002",
132+
"domain": "ROOT",
133+
"network": [
134+
{
135+
"id": "e22cab07-58ac-4a1b-b0a8-fcee1bbecc7d",
136+
"name": "my-network",
137+
"displaytext": "my-network",
138+
"broadcastdomaintype": "Vlan",
139+
"traffictype": "Guest",
140+
"gateway": "10.1.1.1",
141+
"netmask": "255.255.255.0",
142+
"cidr": "10.1.1.0/24",
143+
"zoneid": "04ccc336-d730-42fe-8ff6-5ae36e141e81",
144+
"zonename": "SimZone1",
145+
"networkofferingid": "f26a1059-24df-4f76-9daf-16d42ce9df11",
146+
"networkofferingname": "DefaultIsolatedNetworkOfferingForVpcNetworks",
147+
"networkofferingdisplaytext": "Offering for Isolated Vpc networks with Source Nat service enabled",
148+
"networkofferingconservemode": false,
149+
"networkofferingavailability": "Optional",
150+
"issystem": false,
151+
"state": "Allocated",
152+
"related": "e22cab07-58ac-4a1b-b0a8-fcee1bbecc7d",
153+
"dns1": "10.147.28.6",
154+
"type": "Isolated",
155+
"acltype": "Account",
156+
"account": "admin",
157+
"domainid": "bbae9696-627f-11ec-8fb6-0242ac110002",
158+
"domain": "ROOT",
159+
"service": [
160+
{
161+
"name": "Dns",
162+
"provider": [{ "name": "VpcVirtualRouter" }],
163+
"capability": [
164+
{
165+
"name": "AllowDnsSuffixModification",
166+
"value": "true",
167+
"canchooseservicecapability": false
168+
}
169+
]
170+
},
171+
{
172+
"name": "Dhcp",
173+
"provider": [{ "name": "VpcVirtualRouter" }],
174+
"capability": [
175+
{
176+
"name": "DhcpAccrossMultipleSubnets",
177+
"value": "true",
178+
"canchooseservicecapability": false
179+
}
180+
]
181+
},
182+
{
183+
"name": "PortForwarding",
184+
"provider": [{ "name": "VpcVirtualRouter" }],
185+
"capability": [
186+
{
187+
"name": "SupportedProtocols",
188+
"value": "tcp,udp",
189+
"canchooseservicecapability": false
190+
}
191+
]
192+
},
193+
{
194+
"name": "StaticNat",
195+
"provider": [{ "name": "VpcVirtualRouter" }],
196+
"capability": [
197+
{
198+
"name": "ElasticIp",
199+
"value": "false",
200+
"canchooseservicecapability": false
201+
},
202+
{
203+
"name": "AssociatePublicIP",
204+
"value": "true",
205+
"canchooseservicecapability": false
206+
}
207+
]
208+
},
209+
{
210+
"name": "Vpn",
211+
"provider": [{ "name": "VpcVirtualRouter" }],
212+
"capability": [
213+
{
214+
"name": "SupportedVpnTypes",
215+
"value": "pptp,l2tp,ipsec",
216+
"canchooseservicecapability": false
217+
},
218+
{
219+
"name": "VpnTypes",
220+
"value": "s2svpn",
221+
"canchooseservicecapability": false
222+
}
223+
]
224+
},
225+
{
226+
"name": "SourceNat",
227+
"provider": [{ "name": "VpcVirtualRouter" }],
228+
"capability": [
229+
{
230+
"name": "SupportedSourceNatTypes",
231+
"value": "peraccount",
232+
"canchooseservicecapability": true
233+
},
234+
{
235+
"name": "RedundantRouter",
236+
"value": "false",
237+
"canchooseservicecapability": true
238+
}
239+
]
240+
},
241+
{
242+
"name": "NetworkACL",
243+
"provider": [{ "name": "VpcVirtualRouter" }],
244+
"capability": [
245+
{
246+
"name": "SupportedProtocols",
247+
"value": "tcp,udp,icmp",
248+
"canchooseservicecapability": false
249+
}
250+
]
251+
},
252+
{
253+
"name": "UserData",
254+
"provider": [{ "name": "VpcVirtualRouter" }],
255+
"capability": []
256+
},
257+
{
258+
"name": "Lb",
259+
"provider": [{ "name": "VpcVirtualRouter" }],
260+
"capability": [
261+
{
262+
"name": "SupportedStickinessMethods",
263+
"value": "[{\"methodname\":\"LbCookie\",\"paramlist\":[{\"paramname\":\"cookie-name\",\"required\":false,\"isflag\":false,\"description\":\" \"},{\"paramname\":\"mode\",\"required\":false,\"isflag\":false,\"description\":\" \"},{\"paramname\":\"nocache\",\"required\":false,\"isflag\":true,\"description\":\" \"},{\"paramname\":\"indirect\",\"required\":false,\"isflag\":true,\"description\":\" \"},{\"paramname\":\"postonly\",\"required\":false,\"isflag\":true,\"description\":\" \"},{\"paramname\":\"domain\",\"required\":false,\"isflag\":false,\"description\":\" \"}],\"description\":\"This is loadbalancer cookie based stickiness method.\"},{\"methodname\":\"AppCookie\",\"paramlist\":[{\"paramname\":\"cookie-name\",\"required\":false,\"isflag\":false,\"description\":\" \"},{\"paramname\":\"length\",\"required\":false,\"isflag\":false,\"description\":\" \"},{\"paramname\":\"holdtime\",\"required\":false,\"isflag\":false,\"description\":\" \"},{\"paramname\":\"request-learn\",\"required\":false,\"isflag\":true,\"description\":\" \"},{\"paramname\":\"prefix\",\"required\":false,\"isflag\":true,\"description\":\" \"},{\"paramname\":\"mode\",\"required\":false,\"isflag\":false,\"description\":\" \"}],\"description\":\"This is App session based sticky method. Define session stickiness on an existing application cookie. It can be used only for a specific http traffic\"},{\"methodname\":\"SourceBased\",\"paramlist\":[{\"paramname\":\"tablesize\",\"required\":false,\"isflag\":false,\"description\":\" \"},{\"paramname\":\"expire\",\"required\":false,\"isflag\":false,\"description\":\" \"}],\"description\":\"This is source based Stickiness method, it can be used for any type of protocol.\"}]",
264+
"canchooseservicecapability": false
265+
},
266+
{
267+
"name": "SupportedLbAlgorithms",
268+
"value": "roundrobin,leastconn,source",
269+
"canchooseservicecapability": false
270+
},
271+
{
272+
"name": "LbSchemes",
273+
"value": "Public",
274+
"canchooseservicecapability": false
275+
},
276+
{
277+
"name": "SupportedProtocols",
278+
"value": "tcp, udp, tcp-proxy",
279+
"canchooseservicecapability": false
280+
},
281+
{
282+
"name": "SupportedLBIsolation",
283+
"value": "dedicated",
284+
"canchooseservicecapability": true
285+
},
286+
{
287+
"name": "AutoScaleCounters",
288+
"value": "[{\"methodname\":\"cpu\",\"paramlist\":[]},{\"methodname\":\"memory\",\"paramlist\":[]}]",
289+
"canchooseservicecapability": false
290+
},
291+
{
292+
"name": "ElasticLb",
293+
"value": "false",
294+
"canchooseservicecapability": false
295+
},
296+
{
297+
"name": "InlineMode",
298+
"value": "false",
299+
"canchooseservicecapability": false
300+
}
301+
]
302+
}
303+
],
304+
"networkdomain": "my-domain",
305+
"physicalnetworkid": "ffcffe07-5cbf-4862-9c52-8e7153a5239a",
306+
"restartrequired": false,
307+
"specifyipranges": false,
308+
"vpcid": "78d49100-e4af-4692-9a49-284fa2444eb9",
309+
"vpcname": "my-vpc",
310+
"canusefordeploy": true,
311+
"ispersistent": false,
312+
"tags": [],
313+
"details": {},
314+
"displaynetwork": true,
315+
"strechedl2subnet": false,
316+
"redundantrouter": false,
317+
"created": "2021-12-26T22:28:52+0000",
318+
"receivedbytes": 0,
319+
"sentbytes": 0,
320+
"hasannotations": false
321+
}
322+
],
323+
"restartrequired": false,
324+
"networkdomain": "my-domain",
325+
"tags": [{ "key": "my-tag", "value": "true" }],
326+
"fordisplay": true,
327+
"distributedvpcrouter": false,
328+
"regionlevelvpc": false,
329+
"redundantvpcrouter": false,
330+
"hasannotations": false
331+
}
332+
]
333+
}
334+
}
25335
}
26-
}
336+
}

generate/generate.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,8 @@ func mapType(aName string, pName string, pType string) string {
18501850
case "list":
18511851
if pName == "downloaddetails" || pName == "owner" {
18521852
return "[]map[string]string"
1853+
} else if pName == "network" {
1854+
return "[]*Network"
18531855
}
18541856
return "[]string"
18551857
case "map":

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module github.com/apache/cloudstack-go/v2
22

3-
go 1.13
3+
go 1.17
44

55
require github.com/golang/mock v1.6.0

0 commit comments

Comments
 (0)