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 } }