Merge pull request #249 from afro88/trigger_arrays

For arrays of values to be used in Trigger agent for all rule types

Andrew Cantino 11 anos atrás
pai
commit
b041a51ad1
2 arquivos alterados com 102 adições e 9 exclusões
  1. 16 9
      app/models/agents/trigger_agent.rb
  2. 86 0
      spec/models/agents/trigger_agent_spec.rb

+ 16 - 9
app/models/agents/trigger_agent.rb

@@ -11,6 +11,8 @@ module Agents
11 11
 
12 12
       The `type` can be one of #{VALID_COMPARISON_TYPES.map { |t| "`#{t}`" }.to_sentence} and compares with the `value`.
13 13
 
14
+      The `value` can be a single value or an array of values. In the case of an array, if one or more values match then the rule matches. 
15
+
14 16
       All rules must match for the Agent to match.  The resulting Event will have a payload message of `message`.  You can include extractions in the message, for example: `I saw a bar of: <foo.bar>`
15 17
 
16 18
       Set `expected_receive_period_in_days` to the maximum amount of time that you'd expect to pass between Events being received by this Agent.
@@ -49,25 +51,30 @@ module Agents
49 51
       incoming_events.each do |event|
50 52
         match = options['rules'].all? do |rule|
51 53
           value_at_path = Utils.value_at(event['payload'], rule['path'])
52
-          case rule['type']
54
+          rule_values = rule['value']
55
+          rule_values = [rule_values] unless rule_values.is_a?(Array)
56
+
57
+          match_found = rule_values.any? do |rule_value|
58
+            case rule['type']
53 59
             when "regex"
54
-              value_at_path.to_s =~ Regexp.new(rule['value'], Regexp::IGNORECASE)
60
+              value_at_path.to_s =~ Regexp.new(rule_value, Regexp::IGNORECASE)
55 61
             when "!regex"
56
-              value_at_path.to_s !~ Regexp.new(rule['value'], Regexp::IGNORECASE)
62
+              value_at_path.to_s !~ Regexp.new(rule_value, Regexp::IGNORECASE)
57 63
             when "field>value"
58
-              value_at_path.to_f > rule['value'].to_f
64
+              value_at_path.to_f > rule_value.to_f
59 65
             when "field>=value"
60
-              value_at_path.to_f >= rule['value'].to_f
66
+              value_at_path.to_f >= rule_value.to_f
61 67
             when "field<value"
62
-              value_at_path.to_f < rule['value'].to_f
68
+              value_at_path.to_f < rule_value.to_f
63 69
             when "field<=value"
64
-              value_at_path.to_f <= rule['value'].to_f
70
+              value_at_path.to_f <= rule_value.to_f
65 71
             when "field==value"
66
-              value_at_path.to_s == rule['value'].to_s
72
+              value_at_path.to_s == rule_value.to_s
67 73
             when "field!=value"
68
-              value_at_path.to_s != rule['value'].to_s
74
+              value_at_path.to_s != rule_value.to_s
69 75
             else
70 76
               raise "Invalid type of #{rule['type']} in TriggerAgent##{id}"
77
+            end
71 78
           end
72 79
         end
73 80
 

+ 86 - 0
spec/models/agents/trigger_agent_spec.rb

@@ -71,6 +71,28 @@ describe Agents::TriggerAgent do
71 71
       }.should change { Event.count }.by(1)
72 72
     end
73 73
 
74
+    it "handles array of regex" do
75
+      @event.payload['foo']['bar']['baz'] = "a222b"
76
+      @checker.options['rules'][0] = {
77
+        'type' => "regex",
78
+        'value' => ["a\\db", "a\\Wb"],
79
+        'path' => "foo.bar.baz",
80
+      }
81
+      lambda {
82
+        @checker.receive([@event])
83
+      }.should_not change { Event.count }
84
+
85
+      @event.payload['foo']['bar']['baz'] = "a2b"
86
+      lambda {
87
+        @checker.receive([@event])
88
+      }.should change { Event.count }.by(1)
89
+
90
+      @event.payload['foo']['bar']['baz'] = "a b"
91
+      lambda {
92
+        @checker.receive([@event])
93
+      }.should change { Event.count }.by(1)
94
+    end
95
+
74 96
     it "handles negated regex" do
