-
Notifications
You must be signed in to change notification settings - Fork 351
/
evaluation.go
86 lines (70 loc) · 2.52 KB
/
evaluation.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
package openpolicyagent
import (
"context"
"fmt"
"time"
ext_authz_v3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
"github.com/open-policy-agent/opa-envoy-plugin/envoyauth"
"github.com/open-policy-agent/opa-envoy-plugin/opa/decisionlog"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/server"
"github.com/open-policy-agent/opa/tracing"
"github.com/opentracing/opentracing-go"
)
func (opa *OpenPolicyAgentInstance) Eval(ctx context.Context, req *ext_authz_v3.CheckRequest) (*envoyauth.EvalResult, error) {
decisionId, err := opa.idGenerator.Generate()
if err != nil {
opa.Logger().WithFields(map[string]interface{}{"err": err}).Error("Unable to generate decision ID.")
return nil, err
}
result, stopeval, err := envoyauth.NewEvalResult(withDecisionID(decisionId))
if err != nil {
opa.Logger().WithFields(map[string]interface{}{"err": err}).Error("Unable to generate new result with decision ID.")
return nil, err
}
span := opentracing.SpanFromContext(ctx)
if span != nil {
span.SetTag("opa.decision_id", result.DecisionID)
}
var input map[string]interface{}
defer func() {
stopeval()
err := opa.logDecision(ctx, input, result, err)
if err != nil {
opa.Logger().WithFields(map[string]interface{}{"err": err}).Error("Unable to log decision to control plane.")
}
}()
if ctx.Err() != nil {
return nil, fmt.Errorf("check request timed out before query execution: %w", ctx.Err())
}
logger := opa.manager.Logger().WithFields(map[string]interface{}{"decision-id": result.DecisionID})
input, err = envoyauth.RequestToInput(req, logger, nil, opa.EnvoyPluginConfig().SkipRequestBodyParse)
if err != nil {
return nil, fmt.Errorf("failed to convert request to input: %w", err)
}
inputValue, err := ast.InterfaceToValue(input)
if err != nil {
return nil, err
}
err = envoyauth.Eval(ctx, opa, inputValue, result, rego.DistributedTracingOpts(tracing.Options{opa}))
if err != nil {
return nil, err
}
return result, nil
}
func (opa *OpenPolicyAgentInstance) logDecision(ctx context.Context, input interface{}, result *envoyauth.EvalResult, err error) error {
info := &server.Info{
Timestamp: time.Now(),
Input: &input,
}
if opa.EnvoyPluginConfig().Path != "" {
info.Path = opa.EnvoyPluginConfig().Path
}
return decisionlog.LogDecision(ctx, opa.manager, info, result, err)
}
func withDecisionID(decisionID string) func(*envoyauth.EvalResult) {
return func(result *envoyauth.EvalResult) {
result.DecisionID = decisionID
}
}