/
filter_engine.go
64 lines (52 loc) · 1.54 KB
/
filter_engine.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package filter
import (
"errors"
"github.com/jmespath/go-jmespath"
"github.com/snyk/driftctl/enumeration/resource"
)
type FilterEngine struct {
expr *jmespath.JMESPath
}
func NewFilterEngine(expr *jmespath.JMESPath) *FilterEngine {
return &FilterEngine{expr: expr}
}
type filtrableResource struct {
Attr interface{}
Res *resource.Resource
Type, Id string
}
func (e *FilterEngine) Run(resources []*resource.Resource) ([]*resource.Resource, error) {
if e.expr == nil {
return nil, errors.New("expression is nil")
}
// We convert a list of resource in a list of DTO to run JMESPath on
filtrableResources := make([]filtrableResource, 0, len(resources))
for _, res := range resources {
// We need to serialize all attributes to untyped interface from JMESPath to work
// map[string]string and map[string]SomeThing will not work without it
// https://github.com/jmespath/go-jmespath/issues/22
var attrs map[string]interface{} = *res.Attributes()
f := filtrableResource{
Attr: attrs,
Res: res,
Id: res.ResourceId(),
Type: res.ResourceType(),
}
filtrableResources = append(
filtrableResources,
f,
)
}
// Do the filter
JMESPathOutput, err := e.expr.Search(filtrableResources)
if err != nil {
return nil, err
}
// Convert back filtered results into a resource list
filteredRawList := JMESPathOutput.([]interface{})
results := make([]*resource.Resource, 0, len(filteredRawList))
for _, elem := range filteredRawList {
results = append(results, elem.(filtrableResource).Res)
}
return results, nil
}