75 97
       @event.payload['foo']['bar']['baz'] = "a2b"
76 98
       @checker.options['rules'][0] = {
@@ -89,6 +111,24 @@ describe Agents::TriggerAgent do
89 111
       }.should change { Event.count }.by(1)
90 112
     end
91 113
 
114
+    it "handles array of negated regex" do
115
+      @event.payload['foo']['bar']['baz'] = "a2b"
116
+      @checker.options['rules'][0] = {
117
+        'type' => "!regex",
118
+        'value' => ["a\\db", "a2b"],
119
+        'path' => "foo.bar.baz",
120
+      }
121
+
122
+      lambda {
123
+        @checker.receive([@event])
124
+      }.should_not change { Event.count }
125
+
126
+      @event.payload['foo']['bar']['baz'] = "a3b"
127
+      lambda {
128
+        @checker.receive([@event])
129
+      }.should change { Event.count }.by(1)
130
+    end
131
+
92 132
     it "puts can extract values into the message based on paths" do
93 133
       @checker.receive([@event])
94 134
       Event.last.payload['message'].should == "I saw 'a2b' from Joe"
@@ -109,6 +149,21 @@ describe Agents::TriggerAgent do
109 149
       }.should_not change { Event.count }
110 150
     end
111 151
 
152
+    it "handles array of numerical comparisons" do
153
+      @event.payload['foo']['bar']['baz'] = "5"
154
+      @checker.options['rules'].first['value'] = [6, 3]
155
+      @checker.options['rules'].first['type'] = "field<value"
156
+
157
+      lambda {
158
+        @checker.receive([@event])
159
+      }.should change { Event.count }.by(1)
160
+
161
+      @checker.options['rules'].first['value'] = [4, 3]
162
+      lambda {
163
+        @checker.receive([@event])
164
+      }.should_not change { Event.count }
165
+    end
166
+
112 167
     it "handles exact comparisons" do
113 168
       @event.payload['foo']['bar']['baz'] = "hello world"
114 169
       @checker.options['rules'].first['type'] = "field==value"
@@ -124,6 +179,21 @@ describe Agents::TriggerAgent do
124 179
       }.should change { Event.count }.by(1)
125 180
     end
126 181
 
182
+    it "handles array of exact comparisons" do
183
+      @event.payload['foo']['bar']['baz'] = "hello world"
184
+      @checker.options['rules'].first['type'] = "field==value"
185
+
186
+      @checker.options['rules'].first['value'] = ["hello there", "hello universe"]
187
+      lambda {
188
+        @checker.receive([@event])
189
+      }.should_not change { Event.count }
190
+
191
+      @checker.options['rules'].first['value'] = ["hello world", "hello universe"]
192
+      lambda {
193
+        @checker.receive([@event])
194
+      }.should change { Event.count }.by(1)
195
+    end
196
+
127 197
     it "handles negated comparisons" do
128 198
       @event.payload['foo']['bar']['baz'] = "hello world"
129 199
       @checker.options['rules'].first['type'] = "field!=value"
@@ -140,6 +210,22 @@ describe Agents::TriggerAgent do
140 210
       }.should change { Event.count }.by(1)
141 211
     end
142 212
 
213
+    it "handles array of negated comparisons" do
214
+      @event.payload['foo']['bar']['baz'] = "hello world"
215
+      @checker.options['rules'].first['type'] = "field!=value"
216
+      @checker.options['rules'].first['value'] = ["hello world", "hello world"]
217
+
218
+      lambda {
219
+        @checker.receive([@event])
220
+      }.should_not change { Event.count }
221
+
222
+      @checker.options['rules'].first['value'] = ["hello there", "hello world"]
223
+
224
+      lambda {
225
+        @checker.receive([@event])
226
+      }.should change { Event.count }.by(1)
227
+    end
228
+
143 229
     it "does fine without dots in the path" do
144 230
       @event.payload = { 'hello' => "world" }
145 231
       @checker.options['rules'].first['type'] = "field==value"