plunk 0.0.7 → 0.0.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9995468d364aaf1391ad67f6d1f8ddb4e65a6553
4
- data.tar.gz: f1594cf5f75541b1cfec6a2d82fa9eb55d243345
3
+ metadata.gz: 599c26a054ac47928ba6b476dcf62c2731b07305
4
+ data.tar.gz: d10dbfe0b2c3d3d26611a509b1e699bc42b8e412
5
5
  SHA512:
6
- metadata.gz: 26187e0add2cc39f6fe1e915e701bf237a8638c61d81331c430c934f98f588a89007edf2813765dde894c3da5238b86dadb671f3b7e408a03ee24e8a99d64117
7
- data.tar.gz: 95473787d59e19a6d984a170a78f64ff8dad05e9f69592ffdc57c33d0a5fe4e6bc548328af6c25719c8083e25e3b89d294cec53b3a912f02cb4ecc25c6703d03
6
+ metadata.gz: 1f5facdc7cedcfdb9a94d7f51a148ad72319b1ebd55ae54449c6e860f6a173149da2f5ec95697ef2a7e23bcd2af46535154bfba46030345864f07ab2c244144d
7
+ data.tar.gz: 0b8b372f4b1b5ca0ae46cfcb3d2214e68dcc5490432b9117bb02d84f8e2cbf564f8322b961d385eb0ea57116e1b4b3b2b542d16f105364702573c8a4a0a56ec9
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- plunk (0.0.6)
4
+ plunk (0.0.7)
5
5
  activesupport
6
6
  json
7
7
  parslet
@@ -19,7 +19,7 @@ class Plunk::Parser < Parslet::Parser
19
19
  # Field / value
20
20
  rule(:identifier) { match['_@a-zA-Z.'].repeat(1) }
21
21
  rule(:wildcard) { match('[a-zA-Z0-9.*]').repeat(1) }
22
- rule(:searchop) { match('[=]').as(:op) >> space? }
22
+ rule(:searchop) { match('[=]').as(:op) }
23
23
 
24
24
  # boolean operators search
25
25
  rule(:concatop) { (str('OR') | str('AND')) >> space? }
@@ -30,27 +30,27 @@ class Plunk::Parser < Parslet::Parser
30
30
 
31
31
  # Grammar parts
32
32
  rule(:rhs) {
33
- (regex | wildcard | integer | subsearch |
34
- (lparen >> (space? >> (wildcard | integer) >>
35
- (space >> concatop).maybe).repeat(1) >> rparen))
33
+ regexp | subsearch | integer | wildcard |
34
+ (lparen >> (space? >> (wildcard | integer) >>
35
+ (space >> concatop).maybe).repeat(1) >> rparen).maybe
36
36
  }
37
37
 
