turnout 0.3.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4208ab9f575833c1136e95f562967f73c0d447ff
4
- data.tar.gz: abac3c012ceb68cab13c4f743cc4ba99dd781340
3
+ metadata.gz: 41d171143907e5993b28b8c17d1e45605ec22fbb
4
+ data.tar.gz: fc4f2847372f888e391d8afb282c4ad125d7534f
5
5
  SHA512:
6
- metadata.gz: db27f6aa29b51d5821f9ae79edb5aecc9be8e428c6684d791f65e47424e2342b7a826ae5bc4bd991ba2692f9a0df2e0adc775cce5c097e874568a1ca83dbf189
7
- data.tar.gz: 3285dd2df5fcefd131e1bde7ed4cef9f4c4f489380b25bd59b7c70fb8c6df5496dc3a078d832496bda6fe812131aec06e9fbad5c0feaeb9fdc596caba2fdb836
6
+ metadata.gz: 668f8abb73f83a5581f621e212783561a3334ced28a4348e4780de4c8025bcb190224bf6eca58c9aa3001f64e0264ad71c5e4945452e0c90fd7ea8eda76389a9
7
+ data.tar.gz: 4d962edd21460ec6814a46ff9d59bea226a54d146d8084fbb04d26f87145ec0354255d7675305bbd5a6c70fdf373497534769abbd477c0e73855f25c39f47572
data/README.markdown CHANGED
@@ -1,6 +1,6 @@
1
- Turnout [![Build Status](https://travis-ci.org/biola/turnout.png?branch=master)](https://travis-ci.org/biola/turnout)
1
+ Turnout [![Build Status](https://travis-ci.org/biola/turnout.png?branch=master)](https://travis-ci.org/biola/turnout) [![Code Climate](https://codeclimate.com/github/biola/turnout.png)](https://codeclimate.com/github/biola/turnout)
2
2
  =======
3
- Turnout is a [Ruby on Rails](http://rubyonrails.org) engine with a [Rack](http://rack.rubyforge.org/) component that allows you to put your Rails app in maintenance mode.
3
+ Turnout is [Rack](http://rack.rubyforge.org/) middleware with a [Ruby on Rails](http://rubyonrails.org) engine that allows you to easily put your app in maintenance mode.
4
4
 
5
5
  Features
6
6
  ========
@@ -11,11 +11,12 @@ Features
11
11
  * Allow certain paths to be accessible during maintenance
12
12
  * Easily override the default maintenance.html file with your own
13
13
  * Simple [YAML](http://yaml.org) based config file for easy activation, deactivation and configuration without the rake commands
14
- * Supports Rails 2.3 - 3.0 and Ruby 1.8.7 - 1.9.3
14
+ * SUpport for multiple maintenance page formats. Current [HTML](http://en.wikipedia.org/wiki/HTML) and [JSON](http://en.wikipedia.org/wiki/JSON)
15
+ * Supports Rails, [Sinatra](http://sinatrarb.com) and any other Rack application
15
16
 
16
17
  Installation
17
18
  ============
18
- Rails 3
19
+ Rails 3+
19
20
  -------
20
21
  In your `Gemfile` add:
21
22
 
@@ -25,20 +26,6 @@ then run
25
26
 
26
27
  bundle install
27
28
 
28
- Rails 2.3
29
- ---------
30
- In your `config/environment.rb` file add:
31
-
32
- config.gem 'turnout'
33
-
34
- then run
35
-
36
- rake gems:install
37
-
38
- then in your `Rakefile` add:
39
-
40
- require 'turnout/rake_tasks'
41
-
42
29
 
43
30
  Activation
44
31
  ==========
@@ -74,10 +61,54 @@ Deactivation
74
61
 
75
62
  rake maintenance:end
76
63
 
64
+ Configuration
65
+ =============
66
+
67
+ Turnout can be configured in two different ways:
68
+
69
+ 1. __Pass a config hash to the middleware__
70
+
71
+ ```ruby
72
+ use Rack::Turnout,
73
+ app_root: '/some/path',
74
+ named_maintenance_file_paths: {app: 'tmp/app.yml', server: '/tmp/server.yml'},
75
+ default_mainteance_page: Turnout::MaintenancePage::JSON,
76
+ default_reason: 'Somebody googled Google!',
77
+ default_response_code: 418
78
+ ```
79
+
80
+ 2. __Using a config block__
81
+
82
+ ```ruby
83
+ Turonut.configure do |config|
84
+ config.app_root = '/some/path'
85
+ config.named_maintenance_file_paths = {app: 'tmp/app.yml', server: '/tmp/server.yml'},
86
+ config.default_maintenance_page = Turnout::MaintenancePage::JSON
87
+ config.default_reason = 'Somebody googled Google!'
88
+ config.default_response_code = 418
89
+ end
90
+ ```
91
+
92
+ __NOTICE:__ Any custom configuration should be loaded not only in the app but in the rake task. This should happen automatically in Rails as the `environment` task is run if it exists. But you may want to create your own `environment` task in non-Rails apps.
93
+
94
+ Default Configuration
95
+ ---------------------
96
+
97
+ ```ruby
98
+ Turnout.configure do |config|
99
+ config.app_root = '.',
100
+ config.named_maintenance_file_paths = {default: app_root.join('tmp', 'maintenance.yml').to_s},
101
+ config.default_maintenance_page = Turnout::MaintenancePage::HTML,
102
+ config.default_reason = "The site is temporarily down for maintenance.\nPlease check back soon.",
103
+ config.default_response_code = 503
104
+ end
105
+ }
106
+ ```
107
+
77
108
  Customization
78
109
  =============
79
110
 
80
- A [default maintenance page](https://github.com/biola/turnout/blob/master/public/maintenance.html) is provided, but you can create your own `public/maintenance.html` instead. If you provide a `reason` to the rake task, Turnout will use [Nokogiri](http://nokogiri.org) to parse the `maintenance.html` file and attempt to find a tag with `id="reason"`. It will replace the `inner_html` of the tag with the reason you provided. So be sure your `maintenance.html` file can be parsed as HTML.
111
+ [Default maintenance pages](https://github.com/biola/turnout/blob/master/public/) are provided, but you can create your own `public/maintenance.[html|json]` files instead. If you provide a `reason` to the rake task, Turnout will parse the maintenance page file and attempt to replace a [Liquid](http://liquidmarkup.org/)-style `{{ reason }}` tag with the provided reason. So be sure to include a `{{ reason }}` tag in your `maintenance.html` file.
81
112
 
82
113
  Tips
83
114
  ====
@@ -88,22 +119,27 @@ However you can achieve the same sort of functionality by using
88
119
 
89
120
  rake maintenance:start allowed_paths="^(?!/your/under/maintenance/path)"
90
121
 
122
+ A central `named_maintenance_file_path` can be configured in all your apps such as `/tmp/turnout.yml` so that all apps on a server can be put into mainteance mode at once. You could even configure service based paths such as `/tmp/mongodb_maintenance.yml` so that all apps using MongoDB could be put into maintenance mode.
123
+
91
124
  Behind the Scenes
92
125
  =================
93
126
  On every request the Rack app will check to see if `tmp/maintenance.yml` exists. If the file exists the maintenance page will be shown (unless allowed IPs are given and the requester is in the allowed range).
94
127
 
95
- So if you want to get the maintenance page up or down in a hury `touch tmp/maintenance.yml` and `rm tmp/maintenance.yml` will work.
128
+ So if you want to get the maintenance page up or down in a hurry `touch tmp/maintenance.yml` and `rm tmp/maintenance.yml` will work.
96
129
 
97
- Turnout will attempt to parse the `maintenance.yml` file looking for `reason` and `allowed_ip` settings. The file is not cached so you can change these values manually or just rerun the `rake maintenance:start` command.
130
+ Turnout will attempt to parse the `maintenance.yml` file looking for `reason`, `allowed_ip` and other settings. The file is checked on every request so you can change these values manually or just rerun the `rake maintenance:start` command.
98
131
 
99
132
  Example maintenance.yml File
100
133
  ----------------------------
101
134
 
102
- ---
103
- reason: Someone told me I should type <code>sudo rm -rf /</code>
104
- allowed_paths:
105
- - ^/help
106
- - ^/contact_us
107
- allowed_ips:
108
- - 127.0.0.1
109
- - 192.168.0.0/24
135
+ ```yaml
136
+ ---
137
+ reason: Someone told me I should type <code>sudo rm -rf /</code>
138
+ allowed_paths:
139
+ - ^/help
140
+ - ^/contact_us
141
+ allowed_ips:
142
+ - 127.0.0.1
143
+ - 192.168.0.0/24
144
+ response_code: 503
145
+ ```
data/lib/rack/turnout.rb CHANGED
@@ -1,111 +1,28 @@
1
1
  require 'rack'
2
- require 'yaml'
3
- require 'ipaddr'
4
- require 'nokogiri'
2
+ require 'turnout'
5
3
 
6
4
  class Rack::Turnout
7
5
  def initialize(app, config={})
8
6
  @app = app
9
- @config = config
10
- end
11
7
 
12
- def call(env)
13
- self.request = Rack::Request.new(env)
14
- reload_settings
8
+ Turnout.config.update config
15
9
 
16
- if on?
17
- [ response_code, { 'Content-Type' => 'text/html', 'Content-Length' => content_length }, [content] ]
18
- else
19
- @app.call(env)
10
+ if config[:app_root].nil? && app.respond_to?(:app_root)
11
+ Turnout.config.app_root = app.app_root
20
12
  end
21
13
  end
22
14
 
23
- protected
24
-
25
- attr_accessor :request
26
-
27
- def on?
28
- maintenance_file_exists? && !request_allowed?
29
- end
30
-
31
- def request_allowed?
32
- path_allowed? || ip_allowed?
33
- end
34
-
35
- def path_allowed?
36
- (settings['allowed_paths'] || []).any? do |allowed_path|
37
- request.path =~ Regexp.new(allowed_path)
38
- end
39
- end
40
-
41
- def ip_allowed?
42
- begin
43
- ip = IPAddr.new(request.ip.to_s)
44
- rescue ArgumentError
45
- return false
46
- end
47
-
48
- (settings['allowed_ips'] || []).any? do |allowed_ip|
49
- IPAddr.new(allowed_ip).include? ip
50
- end
51
- end
15
+ def call(env)
16
+ request = Turnout::Request.new(env)
17
+ settings = Turnout::MaintenanceFile.find
52
18
 
53
- def reload_settings
54
- @settings = nil
55
- settings
56
- end
19
+ if settings && !request.allowed?(settings)
20
+ page_class = Turnout::MaintenancePage.best_for(env)
21
+ page = page_class.new(settings.reason)
57
22
 
58
- def settings
59
- @settings ||= if File.exists? settings_file
60
- YAML::load(File.open(settings_file)) || {}
23
+ page.rack_response(settings.response_code)
61
24
  else
62
- {}
63
- end
64
- end
65
-
66
- def app_root
67
- @app_root ||= Pathname.new(
68
- @config[:app_root] || @app.respond_to?(:root)? @app.root.to_s : '.'
69
- )
70
- end
71
-
72
- def settings_file
73
- app_root.join('tmp', 'maintenance.yml')
74
- end
75
-
76
- def maintenance_file_exists?
77
- File.exists? settings_file
78
- end
79
-
80
- def maintenance_page
81
- File.exists?(app_maintenance_page) ? app_maintenance_page : default_maintenance_page
82
- end
83
-
84
- def app_maintenance_page
85
- @app_maintenance_page ||= app_root.join('public', 'maintenance.html')
86
- end
87
-
88
- def default_maintenance_page
89
- @default_maintenance_page ||= File.expand_path('../../../public/maintenance.html', __FILE__)
90
- end
91
-
92
- def content_length
93
- content.size.to_s
94
- end
95
-
96
- def content
97
- content = File.open(maintenance_page, 'rb').read
98
-
99
- if settings['reason']
100
- html = Nokogiri::HTML(content)
101
- html.at_css('#reason').inner_html = Nokogiri::HTML.fragment(settings['reason'])
102
- content = html.to_s
25
+ @app.call(env)
103
26
  end
104
-
105
- content
106
- end
107
-
108
- def response_code
109
- settings['response_code'] || 503
110
27
  end
111
28
  end
@@ -1,45 +1,48 @@
1
+ require 'turnout'
2
+
1
3
  namespace :maintenance do
2
- desc 'Enable the maintenance mode page ("reason", "allowed_paths" and "allowed_ips" can be passed as environment variables)'
3
- task :start do |t, args|
4
- settings = {
5
- 'reason' => ENV['reason'],
6
- 'allowed_paths' => split_paths(ENV['allowed_paths']),
7
- 'allowed_ips' => split_ips(ENV['allowed_ips']),
8
- 'response_code' => ENV['response_code']
9
- }
10
-
11
- file = File.open settings_file, 'w'
12
- file.write settings.to_yaml
13
- file.close
14
-
15
- puts "Created #{settings_file}"
16
- puts "Run `rake maintenance:end` to stop maintenance mode"
4
+ desc 'Enable the maintenance mode page ("reason", "allowed_paths", "allowed_ips" and "response_code" can be passed as environment variables)'
5
+ rule /\Amaintenance:(.*:|)start\Z/ do |task|
6
+ invoke_environment
7
+
8
+ maint_file = maintenance_file_for(task)
9
+ maint_file.import_env_vars(ENV)
10
+ maint_file.write
11
+
12
+ puts "Created #{maint_file.path}"
13
+ puts "Run `rake #{task.name.gsub(/\:start/, ':end')}` to stop maintenance mode"
17
14
  end
18
15
 
19
16
  desc 'Disable the maintenance mode page'
20
- task :end do
21
- File.delete settings_file
17
+ rule /\Amaintenance:(.*:|)end\Z/ do |task|
18
+ invoke_environment
19
+
20
+ maint_file = maintenance_file_for(task)
22
21
 
23
- puts "Deleted #{settings_file}"
22
+ if maint_file.delete
23
+ puts "Deleted #{maint_file.path}"
24
+ else
25
+ fail 'Could not find a maintenance file to delete'
26
+ end
24
27
  end
25
28
 
26
- def settings_file
27
- Rails.root.join('tmp', 'maintenance.yml')
29
+ def invoke_environment
30
+ if Rake::Task.task_defined? 'environment'
31
+ Rake::Task['environment'].invoke
32
+ end
28
33
  end
29
34
 
30
- def split_paths(paths_string)
31
- # I had this for 1.9.2 but no lookbehinds in 1.8.7 :(
32
- #paths = paths_string.to_s.split(/(?<!\\),\ ?/)
35
+ def maintenance_file_for(task)
36
+ path_name = (task.name.split(':') - ['maintenance', 'start', 'end']).join(':')
33
37
 
34
- # Grab everything between commas that aren't escaped with a backslash
35
- paths = paths_string.to_s.scan(/(?:\\,|[^,])+/)
36
- paths.map! do |path|
37
- path.strip.gsub('\,', ',') # remove the escape characters
38
+ maint_file = if path_name == ''
39
+ Turnout::MaintenanceFile.default
40
+ else
41
+ Turnout::MaintenanceFile.named(path_name)
38
42
  end
39
- paths
40
- end
41
43
 
42
- def split_ips(ips_string)
43
- ips_string.to_s.split(',')
44
+ fail %{Unknown path name: "#{path_name}"} if maint_file.nil?
45
+
46
+ maint_file
44
47
  end
45
48
  end
@@ -0,0 +1,36 @@
1
+ module Turnout
2
+ class Configuration
3
+ SETTINGS = [:app_root, :named_maintenance_file_paths, :default_maintenance_page, :default_reason, :default_response_code]
4
+
5
+ SETTINGS.each do |setting|
6
+ attr_accessor setting
7
+ end
8
+
9
+ def initialize
10
+ @app_root = '.'
11
+ @named_maintenance_file_paths = {default: app_root.join('tmp', 'maintenance.yml').to_s}
12
+ @default_maintenance_page = Turnout::MaintenancePage::HTML
13
+ @default_reason = "The site is temporarily down for maintenance.\nPlease check back soon."
14
+ @default_response_code = 503
15
+ end
16
+
17
+ def app_root
18
+ Pathname.new(@app_root.to_s)
19
+ end
20
+
21
+ def named_maintenance_file_paths=(named_paths)
22
+ # Force keys to symbols
23
+ @named_maintenance_file_paths = Hash[named_paths.map { |k, v| [k.to_sym, v] }]
24
+ end
25
+
26
+ def update(settings_hash)
27
+ settings_hash.each do |setting, value|
28
+ unless SETTINGS.include? setting.to_sym
29
+ raise ArgumentError, "invalid setting: #{setting}"
30
+ end
31
+
32
+ self.public_send "#{setting}=", value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,114 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+
4
+ module Turnout
5
+ class MaintenanceFile
6
+ attr_reader :path
7
+
8
+ SETTINGS = [:reason, :allowed_paths, :allowed_ips, :response_code]
9
+ attr_reader *SETTINGS
10
+
11
+ def initialize(path)
12
+ @path = path
13
+ @reason = Turnout.config.default_reason
14
+ @allowed_paths = []
15
+ @allowed_ips = []
16
+ @response_code = Turnout.config.default_response_code
17
+
18
+ import_yaml if exists?
19
+ end
20
+
21
+ def exists?
22
+ File.exists? path
23
+ end
24
+
25
+ def to_h
26
+ SETTINGS.each_with_object({}) do |att, hash|
27
+ hash[att] = send(att)
28
+ end
29
+ end
30
+
31
+ def to_yaml(key_mapper = :to_s)
32
+ to_h.each_with_object({}) { |(key, val), hash|
33
+ hash[key.send(key_mapper)] = val
34
+ }.to_yaml
35
+ end
36
+
37
+ def write
38
+ FileUtils.mkdir_p(dir_path) unless Dir.exists? dir_path
39
+
40
+ File.open(path, 'w') do |file|
41
+ file.write to_yaml
42
+ end
43
+ end
44
+
45
+ def delete
46
+ File.delete(path) if exists?
47
+ end
48
+
49
+ def import(hash)
50
+ SETTINGS.map(&:to_s).each do |att|
51
+ self.send(:"#{att}=", hash[att]) unless hash[att].nil?
52
+ end
53
+
54
+ true
55
+ end
56
+ alias :import_env_vars :import
57
+
58
+ # Find the first MaintenanceFile that exists
59
+ def self.find
60
+ path = named_paths.values.find { |path| File.exists? path }
61
+ self.new(path) if path
62
+ end
63
+
64
+ def self.named(name)
65
+ path = named_paths[name.to_sym]
66
+ self.new(path) unless path.nil?
67
+ end
68
+
69
+ def self.default
70
+ self.new(named_paths.values.first)
71
+ end
72
+
73
+ private
74
+
75
+ def reason=(reason)
76
+ @reason = reason.to_s
77
+ end
78
+
79
+ # Splits strings on commas for easier importing of environment variables
80
+ def allowed_paths=(paths)
81
+ if paths.is_a? String
82
+ # Grab everything between commas that aren't escaped with a backslash
83
+ paths = paths.to_s.split(/(?<!\\),\ ?/).map do |path|
84
+ path.strip.gsub('\,', ',') # remove the escape characters
85
+ end
86
+ end
87
+
88
+ @allowed_paths = paths
89
+ end
90
+
91
+ # Splits strings on commas for easier importing of environment variables
92
+ def allowed_ips=(ips)
93
+ ips = ips.to_s.split(',') if ips.is_a? String
94
+
95
+ @allowed_ips = ips
96
+ end
97
+
98
+ def response_code=(code)
99
+ @response_code = code.to_i
100
+ end
101
+
102
+ def dir_path
103
+ File.dirname(path)
104
+ end
105
+
106
+ def import_yaml
107
+ import YAML::load(File.open(path)) || {}
108
+ end
109
+
110
+ def self.named_paths
111
+ Turnout.config.named_maintenance_file_paths
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,73 @@
1
+ module Turnout
2
+ module MaintenancePage
3
+ class Base
4
+ attr_reader :reason
5
+
6
+ def initialize(reason = nil)
7
+ @reason = reason
8
+ end
9
+
10
+ def rack_response(code = Turnout.config.default_response_code)
11
+ [code, headers, body]
12
+ end
13
+
14
+ # Override with an array of media type strings. i.e. text/html
15
+ def self.media_types
16
+ raise NotImplementedError, '.media_types must be overridden in subclasses'
17
+ end
18
+ def media_types() self.class.media_types end
19
+
20
+ # Override with a file extension value like 'html' or 'json'
21
+ def self.extension
22
+ raise NotImplementedError, '.extension must be overridden in subclasses'
23
+ end
24
+ def extension() self.class.extension end
25
+
26
+ protected
27
+
28
+ def self.inherited(subclass)
29
+ MaintenancePage.all << subclass
30
+ end
31
+
32
+ def headers
33
+ {'Content-Type' => media_types.first, 'Content-Length' => length}
34
+ end
35
+
36
+ def length
37
+ content.size.to_s
38
+ end
39
+
40
+ def body
41
+ [content]
42
+ end
43
+
44
+ def content
45
+ file_content.gsub /{{\s?reason\s?}}/, reason
46
+ end
47
+
48
+ def file_content
49
+ File.read(path)
50
+ end
51
+
52
+ def path
53
+ if File.exists? custom_path
54
+ custom_path
55
+ else
56
+ default_path
57
+ end
58
+ end
59
+
60
+ def default_path
61
+ File.expand_path("../../../../public/#{filename}", __FILE__)
62
+ end
63
+
64
+ def custom_path
65
+ Turnout.config.app_root.join('public', filename)
66
+ end
67
+
68
+ def filename
69
+ "maintenance.#{extension}"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,20 @@
1
+ module Turnout
2
+ module MaintenancePage
3
+ class HTML < Base
4
+ def reason
5
+ super.to_s.split("\n").map{|txt| "<p>#{txt}</p>" }.join("\n")
6
+ end
7
+
8
+ def self.media_types
9
+ %w{
10
+ text/html
11
+ application/xhtml+xml
12
+ }
13
+ end
14
+
15
+ def self.extension
16
+ 'html'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ require 'json'
2
+
3
+ module Turnout
4
+ module MaintenancePage
5
+ class JSON < Base
6
+ def reason
7
+ super.to_s.to_json
8
+ end
9
+
10
+ def self.media_types
11
+ %w{
12
+ application/json
13
+ text/json
14
+ application/x-javascript
15
+ text/javascript
16
+ text/x-javascript
17
+ text/x-json
18
+ }
19
+ end
20
+
21
+ def self.extension
22
+ 'json'
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ module Turnout
2
+ module MaintenancePage
3
+ require 'rack/accept'
4
+
5
+ def self.all
6
+ @all ||= []
7
+ end
8
+
9
+ def self.best_for(env)
10
+ request = Rack::Accept::Request.new(env)
11
+
12
+ all_types = all.map(&:media_types).flatten
13
+ best_type = request.best_media_type(all_types)
14
+
15
+ best = all.find { |page| page.media_types.include? best_type }
16
+
17
+ best || Turnout.default_maintenance_page
18
+ end
19
+
20
+ require 'turnout/maintenance_page/base'
21
+ require 'turnout/maintenance_page/html'
22
+ require 'turnout/maintenance_page/json'
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ require 'ipaddr'
2
+
3
+ module Turnout
4
+ class Request
5
+ def initialize(env)
6
+ @rack_request = Rack::Request.new(env)
7
+ end
8
+
9
+ def allowed?(settings)
10
+ path_allowed?(settings.allowed_paths) || ip_allowed?(settings.allowed_ips)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :rack_request
16
+
17
+ def path_allowed?(allowed_paths)
18
+ allowed_paths.any? do |allowed_path|
19
+ rack_request.path =~ Regexp.new(allowed_path)
20
+ end
21
+ end
22
+
23
+ def ip_allowed?(allowed_ips)
24
+ begin
25
+ ip = IPAddr.new(rack_request.ip.to_s)
26
+ rescue ArgumentError
27
+ return false
28
+ end
29
+
30
+ allowed_ips.any? do |allowed_ip|
31
+ IPAddr.new(allowed_ip).include? ip
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module Turnout
2
- VERSION = '0.3.0'
2
+ VERSION = '1.0.0'
3
3
  end
data/lib/turnout.rb CHANGED
@@ -1,3 +1,15 @@
1
1
  module Turnout
2
+ require 'turnout/configuration'
3
+ require 'turnout/maintenance_file'
4
+ require 'turnout/maintenance_page'
5
+ require 'turnout/request'
2
6
  require 'turnout/engine' if defined? Rails
7
+
8
+ def self.configure
9
+ yield config
10
+ end
11
+
12
+ def self.config
13
+ @config ||= Configuration.new
14
+ end
3
15
  end
@@ -58,9 +58,8 @@
58
58
  </header>
59
59
 
60
60
  <section id="body">
61
- <div id="reason">
62
- <p>The site is temporarily down for maintenance.</p>
63
- <p>Please check back soon.</p>
61
+ <div>
62
+ {{ reason }}
64
63
  </div>
65
64
  </section>
66
65
 
@@ -0,0 +1 @@
1
+ {"error":"Service Unavailable","message":{{ reason }}}
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turnout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Crownoble
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-08 00:00:00.000000000 Z
11
+ date: 2014-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: nokogiri
14
+ name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rack
28
+ name: rack-accept
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '0.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack-test
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,10 +78,18 @@ files:
78
78
  - lib/rack/turnout.rb
79
79
  - lib/tasks/maintenance.rake
80
80
  - lib/turnout.rb
81
+ - lib/turnout/configuration.rb
81
82
  - lib/turnout/engine.rb
83
+ - lib/turnout/maintenance_file.rb
84
+ - lib/turnout/maintenance_page.rb
85
+ - lib/turnout/maintenance_page/base.rb
86
+ - lib/turnout/maintenance_page/html.rb
87
+ - lib/turnout/maintenance_page/json.rb
82
88
  - lib/turnout/rake_tasks.rb
89
+ - lib/turnout/request.rb
83
90
  - lib/turnout/version.rb
84
91
  - public/maintenance.html
92
+ - public/maintenance.json
85
93
  - rails/init.rb
86
94
  homepage: https://github.com/biola/turnout
87
95
  licenses:
@@ -108,3 +116,4 @@ signing_key:
108
116
  specification_version: 4
109
117
  summary: A Rack based maintenance mode plugin for Rails
110
118
  test_files: []
119
+ has_rdoc: