Skip to content

Commit aaf4539

Browse files
committed
merge
Signed-off-by: Abhishek Kumar <[email protected]>
1 parent a6ee865 commit aaf4539

File tree

5 files changed

+93
-42
lines changed

5 files changed

+93
-42
lines changed

cli/completer.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ func (t *autoCompleter) Do(line []rune, pos int) (options [][]rune, offset int)
357357
}
358358
return
359359
}
360+
360361
if arg.Type == config.FAKE && arg.Name == "filter=" {
361362
offset = 0
362363
filterInputs := strings.Split(strings.Replace(argInput, ",", ",|", -1), "|")
@@ -373,6 +374,22 @@ func (t *autoCompleter) Do(line []rune, pos int) (options [][]rune, offset int)
373374
return
374375
}
375376

377+
if arg.Type == config.FAKE && arg.Name == "exclude=" {
378+
offset = 0
379+
excludeFilterInputs := strings.Split(strings.Replace(argInput, ",", ",|", -1), "|")
380+
lastExcludeFilterInput := lastString(excludeFilterInputs)
381+
for _, key := range apiFound.ResponseKeys {
382+
if inArray(key, excludeFilterInputs) {
383+
continue
384+
}
385+
if strings.HasPrefix(key, lastExcludeFilterInput) {
386+
options = append(options, []rune(key[len(lastExcludeFilterInput):]))
387+
offset = len(lastExcludeFilterInput)
388+
}
389+
}
390+
return
391+
}
392+
376393
autocompleteAPI := findAutocompleteAPI(arg, apiFound, apiMap)
377394
if autocompleteAPI == nil {
378395
return nil, 0

cmd/api.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func init() {
8282
if strings.HasSuffix(err.Error(), "context canceled") {
8383
return nil
8484
} else if response != nil {
85-
printResult(r.Config.Core.Output, response, nil)
85+
printResult(r.Config.Core.Output, response, nil, nil)
8686
}
8787
return err
8888
}
@@ -98,8 +98,19 @@ func init() {
9898
}
9999
}
100100

101+
var excludeKeys []string
102+
for _, arg := range apiArgs {
103+
if strings.HasPrefix(arg, "exclude=") {
104+
for _, excludeKey := range strings.Split(strings.Split(arg, "=")[1], ",") {
105+
if len(strings.TrimSpace(excludeKey)) > 0 {
106+
excludeKeys = append(excludeKeys, strings.TrimSpace(excludeKey))
107+
}
108+
}
109+
}
110+
}
111+
101112
if len(response) > 0 {
102-
printResult(r.Config.Core.Output, response, filterKeys)
113+
printResult(r.Config.Core.Output, response, filterKeys, excludeKeys)
103114
}
104115

105116
return nil

