spanx 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ require 'spanx/api/machine'
2
+ require 'webmachine/test'
3
+
4
+ describe Spanx::API::Machine do
5
+ include Webmachine::Test
6
+
7
+ let(:app) { Spanx::API::Machine }
8
+ let(:json) { JSON.parse(response.body) }
9
+
10
+ describe "GET /ips/blocked" do
11
+ it 'returns a list of ips that have been blocked' do
12
+ Spanx::IPChecker.stub(:rate_limited_identifiers).and_return(["127.0.0.1", "123.45.34.1"])
13
+
14
+ get '/ips/blocked'
15
+ expect(response.code).to eq(200)
16
+
17
+ expect(json).to eq(["127.0.0.1", "123.45.34.1"])
18
+ end
19
+ end
20
+
21
+ describe "DELETE /ips/blocked/:ip" do
22
+ it 'unblocks the specified ip' do
23
+ mock_ip_checker = double
24
+ mock_ip_checker.should_receive(:unblock).once
25
+
26
+ Spanx::IPChecker.should_receive(:new).with('127.0.0.1').and_return(mock_ip_checker)
27
+
28
+ delete '/ips/blocked/127.0.0.1'
29
+
30
+ expect(response.code).to eq(204)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ class ::TestCommand < Spanx::CLI
4
+ description 'Test Command'
5
+ end
6
+
7
+ describe Spanx::CLI do
8
+ before do
9
+ Spanx.stub(:redis).and_return(Redis.new)
10
+ end
11
+
12
+ describe 'cli' do
13
+ describe 'class description' do
14
+ let(:command) { ::TestCommand }
15
+
16
+ it 'should be set' do
17
+ expect(command.description).to eql 'Test Command'
18
+ end
19
+ end
20
+ end
21
+
22
+ end
@@ -51,8 +51,8 @@ describe Spanx::Config do
51
51
  context "config file does not exist" do
52
52
  let(:file) { "non_existent_file" }
53
53
  it "should write error to stderr" do
54
- $stderr.should_receive(:puts).with("Error: Unable to find config_file at #{file}")
55
- $stderr.should_receive(:puts).with(Spanx::USAGE)
54
+ $stderr.should_receive(:puts).with("Error: Unable to find config_file at #{file}\n")
55
+ $stderr.should_receive(:puts).with(Spanx::Usage.usage)
56
56
  lambda {
57
57
  Spanx::Config.new(file)
58
58
  }.should raise_error(SystemExit)
@@ -45,7 +45,7 @@ describe Spanx::Notifier::Email, "#publish" do
45
45
  subject { Spanx::Notifier::Email.new(config) }
46
46
 
47
47
  let(:time_blocked) { Time.now }
48
- let(:period) { mock() }
48
+ let(:period) { double() }
49
49
  let(:action) { Spanx::IPChecker.new("1.2.3.4") }
50
50
  let(:blocked_ip) { Pause::RateLimitedEvent.new(action, period, 50, time_blocked) }
