spanx 0.1.1 → 0.3.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,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: