This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack-cloudmonkey.git
The following commit(s) were added to refs/heads/main by this push:
new 94da963 output: allow filtering and honour output format for non-list
apis (#164)
94da963 is described below
commit 94da963cc8a14cc944d805a72f42fb689cec9949
Author: Abhishek Kumar <[email protected]>
AuthorDate: Fri Aug 8 19:22:30 2025 +0530
output: allow filtering and honour output format for non-list apis (#164)
Signed-off-by: Abhishek Kumar <[email protected]>
---
cmd/network.go | 11 ++++++++-
cmd/output.go | 70 +++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 57 insertions(+), 24 deletions(-)
diff --git a/cmd/network.go b/cmd/network.go
index 8665e81..c6d4d3e 100644
--- a/cmd/network.go
+++ b/cmd/network.go
@@ -157,7 +157,16 @@ func pollAsyncJob(r *Request, jobID string)
(map[string]interface{}, error) {
return nil, errors.New("async API job query timed out")
case <-ticker.C:
- queryResult, queryError := NewAPIRequest(r,
"queryAsyncJobResult", []string{"jobid=" + jobID}, false)
+ args := []string{"jobid=" + jobID}
+ if r.Args != nil {
+ for _, arg := range r.Args {
+ if
strings.HasPrefix(strings.ToLower(arg), "filter=") {
+ args = append(args, arg)
+ break
+ }
+ }
+ }
+ queryResult, queryError := NewAPIRequest(r,
"queryAsyncJobResult", args, false)
if queryError != nil {
return queryResult, queryError
}
diff --git a/cmd/output.go b/cmd/output.go
index 17606e6..d817d04 100644
--- a/cmd/output.go
+++ b/cmd/output.go
@@ -62,28 +62,49 @@ func printJSON(response map[string]interface{}) {
enc.Encode(response)
}
+func getItemsFromValue(v interface{}) ([]interface{}, bool) {
+ valueType := reflect.TypeOf(v)
+ if valueType.Kind() == reflect.Slice {
+ sliceItems, ok := v.([]interface{})
+ if !ok {
+ return nil, false
+ }
+ return sliceItems, true
+ } else if valueType.Kind() == reflect.Map {
+ mapItem, ok := v.(map[string]interface{})
+ if !ok {
+ return nil, false
+ }
+ return []interface{}{mapItem}, true
+ }
+ return nil, false
+}
+
func printText(response map[string]interface{}) {
format := "text"
for k, v := range response {
valueType := reflect.TypeOf(v)
- if valueType.Kind() == reflect.Slice {
- fmt.Printf("%v:\n", k)
- for idx, item := range v.([]interface{}) {
- if idx > 0 {
-
fmt.Println("================================================================================")
- }
- row, isMap := item.(map[string]interface{})
- if isMap {
- for field, value := range row {
- fmt.Printf("%s = %v\n", field,
jsonify(value, format))
+ if valueType.Kind() == reflect.Slice || valueType.Kind() ==
reflect.Map {
+ items, ok := getItemsFromValue(v)
+ if ok {
+ fmt.Printf("%v:\n", k)
+ for idx, item := range items {
+ if idx > 0 {
+
fmt.Println("================================================================================")
+ }
+ row, isMap :=
item.(map[string]interface{})
+ if isMap {
+ for field, value := range row {
+ fmt.Printf("%s = %v\n",
field, jsonify(value, format))
+ }
+ } else {
+ fmt.Printf("%v\n", item)
}
- } else {
- fmt.Printf("%v\n", item)
}
+ return
}
- } else {
- fmt.Printf("%v = %v\n", k, jsonify(v, format))
}
+ fmt.Printf("%v = %v\n", k, jsonify(v, format))
}
}
@@ -92,8 +113,8 @@ func printTable(response map[string]interface{}, filter
[]string) {
table := tablewriter.NewWriter(os.Stdout)
for k, v := range response {
valueType := reflect.TypeOf(v)
- if valueType.Kind() == reflect.Slice {
- items, ok := v.([]interface{})
+ if valueType.Kind() == reflect.Slice || valueType.Kind() ==
reflect.Map {
+ items, ok := getItemsFromValue(v)
if !ok {
continue
}
@@ -134,7 +155,7 @@ func printColumn(response map[string]interface{}, filter
[]string) {
for _, v := range response {
valueType := reflect.TypeOf(v)
if valueType.Kind() == reflect.Slice || valueType.Kind() ==
reflect.Map {
- items, ok := v.([]interface{})
+ items, ok := getItemsFromValue(v)
if !ok {
continue
}
@@ -173,7 +194,7 @@ func printCsv(response map[string]interface{}, filter
[]string) {
for _, v := range response {
valueType := reflect.TypeOf(v)
if valueType.Kind() == reflect.Slice || valueType.Kind() ==
reflect.Map {
- items, ok := v.([]interface{})
+ items, ok := getItemsFromValue(v)
if !ok {
continue
}
@@ -207,7 +228,7 @@ func printCsv(response map[string]interface{}, filter
[]string) {
}
func filterResponse(response map[string]interface{}, filter []string,
excludeFilter []string, outputType string) map[string]interface{} {
- if (filter == nil || len(filter) == 0) && (excludeFilter == nil ||
len(excludeFilter) == 0) {
+ if len(filter) == 0 && len(excludeFilter) == 0 {
return response
}
@@ -224,8 +245,12 @@ func filterResponse(response map[string]interface{},
filter []string, excludeFil
filteredResponse := make(map[string]interface{})
for key, value := range response {
- switch items := value.(type) {
- case []interface{}:
+ valueType := reflect.TypeOf(value)
+ if valueType.Kind() == reflect.Slice || valueType.Kind() ==
reflect.Map {
+ items, ok := getItemsFromValue(value)
+ if !ok {
+ continue
+ }
var filteredRows []interface{}
for _, item := range items {
row, ok := item.(map[string]interface{})
@@ -256,8 +281,7 @@ func filterResponse(response map[string]interface{}, filter
[]string, excludeFil
filteredRows = append(filteredRows, filteredRow)
}
filteredResponse[key] = filteredRows
-
- default:
+ } else {
filteredResponse[key] = value
}
}