51
51
 
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spanx::Notifier::Slack do
4
+ subject { Spanx::Notifier::Slack.new(config) }
5
+
6
+ describe "#enabled?" do
7
+ context "with no slack configuration" do
8
+ let(:config) { {} }
9
+
10
+ it { should_not be_enabled }
11
+ end
12
+
13
+ context "with enabled slack configuration" do
14
+ let(:config) { {slack: {enabled: true}} }
15
+
16
+ it { should be_enabled }
17
+ end
18
+ end
19
+
20
+ describe '#endpoint' do
21
+ context 'when there is no configuration' do
22
+ let(:config) { {} }
23
+
24
+ it 'returns nil' do
25
+ expect(subject.endpoint).to be_nil
26
+ end
27
+ end
28
+
29
+ context 'when the configuration is set' do
30
+ let(:config) { {slack: {enabled: true, base_url: 'https://wanelo.slack.com', token: 'shipoopi'}} }
31
+
32
+ it 'should use base_url and token to generate the URL' do
33
+ expect(subject.endpoint.to_s).to eq('https://wanelo.slack.com/services/hooks/incoming-webhook?token=shipoopi')
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ describe "#publish" do
40
+ let(:blocked_ip) { double }
41
+ let(:blocked_ip_message) { 'shenanigans' }
42
+ let!(:stubbed_request) {
43
+ stub_request(:post, "https://wanelo.slack.com/services/hooks/incoming-webhook?token=shipoopi").
44
+ with(:body => "{\"text\":\"#{blocked_ip_message}\"}")
45
+ }
46
+
47
+ context 'when there is no configuration' do
48
+ let(:config) { {} }
49
+
50
+ it 'does not explode' do
51
+ expect { subject.publish(blocked_ip) }.to_not raise_error
52
+ end
53
+ end
54
+
55
+ context 'when it is disabled' do
56
+ let(:config) { { slack: { enabled: false }} }
57
+
58
+ it 'does not publish a message' do
59
+ subject.publish(blocked_ip)
60
+
61
+ expect(stubbed_request).to_not have_been_requested
62
+ end
63
+ end
64
+
65
+ context 'when it is enabled' do
66
+ let(:config) { {slack: {enabled: true, base_url: 'https://wanelo.slack.com', token: 'shipoopi'}} }
67
+
68
+ it 'should publish the message to the endpoint' do
69
+ allow(subject).to receive(:generate_block_ip_message).and_return(blocked_ip_message)
70
+
71
+ subject.publish(blocked_ip)
72
+
73
+ expect(stubbed_request).to have_been_requested
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,20 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Spanx::Runner do
4
- let(:config) { {:access_log => "logfile", :whitelist_file => "whitelist", :log_reader => {:tail_interval => 1}} }
4
+ let(:config) { {:access_log => 'logfile', :whitelist_file => 'whitelist', :log_reader => {:tail_interval => 1}} }
5
5
  let(:runner) { Spanx::Runner.new(config) }
6
6
  let(:faker) { double() }
7
7
 
8
- describe "#new" do
9
- it "should create a new thread queue" do
8
+ describe '#new' do
9
+ it 'should create a new thread queue' do
10
10
  runner.queue.should be_a(Queue)
11
11
  end
12
12
 
13
- context "actor initialization" do
14
- let(:collector) { mock("collector") }
15
- let(:writer) { mock("writer") }
16
- let(:log_reader) { mock("log_reader") }
17
- let(:analyzer) { mock("analyzer") }
13
+ context 'actor initialization' do
14
+ let(:collector) { double('collector') }
15
+ let(:writer) { double('writer') }
16
+ let(:log_reader) { double('log_reader') }
17
+ let(:analyzer) { double('analyzer') }
18
18
 
19
19
  before do
20
20
  Spanx::Runner.any_instance.stub(:collector).and_return(collector)
@@ -23,25 +23,25 @@ describe Spanx::Runner do
23
23
  Spanx::Runner.any_instance.stub(:analyzer).and_return(analyzer)
24
24
  end
25
25
 
26
- it "should match string args" do
27
- Spanx::Runner.new("collector", config).actors.should == [collector]
28
- Spanx::Runner.new("writer", config).actors.should == [writer]
29
- Spanx::Runner.new("log_reader", config).actors.should == [log_reader]
30
- Spanx::Runner.new("analyzer", config).actors.should == [analyzer]
31
- Spanx::Runner.new("collector", "analyzer", config).actors.should == [collector, analyzer]
26
+ it 'should match string args' do
27
+ Spanx::Runner.new('collector', config).actors.should == [collector]
28
+ Spanx::Runner.new('writer', config).actors.should == [writer]
29
+ Spanx::Runner.new('log_reader', config).actors.should == [log_reader]
30
+ Spanx::Runner.new('analyzer', config).actors.should == [analyzer]
31
+ Spanx::Runner.new('collector', 'analyzer', config).actors.should == [collector, analyzer]
32
32
  end
33
33
 
34
- it "raises if an invalid actor is passed" do
34
+ it 'raises if an invalid actor is passed' do
35
35
  lambda {
36
- Spanx::Runner.new("methods", config)
37
- }.should raise_error("Invalid actor")
36
+ Spanx::Runner.new('methods', config)
37
+ }.should raise_error('Invalid actor')
38
38
  end
39
39
  end
40
40
  end
41
41
 
42
- describe "#run" do
43
- let(:actor1) { mock("actor") }
44
- let(:actor2) { mock("actor") }
42
+ describe '#run' do
43
+ let(:actor1) { double('actor') }
44
+ let(:actor2) { double('actor') }
45
45
 
46
46
  before do
