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 <abhishek.mr...@gmail.com>
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 <abhishek.mr...@gmail.com>
---
 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
                }
        }

Reply via email to