maitre_d 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/Gemfile +1 -1
- data/HISTORY +5 -0
- data/README.textile +30 -9
- data/config/routes.rb +3 -2
- data/lib/maitre_d.rb +1 -1
- data/lib/maitre_d/cloud_control.rb +40 -0
- data/lib/maitre_d/cloud_control/api.rb +47 -0
- data/lib/maitre_d/cloud_control/api_helpers.rb +26 -0
- data/lib/maitre_d/heroku/api.rb +7 -7
- data/lib/maitre_d/heroku/api_helpers.rb +8 -0
- data/maitre_d.gemspec +1 -2
- data/spec/api/cloud_control/provisioning_spec.rb +94 -0
- data/spec/api/cloud_control/single_sign_on_spec.rb +49 -0
- data/spec/api/heroku/provisioning_spec.rb +7 -0
- data/spec/internal/app/listeners/cloud_control_listener.rb +29 -0
- data/spec/internal/app/listeners/heroku_listener.rb +3 -2
- data/spec/internal/config/initializers/cloud_control.rb +6 -0
- metadata +71 -79
- data/lib/maitre_d/version.rb +0 -3
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/HISTORY
CHANGED
data/README.textile
CHANGED
@@ -1,18 +1,27 @@
|
|
1
1
|
h1. Maître d'
|
2
2
|
|
3
|
-
|
3
|
+
"!https://secure.travis-ci.org/flying-sphinx/maitre_d.png!":http://travis-ci.org/flying-sphinx/maitre_d
|
4
|
+
|
5
|
+
Rack APIs powered by Grape for managing Heroku, CloudControl and Opperator add-ons. If used within a Rails application, it'll automatically be mounted as a Rails engine at the appropriate paths.
|
4
6
|
|
5
7
|
Maître d' manages all the authorisation checking for API requests and provides simple hooks for you to write just the code you need to handle provisioning, plan changes, deprovisioning and single-sign-on (SSO) requests.
|
6
8
|
|
7
9
|
h2. Installing
|
8
10
|
|
11
|
+
Add the following to your Gemfile - and take note that we need the git repository reference for Grape, as it includes some needed commits that aren't in the latest gem release.
|
12
|
+
|
13
|
+
<pre><code>gem 'grape',
|
14
|
+
:git => 'git://github.com/intridea/grape.git',
|
15
|
+
:ref => '212c96cdfb253a59bc93790808c568e559d04468'
|
16
|
+
gem 'maitre_d', '~> 0.1.2'</code></pre>
|
17
|
+
|
9
18
|
h3. With Rails
|
10
19
|
|
11
20
|
Because there's a Rails engine as part of Maître d', the API routing is set up automatically. Jump forward to the configuration and listener setup below.
|
12
21
|
|
13
|
-
h3. Without
|
22
|
+
h3. Without Rails
|
14
23
|
|
15
|
-
This library provides two APIs as mountable Rack applications for you - so you'll want to mount them at the appropriate paths: @MaitreD::Heroku::API@ at @/heroku@, and/or @MaitreD::Opperator::API@ at @/opperator@.
|
24
|
+
This library provides two APIs as mountable Rack applications for you - so you'll want to mount them at the appropriate paths: @MaitreD::Heroku::API@ at @/heroku@, @MaitreD::CloudControl::API@ at @/cloudcontrol@, and/or @MaitreD::Opperator::API@ at @/opperator@.
|
16
25
|
|
17
26
|
h2. Configuration
|
18
27
|
|
@@ -25,6 +34,13 @@ You'll need to provide Maître d' with the appropriate provider credentials - in
|
|
25
34
|
config.listener = HerokuListener
|
26
35
|
end
|
27
36
|
|
37
|
+
MaitreD::CloudControl.configure do |config|
|
38
|
+
config.id = 'addon-id'
|
39
|
+
config.password = 'random'
|
40
|
+
config.sso_salt = 'gibberish'
|
41
|
+
config.listener = CloudControlListener
|
42
|
+
end
|
43
|
+
|
28
44
|
MaitreD::Opperator.configure do |config|
|
29
45
|
config.shared_secret = 'something-special'
|
30
46
|
config.listener = OpperatorListener
|
@@ -34,9 +50,9 @@ The listeners that are mentioned in the code above are classes, which will handl
|
|
34
50
|
|
35
51
|
h2. Heroku Listener
|
36
52
|
|
37
|
-
Your Heroku listener class should
|
53
|
+
Your Heroku listener class should handle the following four methods:
|
38
54
|
|
39
|
-
h3. @provision(heroku_id, plan, callback_url, logplex_token, options)@
|
55
|
+
h3. @provision(heroku_id, plan, region, callback_url, logplex_token, options)@
|
40
56
|
|
41
57
|
This gets called when Heroku's requesting an app be provisioned within your service, and expects a hash to be returned with the following keys:
|
42
58
|
|
@@ -77,13 +93,14 @@ Maître d' will check the token and timestamp provided, and sets up the nav-data
|
|
77
93
|
|
78
94
|
Here's a very basic example:
|
79
95
|
|
80
|
-
<pre><code>class HerokuListener
|
81
|
-
def provision(heroku_id, plan, callback_url, logplex_token, options)
|
96
|
+
<pre><code>class HerokuListener
|
97
|
+
def provision(heroku_id, plan, region, callback_url, logplex_token, options)
|
82
98
|
plan = Plan.find_by_name plan
|
83
99
|
widget = Widget.create(
|
84
100
|
:heroku_id => heroku_id,
|
85
101
|
:callback_url => callback_url,
|
86
|
-
:plan => plan
|
102
|
+
:plan => plan,
|
103
|
+
:region => region
|
87
104
|
)
|
88
105
|
|
89
106
|
{
|
@@ -119,6 +136,10 @@ end</code></pre>
|
|
119
136
|
|
120
137
|
You can have the listener class wherever you like - as long as it's available within the context of your Rails/Rack site, it'll work as expected.
|
121
138
|
|
139
|
+
h2. CloudControl Listener
|
140
|
+
|
141
|
+
CloudControl is pretty much the same as Heroku - it has the same expectations for a listener, so perhaps you can use the same class if you like. Anything that Heroku sends through as the heroku_id becomes cloudcontrol_id - but that's just a matter of treating the given parameter appropriately.
|
142
|
+
|
122
143
|
h2. Opperator Listener
|
123
144
|
|
124
145
|
This listener is currently in progress as the Opperator API is established.
|
@@ -133,4 +154,4 @@ Contributions are very much welcome - but keep in mind the following:
|
|
133
154
|
|
134
155
|
h2. Credits
|
135
156
|
|
136
|
-
Copyright (c) 2011, Maître d' is developed and maintained by Pat Allan, and is released under the open MIT Licence.
|
157
|
+
Copyright (c) 2011-2012, Maître d' is developed and maintained by Pat Allan, and is released under the open MIT Licence.
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
-
mount MaitreD::Heroku::API
|
3
|
-
mount MaitreD::
|
2
|
+
mount MaitreD::Heroku::API => '/heroku'
|
3
|
+
mount MaitreD::CloudControl::API => '/cloudcontrol'
|
4
|
+
mount MaitreD::Opperator::API => '/opperator'
|
4
5
|
end
|
data/lib/maitre_d.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module MaitreD::CloudControl
|
2
|
+
def self.configure
|
3
|
+
yield self
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.listener
|
7
|
+
@listener
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.listener=(listener)
|
11
|
+
@listener = listener
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.id
|
15
|
+
@id
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.id=(id)
|
19
|
+
@id = id
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.password
|
23
|
+
@password
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.password=(password)
|
27
|
+
@password = password
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.sso_salt
|
31
|
+
@sso_salt
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.sso_salt=(salt)
|
35
|
+
@sso_salt = salt
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
require 'maitre_d/cloud_control/api_helpers'
|
40
|
+
require 'maitre_d/cloud_control/api'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class MaitreD::CloudControl::API < Grape::API
|
2
|
+
helpers MaitreD::CloudControl::APIHelpers
|
3
|
+
|
4
|
+
resources :resources do
|
5
|
+
get ':id' do
|
6
|
+
error!('403 Forbidden', 403) unless valid_token? && valid_timestamp?
|
7
|
+
|
8
|
+
hash = listener.single_sign_on(params[:id])
|
9
|
+
|
10
|
+
hash[:session] ||= {}
|
11
|
+
hash[:session].each { |key, value| session[key] = value }
|
12
|
+
|
13
|
+
if env['action_dispatch.cookies']
|
14
|
+
env['action_dispatch.cookies']['heroku-nav-data'] = params['nav-data']
|
15
|
+
else
|
16
|
+
Rack::Utils.set_cookie_header! header, 'heroku-nav-data',
|
17
|
+
:value => params['nav-data']
|
18
|
+
end
|
19
|
+
|
20
|
+
status 302
|
21
|
+
header 'Location', hash[:uri]
|
22
|
+
end
|
23
|
+
|
24
|
+
post do
|
25
|
+
authenticate!
|
26
|
+
|
27
|
+
listener.provision(
|
28
|
+
provider_id, params[:plan], params[:callback_url],
|
29
|
+
params[:logplex_token], params[:options]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
put ':id' do
|
34
|
+
authenticate!
|
35
|
+
|
36
|
+
listener.plan_change(
|
37
|
+
params[:id], provider_id, params[:plan]
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
delete ':id' do
|
42
|
+
authenticate!
|
43
|
+
|
44
|
+
listener.deprovision params[:id]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MaitreD::CloudControl::APIHelpers
|
2
|
+
include MaitreD::Heroku::APIHelpers
|
3
|
+
|
4
|
+
def listener
|
5
|
+
MaitreD::CloudControl.listener.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def provider_id
|
9
|
+
params[:cloudcontrol_id]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def expected_token
|
15
|
+
@expected_token ||= Digest::SHA1.hexdigest(
|
16
|
+
"#{params[:id]}:#{MaitreD::CloudControl.sso_salt}:#{params[:timestamp]}"
|
17
|
+
).to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid_authorization
|
21
|
+
encoded_authorization = Base64.encode64(
|
22
|
+
"#{MaitreD::CloudControl.id}:#{MaitreD::CloudControl.password}"
|
23
|
+
)
|
24
|
+
"Basic #{encoded_authorization}"
|
25
|
+
end
|
26
|
+
end
|
data/lib/maitre_d/heroku/api.rb
CHANGED
@@ -5,7 +5,7 @@ class MaitreD::Heroku::API < Grape::API
|
|
5
5
|
get ':id' do
|
6
6
|
error!('403 Forbidden', 403) unless valid_token? && valid_timestamp?
|
7
7
|
|
8
|
-
hash =
|
8
|
+
hash = listener.single_sign_on(params[:id])
|
9
9
|
|
10
10
|
hash[:session] ||= {}
|
11
11
|
hash[:session].each { |key, value| session[key] = value }
|
@@ -24,24 +24,24 @@ class MaitreD::Heroku::API < Grape::API
|
|
24
24
|
post do
|
25
25
|
authenticate!
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
params[:logplex_token], params[:options]
|
27
|
+
listener.provision(
|
28
|
+
provider_id, params[:plan], params[:region],
|
29
|
+
params[:callback_url], params[:logplex_token], params[:options]
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
33
|
put ':id' do
|
34
34
|
authenticate!
|
35
35
|
|
36
|
-
|
37
|
-
params[:id],
|
36
|
+
listener.plan_change(
|
37
|
+
params[:id], provider_id, params[:plan]
|
38
38
|
)
|
39
39
|
end
|
40
40
|
|
41
41
|
delete ':id' do
|
42
42
|
authenticate!
|
43
43
|
|
44
|
-
|
44
|
+
listener.deprovision params[:id]
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
data/maitre_d.gemspec
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$:.push File.expand_path('../lib', __FILE__)
|
3
|
-
require 'maitre_d/version'
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = 'maitre_d'
|
7
|
-
s.version =
|
6
|
+
s.version = '0.2.0'
|
8
7
|
s.authors = ['Pat Allan']
|
9
8
|
s.email = ['pat@freelancing-gods.com']
|
10
9
|
s.homepage = 'http://github.com/flying-sphinx/maitre_d'
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CloudControl Provisioning API' do
|
4
|
+
let(:authorisation) { "Basic #{Base64.encode64('baz:qux')}" }
|
5
|
+
let(:json_response) { JSON.parse response.body }
|
6
|
+
|
7
|
+
describe 'Provisioning' do
|
8
|
+
let(:params) {
|
9
|
+
{
|
10
|
+
:plan => 'basic',
|
11
|
+
:callback_url => 'https://domain/vendor/apps/app123%40heroku.com',
|
12
|
+
:cloudcontrol_id => 'app123@heroku.com'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
it "returns a 401 if the HTTP authorisation does not match" do
|
17
|
+
post '/cloudcontrol/resources', params,
|
18
|
+
{'HTTP_AUTHORIZATION' => 'Basic foobarbaz'}
|
19
|
+
|
20
|
+
response.status.should == 401
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns the resource id" do
|
24
|
+
post '/cloudcontrol/resources', params,
|
25
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
26
|
+
|
27
|
+
json_response['id'].should == '123'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns the resource configuration" do
|
31
|
+
post '/cloudcontrol/resources', params,
|
32
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
33
|
+
|
34
|
+
json_response['config'].should == {'FOO_PROVISIONED' => "true"}
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns a custom message" do
|
38
|
+
post '/cloudcontrol/resources', params,
|
39
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
40
|
+
|
41
|
+
json_response['message'].should == 'Add-on provisioned!'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'Changing Plans' do
|
46
|
+
let(:params) {
|
47
|
+
{:cloudcontrol_id => 'app123@heroku.com', :plan => 'premium'}
|
48
|
+
}
|
49
|
+
|
50
|
+
it "returns a 401 if the HTTP authorisation does not match" do
|
51
|
+
put '/cloudcontrol/resources/7', params,
|
52
|
+
{'HTTP_AUTHORIZATION' => 'Basic foobarbaz'}
|
53
|
+
|
54
|
+
response.status.should == 401
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns the new resource configuration" do
|
58
|
+
put '/cloudcontrol/resources/7', params,
|
59
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
60
|
+
|
61
|
+
json_response['config'].should == {'FOO_PROVISIONED' => "false"}
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns a custom message" do
|
65
|
+
put '/cloudcontrol/resources/7', params,
|
66
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
67
|
+
|
68
|
+
json_response['message'].should == 'Add-on upgraded or downgraded.'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'Deprovisioning' do
|
73
|
+
it "returns a 401 if the HTTP authorisation does not match" do
|
74
|
+
delete '/cloudcontrol/resources/28', {},
|
75
|
+
{'HTTP_AUTHORIZATION' => 'Basic foobarbaz'}
|
76
|
+
|
77
|
+
response.status.should == 401
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns with a status of 200" do
|
81
|
+
delete '/cloudcontrol/resources/28', {},
|
82
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
83
|
+
|
84
|
+
response.status.should == 200
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns a custom message" do
|
88
|
+
delete '/cloudcontrol/resources/28', {},
|
89
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
90
|
+
|
91
|
+
json_response['message'].should == 'Add-on removed.'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CloudControl SSO API' do
|
4
|
+
let(:timestamp) { Time.now.to_i }
|
5
|
+
let(:nav_data) { 'heroku-nav-data-goes-here' }
|
6
|
+
let(:token) {
|
7
|
+
pre_token = "789:rock salt:#{timestamp.to_s}"
|
8
|
+
Digest::SHA1.hexdigest(pre_token).to_s
|
9
|
+
}
|
10
|
+
|
11
|
+
it "renders a 403 if the token is incorrect" do
|
12
|
+
get '/cloudcontrol/resources/789', :token => 'foo',
|
13
|
+
:timestamp => timestamp, 'nav-data' => nav_data
|
14
|
+
|
15
|
+
response.status.should == 403
|
16
|
+
end
|
17
|
+
|
18
|
+
it "renders a 403 if the timestamp is older than 5 minutes" do
|
19
|
+
timestamp = 5.minutes.ago.to_i - 1
|
20
|
+
pre_token = "789:rock salt:#{timestamp.to_s}"
|
21
|
+
token = Digest::SHA1.hexdigest(pre_token).to_s
|
22
|
+
|
23
|
+
get '/cloudcontrol/resources/789', :token => token,
|
24
|
+
:timestamp => timestamp, 'nav-data' => nav_data
|
25
|
+
|
26
|
+
response.status.should == 403
|
27
|
+
end
|
28
|
+
|
29
|
+
it "sets the heroku nav data cookie" do
|
30
|
+
get '/cloudcontrol/resources/789', :token => token,
|
31
|
+
:timestamp => timestamp, 'nav-data' => nav_data
|
32
|
+
|
33
|
+
cookies['heroku-nav-data'].should == nav_data
|
34
|
+
end
|
35
|
+
|
36
|
+
it "redirects to the appropriate URL" do
|
37
|
+
get '/cloudcontrol/resources/789', :token => token,
|
38
|
+
:timestamp => timestamp, 'nav-data' => nav_data
|
39
|
+
|
40
|
+
response.should redirect_to('/my/dashboard')
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set the provided session variables" do
|
44
|
+
get '/cloudcontrol/resources/789', :token => token,
|
45
|
+
:timestamp => timestamp, 'nav-data' => nav_data
|
46
|
+
|
47
|
+
session[:app_id].should == '789'
|
48
|
+
end
|
49
|
+
end
|
@@ -37,6 +37,13 @@ describe 'Heroku Provisioning API' do
|
|
37
37
|
|
38
38
|
json_response['message'].should == 'Add-on provisioned!'
|
39
39
|
end
|
40
|
+
|
41
|
+
it "returns the region if it exists" do
|
42
|
+
post '/heroku/resources', params.merge(:region => 'us-west'),
|
43
|
+
{'HTTP_AUTHORIZATION' => authorisation}
|
44
|
+
|
45
|
+
json_response['region'].should == 'us-west'
|
46
|
+
end
|
40
47
|
end
|
41
48
|
|
42
49
|
describe 'Changing Plans' do
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class CloudControlListener
|
2
|
+
def provision(cloud_control_id, plan, callback_url, logplex_token, options)
|
3
|
+
{
|
4
|
+
:id => '123',
|
5
|
+
:config => {'FOO_PROVISIONED' => 'true'},
|
6
|
+
:message => 'Add-on provisioned!'
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
def plan_change(resource_id, cloud_control_id, plan)
|
11
|
+
{
|
12
|
+
:config => {'FOO_PROVISIONED' => 'false'},
|
13
|
+
:message => 'Add-on upgraded or downgraded.'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def deprovision(resource_id)
|
18
|
+
{
|
19
|
+
:message => 'Add-on removed.'
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def single_sign_on(resource_id)
|
24
|
+
{
|
25
|
+
:uri => '/my/dashboard',
|
26
|
+
:session => {:app_id => resource_id}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
class HerokuListener < MaitreD::Heroku::Listener
|
2
|
-
def provision(heroku_id, plan, callback_url, logplex_token, options)
|
2
|
+
def provision(heroku_id, plan, region, callback_url, logplex_token, options)
|
3
3
|
{
|
4
4
|
:id => '123',
|
5
5
|
:config => {'FOO_PROVISIONED' => 'true'},
|
6
|
-
:message => 'Add-on provisioned!'
|
6
|
+
:message => 'Add-on provisioned!',
|
7
|
+
:region => region
|
7
8
|
}
|
8
9
|
end
|
9
10
|
|
metadata
CHANGED
@@ -1,82 +1,74 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: maitre_d
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 2
|
10
|
-
version: 0.1.2
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Pat Allan
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-12-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: kensa
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 27
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 3
|
33
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 1.3.0
|
35
22
|
type: :development
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: rails
|
39
23
|
prerelease: false
|
40
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.3.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rails
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
41
33
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 5
|
46
|
-
segments:
|
47
|
-
- 3
|
48
|
-
- 1
|
49
|
-
- 3
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
50
37
|
version: 3.1.3
|
51
38
|
type: :development
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: rspec-rails
|
55
39
|
prerelease: false
|
56
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
41
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.1.3
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec-rails
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
66
53
|
version: 2.7.0
|
67
54
|
type: :development
|
68
|
-
|
69
|
-
|
70
|
-
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.7.0
|
62
|
+
description: A Rack API (through Grape) for Heroku and Opperator add-on providers
|
63
|
+
- which can also be attached as a Rails Engine.
|
64
|
+
email:
|
71
65
|
- pat@freelancing-gods.com
|
72
66
|
executables: []
|
73
|
-
|
74
67
|
extensions: []
|
75
|
-
|
76
68
|
extra_rdoc_files: []
|
77
|
-
|
78
|
-
files:
|
69
|
+
files:
|
79
70
|
- .gitignore
|
71
|
+
- .travis.yml
|
80
72
|
- Gemfile
|
81
73
|
- HISTORY
|
82
74
|
- LICENCE
|
@@ -86,6 +78,9 @@ files:
|
|
86
78
|
- config.ru
|
87
79
|
- config/routes.rb
|
88
80
|
- lib/maitre_d.rb
|
81
|
+
- lib/maitre_d/cloud_control.rb
|
82
|
+
- lib/maitre_d/cloud_control/api.rb
|
83
|
+
- lib/maitre_d/cloud_control/api_helpers.rb
|
89
84
|
- lib/maitre_d/engine.rb
|
90
85
|
- lib/maitre_d/heroku.rb
|
91
86
|
- lib/maitre_d/heroku/api.rb
|
@@ -95,59 +90,56 @@ files:
|
|
95
90
|
- lib/maitre_d/opperator/api.rb
|
96
91
|
- lib/maitre_d/opperator/api_helpers.rb
|
97
92
|
- lib/maitre_d/opperator/listener.rb
|
98
|
-
- lib/maitre_d/version.rb
|
99
93
|
- maitre_d.gemspec
|
94
|
+
- spec/api/cloud_control/provisioning_spec.rb
|
95
|
+
- spec/api/cloud_control/single_sign_on_spec.rb
|
100
96
|
- spec/api/heroku/provisioning_spec.rb
|
101
97
|
- spec/api/heroku/single_sign_on_spec.rb
|
102
98
|
- spec/api/opperator/provisioning_spec.rb
|
99
|
+
- spec/internal/app/listeners/cloud_control_listener.rb
|
103
100
|
- spec/internal/app/listeners/heroku_listener.rb
|
104
101
|
- spec/internal/app/listeners/opperator_listener.rb
|
102
|
+
- spec/internal/config/initializers/cloud_control.rb
|
105
103
|
- spec/internal/config/initializers/heroku.rb
|
106
104
|
- spec/internal/config/initializers/opperator.rb
|
107
105
|
- spec/internal/config/routes.rb
|
108
106
|
- spec/internal/log/.gitignore
|
109
107
|
- spec/internal/public/favicon.ico
|
110
108
|
- spec/spec_helper.rb
|
111
|
-
has_rdoc: true
|
112
109
|
homepage: http://github.com/flying-sphinx/maitre_d
|
113
110
|
licenses: []
|
114
|
-
|
115
111
|
post_install_message:
|
116
112
|
rdoc_options: []
|
117
|
-
|
118
|
-
require_paths:
|
113
|
+
require_paths:
|
119
114
|
- lib
|
120
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
116
|
none: false
|
122
|
-
requirements:
|
123
|
-
- -
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
|
126
|
-
|
127
|
-
- 0
|
128
|
-
version: "0"
|
129
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
122
|
none: false
|
131
|
-
requirements:
|
132
|
-
- -
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
|
135
|
-
segments:
|
136
|
-
- 0
|
137
|
-
version: "0"
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
138
127
|
requirements: []
|
139
|
-
|
140
128
|
rubyforge_project: maitre_d
|
141
|
-
rubygems_version: 1.
|
129
|
+
rubygems_version: 1.8.23
|
142
130
|
signing_key:
|
143
131
|
specification_version: 3
|
144
132
|
summary: Rack API and Rails Engine for Heroku and Opperator add-ons
|
145
|
-
test_files:
|
133
|
+
test_files:
|
134
|
+
- spec/api/cloud_control/provisioning_spec.rb
|
135
|
+
- spec/api/cloud_control/single_sign_on_spec.rb
|
146
136
|
- spec/api/heroku/provisioning_spec.rb
|
147
137
|
- spec/api/heroku/single_sign_on_spec.rb
|
148
138
|
- spec/api/opperator/provisioning_spec.rb
|
139
|
+
- spec/internal/app/listeners/cloud_control_listener.rb
|
149
140
|
- spec/internal/app/listeners/heroku_listener.rb
|
150
141
|
- spec/internal/app/listeners/opperator_listener.rb
|
142
|
+
- spec/internal/config/initializers/cloud_control.rb
|
151
143
|
- spec/internal/config/initializers/heroku.rb
|
152
144
|
- spec/internal/config/initializers/opperator.rb
|
153
145
|
- spec/internal/config/routes.rb
|
data/lib/maitre_d/version.rb
DELETED