cmd/network.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func NewAPIRequest(r *Request, api string, args []string, isAsync bool) (map[str
216216
expiresKey := "expires"
217217
params.Add("response", "json")
218218
params.Add("signatureversion", signatureversion)
219-
params.Add(expiresKey, time.Now().UTC().Add(15 * time.Minute).Format(time.RFC3339))
219+
params.Add(expiresKey, time.Now().UTC().Add(15*time.Minute).Format(time.RFC3339))
220220

221221
var encodedParams string
222222
var err error

cmd/output.go

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ func printJSON(response map[string]interface{}) {
6262
enc.Encode(response)
6363
}
6464

65+
func getItemsFromValue(v interface{}) ([]interface{}, bool) {
66+
valueType := reflect.TypeOf(v)
67+
if valueType.Kind() == reflect.Slice {
68+
sliceItems, ok := v.([]interface{})
69+
if !ok {
70+
return nil, false
71+
}
72+
return sliceItems, true
73+
} else if valueType.Kind() == reflect.Map {
74+
mapItem, ok := v.(map[string]interface{})
75+
if !ok {
76+
return nil, false
77+
}
78+
return []interface{}{mapItem}, true
79+
}
80+
return nil, false
81+
}
82+
6583
func printText(response map[string]interface{}) {
6684
format := "text"
6785
for k, v := range response {
@@ -209,72 +227,70 @@ func printCsv(response map[string]interface{}, filter []string) {
209227
enc.Flush()
210228
}
211229

212-
func getItemsFromValue(v interface{}) ([]interface{}, bool) {
213-
valueType := reflect.TypeOf(v)
214-
if valueType.Kind() == reflect.Slice {
215-
sliceItems, ok := v.([]interface{})
216-
if !ok {
217-
return nil, false
218-
}
219-
return sliceItems, true
220-
} else if valueType.Kind() == reflect.Map {
221-
mapItem, ok := v.(map[string]interface{})
222-
if !ok {
223-
return nil, false
224-
}
225-
return []interface{}{mapItem}, true
230+
func filterResponse(response map[string]interface{}, filter []string, excludeFilter []string, outputType string) map[string]interface{} {
231+
if len(filter) == 0 && len(excludeFilter) == 0 {
232+
return response
226233
}
227-
return nil, false
228-
}
229234

230-
func filterResponse(response map[string]interface{}, filter []string, outputType string) map[string]interface{} {
231-
config.Debug("Filtering response with filter:", filter, "and output type:", outputType)
232-
if len(filter) == 0 {
233-
return response
235+
excludeSet := make(map[string]struct{}, len(excludeFilter))
236+
for _, key := range excludeFilter {
237+
excludeSet[key] = struct{}{}
238+
}
239+
240+
filterSet := make(map[string]struct{}, len(filter))
241+
for _, key := range filter {
242+
filterSet[key] = struct{}{}
234243
}
244+
235245
filteredResponse := make(map[string]interface{})
236-
for k, v := range response {
237-
valueType := reflect.TypeOf(v)
246+
247+
for key, value := range response {
248+
valueType := reflect.TypeOf(value)
238249
if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
239-
items, ok := getItemsFromValue(v)
250+
items, ok := getItemsFromValue(value)
240251
if !ok {
241-
config.Debug("Skipping non-slice/map value for key:", k)
242252
continue
243253
}
244254
var filteredRows []interface{}
245255
for _, item := range items {
246256
row, ok := item.(map[string]interface{})
247-
if !ok || len(row) < 1 {
248-
config.Debug("Skipping non-map item for key:", k)
257+
if !ok || len(row) == 0 {
249258
continue
250259
}
260+
251261
filteredRow := make(map[string]interface{})
252-
for _, filterKey := range filter {
253-
for field := range row {
254-
if filterKey == field {
255-
filteredRow[field] = row[field]
262+
263+
if len(filter) > 0 {
264+
// Include only keys that exist in filterSet
265+
for filterKey := range filterSet {
266+
if val, exists := row[filterKey]; exists {
267+
filteredRow[filterKey] = val
268+
} else if outputType == config.COLUMN || outputType == config.CSV || outputType == config.TABLE {
269+
filteredRow[filterKey] = "" // Ensure all filter keys exist in row
256270
}
257271
}
258-
if outputType == config.COLUMN || outputType == config.CSV || outputType == config.TABLE {
259-
if _, ok := filteredRow[filterKey]; !ok {
260-
filteredRow[filterKey] = ""
272+
} else {
273+
// Exclude keys from excludeFilter
274+
for field, val := range row {
275+
if _, excluded := excludeSet[field]; !excluded {
276+
filteredRow[field] = val
261277
}
262278
}
263279
}
280+
264281
filteredRows = append(filteredRows, filteredRow)
265282
}
266-
filteredResponse[k] = filteredRows
283+
filteredResponse[key] = filteredRows
267284
} else {
268-
filteredResponse[k] = v
269-
continue
285+
filteredResponse[key] = value
270286
}
271-
272287
}
288+
273289
return filteredResponse
274290
}
275291

276-
func printResult(outputType string, response map[string]interface{}, filter []string) {
277-
response = filterResponse(response, filter, outputType)
292+
func printResult(outputType string, response map[string]interface{}, filter []string, excludeFilter []string) {
293+
response = filterResponse(response, filter, excludeFilter, outputType)
278294
switch outputType {
279295
case config.JSON:
280296
printJSON(response)

config/cache.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ func (c *Config) UpdateCache(response map[string]interface{}) interface{} {
151151
Description: "cloudmonkey specific response key filtering",
152152
})
153153

154+
// Add exclude arg
155+
apiArgs = append(apiArgs, &APIArg{
156+
Name: "exclude=",
157+
Type: FAKE,
158+
Description: "cloudmonkey specific response key to exlude when filtering",
159+
})
160+
154161
sort.Slice(apiArgs, func(i, j int) bool {
155162
return apiArgs[i].Name < apiArgs[j].Name
156163
})

0 commit comments

Comments
 (0)