47
47
  actor1.should_receive(:run).and_return(actor1)
@@ -49,53 +49,53 @@ describe Spanx::Runner do
49
49
  actor2.should_receive(:join).and_return(true)
50
50
  end
51
51
 
52
- it "runs all actors and joins the last one" do
52
+ it 'runs all actors and joins the last one' do
53
53
  runner.actors = [actor1, actor2]
54
54
  runner.run
55
55
  end
56
56
  end
57
57
 
58
- describe "#collector" do
58
+ describe '#collector' do
59
59
  before { Spanx::Actor::Collector.should_receive(:new).with(config, runner.queue).and_return(faker) }
60
60
 
61
- it "should create a collector" do
61
+ it 'should create a collector' do
62
62
  runner.collector.should === faker
63
63
  end
64
64
  end
65
65
 
66
- describe "#whitelist" do
67
- before { Spanx::Whitelist.should_receive(:new).with("whitelist").and_return(faker) }
66
+ describe '#whitelist' do
67
+ before { Spanx::Whitelist.should_receive(:new).with('whitelist').and_return(faker) }
68
68
 
69
- it "should create a collector" do
69
+ it 'should create a collector' do
70
70
  runner.whitelist.should === faker
71
71
  end
72
72
  end
73
73
 
74
- describe "#log_reader" do
74
+ describe '#log_reader' do
75
75
  let(:whitelist) { double() }
76
76
 
77
77
  before do
78
78
  runner.should_receive(:whitelist).and_return(whitelist)
79
- Spanx::Actor::LogReader.should_receive(:new).with("logfile", runner.queue, 1, whitelist).and_return(faker)
79
+ Spanx::Actor::LogReader.should_receive(:new).with('logfile', runner.queue, 1, whitelist).and_return(faker)
80
80
  end
81
81
 
82
- it "should create a log reader" do
82
+ it 'should create a log reader' do
83
83
  runner.log_reader.should === faker
84
84
  end
85
85
  end
86
86
 
87
- describe "#analyzer" do
87
+ describe '#analyzer' do
88
88
  before { Spanx::Actor::Analyzer.should_receive(:new).with(config).and_return(faker) }
89
89
 
90
- it "should create an analyzer" do
90
+ it 'should create an analyzer' do
91
91
  runner.analyzer.should === faker
92
92
  end
93
93
  end
94
94
 
95
- describe "#writer" do
95
+ describe '#writer' do
96
96
  before { Spanx::Actor::Writer.should_receive(:new).with(config).and_return(faker) }
97
97
 
98
- it "should create an analyzer" do
98
+ it 'should create an analyzer' do
99
99
  runner.writer.should === faker
100
100
  end
101
101
  end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spanx::Usage do
4
+ describe 'usage' do
5
+ let(:usage) { Spanx::Usage.usage }
6
+ it 'should be set' do
7
+
8
+ expect(usage).to match /flush/
9
+ expect(usage).to match /analyze/
10
+ expect(usage).to match /Analyze IP traffic and save blocked IPs/
11
+ end
12
+ end
13
+ end
@@ -2,32 +2,32 @@ require 'spec_helper'
2
2
 
3
3
  describe Spanx::Whitelist do
4
4
  let(:whitelist) { Spanx::Whitelist.new(file) }
5
- let(:file) { "spec/fixtures/whitelist.txt" }
5
+ let(:file) { 'spec/fixtures/whitelist.txt' }
6
6
 
7
7
 
8
- describe "#new" do
9
- context "with filename" do
10
- it "loads whitelist patterns into memory" do
8
+ describe '#new' do
9
+ context 'with filename' do
10
+ it 'loads whitelist patterns into memory' do
11
11
  whitelist.patterns[0].should eql(/^127\.0\.0\.1/)
12
12
  whitelist.patterns[1].should eql(/^10\.1\.\d{1,3}\.\d{1,3}/)
13
- whitelist.patterns.each{ |p| p.is_a?(Regexp).should be_true }
13
+ whitelist.patterns.each{ |p| p.is_a?(Regexp).should be_truthy }
14
14
  end
15
15
  end
16
16
 
17
- context "without filename" do
17
+ context 'without filename' do
18
18
  let(:file) { nil }
19
19
 
20
- it "keeps an empty whitelist table" do
20
+ it 'keeps an empty whitelist table' do
21
21
  whitelist.patterns.should == []
