peruse 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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