38
- rule(:regex) {
38
+ rule(:regexp) {
39
39
  str('/') >> match('[^/]').repeat >> str('/')
40
40
  }
41
41
 
42
+ rule(:last) {
43
+ str("last") >> space >> timerange.as(:timerange) >> (space >>
44
+ search.as(:search)).maybe
45
+ }
46
+
42
47
  rule(:search) {
43
48
  identifier.as(:field) >> space? >> searchop >> space? >>
44
49
  rhs.as(:value) | rhs.as(:match)
45
50
  }
46
51
 
47
- rule(:last) {
48
- str("last") >> space >> timerange.as(:timerange) >> space >>
49
- search.as(:search)
50
- }
51
-
52
52
  rule(:binaryop) {
53
- (paren | search).as(:left) >> space? >> operator >> job.as(:right)
53
+ (search | paren).as(:left) >> space? >> operator >> job.as(:right)
54
54
  }
55
55
 
56
56
  rule(:subsearch) {
@@ -58,12 +58,9 @@ class Plunk::Parser < Parslet::Parser
58
58
  }
59
59
 
60
60
  rule(:nested_search) {
61
- match('[^|]').repeat.as(:term) >> str('|') >> space? >>
61
+ match('[^|]').repeat.as(:initial_query) >> str('|') >> space? >>
62
62
  match('[^`]').repeat.as(:extractors)
63
- }
64
-
65
- rule(:joined_search) {
66
-
63
+ # job >> str('|') >> space? >>
67
64
  }
68
65
 
69
66
  rule(:paren) {
@@ -71,7 +68,7 @@ class Plunk::Parser < Parslet::Parser
71
68
  }
72
69
 
73
70
  rule(:job) {
74
- binaryop | paren | last | search
71
+ last | search | binaryop | paren
75
72
  }
76
73
 
77
74
  # root :job
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "plunk"
3
- s.version = "0.0.7"
3
+ s.version = "0.0.8"
4
4
  s.date = "2013-12-03"
5
5
  s.add_runtime_dependency "json"
6
6
  s.add_runtime_dependency "parslet"
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'basic searches' do
4
+ before :each do
5
+ @parsed = @parser.parse 'bar'
6
+ end
7
+
8
+ it 'should parse a single keyword' do
9
+ expect(@parsed[:match].to_s).to eq 'bar'
10
+ end
11
+
12
+ context 'transformed' do
13
+ before :each do
14
+ @result_set = @transformer.apply(@parsed)
15
+ end
16
+
17
+ it 'should be a proper query' do
18
+ @result_set.query.should eq({
19
+ query: {
20
+ query_string: {
21
+ query: 'bar'
22
+ }}})
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'boolean searches' do
4
+ it 'should parse last command with boolean' do
5
+ @parsed = @parser.parse 'last 1h (foo OR bar)'
6
+ expect(@parsed[:search][:match].to_s).to eq '(foo OR bar)'
7
+ end
8
+
9
+ it 'should parse a single field / value complex boolean expression' do
10
+ @parsed = @parser.parse 'ids.attackers=(bar OR car)'
11
+ expect(@parsed[:field].to_s).to eq 'ids.attackers'
12
+ expect(@parsed[:value].to_s).to eq '(bar OR car)'
13
+ expect(@parsed[:op].to_s).to eq '='
14
+ end
15
+
16
+ it 'should parse a single boolean expression' do
17
+ @parsed = @parser.parse '(bar OR car)'
18
+ expect(@parsed[:match].to_s).to eq '(bar OR car)'
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'field / value searches' do
4
+ it 'should parse a single field/value combo' do
5
+ @parsed = @parser.parse 'tshark.http.@src_ip=bar'
6
+ expect(@parsed[:field].to_s).to eq 'tshark.http.@src_ip'
7
+ expect(@parsed[:value].to_s).to eq 'bar'
8
+ expect(@parsed[:op].to_s).to eq '='
9
+ end
10
+
11
+ it 'should parse a single field / parenthesized value' do
12
+ @parsed = @parser.parse 'ids.attacker=(10.150.44.195)'
13
+ expect(@parsed[:field].to_s).to eq 'ids.attacker'
14
+ expect(@parsed[:value].to_s).to eq '(10.150.44.195)'
15
+ expect(@parsed[:op].to_s).to eq '='
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'the last command' do
4
+ context 'basic' do
5
+ it 'should parse a standalone last command' do
6
+ @parsed = @parser.parse 'last 24h'
7
+ expect(@parsed[:timerange][:quantity].to_s).to eq '24'
8
+ expect(@parsed[:timerange][:quantifier].to_s).to eq 'h'
9
+ end
10
+ end
11
+
12
+ context 'complex' do
13
+ before :all do
14
+ @parsed = @parser.parse 'last 24w tshark.@src_ip = bar'
15
+ end
16
+
17
+ it 'should parse last command with a search' do
18
+ expect(@parsed[:timerange][:quantity].to_s).to eq '24'
19
+ expect(@parsed[:timerange][:quantifier].to_s).to eq 'w'
20
+ expect(@parsed[:search][:field].to_s).to eq 'tshark.@src_ip'
21
+ expect(@parsed[:search][:value].to_s).to eq 'bar'
22
+ end
23
+
24
+ context 'transformation' do
25
+ before :each do
26
+ @result_set = @transformer.apply(@parsed)
27
+ end
28
+
29
+ it 'should have the proper result set' do
30
+ @result_set.should be_a Plunk::ResultSet
31
+ @result_set.query.should be_present
32
+
33
+ query = { query: {
34
+ query_string: {
35
+ query: "tshark.@src_ip:bar"
36
+ },
37
+ range: {
38
+ '@timestamp' => {
39
+ gte: 24.weeks.ago,
40
+ lte: Time.now
41
+ }}}}
42
+
43
+ @result_set.query.to_json.should eq query.to_json
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'nested searches' do
4
+ it 'should parse a nested basic search' do
5
+ @parsed = @parser.parse 'tshark.len = ` 226 | tshark.frame.time_epoch,tshark.ip.src`'
6
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
7
+ expect(@parsed[:op].to_s).to eq '='
8
+ expect(@parsed[:value][:initial_query].to_s).to eq '226 '
9
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
10
+ end
11
+
12
+ it 'should parse a nested regexp' do
13
+ @parsed = @parser.parse 'tshark.len = ` cif.malicious_ips=/foo/ | tshark.frame.time_epoch,tshark.ip.src`'
14
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
15
+ expect(@parsed[:op].to_s).to eq '='
16
+ expect(@parsed[:value][:initial_query].to_s).to eq 'cif.malicious_ips=/foo/ '
17
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
18
+ end
19
+
20
+ it 'should parse a nested basic boolean' do
21
+ @parsed = @parser.parse 'tshark.len = `(foo OR bar) | tshark.frame.time_epoch,tshark.ip.src`'
22
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
23
+ expect(@parsed[:op].to_s).to eq '='
24
+ expect(@parsed[:value][:initial_query].to_s).to eq '(foo OR bar) '
25
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
26
+ end
27
+
28
+ it 'should parse a nested field / value boolean' do
29
+ @parsed = @parser.parse 'tshark.len = `baz=(foo OR bar AND (bar OR fez)) | tshark.frame.time_epoch,tshark.ip.src`'
30
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
31
+ expect(@parsed[:op].to_s).to eq '='
32
+ expect(@parsed[:value][:initial_query].to_s).to eq 'baz=(foo OR bar AND (bar OR fez)) '
33
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
34
+ end
35
+
36
+ it 'should parse a nested last standalone timerange' do
37
+ @parsed = @parser.parse 'tshark.len = `last 24h | tshark.frame.time_epoch,tshark.ip.src`'
38
+ expect(@parsed[:field].to_s).to eq 'tshark.len'
39
+ expect(@parsed[:op].to_s).to eq '='
40
+ expect(@parsed[:value][:initial_query].to_s).to eq 'last 24h '
41
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
42
+ end
43
+
44
+ it 'should parse a nested last timerange and field / value pair' do
45
+ @parsed = @parser.parse 'tshark.len = `last 24h foo=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].to_s).to eq 'last 24h foo=bar '
49
+ expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'regexp searches' do
4
+ context 'simple' do
5
+ it 'should parse a basic regexp search' do
6
+ @parsed = @parser.parse 'foo=/blah foo/'
7
+ expect(@parsed[:field].to_s).to eq 'foo'
8
+ expect(@parsed[:value].to_s).to eq '/blah foo/'
9
+ end
10
+ end
11
+
12
+ context 'complex' do
13
+ it 'should parse key/value with regex' do
14
+ @parsed = @parser.parse 'foo=bar fe.ip=/whodunnit/'
15
+ expect(@parsed[0][:field].to_s).to eq 'foo'
16
+ expect(@parsed[0][:value].to_s).to eq 'bar'
17
+ expect(@parsed[1][:field].to_s).to eq 'fe.ip'
18
+ expect(@parsed[1][:value].to_s).to eq '/whodunnit/'
19
+ end
20
+
21
+ it 'should parse last command with a regex' do
22
+ @parsed = @parser.parse 'last 24w foo=/blah/'
23
+ expect(@parsed[:timerange][:quantity].to_s).to eq '24'
24
+ expect(@parsed[:timerange][:quantifier].to_s).to eq 'w'
25
+ expect(@parsed[:search][:field].to_s).to eq 'foo'
26
+ expect(@parsed[:search][:value].to_s).to eq '/blah/'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ require 'rspec'
2
+ require 'plunk'
3
+ require 'plunk/parser'
4
+ require 'plunk/transformer'
5
+ require 'plunk/result_set'
6
+ require 'parslet/rig/rspec'
7
+
8
+ # Print ascii_tree when exception occurs
9
+ class Plunk::ParserWrapper < Plunk::Parser
10
+ def parse(query)
11
+ begin
12
+ super(query)
13
+ rescue Parslet::ParseFailed => failure
14
+ puts failure.cause.ascii_tree
15
+ end
16
+ end
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.before :all do
21
+ @parser = Plunk::ParserWrapper.new
22
+ @transformer = Plunk::Transformer.new
23
+ end
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plunk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ram Mehta
@@ -101,10 +101,14 @@ files:
101
101
  - lib/plunk/result_set.rb
102
102
  - lib/plunk/transformer.rb
103
103
  - plunk.gemspec
104
+ - spec/basic_spec.rb
105
+ - spec/boolean_spec.rb
104
106
  - spec/elasticsearch_spec.rb
105
- - spec/parser_spec.rb
106
- - spec/result_set_spec.rb
107
- - spec/transformer_spec.rb
107
+ - spec/field_value_spec.rb
108
+ - spec/last_spec.rb
109
+ - spec/nested_search_spec.rb
110
+ - spec/regexp_spec.rb
111
+ - spec/spec_helper.rb
108
112
  homepage: https://github.com/elbii/plunk
109
113
  licenses:
110
114
  - MIT
@@ -1,128 +0,0 @@
1
- require 'plunk'
2
- require 'plunk/parser'
3
-
4
- # Print ascii_tree when exception occurs
5
- class Plunk::ParserWrapper < Plunk::Parser
6
- def parse(query)
7
- begin
8
- super(query)
9
- rescue Parslet::ParseFailed => failure
10
- puts failure.cause.ascii_tree
11
- end
12
- end
13
- end
14
-
15
- describe Plunk::Parser do
16
- before :all do
17
- @parser = Plunk::ParserWrapper.new
18
- @transformer = Plunk::Transformer.new
19
- end
20
-
21
- context 'single-query searches' do
22
- it 'should parse a single keyword' do
23
- @parsed = @parser.parse 'bar'
24
- expect(@parsed[:match].to_s).to eq 'bar'
25
- end
26
-
27
- it 'should parse a single field/value combo' do
28
- @parsed = @parser.parse 'tshark.http.@src_ip=bar'
29
- expect(@parsed[:field].to_s).to eq 'tshark.http.@src_ip'
30
- expect(@parsed[:value].to_s).to eq 'bar'
31
- expect(@parsed[:op].to_s).to eq '='
32
- end
33
-
34
- it 'should parse a single boolean expression' do
35
- @parsed = @parser.parse '(bar OR car)'
36
- expect(@parsed[:match].to_s).to eq '(bar OR car)'
37
- end
38
-
39
- it 'should parse a single field / value complex boolean expression' do
40
- @parsed = @parser.parse 'ids.attackers=(bar OR car)'
41
- expect(@parsed[:field].to_s).to eq 'ids.attackers'
42
- expect(@parsed[:value].to_s).to eq '(bar OR car)'
43
- expect(@parsed[:op].to_s).to eq '='
44
- end
45
-
46
- it 'should parse a single field / parenthesized value' do
47
- @parsed = @parser.parse 'ids.attacker=(10.150.44.195)'
48
- expect(@parsed[:field].to_s).to eq 'ids.attacker'
49
- expect(@parsed[:value].to_s).to eq '(10.150.44.195)'
50
- expect(@parsed[:op].to_s).to eq '='
51
- end
52
-
53
- it 'should parse a basic regex search' do
54
- @parsed = @parser.parse 'foo=/blah foo/'
55
- expect(@parsed[:field].to_s).to eq 'foo'
56
- expect(@parsed[:value].to_s).to eq '/blah foo/'
57
- end
58
-
59
- context 'the last command' do
60
- before :each do
61
- @parsed = @parser.parse 'last 24w tshark.@src_ip = bar'
62
- end
63
-
64
- it 'should parse last command with a search' do
65
- expect(@parsed[:timerange][:quantity].to_s).to eq '24'
66
- expect(@parsed[:timerange][:quantifier].to_s).to eq 'w'
67
- expect(@parsed[:search][:field].to_s).to eq 'tshark.@src_ip'
68
- expect(@parsed[:search][:value].to_s).to eq 'bar'
69
- end
70
-
71
- context 'transformation' do
72
- before :each do
73
- @result_set = @transformer.apply(@parsed)
74
- end
75
-
76
- it 'should have the proper result set' do
77
- @result_set.should be_a Plunk::ResultSet
78
- @result_set.query.should be_present
79
-
80
- query = { query: {
81
- query_string: {
82
- query: "tshark.@src_ip:bar"
83
- },
84
- range: {
85
- '@timestamp' => {
86
- gte: 24.weeks.ago,
87
- lte: Time.now
88
- }}}}
89
-
90
- @result_set.query.to_json.should eq query.to_json
91
- end
92
- end
93
- end
94
-
95
- context 'chained searches' do
96
- it 'should parse last command with a regex' do
97
- @parsed = @parser.parse 'last 24w foo=/blah/'
98
- expect(@parsed[:timerange][:quantity].to_s).to eq '24'
99
- expect(@parsed[:timerange][:quantifier].to_s).to eq 'w'
100
- expect(@parsed[:search][:field].to_s).to eq 'foo'
101
- expect(@parsed[:search][:value].to_s).to eq '/blah/'
102
- end
103
- end
104
-
105
- it 'should parse last command with boolean' do
106
- @parsed = @parser.parse 'last 1h (foo OR bar)'
107
- expect(@parsed[:search][:match].to_s).to eq '(foo OR bar)'
108
- end
109
-
110
- it 'should parse key/value with regex' do
111
- @parsed = @parser.parse 'foo=bar fe.ip=/whodunnit/'
112
- expect(@parsed[0][:field].to_s).to eq 'foo'
113
- expect(@parsed[0][:value].to_s).to eq 'bar'
114
- expect(@parsed[1][:field].to_s).to eq 'fe.ip'
115
- expect(@parsed[1][:value].to_s).to eq '/whodunnit/'
116
- end
117
- end
118
-
119
- context 'nested search' do
120
- it 'should parse the nested search' do
121
- @parsed = @parser.parse 'tshark.len = ` 226 | tshark.frame.time_epoch,tshark.ip.src`'
122
- expect(@parsed[:field].to_s).to eq 'tshark.len'
123
- expect(@parsed[:op].to_s).to eq '='
124
- expect(@parsed[:value][:term].to_s).to eq '226 '
125
- expect(@parsed[:value][:extractors].to_s).to eq 'tshark.frame.time_epoch,tshark.ip.src'
126
- end
127
- end
128
- end
@@ -1,4 +0,0 @@
1
- require 'plunk/result_set'
2
-
3
- describe Plunk::ResultSet do
4
- end
@@ -1,4 +0,0 @@
1
- require 'plunk/transformer'
2
-
3
- describe Plunk::Transformer do
4
- end