This is an automated email from the ASF dual-hosted git repository.
abh1sar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack-go.git
The following commit(s) were added to refs/heads/main by this push:
new 37d668c Fix listing virtual machines with vnfnics (#161)
37d668c is described below
commit 37d668c751c41e8d67cff6f8e9907fc2420b1a19
Author: Wei Zhou <[email protected]>
AuthorDate: Mon Aug 10 16:50:10 2026 +0200
Fix listing virtual machines with vnfnics (#161)
* Fix listing virtual machines with vnfnics
* Fix response key for ListVnfTemplates and ListVnfAppliances
Both list structs took their json tag from the API name, so they looked for
"vnftemplate" and "vnfappliance". Neither key exists in the server response:
ListVnfTemplatesCmd is an empty subclass of ListTemplatesCmd and returns its
items under "template", and ListVnfAppliancesCmd inherits execute() from
ListVMsCmd and returns its items under "virtualmachine". Both calls
therefore
returned a correct Count with an always-empty slice, which also made
GetVnfTemplateByName/ByID and GetVnfApplianceByName/ByID always report that
the resource was not found.
Adds both to the existing switch of APIs whose response key differs from the
API name, alongside cases like listVirtualMachinesUsageHistory, and
regenerates. Verified against a 4.22.1.0 server response that returns one
VNF
template: it decodes to one element instead of zero.
---------
---
cloudstack/AffinityGroupService.go | 2 +-
cloudstack/BackupService.go | 2 +-
cloudstack/ISOService.go | 4 +--
cloudstack/NicService.go | 2 +-
cloudstack/SSHService.go | 2 +-
cloudstack/SnapshotService.go | 2 +-
cloudstack/VirtualMachineService.go | 42 ++++++++++++++--------------
cloudstack/VirtualNetworkFunctionsService.go | 18 +++++++++---
generate/generate.go | 27 ++++++++++++++++++
9 files changed, 69 insertions(+), 32 deletions(-)
diff --git a/cloudstack/AffinityGroupService.go
b/cloudstack/AffinityGroupService.go
index f202a81..38fa9a0 100644
--- a/cloudstack/AffinityGroupService.go
+++ b/cloudstack/AffinityGroupService.go
@@ -1233,7 +1233,7 @@ type UpdateVMAffinityGroupResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
diff --git a/cloudstack/BackupService.go b/cloudstack/BackupService.go
index 783d519..35f1f48 100644
--- a/cloudstack/BackupService.go
+++ b/cloudstack/BackupService.go
@@ -2347,7 +2347,7 @@ type CreateVMFromBackupResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
diff --git a/cloudstack/ISOService.go b/cloudstack/ISOService.go
index 09510e8..df933f5 100644
--- a/cloudstack/ISOService.go
+++ b/cloudstack/ISOService.go
@@ -291,7 +291,7 @@ type AttachIsoResponse struct {
Videoram int64 `json:"videoram"`
Vmtype string `json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string `json:"vnfnics"`
+ Vnfnics []*VnfNic `json:"vnfnics"`
Zoneid string `json:"zoneid"`
Zonename string `json:"zonename"`
}
@@ -926,7 +926,7 @@ type DetachIsoResponse struct {
Videoram int64 `json:"videoram"`
Vmtype string `json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string `json:"vnfnics"`
+ Vnfnics []*VnfNic `json:"vnfnics"`
Zoneid string `json:"zoneid"`
Zonename string `json:"zonename"`
}
diff --git a/cloudstack/NicService.go b/cloudstack/NicService.go
index eee7d36..0aa4017 100644
--- a/cloudstack/NicService.go
+++ b/cloudstack/NicService.go
@@ -696,7 +696,7 @@ type UpdateVmNicIpResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
diff --git a/cloudstack/SSHService.go b/cloudstack/SSHService.go
index 9c583d8..edcccdb 100644
--- a/cloudstack/SSHService.go
+++ b/cloudstack/SSHService.go
@@ -1246,7 +1246,7 @@ type ResetSSHKeyForVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
diff --git a/cloudstack/SnapshotService.go b/cloudstack/SnapshotService.go
index 6f497b9..6add410 100644
--- a/cloudstack/SnapshotService.go
+++ b/cloudstack/SnapshotService.go
@@ -3862,7 +3862,7 @@ type RevertToVMSnapshotResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
diff --git a/cloudstack/VirtualMachineService.go
b/cloudstack/VirtualMachineService.go
index 4f9bab6..f0c7784 100644
--- a/cloudstack/VirtualMachineService.go
+++ b/cloudstack/VirtualMachineService.go
@@ -398,7 +398,7 @@ type AddNicToVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -762,7 +762,7 @@ type AssignVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -1156,7 +1156,7 @@ type ChangeServiceForVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -2956,7 +2956,7 @@ type DeployVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -3268,7 +3268,7 @@ type DestroyVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -4821,7 +4821,7 @@ type VirtualMachine struct {
Videoram int64 `json:"videoram"`
Vmtype string `json:"vmtype"`
Vnfdetails map[string]string `json:"vnfdetails"`
- Vnfnics []string `json:"vnfnics"`
+ Vnfnics []*VnfNic `json:"vnfnics"`
Zoneid string `json:"zoneid"`
Zonename string `json:"zonename"`
}
@@ -6233,7 +6233,7 @@ type VirtualMachinesMetric struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -6842,7 +6842,7 @@ type MigrateVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -7196,7 +7196,7 @@ type MigrateVirtualMachineWithVolumeResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -7508,7 +7508,7 @@ type RebootVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -7750,7 +7750,7 @@ type RecoverVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -8037,7 +8037,7 @@ type RemoveNicFromVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -8323,7 +8323,7 @@ type ResetPasswordForVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -8712,7 +8712,7 @@ type ResetUserDataForVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -9099,7 +9099,7 @@ type RestoreVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -9741,7 +9741,7 @@ type StartVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -10028,7 +10028,7 @@ type StopVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -10315,7 +10315,7 @@ type UpdateDefaultNicForVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -11094,7 +11094,7 @@ type UpdateVirtualMachineResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -12667,7 +12667,7 @@ type ImportVmResponse struct {
Videoram int64 `json:"videoram"`
Vmtype string `json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string `json:"vnfnics"`
+ Vnfnics []*VnfNic `json:"vnfnics"`
Zoneid string `json:"zoneid"`
Zonename string `json:"zonename"`
}
@@ -13621,7 +13621,7 @@ type ImportUnmanagedInstanceResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
diff --git a/cloudstack/VirtualNetworkFunctionsService.go
b/cloudstack/VirtualNetworkFunctionsService.go
index 79313e2..7f078b6 100644
--- a/cloudstack/VirtualNetworkFunctionsService.go
+++ b/cloudstack/VirtualNetworkFunctionsService.go
@@ -1871,7 +1871,7 @@ type DeployVnfApplianceResponse struct {
Videoram int64
`json:"videoram"`
Vmtype string
`json:"vmtype"`
Vnfdetails map[string]string
`json:"vnfdetails"`
- Vnfnics []string
`json:"vnfnics"`
+ Vnfnics []*VnfNic
`json:"vnfnics"`
Zoneid string
`json:"zoneid"`
Zonename string
`json:"zonename"`
}
@@ -3070,9 +3070,19 @@ func (s *VirtualNetworkFunctionsService)
ListVnfAppliances(p *ListVnfAppliancesP
return &r, nil
}
+type VnfNic struct {
+ Deviceid int64 `json:"deviceid"`
+ Description string `json:"description"`
+ Management bool `json:"management"`
+ Name string `json:"name"`
+ Networkid string `json:"networkid"`
+ Networkname string `json:"networkname"`
+ Required bool `json:"required"`
+}
+
type ListVnfAppliancesResponse struct {
Count int `json:"count"`
- VnfAppliances []*VnfAppliance `json:"vnfappliance"`
+ VnfAppliances []*VnfAppliance `json:"virtualmachine"`
}
type VnfAppliance struct {
@@ -3180,7 +3190,7 @@ type VnfAppliance struct {
Videoram int64 `json:"videoram"`
Vmtype string `json:"vmtype"`
Vnfdetails map[string]string `json:"vnfdetails"`
- Vnfnics []string `json:"vnfnics"`
+ Vnfnics []*VnfNic `json:"vnfnics"`
Zoneid string `json:"zoneid"`
Zonename string `json:"zonename"`
}
@@ -4044,7 +4054,7 @@ func (s *VirtualNetworkFunctionsService)
ListVnfTemplates(p *ListVnfTemplatesPar
type ListVnfTemplatesResponse struct {
Count int `json:"count"`
- VnfTemplates []*VnfTemplate `json:"vnftemplate"`
+ VnfTemplates []*VnfTemplate `json:"template"`
}
type VnfTemplate struct {
diff --git a/generate/generate.go b/generate/generate.go
index 3eb6567..c2d1bac 100644
--- a/generate/generate.go
+++ b/generate/generate.go
@@ -2048,6 +2048,20 @@ func (s *service) generateResponseType(a *API) {
pn("")
return
}
+ if a.Name == "listVnfAppliances" {
+ // The API docs do not describe the shape of the "vnfnics"
field, so this
+ // type is hand maintained to mirror
org.apache.cloudstack.api.response.VnfNicResponse.
+ pn("type VnfNic struct {")
+ pn(" Deviceid int64 `json:\"deviceid\"`")
+ pn(" Description string `json:\"description\"`")
+ pn(" Management bool `json:\"management\"`")
+ pn(" Name string `json:\"name\"`")
+ pn(" Networkid string `json:\"networkid\"`")
+ pn(" Networkname string `json:\"networkname\"`")
+ pn(" Required bool `json:\"required\"`")
+ pn("}")
+ pn("")
+ }
ln := capitalize(strings.TrimPrefix(a.Name, "list"))
@@ -2156,6 +2170,16 @@ func (s *service) generateResponseType(a *API) {
case "listLBStickinessPolicies":
pn(" Count int `json:\"count\"`")
pn(" %s []*%s `json:\"%s\"`", ln, parseSingular(ln),
"stickinesspolicies")
+ case "listVnfTemplates":
+ // ListVnfTemplatesCmd is an empty subclass of
ListTemplatesCmd, so the
+ // server returns the items under "template", not
"vnftemplate".
+ pn(" Count int `json:\"count\"`")
+ pn(" %s []*%s `json:\"%s\"`", ln, parseSingular(ln),
"template")
+ case "listVnfAppliances":
+ // ListVnfAppliancesCmd inherits execute() from
ListVMsCmd, so the server
+ // returns the items under "virtualmachine", not
"vnfappliance".
+ pn(" Count int `json:\"count\"`")
+ pn(" %s []*%s `json:\"%s\"`", ln, parseSingular(ln),
"virtualmachine")
default:
pn(" Count int `json:\"count\"`")
pn(" %s []*%s `json:\"%s\"`", ln, parseSingular(ln),
strings.ToLower(parseSingular(ln)))
@@ -2451,6 +2475,9 @@ func mapType(aName string, pName string, pType string)
string {
if pName == "scaledownpolicies" || pName == "scaleuppolicies" {
return "[]*AutoScalePolicy"
}
+ if pName == "vnfnics" {
+ return "[]*VnfNic"
+ }
return "[]string"
case "map":
if mapRequireList[aName] != nil && mapRequireList[aName][pName]
{