-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
embed.go
108 lines (92 loc) · 2.46 KB
/
embed.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package rego
import (
"context"
"io/fs"
"path/filepath"
"strings"
"github.com/open-policy-agent/opa/ast"
checks "github.com/aquasecurity/trivy-checks"
"github.com/aquasecurity/trivy/pkg/iac/rules"
)
func init() {
modules, err := LoadEmbeddedPolicies()
if err != nil {
// we should panic as the policies were not embedded properly
panic(err)
}
loadedLibs, err := LoadEmbeddedLibraries()
if err != nil {
panic(err)
}
for name, policy := range loadedLibs {
modules[name] = policy
}
RegisterRegoRules(modules)
}
func RegisterRegoRules(modules map[string]*ast.Module) {
ctx := context.TODO()
schemaSet, _, _ := BuildSchemaSetFromPolicies(modules, nil, nil)
compiler := ast.NewCompiler().
WithSchemas(schemaSet).
WithCapabilities(nil).
WithUseTypeCheckAnnotations(true)
compiler.Compile(modules)
if compiler.Failed() {
// we should panic as the embedded rego policies are syntactically incorrect...
panic(compiler.Errors)
}
retriever := NewMetadataRetriever(compiler)
for _, module := range modules {
metadata, err := retriever.RetrieveMetadata(ctx, module)
if err != nil {
continue
}
if metadata.AVDID == "" {
continue
}
rules.Register(
metadata.ToRule(),
)
}
}
func LoadEmbeddedPolicies() (map[string]*ast.Module, error) {
return LoadPoliciesFromDirs(checks.EmbeddedPolicyFileSystem, ".")
}
func LoadEmbeddedLibraries() (map[string]*ast.Module, error) {
return LoadPoliciesFromDirs(checks.EmbeddedLibraryFileSystem, ".")
}
func LoadPoliciesFromDirs(target fs.FS, paths ...string) (map[string]*ast.Module, error) {
modules := make(map[string]*ast.Module)
for _, path := range paths {
if err := fs.WalkDir(target, sanitisePath(path), func(path string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if strings.HasSuffix(filepath.Dir(filepath.ToSlash(path)), filepath.Join("advanced", "optional")) {
return fs.SkipDir
}
if !IsRegoFile(info.Name()) || IsDotFile(info.Name()) {
return nil
}
data, err := fs.ReadFile(target, filepath.ToSlash(path))
if err != nil {
return err
}
module, err := ast.ParseModuleWithOpts(path, string(data), ast.ParserOptions{
ProcessAnnotation: true,
})
if err != nil {
// s.debug.Log("Failed to load module: %s, err: %s", filepath.ToSlash(path), err.Error())
return err
}
modules[path] = module
return nil
}); err != nil {
return nil, err
}
}
return modules, nil
}