22
22
  end
23
23
  end
24
24
 
25
- context "with non-existent file" do
26
- let(:file) { "non-existent-whitelist" }
25
+ context 'with non-existent file' do
26
+ let(:file) { 'non-existent-whitelist' }
27
27
 
28
- it "writes an error to stderr and exits" do
29
- $stderr.should_receive(:puts).with("Error: Unable to find whitelist file at #{file}")
30
- $stderr.should_receive(:puts).with(Spanx::USAGE)
28
+ it 'writes an error to stderr and exits' do
29
+ $stderr.should_receive(:puts).with("Error: Unable to find whitelist file at #{file}\n")
30
+ $stderr.should_receive(:puts).with(Spanx::Usage.usage)
31
31
 
32
32
  lambda {
33
33
  whitelist.patterns
@@ -37,28 +37,28 @@ describe Spanx::Whitelist do
37
37
  end
38
38
 
39
39
 
40
- describe "#match?" do
41
- context "IP address matching" do
40
+ describe '#match?' do
41
+ context 'IP address matching' do
42
42
  it 'is true if IP address is in match list' do
43
- whitelist.match?("127.0.0.1").should be_true
43
+ expect(whitelist.match?('127.0.0.1')).to be_truthy
44
44
  end
45
45
 
46
46
  it 'is false if IP address does not match patterns' do
47
- whitelist.match?("sadfasdf").should be_false
47
+ whitelist.match?('sadfasdf').should be_falsy
48
48
  end
49
49
  end
50
50
 
51
- context "User agent matches pattern" do
52
- let(:googlebot) { %Q{66.249.73.24 - - [18/Oct/2012:03:25:33 -0700] GET /p/2213071/39535615 HTTP/1.1 "200" 3943 "-" "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "2.87""Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "-"upstream_addr 127.0.0.1:8100upstream_response_time 0.082 request_time 0.082} }
53
- it "whitelists googlebot" do
54
- whitelist.match?(googlebot).should be_true
51
+ context 'User agent matches pattern' do
52
+ let(:googlebot) { '66.249.73.24 - - [18/Oct/2012:03:25:33 -0700] GET /p/2213071/39535615 HTTP/1.1 "200" 3943 "-" "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "2.87""Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "-"upstream_addr 127.0.0.1:8100upstream_response_time 0.082 request_time 0.082' }
53
+ it 'whitelists googlebot' do
54
+ whitelist.match?(googlebot).should be_truthy
55
55
  end
56
56
  end
57
57
 
58
- context "users/me matches" do
59
- let(:log) { %Q{66.249.73.24 - - [18/Oct/2012:03:25:33 -0700] GET /users/me HTTP/1.1 "200" 3943 "-" "-" "Mozilla/5.0 } }
60
- it "excludes users/me" do
61
- whitelist.match?(log).should be_true
58
+ context 'users/me matches' do
59
+ let(:log) { '66.249.73.24 - - [18/Oct/2012:03:25:33 -0700] GET /users/me HTTP/1.1 "200" 3943 "-" "-" "Mozilla/5.0 ' }
60
+ it 'excludes users/me' do
61
+ whitelist.match?(log).should be_truthy
62
62
  end
63
63
  end
64
64
 
@@ -9,6 +9,7 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
9
9
  require 'rubygems'
10
10
  require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
11
11
  require 'spanx'
12
+ require 'webmock/rspec'
12
13
 
13
14
  Dir['spec/support/**/*.rb'].each { |filename| require_relative "../#{filename}" }
14
15
 
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spanx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Konstantin Gredeskoul
@@ -10,182 +9,104 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-11-14 00:00:00.000000000 Z
12
+ date: 2014-11-13 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: pause
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ~>
18
+ - - ">="
21
19
  - !ruby/object:Gem::Version
22
- version: 0.0.4
20
+ version: '0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ~>
25
+ - - ">="
29
26
  - !ruby/object:Gem::Version
30
- version: 0.0.4
27
+ version: '0'
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: file-tail
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - ">="
37
33
  - !ruby/object:Gem::Version
38
34
  version: '0'
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - ">="
45
40
  - !ruby/object:Gem::Version
46
41
  version: '0'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: mixlib-cli
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - ">="
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0'
55
49
  type: :runtime
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - ">="
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: daemons
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - ">="
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :runtime
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - ">="
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: tinder
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
- - - ! '>='
74
+ - - ">="
85
75
  - !ruby/object:Gem::Version
86
76
  version: '0'
87
77
  type: :runtime
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
- - - ! '>='
81
+ - - ">="
93
82
  - !ruby/object:Gem::Version
94
83
  version: '0'
95
84
  - !ruby/object:Gem::Dependency
96
85
  name: mail
97
86
  requirement: !ruby/object:Gem::Requirement
98
- none: false
99
- requirements:
100
- - - ~>
101
- - !ruby/object:Gem::Version
102
- version: 2.4.4
103
- type: :runtime
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
- requirements:
108
- - - ~>
109
- - !ruby/object:Gem::Version
110
- version: 2.4.4
111
- - !ruby/object:Gem::Dependency
112
- name: rspec
113
- requirement: !ruby/object:Gem::Requirement
114
- none: false
115
87
  requirements:
116
- - - ! '>='
88
+ - - ">="
117
89
  - !ruby/object:Gem::Version
118
90
  version: '0'
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- none: false
123
- requirements:
124
- - - ! '>='
125
- - !ruby/object:Gem::Version
126
- version: '0'
127
- - !ruby/object:Gem::Dependency
128
- name: fakeredis
129
- requirement: !ruby/object:Gem::Requirement
130
- none: false
131
- requirements:
132
- - - ! '>='
133
- - !ruby/object:Gem::Version
134
- version: '0'
135
- type: :development
136
- prerelease: false
137
- version_requirements: !ruby/object:Gem::Requirement
138
- none: false
139
- requirements:
140
- - - ! '>='
141
- - !ruby/object:Gem::Version
142
- version: '0'
143
- - !ruby/object:Gem::Dependency
144
- name: timecop
145
- requirement: !ruby/object:Gem::Requirement
146
- none: false
147
- requirements:
148
- - - ! '>='
149
- - !ruby/object:Gem::Version
150
- version: '0'
151
- type: :development
152
- prerelease: false
153
- version_requirements: !ruby/object:Gem::Requirement
154
- none: false
155
- requirements:
156
- - - ! '>='
157
- - !ruby/object:Gem::Version
158
- version: '0'
159
- - !ruby/object:Gem::Dependency
160
- name: guard-rspec
161
- requirement: !ruby/object:Gem::Requirement
162
- none: false
163
- requirements:
164
- - - ! '>='
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- type: :development
91
+ type: :runtime
168
92
  prerelease: false
169
93
  version_requirements: !ruby/object:Gem::Requirement
170
- none: false
171
94
  requirements:
172
- - - ! '>='
95
+ - - ">="
173
96
  - !ruby/object:Gem::Version
174
97
  version: '0'
175
98
  - !ruby/object:Gem::Dependency
176
- name: rb-fsevent
99
+ name: webmachine
177
100
  requirement: !ruby/object:Gem::Requirement
178
- none: false
179
101
  requirements:
180
- - - ! '>='
102
+ - - ">="
181
103
  - !ruby/object:Gem::Version
182
104
  version: '0'
183
- type: :development
105
+ type: :runtime
184
106
  prerelease: false
185
107
  version_requirements: !ruby/object:Gem::Requirement
186
- none: false
187
108
  requirements:
188
- - - ! '>='
109
+ - - ">="
189
110
  - !ruby/object:Gem::Version
190
111
  version: '0'
191
112
  description: Real time IP parsing and rate detection gem for access_log files
@@ -197,11 +118,10 @@ executables:
197
118
  extensions: []
198
119
  extra_rdoc_files: []
199
120
  files:
200
- - .gitignore
201
- - .pairs
202
- - .rspec
203
- - .rvmrc
204
- - .travis.yml
121
+ - ".gitignore"
122
+ - ".rspec"
123
+ - ".rvmrc"
124
+ - ".travis.yml"
205
125
  - Gemfile
206
126
  - Guardfile
207
127
  - LICENSE
@@ -215,11 +135,17 @@ files:
215
135
  - lib/spanx/actor/collector.rb
216
136
  - lib/spanx/actor/log_reader.rb
217
137
  - lib/spanx/actor/writer.rb
138
+ - lib/spanx/api.rb
139
+ - lib/spanx/api/machine.rb
140
+ - lib/spanx/api/resources/blocked_ips.rb
141
+ - lib/spanx/api/resources/unblock_ip.rb
218
142
  - lib/spanx/cli.rb
219
143
  - lib/spanx/cli/analyze.rb
144
+ - lib/spanx/cli/api.rb
220
145
  - lib/spanx/cli/disable.rb
221
146
  - lib/spanx/cli/enable.rb
222
147
  - lib/spanx/cli/flush.rb
148
+ - lib/spanx/cli/report.rb
223
149
  - lib/spanx/cli/watch.rb
224
150
  - lib/spanx/config.rb
225
151
  - lib/spanx/helper.rb
@@ -232,6 +158,7 @@ files:
232
158
  - lib/spanx/notifier/base.rb
233
159
  - lib/spanx/notifier/campfire.rb
234
160
  - lib/spanx/notifier/email.rb
161
+ - lib/spanx/notifier/slack.rb
235
162
  - lib/spanx/runner.rb
236
163
  - lib/spanx/usage.rb
237
164
  - lib/spanx/version.rb
@@ -246,39 +173,42 @@ files:
246
173
  - spec/spanx/actor/collector_spec.rb
247
174
  - spec/spanx/actor/log_reader_spec.rb
248
175
  - spec/spanx/actor/writer_spec.rb
176
+ - spec/spanx/api/machine_spec.rb
177
+ - spec/spanx/cli/cli_spec.rb
249
178
  - spec/spanx/config_spec.rb
250
179
  - spec/spanx/helper/timing_spec.rb
251
180
  - spec/spanx/notifier/base_spec.rb
252
181
  - spec/spanx/notifier/campfire_spec.rb
253
182
  - spec/spanx/notifier/email_spec.rb
183
+ - spec/spanx/notifier/slack_spec.rb
254
184
  - spec/spanx/runner_spec.rb
185
+ - spec/spanx/usage_spec.rb
255
186
  - spec/spanx/whitelist_spec.rb
256
187
  - spec/spec_helper.rb
257
188
  - spec/support/fakeredis.rb
258
189
  - spec/support/mail.rb
259
190
  homepage: https://github.com/wanelo/spanx
260
191
  licenses: []
192
+ metadata: {}
261
193
  post_install_message:
262
194
  rdoc_options: []
263
195
  require_paths:
264
196
  - lib
265
197
  required_ruby_version: !ruby/object:Gem::Requirement
266
- none: false
267
198
  requirements:
268
- - - ! '>='
199
+ - - ">="
269
200
  - !ruby/object:Gem::Version
270
201
  version: '0'
271
202
  required_rubygems_version: !ruby/object:Gem::Requirement
272
- none: false
273
203
  requirements:
274
- - - ! '>='
204
+ - - ">="
275
205
  - !ruby/object:Gem::Version
276
206
  version: '0'
277
207
  requirements: []
278
208
  rubyforge_project:
279
- rubygems_version: 1.8.24
209
+ rubygems_version: 2.2.2
280
210
  signing_key:
281
- specification_version: 3
211
+ specification_version: 4
282
212
  summary: Real time IP parsing and rate detection gem for access_log files
283
213
  test_files:
284
214
  - spec/fixtures/access.log.1
@@ -290,13 +220,18 @@ test_files:
290
220
  - spec/spanx/actor/collector_spec.rb
291
221
  - spec/spanx/actor/log_reader_spec.rb
292
222
  - spec/spanx/actor/writer_spec.rb
223
+ - spec/spanx/api/machine_spec.rb
224
+ - spec/spanx/cli/cli_spec.rb
293
225
  - spec/spanx/config_spec.rb
294
226
  - spec/spanx/helper/timing_spec.rb
295
227
  - spec/spanx/notifier/base_spec.rb
296
228
  - spec/spanx/notifier/campfire_spec.rb
297
229
  - spec/spanx/notifier/email_spec.rb
230
+ - spec/spanx/notifier/slack_spec.rb
298
231
  - spec/spanx/runner_spec.rb
232
+ - spec/spanx/usage_spec.rb
299
233
  - spec/spanx/whitelist_spec.rb
300
234
  - spec/spec_helper.rb
301
235
  - spec/support/fakeredis.rb
302
236
  - spec/support/mail.rb
237
+ has_rdoc: