ops 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -0
- data/README.md +38 -2
- data/examples/rails3/config/application.rb +3 -0
- data/examples/sinatra/config.ru +3 -0
- data/lib/ops/revision.rb +9 -1
- data/lib/ops/server.rb +13 -0
- data/lib/ops/version.rb +1 -1
- data/spec/ops/revision_spec.rb +3 -2
- data/spec/ops/server_spec.rb +66 -0
- metadata +3 -5
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -35,6 +35,7 @@ GEM
|
|
35
35
|
arel (4.0.0)
|
36
36
|
atomic (1.1.10)
|
37
37
|
builder (3.1.4)
|
38
|
+
coderay (1.1.0)
|
38
39
|
diff-lcs (1.2.4)
|
39
40
|
erubis (2.7.0)
|
40
41
|
hike (1.2.3)
|
@@ -42,10 +43,15 @@ GEM
|
|
42
43
|
mail (2.5.4)
|
43
44
|
mime-types (~> 1.16)
|
44
45
|
treetop (~> 1.4.8)
|
46
|
+
method_source (0.8.2)
|
45
47
|
mime-types (1.23)
|
46
48
|
minitest (4.7.5)
|
47
49
|
multi_json (1.7.7)
|
48
50
|
polyglot (0.3.3)
|
51
|
+
pry (0.9.12.6)
|
52
|
+
coderay (~> 1.0)
|
53
|
+
method_source (~> 0.8)
|
54
|
+
slop (~> 3.4)
|
49
55
|
rack (1.5.2)
|
50
56
|
rack-protection (1.5.1)
|
51
57
|
rack
|
@@ -87,6 +93,7 @@ GEM
|
|
87
93
|
tilt (~> 1.3, >= 1.3.4)
|
88
94
|
sinatra-respond_to (0.9.0)
|
89
95
|
sinatra (~> 1.3)
|
96
|
+
slop (3.5.0)
|
90
97
|
sprockets (2.10.0)
|
91
98
|
hike (~> 1.2)
|
92
99
|
multi_json (~> 1.0)
|
@@ -110,6 +117,7 @@ PLATFORMS
|
|
110
117
|
|
111
118
|
DEPENDENCIES
|
112
119
|
ops!
|
120
|
+
pry
|
113
121
|
rack-test
|
114
122
|
rails
|
115
123
|
rails-api
|
data/README.md
CHANGED
@@ -3,7 +3,14 @@ Ops
|
|
3
3
|
|
4
4
|
[![Code Climate](https://codeclimate.com/github/primedia/ops.png)](https://codeclimate.com/github/primedia/ops)
|
5
5
|
|
6
|
-
This gem provides standardized support for obtaining version and heartbeat information from Sinatra or Rails-based web applications.
|
6
|
+
This gem provides standardized support for obtaining environment, version, and heartbeat information from Sinatra or Rails-based web applications.
|
7
|
+
|
8
|
+
**You will likely want to block or restrict access to the following routes:**
|
9
|
+
|
10
|
+
Route | Notes
|
11
|
+
--------------| -----
|
12
|
+
`/ops/env` | Exposes all of your environment variables (e.g. any API keys set as environment variables) to the public
|
13
|
+
`/ops/config` | Exposes all of your configuration keys and values to the public (if you're using a configuration service).
|
7
14
|
|
8
15
|
Typical usage:
|
9
16
|
|
@@ -11,6 +18,8 @@ Typical usage:
|
|
11
18
|
/ops/version - displays version info as HTML
|
12
19
|
/ops/version.json - displays version info as JSON
|
13
20
|
/ops/heartbeat - returns 'OK' if the app is alive
|
21
|
+
/ops/env - display the currently set environment variables
|
22
|
+
/ops/config - display all configuration values as JSON (optional)
|
14
23
|
```
|
15
24
|
|
16
25
|
This gem replaces the now-deprecated [ops_routes](https://github.com/primedia/ops_routes).
|
@@ -31,6 +40,7 @@ Installation
|
|
31
40
|
Ops.setup do |config|
|
32
41
|
config.file_root = Rails.root
|
33
42
|
config.environment = Rails.env
|
43
|
+
config.config_service_adapter = something_that_responds_to_call # optional
|
34
44
|
end
|
35
45
|
```
|
36
46
|
|
@@ -58,6 +68,7 @@ Installation
|
|
58
68
|
Ops.setup do |config|
|
59
69
|
config.file_root = File.dirname __FILE__
|
60
70
|
config.environment = ENV['RACK_ENV']
|
71
|
+
config.config_service_adapter = something_that_responds_to_call # optional
|
61
72
|
end
|
62
73
|
|
63
74
|
run Rack::URLMap.new \
|
@@ -82,9 +93,34 @@ Additionally, you can specify custom heartbeat monitoring pages as follows:
|
|
82
93
|
```ruby
|
83
94
|
Ops.add_heartbeat :mysql do
|
84
95
|
conn = ActiveRecord::Base.connection
|
85
|
-
migrations = conn.select_all("SELECT COUNT(1) FROM schema_migrations;")
|
96
|
+
migrations = conn.select_all("SELECT COUNT(1) FROM schema_migrations;")
|
86
97
|
conn.disconnect!
|
87
98
|
end
|
88
99
|
```
|
89
100
|
|
90
101
|
The mysql example shown above would be accessed at ops/heartbeat/mysql. The heartbeat page will return a `200 ‘OK’` as long as the provided block returns true. If an error is raised, the heartbeat does not exist, or the block returns a falsey value, a `500` will be returned instead.
|
102
|
+
|
103
|
+
|
104
|
+
## The Configuration Service Adapter (Optional)
|
105
|
+
|
106
|
+
If you wish to use the optional configuration service, you must provide
|
107
|
+
something that responds to `#call` with an optional `Hash` argument.
|
108
|
+
|
109
|
+
For example:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
class MyConfigurationService
|
113
|
+
def call(options = {})
|
114
|
+
{ key: 'value' }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
or
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
Proc.new { |_| { key: 'value' } }
|
123
|
+
```
|
124
|
+
|
125
|
+
Then just provide your "callable" per the installation instructions above.
|
126
|
+
|
@@ -28,6 +28,9 @@ module Rails3
|
|
28
28
|
Ops.setup do |config|
|
29
29
|
config.file_root = File.join(Rails.root,'/../sample_deploys/4123')
|
30
30
|
config.environment = Rails.env
|
31
|
+
|
32
|
+
# Optionally use a configuration service
|
33
|
+
# config.config_service_adapter = something_that_responds_to_call
|
31
34
|
end
|
32
35
|
|
33
36
|
end
|
data/examples/sinatra/config.ru
CHANGED
@@ -10,6 +10,9 @@ use Rack::ShowExceptions
|
|
10
10
|
Ops.setup do |config|
|
11
11
|
config.file_root = '../sample_deploys/4123'
|
12
12
|
config.environment = ENV['RACK_ENV']
|
13
|
+
|
14
|
+
# Optionally use a configuration service
|
15
|
+
# config.config_service_adapter = something_that_responds_to_call
|
13
16
|
end
|
14
17
|
|
15
18
|
run Rack::URLMap.new \
|
data/lib/ops/revision.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Ops
|
2
2
|
class Revision
|
3
|
+
attr_writer :branch_source
|
4
|
+
|
3
5
|
def initialize(new_headers={}, opts = Ops.config)
|
4
6
|
@file_root = opts.file_root.to_s # convert to string in case they pass us a Pathname
|
5
7
|
@environment = opts.environment
|
@@ -9,7 +11,7 @@ module Ops
|
|
9
11
|
def version_or_branch
|
10
12
|
@version ||= if version_file?
|
11
13
|
chomp(version_file).gsub('^{}', '')
|
12
|
-
elsif development? &&
|
14
|
+
elsif development? && branch_source.call =~ /^\* (.*)$/
|
13
15
|
$1
|
14
16
|
else
|
15
17
|
'Unknown (VERSION file is missing)'
|
@@ -113,5 +115,11 @@ module Ops
|
|
113
115
|
def headers
|
114
116
|
@headers.select{|k,v| k.match(/^[-A-Z_].*$/) }
|
115
117
|
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def branch_source
|
122
|
+
@branch_source ||= ->{ `git branch` }
|
123
|
+
end
|
116
124
|
end
|
117
125
|
end
|
data/lib/ops/server.rb
CHANGED
@@ -52,6 +52,19 @@ module Ops
|
|
52
52
|
"#{name} does not have a heartbeat"
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
56
|
+
get '/config/?' do
|
57
|
+
if config_adapter = Ops.config.config_service_adapter
|
58
|
+
begin
|
59
|
+
body config_adapter.call(params).to_json
|
60
|
+
rescue StandardError => e
|
61
|
+
status 422
|
62
|
+
body({ 'error' => e.message }.to_json)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
status 501
|
66
|
+
end
|
67
|
+
end
|
55
68
|
end
|
56
69
|
end
|
57
70
|
|
data/lib/ops/version.rb
CHANGED
data/spec/ops/revision_spec.rb
CHANGED
@@ -26,7 +26,8 @@ describe Ops::Revision do
|
|
26
26
|
it "development env should have branch" do
|
27
27
|
dev_settings = double("settings", {:file_root => @root, :environment => 'development'})
|
28
28
|
dev_version = Ops::Revision.new({}, dev_settings)
|
29
|
-
dev_version.
|
29
|
+
dev_version.branch_source = ->{ "* dev\nsome-topic-branch\nother-topic-branch" }
|
30
|
+
dev_version.version_or_branch.should eq('dev')
|
30
31
|
end
|
31
32
|
|
32
33
|
it "should have request headers" do
|
@@ -38,4 +39,4 @@ describe Ops::Revision do
|
|
38
39
|
|
39
40
|
# TODO: add tests for json and previous_version
|
40
41
|
|
41
|
-
end
|
42
|
+
end
|
data/spec/ops/server_spec.rb
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'ops/server'
|
4
|
+
|
5
|
+
class ReliableConfigService
|
6
|
+
def call(options = {})
|
7
|
+
{ foo: 'bar' }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ErrorProneConfigService
|
12
|
+
def call(options = {})
|
13
|
+
raise StandardError, 'oops'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Ops::Server do
|
18
|
+
include Rack::Test::Methods
|
19
|
+
|
20
|
+
def app
|
21
|
+
Ops::Server
|
22
|
+
end
|
23
|
+
|
24
|
+
def enable_config_service(adapter)
|
25
|
+
Ops.setup do |config|
|
26
|
+
config.config_service_adapter = adapter
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def disable_config_service
|
31
|
+
Ops.setup do |config|
|
32
|
+
config.config_service_adapter = nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'GET /config' do
|
37
|
+
describe 'when config service is enabled' do
|
38
|
+
it 'responds with response from config service' do
|
39
|
+
enable_config_service(ReliableConfigService.new)
|
40
|
+
get '/config'
|
41
|
+
last_response.status.should == 200
|
42
|
+
body = JSON.parse(last_response.body)
|
43
|
+
body.should == { 'foo' => 'bar' }
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'responds with an error from config service' do
|
47
|
+
enable_config_service(ErrorProneConfigService.new)
|
48
|
+
get '/config'
|
49
|
+
last_response.status.should == 422
|
50
|
+
body = JSON.parse(last_response.body)
|
51
|
+
body.should == { 'error' => 'oops' }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'when config service is disabled' do
|
56
|
+
before do
|
57
|
+
disable_config_service
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'responds with an error' do
|
61
|
+
get '/config'
|
62
|
+
last_response.status.should == 501
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ops
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2014-05-15 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: sinatra
|
@@ -137,9 +137,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
- - ! '>='
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
|
-
segments:
|
141
|
-
- 0
|
142
|
-
hash: -4276810147624476791
|
143
140
|
requirements: []
|
144
141
|
rubyforge_project:
|
145
142
|
rubygems_version: 1.8.23
|
@@ -147,3 +144,4 @@ signing_key:
|
|
147
144
|
specification_version: 3
|
148
145
|
summary: Provide ops info endpoints.
|
149
146
|
test_files: []
|
147
|
+
has_rdoc:
|