Skip to content

Commit 887a28c

Browse files
authored
[CWS] allow to set variable in cli eval (#37653)
1 parent 24f3536 commit 887a28c

File tree

1 file changed

+101
-26
lines changed

1 file changed

+101
-26
lines changed

pkg/security/clihelpers/eval.go

Lines changed: 101 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ type EvalReport struct {
3636
Error error `json:",omitempty"`
3737
}
3838

39-
// EventData defines the structure used to represent an event
40-
type EventData struct {
41-
Type eval.EventType
42-
Values map[string]interface{}
39+
// TestData defines the structure used to represent an event and its variables
40+
type TestData struct {
41+
Type eval.EventType
42+
Values map[string]any
43+
Variables map[string]any
4344
}
4445

4546
// EvalRuleParams are parameters to the EvalRule function
@@ -54,11 +55,16 @@ type EvalRuleParams struct {
5455
func EvalRule(evalArgs EvalRuleParams) error {
5556
policiesDir := evalArgs.Dir
5657

58+
event, variables, err := dataFromJSON(evalArgs.EventFile)
59+
if err != nil {
60+
return err
61+
}
62+
5763
// enabled all the rules
5864
enabled := map[eval.EventType]bool{"*": true}
5965

6066
ruleOpts := rules.NewRuleOpts(enabled)
61-
evalOpts := newEvalOpts(evalArgs.UseWindowsModel)
67+
evalOpts := newEvalOpts(evalArgs.UseWindowsModel).WithVariables(variables)
6268
ruleOpts.WithLogger(seclog.DefaultLogger)
6369

6470
agentVersionFilter, err := newAgentVersionFilter()
@@ -95,11 +101,6 @@ func EvalRule(evalArgs EvalRuleParams) error {
95101
return err
96102
}
97103

98-
event, err := eventDataFromJSON(evalArgs.EventFile)
99-
if err != nil {
100-
return err
101-
}
102-
103104
report := EvalReport{
104105
Event: event,
105106
}
@@ -127,22 +128,9 @@ func EvalRule(evalArgs EvalRuleParams) error {
127128
return nil
128129
}
129130

130-
func eventDataFromJSON(file string) (eval.Event, error) {
131-
f, err := os.Open(file)
132-
if err != nil {
133-
return nil, err
134-
}
135-
defer f.Close()
136-
137-
decoder := json.NewDecoder(f)
138-
decoder.UseNumber()
131+
func eventFromTestData(testData TestData) (eval.Event, error) {
139132

140-
var eventData EventData
141-
if err := decoder.Decode(&eventData); err != nil {
142-
return nil, err
143-
}
144-
145-
kind := secconfig.ParseEvalEventType(eventData.Type)
133+
kind := secconfig.ParseEvalEventType(testData.Type)
146134
if kind == model.UnknownEventType {
147135
return nil, errors.New("unknown event type")
148136
}
@@ -156,7 +144,7 @@ func eventDataFromJSON(file string) (eval.Event, error) {
156144
}
157145
event.Init()
158146

159-
for k, v := range eventData.Values {
147+
for k, v := range testData.Values {
160148
switch v := v.(type) {
161149
case json.Number:
162150
value, err := v.Int64()
@@ -186,6 +174,93 @@ func eventDataFromJSON(file string) (eval.Event, error) {
186174
return event, nil
187175
}
188176

177+
func variablesFromTestData(testData TestData) (map[string]eval.SECLVariable, error) {
178+
variables := make(map[string]eval.SECLVariable)
179+
180+
// copy the embedded variables
181+
for k, v := range model.SECLVariables {
182+
variables[k] = v
183+
}
184+
185+
for k, v := range testData.Variables {
186+
switch v := v.(type) {
187+
case string:
188+
variables[k] = eval.NewScopedStringVariable(func(_ *eval.Context) (string, bool) {
189+
return v, true
190+
}, nil)
191+
case []any:
192+
switch v[0].(type) {
193+
case string:
194+
values := make([]string, len(v))
195+
for i, value := range v {
196+
values[i] = value.(string)
197+
}
198+
variables[k] = eval.NewScopedStringArrayVariable(func(_ *eval.Context) ([]string, bool) {
199+
return values, true
200+
}, nil)
201+
case json.Number:
202+
values := make([]int, len(v))
203+
for i, value := range v {
204+
v64, err := value.(json.Number).Int64()
205+
if err != nil {
206+
return nil, fmt.Errorf("failed to convert %s to int: %w", v, err)
207+
}
208+
values[i] = int(v64)
209+
}
210+
variables[k] = eval.NewScopedIntArrayVariable(func(_ *eval.Context) ([]int, bool) {
211+
return values, true
212+
}, nil)
213+
default:
214+
return nil, fmt.Errorf("unknown variable type %s: %T", k, v)
215+
}
216+
case json.Number:
217+
value, err := v.Int64()
218+
if err != nil {
219+
return nil, fmt.Errorf("failed to convert %s to int: %w", v, err)
220+
}
221+
variables[k] = eval.NewScopedIntVariable(func(_ *eval.Context) (int, bool) {
222+
return int(value), true
223+
}, nil)
224+
case bool:
225+
variables[k] = eval.NewScopedBoolVariable(func(_ *eval.Context) (bool, bool) {
226+
return v, true
227+
}, nil)
228+
default:
229+
return nil, fmt.Errorf("unknown variable type %s: %T", k, v)
230+
}
231+
}
232+
233+
return variables, nil
234+
}
235+
236+
func dataFromJSON(file string) (eval.Event, map[string]eval.SECLVariable, error) {
237+
f, err := os.Open(file)
238+
if err != nil {
239+
return nil, nil, err
240+
}
241+
defer f.Close()
242+
243+
decoder := json.NewDecoder(f)
244+
decoder.UseNumber()
245+
246+
var testData TestData
247+
if err := decoder.Decode(&testData); err != nil {
248+
return nil, nil, err
249+
}
250+
251+
event, err := eventFromTestData(testData)
252+
if err != nil {
253+
return nil, nil, err
254+
}
255+
256+
variables, err := variablesFromTestData(testData)
257+
if err != nil {
258+
return nil, nil, err
259+
}
260+
261+
return event, variables, nil
262+
}
263+
189264
func anySliceToStringSlice(in []any) ([]string, bool) {
190265
out := make([]string, len(in))
191266
for i, v := range in {

0 commit comments

Comments
 (0)