Skip to content

Commit 3c8285a

Browse files
committed
cmd: get comma-separated resource types
1 parent c79380d commit 3c8285a

1 file changed

Lines changed: 85 additions & 60 deletions

File tree

cmd/cli/get.go

Lines changed: 85 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"log"
99
"net/url"
10+
"strings"
1011

1112
cs "github.com/apache/cloudstack-go/v2/cloudstack"
1213

@@ -20,87 +21,111 @@ var getCmd = &cobra.Command{
2021
Long: `List resources managed by cloudstackctl (Application/Component/VirtualMachine/Network/Volume/etc.)`,
2122
Run: func(cmd *cobra.Command, args []string) {
2223
if len(args) < 1 {
23-
log.Fatal("Usage: cloudstackctl get <resource-type> [name]")
24+
log.Fatal("Usage: cloudstackctl get <resource-type>[,...] [name]")
25+
}
26+
27+
// Support comma-separated resource types: e.g. "apps,comps,vms"
28+
rawKinds := strings.Split(args[0], ",")
29+
kinds := make([]string, 0, len(rawKinds))
30+
for _, k := range rawKinds {
31+
kinds = append(kinds, normalizeResourceType(k))
2432
}
2533

26-
resourceType := normalizeResourceType(args[0])
2734
name := ""
2835
if len(args) > 1 {
2936
name = args[1]
3037
}
3138

32-
// Standalone: call local handler wrapper
39+
// Standalone: call local handler wrapper. If any requested kind is
40+
// managed by the controller, fail in standalone mode.
3341
if standalone {
34-
if resourceType == "Application" || resourceType == "Component" || resourceType == "VirtualMachineSpec" {
35-
log.Fatalf("'%s' is not supported in standalone mode", resourceType)
36-
}
37-
38-
payload := map[string]string{"kind": resourceType}
39-
if name != "" {
40-
payload["name"] = name
42+
for _, resourceType := range kinds {
43+
if resourceType == "Application" || resourceType == "Component" || resourceType == "VirtualMachineSpec" {
44+
log.Fatalf("'%s' is not supported in standalone mode", resourceType)
45+
}
4146
}
42-
raw, _ := json.Marshal(payload)
43-
if resp, err := handlers.GetCloudStackResource(raw); err != nil {
44-
log.Fatalf("Local get failed: %v", err)
45-
} else {
46-
handlers.PrintCloudStackResource(resourceType, resp)
47+
for i, resourceType := range kinds {
48+
payload := map[string]string{"kind": resourceType}
49+
if name != "" {
50+
payload["name"] = name
51+
}
52+
raw, _ := json.Marshal(payload)
53+
if resp, err := handlers.GetCloudStackResource(raw); err != nil {
54+
log.Fatalf("Local get failed: %v", err)
55+
} else {
56+
if i > 0 {
57+
fmt.Printf("\n")
58+
}
59+
handlers.PrintCloudStackResource(resourceType, resp)
60+
}
4761
}
4862
return
4963
}
5064

51-
// Cluster mode: forward to controller HTTP API (/list)
52-
var endpoint = "/list"
53-
q := url.Values{}
54-
if getAll && resourceType == "VirtualMachine" {
55-
q.Set("all", "true")
56-
}
57-
q.Set("kind", resourceType)
58-
if name != "" {
59-
q.Set("name", name)
60-
}
61-
path := endpoint + "?" + q.Encode()
62-
body, err := ControllerRequest("GET", path, nil)
63-
if err != nil {
64-
log.Fatalf("Failed to query controller: %v", err)
65-
}
65+
// Controller mode: query controller for each requested kind and print
66+
// results sequentially with simple headers.
67+
for i, resourceType := range kinds {
68+
var endpoint = "/list"
69+
q := url.Values{}
70+
if getAll && resourceType == "VirtualMachine" {
71+
q.Set("all", "true")
72+
}
73+
q.Set("kind", resourceType)
74+
if name != "" {
75+
q.Set("name", name)
76+
}
77+
path := endpoint + "?" + q.Encode()
78+
body, err := ControllerRequest("GET", path, nil)
79+
if err != nil {
80+
log.Fatalf("Failed to query controller for %s: %v", resourceType, err)
81+
}
6682

67-
// If controller returned VM objects from DB, pretty-print them
68-
if resourceType == "VirtualMachine" && !getAll {
69-
var vms []v1.VirtualMachine
70-
if err := json.Unmarshal(body, &vms); err == nil {
71-
handlers.PrintVMsFromController(vms)
72-
return
83+
if i > 0 {
84+
fmt.Printf("\n")
7385
}
74-
}
7586

76-
if tryDecodeAndPrint(resourceType, body) {
77-
return
78-
}
87+
// If controller returned VM objects from DB, pretty-print them
88+
if resourceType == "VirtualMachine" && !getAll {
89+
var vms []v1.VirtualMachine
90+
if err := json.Unmarshal(body, &vms); err == nil {
91+
handlers.PrintVMsFromController(vms)
92+
continue
93+
}
94+
}
7995

80-
// Controller may return DB-backed resources; print them in-table when possible
81-
switch resourceType {
82-
case "Component":
83-
var comps []v1.Component
84-
if err := json.Unmarshal(body, &comps); err == nil {
85-
handlers.PrintComponents(comps)
86-
return
96+
if tryDecodeAndPrint(resourceType, body) {
97+
continue
8798
}
88-
case "VirtualMachineSpec":
89-
var specs []v1.VirtualMachineSpecResource
90-
if err := json.Unmarshal(body, &specs); err == nil {
91-
handlers.PrintVMSpecs(specs)
92-
return
99+
100+
// Controller may return DB-backed resources; print them in-table when possible
101+
handled := false
102+
switch resourceType {
103+
case "Component":
104+
var comps []v1.Component
105+
if err := json.Unmarshal(body, &comps); err == nil {
106+
handlers.PrintComponents(comps)
107+
handled = true
108+
}
109+
case "VirtualMachineSpec":
110+
var specs []v1.VirtualMachineSpecResource
111+
if err := json.Unmarshal(body, &specs); err == nil {
112+
handlers.PrintVMSpecs(specs)
113+
handled = true
114+
}
115+
case "Application":
116+
var apps []v1.Application
117+
if err := json.Unmarshal(body, &apps); err == nil {
118+
handlers.PrintApplications(apps)
119+
handled = true
120+
}
93121
}
94-
case "Application":
95-
var apps []v1.Application
96-
if err := json.Unmarshal(body, &apps); err == nil {
97-
handlers.PrintApplications(apps)
98-
return
122+
if handled {
123+
continue
99124
}
100-
}
101125

102-
// Fallback: print raw body
103-
fmt.Println(string(body))
126+
// Fallback: print raw body
127+
fmt.Println(string(body))
128+
}
104129
},
105130
}
106131

0 commit comments

Comments
 (0)