|
@@ -86,144 +86,147 @@ func (rt *sinkRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interfa
|
|
|
var stateMatch map[string]interface{}
|
|
|
var priority int
|
|
|
var statements *parser.ASTNode
|
|
|
- var err error
|
|
|
|
|
|
- // Create default scope
|
|
|
+ _, err := rt.baseRuntime.Eval(vs, is)
|
|
|
|
|
|
- scopeMatch = []string{}
|
|
|
+ if err == nil {
|
|
|
+ // Create default scope
|
|
|
+
|
|
|
+ scopeMatch = []string{}
|
|
|
|
|
|
- // Get the name of the sink
|
|
|
+ // Get the name of the sink
|
|
|
|
|
|
- name := rt.node.Children[0].Token.Val
|
|
|
+ name := rt.node.Children[0].Token.Val
|
|
|
|
|
|
- // Create helper function
|
|
|
+ // Create helper function
|
|
|
|
|
|
- makeStringList := func(child *parser.ASTNode) ([]string, error) {
|
|
|
- var ret []string
|
|
|
+ makeStringList := func(child *parser.ASTNode) ([]string, error) {
|
|
|
+ var ret []string
|
|
|
|
|
|
- val, err := child.Runtime.Eval(vs, is)
|
|
|
+ val, err := child.Runtime.Eval(vs, is)
|
|
|
|
|
|
- if err == nil {
|
|
|
- for _, v := range val.([]interface{}) {
|
|
|
- ret = append(ret, fmt.Sprint(v))
|
|
|
+ if err == nil {
|
|
|
+ for _, v := range val.([]interface{}) {
|
|
|
+ ret = append(ret, fmt.Sprint(v))
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return ret, err
|
|
|
- }
|
|
|
+ return ret, err
|
|
|
+ }
|
|
|
|
|
|
- // Collect values from children
|
|
|
+ // Collect values from children
|
|
|
|
|
|
- for _, child := range rt.node.Children[1:] {
|
|
|
+ for _, child := range rt.node.Children[1:] {
|
|
|
|
|
|
- switch child.Name {
|
|
|
+ switch child.Name {
|
|
|
|
|
|
- case parser.NodeKINDMATCH:
|
|
|
- kindMatch, err = makeStringList(child)
|
|
|
- break
|
|
|
+ case parser.NodeKINDMATCH:
|
|
|
+ kindMatch, err = makeStringList(child)
|
|
|
+ break
|
|
|
|
|
|
- case parser.NodeSCOPEMATCH:
|
|
|
- scopeMatch, err = makeStringList(child)
|
|
|
- break
|
|
|
+ case parser.NodeSCOPEMATCH:
|
|
|
+ scopeMatch, err = makeStringList(child)
|
|
|
+ break
|
|
|
|
|
|
- case parser.NodeSTATEMATCH:
|
|
|
- var val interface{}
|
|
|
- stateMatch = make(map[string]interface{})
|
|
|
+ case parser.NodeSTATEMATCH:
|
|
|
+ var val interface{}
|
|
|
+ stateMatch = make(map[string]interface{})
|
|
|
|
|
|
- if val, err = child.Runtime.Eval(vs, is); err == nil {
|
|
|
- for k, v := range val.(map[interface{}]interface{}) {
|
|
|
- stateMatch[fmt.Sprint(k)] = v
|
|
|
+ if val, err = child.Runtime.Eval(vs, is); err == nil {
|
|
|
+ for k, v := range val.(map[interface{}]interface{}) {
|
|
|
+ stateMatch[fmt.Sprint(k)] = v
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- break
|
|
|
+ break
|
|
|
|
|
|
- case parser.NodePRIORITY:
|
|
|
- var val interface{}
|
|
|
+ case parser.NodePRIORITY:
|
|
|
+ var val interface{}
|
|
|
|
|
|
- if val, err = child.Runtime.Eval(vs, is); err == nil {
|
|
|
- priority = int(math.Floor(val.(float64)))
|
|
|
- }
|
|
|
- break
|
|
|
+ if val, err = child.Runtime.Eval(vs, is); err == nil {
|
|
|
+ priority = int(math.Floor(val.(float64)))
|
|
|
+ }
|
|
|
+ break
|
|
|
|
|
|
- case parser.NodeSUPPRESSES:
|
|
|
- suppresses, err = makeStringList(child)
|
|
|
- break
|
|
|
+ case parser.NodeSUPPRESSES:
|
|
|
+ suppresses, err = makeStringList(child)
|
|
|
+ break
|
|
|
|
|
|
- case parser.NodeSTATEMENTS:
|
|
|
- statements = child
|
|
|
- break
|
|
|
- }
|
|
|
+ case parser.NodeSTATEMENTS:
|
|
|
+ statements = child
|
|
|
+ break
|
|
|
+ }
|
|
|
|
|
|
- if err != nil {
|
|
|
- break
|
|
|
+ if err != nil {
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if err == nil && statements != nil {
|
|
|
- var desc string
|
|
|
+ if err == nil && statements != nil {
|
|
|
+ var desc string
|
|
|
|
|
|
- sinkName := fmt.Sprint(name)
|
|
|
+ sinkName := fmt.Sprint(name)
|
|
|
|
|
|
- if len(rt.node.Meta) > 0 &&
|
|
|
- (rt.node.Meta[0].Type() == parser.MetaDataPreComment ||
|
|
|
- rt.node.Meta[0].Type() == parser.MetaDataPostComment) {
|
|
|
- desc = strings.TrimSpace(rt.node.Meta[0].Value())
|
|
|
- }
|
|
|
+ if len(rt.node.Meta) > 0 &&
|
|
|
+ (rt.node.Meta[0].Type() == parser.MetaDataPreComment ||
|
|
|
+ rt.node.Meta[0].Type() == parser.MetaDataPostComment) {
|
|
|
+ desc = strings.TrimSpace(rt.node.Meta[0].Value())
|
|
|
+ }
|
|
|
|
|
|
- rule := &engine.Rule{
|
|
|
- Name: sinkName, // Name
|
|
|
- Desc: desc, // Description
|
|
|
- KindMatch: kindMatch, // Kind match
|
|
|
- ScopeMatch: scopeMatch, // Match on event cascade scope
|
|
|
- StateMatch: stateMatch, // No state match
|
|
|
- Priority: priority, // Priority of the rule
|
|
|
- SuppressionList: suppresses, // List of suppressed rules by this rule
|
|
|
- Action: func(p engine.Processor, m engine.Monitor, e *engine.Event) error { // Action of the rule
|
|
|
+ rule := &engine.Rule{
|
|
|
+ Name: sinkName, // Name
|
|
|
+ Desc: desc, // Description
|
|
|
+ KindMatch: kindMatch, // Kind match
|
|
|
+ ScopeMatch: scopeMatch, // Match on event cascade scope
|
|
|
+ StateMatch: stateMatch, // No state match
|
|
|
+ Priority: priority, // Priority of the rule
|
|
|
+ SuppressionList: suppresses, // List of suppressed rules by this rule
|
|
|
+ Action: func(p engine.Processor, m engine.Monitor, e *engine.Event) error { // Action of the rule
|
|
|
|
|
|
- // Create a new root variable scope
|
|
|
+ // Create a new root variable scope
|
|
|
|
|
|
- sinkVS := scope.NewScope(fmt.Sprintf("sink: %v", sinkName))
|
|
|
+ sinkVS := scope.NewScope(fmt.Sprintf("sink: %v", sinkName))
|
|
|
|
|
|
- // Create a new instance state with the monitor - everything called
|
|
|
- // by the rule will have access to the current monitor.
|
|
|
+ // Create a new instance state with the monitor - everything called
|
|
|
+ // by the rule will have access to the current monitor.
|
|
|
|
|
|
- sinkIs := map[string]interface{}{
|
|
|
- "monitor": m,
|
|
|
- }
|
|
|
+ sinkIs := map[string]interface{}{
|
|
|
+ "monitor": m,
|
|
|
+ }
|
|
|
|
|
|
- err = sinkVS.SetValue("event", map[interface{}]interface{}{
|
|
|
- "name": e.Name(),
|
|
|
- "kind": strings.Join(e.Kind(), engine.RuleKindSeparator),
|
|
|
- "state": e.State(),
|
|
|
- })
|
|
|
+ err = sinkVS.SetValue("event", map[interface{}]interface{}{
|
|
|
+ "name": e.Name(),
|
|
|
+ "kind": strings.Join(e.Kind(), engine.RuleKindSeparator),
|
|
|
+ "state": e.State(),
|
|
|
+ })
|
|
|
|
|
|
- if err == nil {
|
|
|
- scope.SetParentOfScope(sinkVS, vs)
|
|
|
+ if err == nil {
|
|
|
+ scope.SetParentOfScope(sinkVS, vs)
|
|
|
|
|
|
- if _, err = statements.Runtime.Eval(sinkVS, sinkIs); err != nil {
|
|
|
+ if _, err = statements.Runtime.Eval(sinkVS, sinkIs); err != nil {
|
|
|
|
|
|
- if sre, ok := err.(*SinkRuntimeError); ok {
|
|
|
- sre.environment = sinkVS
|
|
|
+ if sre, ok := err.(*SinkRuntimeError); ok {
|
|
|
+ sre.environment = sinkVS
|
|
|
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
|
|
|
- // Provide additional information for unexpected errors
|
|
|
+ // Provide additional information for unexpected errors
|
|
|
|
|
|
- err = &SinkRuntimeError{
|
|
|
- err.(*util.RuntimeError),
|
|
|
- sinkVS,
|
|
|
- nil,
|
|
|
+ err = &SinkRuntimeError{
|
|
|
+ err.(*util.RuntimeError),
|
|
|
+ sinkVS,
|
|
|
+ nil,
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return err
|
|
|
- },
|
|
|
- }
|
|
|
+ return err
|
|
|
+ },
|
|
|
+ }
|
|
|
|
|
|
- if err = rt.erp.Processor.AddRule(rule); err != nil {
|
|
|
- err = rt.erp.NewRuntimeError(util.ErrInvalidState, err.Error(), rt.node)
|
|
|
+ if err = rt.erp.Processor.AddRule(rule); err != nil {
|
|
|
+ err = rt.erp.NewRuntimeError(util.ErrInvalidState, err.Error(), rt.node)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -254,34 +257,38 @@ type sinkDetailRuntime struct {
|
|
|
Eval evaluate this runtime component.
|
|
|
*/
|
|
|
func (rt *sinkDetailRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interface{}, error) {
|
|
|
+ var ret interface{}
|
|
|
|
|
|
- ret, err := rt.node.Children[0].Runtime.Eval(vs, is)
|
|
|
+ _, err := rt.baseRuntime.Eval(vs, is)
|
|
|
|
|
|
if err == nil {
|
|
|
|
|
|
- // Check value is of expected type
|
|
|
+ if ret, err = rt.node.Children[0].Runtime.Eval(vs, is); err == nil {
|
|
|
|
|
|
- if rt.valType == "list" {
|
|
|
- if _, ok := ret.([]interface{}); !ok {
|
|
|
- return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
|
|
|
- fmt.Sprintf("Expected a list as value"),
|
|
|
- rt.node)
|
|
|
- }
|
|
|
+ // Check value is of expected type
|
|
|
|
|
|
- } else if rt.valType == "map" {
|
|
|
+ if rt.valType == "list" {
|
|
|
+ if _, ok := ret.([]interface{}); !ok {
|
|
|
+ return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
|
|
|
+ fmt.Sprintf("Expected a list as value"),
|
|
|
+ rt.node)
|
|
|
+ }
|
|
|
|
|
|
- if _, ok := ret.(map[interface{}]interface{}); !ok {
|
|
|
- return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
|
|
|
- fmt.Sprintf("Expected a map as value"),
|
|
|
- rt.node)
|
|
|
- }
|
|
|
+ } else if rt.valType == "map" {
|
|
|
|
|
|
- } else if rt.valType == "int" {
|
|
|
+ if _, ok := ret.(map[interface{}]interface{}); !ok {
|
|
|
+ return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
|
|
|
+ fmt.Sprintf("Expected a map as value"),
|
|
|
+ rt.node)
|
|
|
+ }
|
|
|
|
|
|
- if _, ok := ret.(float64); !ok {
|
|
|
- return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
|
|
|
- fmt.Sprintf("Expected a number as value"),
|
|
|
- rt.node)
|
|
|
+ } else if rt.valType == "int" {
|
|
|
+
|
|
|
+ if _, ok := ret.(float64); !ok {
|
|
|
+ return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
|
|
|
+ fmt.Sprintf("Expected a number as value"),
|
|
|
+ rt.node)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|