-
Notifications
You must be signed in to change notification settings - Fork 2
/
compile.go
91 lines (74 loc) · 2.24 KB
/
compile.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
package runtime
import (
"context"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/metrics"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/server/types"
"github.com/open-policy-agent/opa/topdown"
"github.com/pkg/errors"
)
// Result contains the results of a Compile execution.
type CompileResult struct {
Result *interface{}
Metrics map[string]interface{}
Explanation types.TraceV1
}
func (r *Runtime) Compile(ctx context.Context, qStr string, input map[string]interface{}, unknowns []string, disableInlining []string,
pretty, includeMetrics, includeInstrumentation bool, explain types.ExplainModeV1) (*CompileResult, error) {
m := metrics.New()
m.Timer(metrics.ServerHandler).Start()
txn, err := r.storage.NewTransaction(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to create new OPA store transaction")
}
defer r.storage.Abort(ctx, txn)
var buf *topdown.BufferTracer
if explain != types.ExplainOffV1 {
buf = topdown.NewBufferTracer()
}
m.Timer(metrics.RegoQueryParse).Start()
parsedQuery, err := r.ValidateQuery(qStr)
if err != nil {
return nil, errors.Wrap(err, "failed to validate query")
}
m.Timer(metrics.RegoQueryParse).Stop()
eval := rego.New(
rego.Compiler(r.GetPluginsManager().GetCompiler()),
rego.Store(r.storage),
rego.Transaction(txn),
rego.ParsedQuery(parsedQuery),
rego.Input(input),
rego.Unknowns(unknowns),
rego.DisableInlining(disableInlining),
rego.QueryTracer(buf),
rego.Instrument(includeInstrumentation),
rego.Metrics(m),
rego.Runtime(r.pluginsManager.Info),
rego.UnsafeBuiltins(unsafeBuiltinsMap),
rego.InterQueryBuiltinCache(r.InterQueryCache),
)
pq, err := eval.Partial(ctx)
if err != nil {
switch err := err.(type) {
case ast.Errors:
return nil, errors.Wrap(err, "ast error")
default:
return nil, err
}
}
m.Timer(metrics.ServerHandler).Stop()
result := &CompileResult{}
if includeMetrics || includeInstrumentation {
result.Metrics = m.All()
}
if explain != types.ExplainOffV1 {
result.Explanation = r.getExplainResponse(explain, *buf, pretty)
}
var i interface{} = types.PartialEvaluationResultV1{
Queries: pq.Queries,
Support: pq.Support,
}
result.Result = &i
return result, nil
}