1
- package cel
1
+ package constraints
2
2
3
3
import (
4
4
"fmt"
@@ -16,6 +16,7 @@ import (
16
16
// PropertiesKey is the key for bundle properties map (input data for CEL evaluation)
17
17
const PropertiesKey = "properties"
18
18
19
+ // Constraint is a struct representing the new generic constraint type
19
20
type Constraint struct {
20
21
// Constraint message that surfaces in resolution
21
22
// This field is optional
@@ -26,37 +27,38 @@ type Constraint struct {
26
27
Cel * Cel `json:"cel" yaml:"cel"`
27
28
}
28
29
30
+ // Cel is a struct representing CEL expression information
29
31
type Cel struct {
30
32
// The CEL expression
31
33
Rule string `json:"rule" yaml:"rule"`
32
34
}
33
35
34
- type Evaluator interface {
35
- Evaluate (env map [string ]interface {}) (bool , error )
36
- }
37
-
38
- type EvaluatorProvider interface {
39
- Evaluator (rule string ) (Evaluator , error )
40
- }
41
-
42
- func NewCelEvaluatorProvider () * celEvaluatorProvider {
36
+ // NewCelEnvironment returns a CEL environment which can be used to
37
+ // evaluate CEL expression and an error if occurs
38
+ func NewCelEnvironment () * CelEnvironment {
43
39
env , err := cel .NewEnv (cel .Declarations (
44
40
decls .NewVar (PropertiesKey , decls .NewListType (decls .NewMapType (decls .String , decls .Any )))),
45
41
cel .Lib (semverLib {}),
46
42
)
43
+ // If an error occurs here, it means the CEL enviroment is unable to load
44
+ // configuration for custom libraries propertly. Hence, the CEL enviroment is
45
+ // unusable. Panic here will cause the program to fail immediately to prevent
46
+ // cascading failures later on when this CEL env is in use.
47
47
if err != nil {
48
48
panic (err )
49
49
}
50
- return & celEvaluatorProvider {
50
+ return & CelEnvironment {
51
51
env : env ,
52
52
}
53
53
}
54
54
55
- type celEvaluatorProvider struct {
55
+ // CelEnvironment is a struct that encapsulates CEL custom program enviroment
56
+ type CelEnvironment struct {
56
57
env * cel.Env
57
58
}
58
59
59
- type celEvaluator struct {
60
+ // CelProgram is a struct that encapsulates compiled CEL program
61
+ type CelProgram struct {
60
62
program cel.Program
61
63
}
62
64
@@ -110,8 +112,9 @@ func semverCompare(val1, val2 ref.Val) ref.Val {
110
112
return types .Int (v1 .Compare (v2 ))
111
113
}
112
114
113
- func (e celEvaluator ) Evaluate (env map [string ]interface {}) (bool , error ) {
114
- result , _ , err := e .program .Eval (env )
115
+ // Evaluate to evaluate the compiled CEL program against input data (map)
116
+ func (e CelProgram ) Evaluate (data map [string ]interface {}) (bool , error ) {
117
+ result , _ , err := e .program .Eval (data )
115
118
if err != nil {
116
119
return false , err
117
120
}
@@ -123,19 +126,21 @@ func (e celEvaluator) Evaluate(env map[string]interface{}) (bool, error) {
123
126
return false , fmt .Errorf ("cel expression evalutated to %T, not bool" , result .Value ())
124
127
}
125
128
126
- func (e * celEvaluatorProvider ) Evaluator (rule string ) (Evaluator , error ) {
129
+ // Validate to validate the CEL expression string by compiling it into CEL program
130
+ func (e * CelEnvironment ) Validate (rule string ) (CelProgram , error ) {
131
+ var celProg CelProgram
127
132
ast , issues := e .env .Compile (rule )
128
133
if err := issues .Err (); err != nil {
129
- return nil , err
134
+ return celProg , err
130
135
}
131
136
132
137
if ast .ResultType () != decls .Bool {
133
- return nil , fmt .Errorf ("cel expressions must have type Bool" )
138
+ return celProg , fmt .Errorf ("cel expressions must have type Bool" )
134
139
}
135
140
136
141
prog , err := e .env .Program (ast )
137
142
if err != nil {
138
- return nil , err
143
+ return celProg , err
139
144
}
140
- return celEvaluator {program : prog }, nil
145
+ return CelProgram {program : prog }, nil
141
146
}
0 commit comments