peruse 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'shared/time_stubs'
3
+ require 'shared/peruse_stubs'
4
+
5
+ describe 'chained searches' do
6
+ include_context "time stubs"
7
+ include_context "peruse stubs"
8
+
9
+ it 'should parse last 24h & foo_type=bar & baz="fez" & host=27.224.123.110' do
10
+ result = Peruse.search 'last 24h & foo_type=bar & baz="fez" & host=27.224.123.110'
11
+ expected = Peruse::Helper.filter_builder({
12
+ and: [
13
+ Peruse::Helper.range_builder(
14
+ (@time - 24.hours).utc.to_datetime.iso8601(3),
15
+ @time.utc.to_datetime.iso8601(3)
16
+ ),
17
+ Peruse::Helper.query_builder('foo_type:bar'),
18
+ Peruse::Helper.query_builder('baz:"fez"'),
19
+ Peruse::Helper.query_builder('host:27.224.123.110')
20
+ ]
21
+ })
22
+ expect(result).to eq(expected)
23
+ end
24
+
25
+ it 'should parse last 24h & (foo_type=bar AND baz="fez" AND host=27.224.123.110)' do
26
+ result = Peruse.search 'last 24h & (foo_type=bar AND baz="fez" AND host=27.224.123.110)'
27
+ expected = Peruse::Helper.filter_builder({
28
+ and: [
29
+ Peruse::Helper.range_builder(
30
+ (@time - 24.hours).utc.to_datetime.iso8601(3),
31
+ @time.utc.to_datetime.iso8601(3)
32
+ ),
33
+ Peruse::Helper.query_builder('foo_type:bar'),
34
+ Peruse::Helper.query_builder('baz:"fez"'),
35
+ Peruse::Helper.query_builder('host:27.224.123.110')
36
+ ]
37
+ })
38
+ expect(result).to eq(expected)
39
+ end
40
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'field / value searches' do
4
+
5
+ it 'should parse _foo.@bar=baz' do
6
+ result = Peruse.search '_foo.@bar=baz'
7
+ expected = Peruse::Helper.filter_builder(
8
+ Peruse::Helper.query_builder('_foo.@bar:baz')
9
+ )
10
+ expect(result).to eq(expected)
11
+ end
12
+
13
+ it 'should parse _foo.@bar=(baz)' do
14
+ result = Peruse.search '_foo.@bar=(baz)'
15
+ expected = Peruse::Helper.filter_builder(
16
+ Peruse::Helper.query_builder('_foo.@bar:(baz)')
17
+ )
18
+ expect(result).to eq(expected)
19
+ end
20
+
21
+ it 'should parse _foo.@fields.@bar="bar baz"' do
22
+ result = Peruse.search '_foo.@fields.@bar="bar baz"'
23
+ expected = Peruse::Helper.filter_builder(
24
+ Peruse::Helper.query_builder('_foo.@fields.@bar:"bar baz"')
25
+ )
26
+ expect(result).to eq(expected)
27
+ end
28
+
29
+ it 'should parse _foo-barcr@5Y_+f!3*(name=bar' do
30
+ result = Peruse.search '_foo-barcr@5Y_+f!3*(name=bar'
31
+ expected = Peruse::Helper.filter_builder(
32
+ Peruse::Helper.query_builder('_foo-barcr@5Y_+f!3*(name:bar')
33
+ )
34
+ expect(result).to eq(expected)
35
+ end
36
+
37
+ it 'should parse foo=bar-baz' do
38
+ result = Peruse.search 'foo=bar-baz'
39
+ expected = Peruse::Helper.filter_builder(
40
+ Peruse::Helper.query_builder('foo:bar-baz')
41
+ )
42
+ expect(result).to eq(expected)
43
+ end
44
+
45
+ it 'should parse !src_ip=0.0.0.0' do
46
+ result = Peruse.search '!src_ip=0.0.0.0'
47
+ expected = Peruse::Helper.filter_builder(
48
+ Peruse::Helper.query_builder('!src_ip:0.0.0.0')
49
+ )
50
+ expect(result).to eq(expected)
51
+ end
52
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'the indices command' do
4
+ it 'should parse indices foo,bar,baz' do
5
+ result = Peruse.search 'indices foo,bar,baz'
6
+ expected = Peruse::Helper.filter_builder(
7
+ Peruse::Helper.indices_builder(%w(foo bar baz))
8
+ )
9
+ expect(result).to eq(expected)
10
+ end
11
+
12
+ it 'should parse indices foo , bar , baz' do
13
+ result = Peruse.search 'indices foo , bar , baz'
14
+ expected = Peruse::Helper.filter_builder(
15
+ Peruse::Helper.indices_builder(%w(foo bar baz))
16
+ )
17
+ expect(result).to eq(expected)
18
+ end
19
+
20
+ it 'should parse indices foo , bar , baz & key = value' do
21
+ result = Peruse.search 'indices foo , bar , baz & key = value'
22
+ expected = Peruse::Helper.filter_builder(
23
+ and: [
24
+ Peruse::Helper.indices_builder(%w(foo bar baz)),
25
+ Peruse::Helper.query_builder('key:value')
26
+ ]
27
+ )
28
+ expect(result).to eq(expected)
29
+ end
30
+
31
+ it 'should parse key = value & indices foo , bar , baz' do
32
+ result = Peruse.search 'key = value & indices foo , bar , baz'
33
+ expected = Peruse::Helper.filter_builder(
34
+ and: [
35
+ Peruse::Helper.query_builder('key:value'),
36
+ Peruse::Helper.indices_builder(%w(foo bar baz))
37
+ ]
38
+ )
39
+ expect(result).to eq(expected)
40
+ end
41
+ end
data/spec/last_spec.rb ADDED
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'shared/time_stubs'
3
+ require 'shared/peruse_stubs'
4
+
5
+ describe 'the last command' do
6
+ include_context "time stubs"
7
+ include_context "peruse stubs"
8
+
9
+ it 'should parse last 24h' do
10
+ result = Peruse.search 'last 24h'
11
+ expected = Peruse::Helper.filter_builder(
12
+ Peruse::Helper.range_builder(
13
+ (@time - 24.hours).utc.to_datetime.iso8601(3),
14
+ @time.utc.to_datetime.iso8601(3)
15
+ )
16
+ )
17
+ expect(result).to eq(expected)
18
+ end
19
+
20
+ it 'should parse last 24d' do
21
+ result = Peruse.search 'last 24d'
22
+ expected = Peruse::Helper.filter_builder(
23
+ Peruse::Helper.range_builder(
24
+ (@time - 24.days).utc.to_datetime.iso8601(3),
25
+ @time.utc.to_datetime.iso8601(3)
26
+ )
27
+ )
28
+ expect(result).to eq(expected)
29
+ end
30
+
31
+ it 'should parse last 24w' do
32
+ result = Peruse.search 'last 24w'
33
+ expected = Peruse::Helper.filter_builder(
34
+ Peruse::Helper.range_builder(
35
+ (@time - 24.weeks).utc.to_datetime.iso8601(3),
36
+ @time.utc.to_datetime.iso8601(3)
37
+ )
38
+ )
39
+ expect(result).to eq(expected)
40
+ end
41
+
42
+ it 'should parse last 24s' do
43
+ result = Peruse.search 'last 24s'
44
+ expected = Peruse::Helper.filter_builder(
45
+ Peruse::Helper.range_builder(
46
+ (@time - 24.seconds).utc.to_datetime.iso8601(3),
47
+ @time.utc.to_datetime.iso8601(3)
48
+ )
49
+ )
50
+ expect(result).to eq(expected)
51
+ end
52
+
53
+ it 'should parse last 24m' do
54
+ result = Peruse.search 'last 24m'
55
+ expected = Peruse::Helper.filter_builder(
56
+ Peruse::Helper.range_builder(
57
+ (@time - 24.minutes).utc.to_datetime.iso8601(3),
58
+ @time.utc.to_datetime.iso8601(3)
59
+ )
60
+ )
61
+ expect(result).to eq(expected)
62
+ end
63
+
64
+ it 'should parse last 1h & @fields.foo.@field=bar' do
65
+ result = Peruse.search 'last 1h & @fields.foo.@field=bar'
66
+ expected = Peruse::Helper.filter_builder(
67
+ and: [
68
+ Peruse::Helper.range_builder(
69
+ (@time - 1.hour).utc.to_datetime.iso8601(3),
70
+ @time.utc.to_datetime.iso8601(3)
71
+ ),
72
+ Peruse::Helper.query_builder('@fields.foo.@field:bar')
73
+ ]
74
+ )
75
+ expect(result).to eq(expected)
76
+ end
77
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'the limit command' do
4
+ it 'should parse limit 1' do
5
+ result = Peruse.search 'limit 1'
6
+ expected = Peruse::Helper.filter_builder(
7
+ Peruse::Helper.limit_builder(1)
8
+ )
9
+ expect(result).to eq(expected)
10
+ end
11
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+ require 'shared/time_stubs'
3
+ require 'shared/peruse_stubs'
4
+
5
+ describe 'nested searches' do
6
+ include_context "time stubs"
7
+ include_context "peruse stubs"
8
+
9
+ before :each do
10
+ fake_results = {
11
+ foo: 'bar',
12
+ baz: 5,
13
+ arr: [ 0, 1, 2, 3 ],
14
+ :timestamp => @time.utc.to_datetime.iso8601(3)
15
+ }.to_json
16
+ allow_any_instance_of(Peruse::ResultSet).to receive(:eval).and_return(fake_results)
17
+ end
18
+
19
+ skip 'should transform' do
20
+ results = @transformer.apply @parser.parse('foo=`bar=baz|baz,fass,fdsd`')
21
+ expect(results.query).to eq({query:{filtered:{query:{query_string:{
22
+ query: 'foo:(5)'
23
+ }}}}})
24
+ end
25
+
26
+ skip 'should parse a nested basic search' do
27
+ @parsed = @parser.parse 'tshark.len = ` 226 | tshark.frame.time_epoch,tshark.ip.src`'
28
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
29
+ expect(@parsed[:op].to_s).to eq '='
30
+ expect(@parsed[:value][:initial_query][:match].to_s).to eq '226'
31
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
32
+ end
33
+
34
+ skip 'should parse a nested regexp' do
35
+ @parsed = @parser.parse 'tshark.len = ` cif.malicious_ips=/foo/ | tshark.frame.time_epoch,tshark.ip.src`'
36
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
37
+ expect(@parsed[:op].to_s).to eq '='
38
+ expect(@parsed[:value][:initial_query][:field].to_s).to eq 'cif.malicious_ips'
39
+ expect(@parsed[:value][:initial_query][:op].to_s).to eq '='
40
+ expect(@parsed[:value][:initial_query][:value].to_s).to eq '/foo/'
41
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
42
+ end
43
+
44
+ skip 'should parse a nested basic boolean' do
45
+ @parsed = @parser.parse 'tshark.len = `(foo OR bar) | tshark.frame.time_epoch,tshark.ip.src`'
46
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
47
+ expect(@parsed[:op].to_s).to eq '='
48
+ expect(@parsed[:value][:initial_query][:match].to_s).to eq '(foo OR bar) '
49
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
50
+ end
51
+
52
+ skip 'should parse a nested field / value boolean' do
53
+ @parsed = @parser.parse 'tshark.len = `baz=(foo OR bar AND (bar OR fez)) | tshark.frame.time_epoch,tshark.ip.src`'
54
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
55
+ expect(@parsed[:op].to_s).to eq '='
56
+ expect(@parsed[:value][:initial_query][:field].to_s).to eq 'baz'
57
+ expect(@parsed[:value][:initial_query][:op].to_s).to eq '='
58
+ expect(@parsed[:value][:initial_query][:value].to_s).to eq '(foo OR bar AND (bar OR fez)) '
59
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
60
+ end
61
+
62
+ skip 'should parse a nested last standalone timerange' do
63
+ @parsed = @parser.parse 'tshark.len = `last 24h | tshark.frame.time_epoch,tshark.ip.src`'
64
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
65
+ expect(@parsed[:op].to_s).to eq '='
66
+ expect(@parsed[:value][:initial_query][:timerange][:quantity].to_s).to eq '24'
67
+ expect(@parsed[:value][:initial_query][:timerange][:quantifier].to_s).to eq 'h'
68
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
69
+ end
70
+
71
+ skip 'should parse a nested last timerange and field / value pair' do
72
+ @parsed = @parser.parse 'tshark.len = `last 24h foo=bar | tshark.frame.time_epoch,tshark.ip.src`'
73
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
74
+ expect(@parsed[:op].to_s).to eq '='
75
+ expect(@parsed[:value][:initial_query][:timerange][:quantity].to_s).to eq '24'
76
+ expect(@parsed[:value][:initial_query][:timerange][:quantifier].to_s).to eq 'h'
77
+ expect(@parsed[:value][:initial_query][:search][:field].to_s).to eq 'foo'
78
+ expect(@parsed[:value][:initial_query][:search][:op].to_s).to eq '='
79
+ expect(@parsed[:value][:initial_query][:search][:value].to_s).to eq 'bar'
80
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
81
+ end
82
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'regexp searches' do
4
+
5
+ it 'should parse foo=/blah foo/' do
6
+ result = Peruse.search 'foo=/blah foo/'
7
+ expected = Peruse::Helper.filter_builder(
8
+ Peruse::Helper.regexp_builder(
9
+ 'foo',
10
+ 'blah foo'
11
+ )
12
+ )
13
+ expect(result).to eq(expected)
14
+ end
15
+
16
+ it 'should parse foo=/blah\/ foo/' do
17
+ result = Peruse.search 'foo=/blah\/ foo/'
18
+ expected = Peruse::Helper.filter_builder(
19
+ Peruse::Helper.regexp_builder(
20
+ 'foo',
21
+ 'blah\/ foo'
22
+ )
23
+ )
24
+ expect(result).to eq(expected)
25
+ end
26
+
27
+ it 'should parse foo=/blah\. foo/' do
28
+ result = Peruse.search 'foo=/blah\. foo/'
29
+ expected = Peruse::Helper.filter_builder(
30
+ Peruse::Helper.regexp_builder(
31
+ 'foo',
32
+ 'blah\. foo'
33
+ )
34
+ )
35
+ expect(result).to eq(expected)
36
+ end
37
+
38
+ it 'should parse http.headers=/.*User\-Agent\: Microsoft\-WebDAV.*/' do
39
+ result = Peruse.search 'http.headers=/.*User\-Agent\: Microsoft\-WebDAV.*/'
40
+ expected = Peruse::Helper.filter_builder(
41
+ Peruse::Helper.regexp_builder(
42
+ 'http.headers',
43
+ '.*User\-Agent\: Microsoft\-WebDAV.*'
44
+ )
45
+ )
46
+ expect(result).to eq(expected)
47
+ end
48
+ end
@@ -0,0 +1,14 @@
1
+ # Dummy Elasticsearch Client for specs
2
+
3
+ module Elasticsearch
4
+ module Transport
5
+ class Client
6
+ def initialize(opts)
7
+ end
8
+
9
+ def search(payload)
10
+ payload[:body]
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ shared_context "peruse stubs" do
2
+ before :each do
3
+ allow(Peruse).to receive(:timestamp_field).and_return(:@timestamp)
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ require 'timecop'
2
+
3
+ shared_context "time stubs" do
4
+ before do
5
+ Timecop.freeze(Time.local(2012))
6
+ @time = Time.now
7
+ end
8
+
9
+ after do
10
+ Timecop.return
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ require 'rspec'
2
+ require 'peruse'
3
+ require 'parslet/rig/rspec'
4
+ require 'shared/dummy_client'
5
+
6
+ # Print ascii_tree when exception occurs
7
+ module Peruse
8
+ class ParserWrapper < Parser
9
+ def parse(query)
10
+ begin
11
+ super(query)
12
+ rescue Parslet::ParseFailed => failure
13
+ puts failure.cause.ascii_tree
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.before :all do
21
+
22
+ # configure test instance of Peruse to use wrapper parser
23
+ Peruse.configure do |c|
24
+ c.parser = Peruse::ParserWrapper.new
25
+ c.transformer = Peruse::Transformer.new
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'shared/time_stubs'
3
+ require 'shared/peruse_stubs'
4
+ require 'chronic'
5
+
6
+ describe 'the window command' do
7
+ include_context 'time stubs'
8
+ include_context 'peruse stubs'
9
+
10
+ it 'should parse window 3/11/13 to 3/12/13' do
11
+ result = Peruse.search 'window 3/11/13 to 3/12/13'
12
+ expected = Peruse::Helper.filter_builder(
13
+ Peruse::Helper.range_builder(
14
+ Peruse::Helper.timestamp_format(Chronic.parse('3/11/13')),
15
+ Peruse::Helper.timestamp_format(Chronic.parse('3/12/13'))
16
+ )
17
+ )
18
+ expect(result).to eq(expected)
19
+ end
20
+
21
+ it 'should parse window "last monday" to "last thursday"' do
22
+ result = Peruse.search 'window "last monday" to "last thursday"'
23
+ expected = Peruse::Helper.filter_builder(
24
+ Peruse::Helper.range_builder(
25
+ Peruse::Helper.timestamp_format(Chronic.parse('last monday')),
26
+ Peruse::Helper.timestamp_format(Chronic.parse('last thursday'))
27
+ )
28
+ )
29
+ expect(result).to eq(expected)
30
+ end
31
+
32
+ it 'should parse window -60m to -30m' do
33
+ result = Peruse.search 'window -60m to -30m'
34
+ expected = Peruse::Helper.filter_builder(
35
+ Peruse::Helper.range_builder(
36
+ Peruse::Helper.timestamp_format(@time - 60.minutes),
37
+ Peruse::Helper.timestamp_format(@time - 30.minutes)
38
+ )
39
+ )
40
+ expect(result).to eq(expected)
41
+ end
42
+
43
+ it 'should parse NOT window -60m to -30m' do
44
+ result = Peruse.search 'NOT window -60m to -30m'
45
+ expected = Peruse::Helper.filter_builder(
46
+ not:
47
+ Peruse::Helper.range_builder(
48
+ Peruse::Helper.timestamp_format(@time - 60.minutes),
49
+ Peruse::Helper.timestamp_format(@time - 30.minutes)
50
+ )
51
+ )
52
+ expect(result).to eq(expected)
53
+ end
54
+ end