maitre_d 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile +0 -5
- data/README.textile +13 -31
- data/addon-manifest.json +11 -4
- data/lib/maitre_d.rb +4 -1
- data/lib/maitre_d/api.rb +30 -0
- data/lib/maitre_d/api/authenticated.rb +45 -0
- data/lib/maitre_d/api/change_plan.rb +15 -0
- data/lib/maitre_d/api/create.rb +10 -0
- data/lib/maitre_d/api/delete.rb +13 -0
- data/lib/maitre_d/api/sso.rb +65 -0
- data/lib/maitre_d/cloud_control.rb +4 -3
- data/lib/maitre_d/heroku.rb +4 -4
- data/maitre_d.gemspec +7 -4
- data/spec/api/cloud_control/provisioning_spec.rb +18 -18
- data/spec/api/cloud_control/single_sign_on_spec.rb +13 -13
- data/spec/api/heroku/provisioning_spec.rb +31 -23
- data/spec/api/heroku/single_sign_on_spec.rb +15 -15
- data/spec/internal/app/listeners/cloud_control_listener.rb +1 -1
- data/spec/internal/app/listeners/heroku_listener.rb +1 -1
- data/spec/internal/config/initializers/heroku.rb +2 -2
- data/spec/internal/config/routes.rb +3 -5
- data/spec/spec_helper.rb +1 -2
- metadata +50 -42
- data/lib/maitre_d/broadstack.rb +0 -40
- data/lib/maitre_d/broadstack/api.rb +0 -49
- data/lib/maitre_d/broadstack/api_helpers.rb +0 -44
- data/lib/maitre_d/cloud_control/api.rb +0 -47
- data/lib/maitre_d/cloud_control/api_helpers.rb +0 -28
- data/lib/maitre_d/heroku/api.rb +0 -47
- data/lib/maitre_d/heroku/api_helpers.rb +0 -46
- data/lib/maitre_d/heroku/listener.rb +0 -17
- data/lib/maitre_d/opperator.rb +0 -25
- data/lib/maitre_d/opperator/api.rb +0 -25
- data/lib/maitre_d/opperator/api_helpers.rb +0 -11
- data/lib/maitre_d/opperator/listener.rb +0 -13
- data/spec/api/broadstack/provisioning_spec.rb +0 -94
- data/spec/api/broadstack/single_sign_on_spec.rb +0 -49
- data/spec/api/opperator/provisioning_spec.rb +0 -55
- data/spec/internal/app/listeners/broadstack_listener.rb +0 -30
- data/spec/internal/app/listeners/opperator_listener.rb +0 -16
- data/spec/internal/config/initializers/broadstack.rb +0 -8
- data/spec/internal/config/initializers/opperator.rb +0 -6
data/lib/maitre_d/broadstack.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
module MaitreD::Broadstack
|
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/broadstack/api_helpers'
|
40
|
-
require 'maitre_d/broadstack/api'
|
@@ -1,49 +0,0 @@
|
|
1
|
-
class MaitreD::Broadstack::API < Grape::API
|
2
|
-
helpers MaitreD::Broadstack::APIHelpers
|
3
|
-
|
4
|
-
resources :sso do
|
5
|
-
post 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
|
-
end
|
24
|
-
|
25
|
-
resources :resources do
|
26
|
-
post do
|
27
|
-
authenticate!
|
28
|
-
|
29
|
-
listener.provision(
|
30
|
-
provider_id, params[:plan], params[:region],
|
31
|
-
params[:callback_url], params[:logplex_token], params[:options]
|
32
|
-
)
|
33
|
-
end
|
34
|
-
|
35
|
-
put ':id' do
|
36
|
-
authenticate!
|
37
|
-
|
38
|
-
listener.plan_change(
|
39
|
-
params[:id], provider_id, params[:plan]
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
delete ':id' do
|
44
|
-
authenticate!
|
45
|
-
|
46
|
-
listener.deprovision params[:id]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module MaitreD::Broadstack::APIHelpers
|
2
|
-
def authenticate!
|
3
|
-
error!('401 Unauthorized', 401) unless valid_authorization?
|
4
|
-
end
|
5
|
-
|
6
|
-
def listener
|
7
|
-
MaitreD::Broadstack.listener.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def provider_id
|
11
|
-
params[:broadstack_id]
|
12
|
-
end
|
13
|
-
|
14
|
-
def session
|
15
|
-
env['rack.session']
|
16
|
-
end
|
17
|
-
|
18
|
-
def valid_timestamp?
|
19
|
-
params[:timestamp].to_i >= (Time.now - 5*60).to_i
|
20
|
-
end
|
21
|
-
|
22
|
-
def valid_token?
|
23
|
-
expected_token == params[:token]
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def expected_token
|
29
|
-
@expected_token ||= Digest::SHA1.hexdigest(
|
30
|
-
"#{params[:id]}:#{MaitreD::Broadstack.sso_salt}:#{params[:timestamp]}"
|
31
|
-
).to_s
|
32
|
-
end
|
33
|
-
|
34
|
-
def valid_authorization?
|
35
|
-
valid_authorization.strip == env['HTTP_AUTHORIZATION'].strip
|
36
|
-
end
|
37
|
-
|
38
|
-
def valid_authorization
|
39
|
-
encoded_authorization = Base64.encode64(
|
40
|
-
"#{MaitreD::Broadstack.id}:#{MaitreD::Broadstack.password}"
|
41
|
-
)
|
42
|
-
"Basic #{encoded_authorization}"
|
43
|
-
end
|
44
|
-
end
|
@@ -1,47 +0,0 @@
|
|
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
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'maitre_d/heroku/api_helpers'
|
2
|
-
|
3
|
-
module MaitreD::CloudControl::APIHelpers
|
4
|
-
include MaitreD::Heroku::APIHelpers
|
5
|
-
|
6
|
-
def listener
|
7
|
-
MaitreD::CloudControl.listener.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def provider_id
|
11
|
-
params[:cloudcontrol_id]
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def expected_token
|
17
|
-
@expected_token ||= Digest::SHA1.hexdigest(
|
18
|
-
"#{params[:id]}:#{MaitreD::CloudControl.sso_salt}:#{params[:timestamp]}"
|
19
|
-
).to_s
|
20
|
-
end
|
21
|
-
|
22
|
-
def valid_authorization
|
23
|
-
encoded_authorization = Base64.encode64(
|
24
|
-
"#{MaitreD::CloudControl.id}:#{MaitreD::CloudControl.password}"
|
25
|
-
)
|
26
|
-
"Basic #{encoded_authorization}"
|
27
|
-
end
|
28
|
-
end
|
data/lib/maitre_d/heroku/api.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
class MaitreD::Heroku::API < Grape::API
|
2
|
-
helpers MaitreD::Heroku::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[:region],
|
29
|
-
params[:callback_url], 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
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module MaitreD::Heroku
|
2
|
-
module APIHelpers
|
3
|
-
def authenticate!
|
4
|
-
error!('401 Unauthorized', 401) unless valid_authorization?
|
5
|
-
end
|
6
|
-
|
7
|
-
def listener
|
8
|
-
MaitreD::Heroku.listener.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def provider_id
|
12
|
-
params[:heroku_id]
|
13
|
-
end
|
14
|
-
|
15
|
-
def session
|
16
|
-
env['rack.session']
|
17
|
-
end
|
18
|
-
|
19
|
-
def valid_timestamp?
|
20
|
-
params[:timestamp].to_i >= (Time.now - 5*60).to_i
|
21
|
-
end
|
22
|
-
|
23
|
-
def valid_token?
|
24
|
-
expected_token == params[:token]
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def expected_token
|
30
|
-
@expected_token ||= Digest::SHA1.hexdigest(
|
31
|
-
"#{params[:id]}:#{MaitreD::Heroku.sso_salt}:#{params[:timestamp]}"
|
32
|
-
).to_s
|
33
|
-
end
|
34
|
-
|
35
|
-
def valid_authorization?
|
36
|
-
valid_authorization.strip == env['HTTP_AUTHORIZATION'].strip
|
37
|
-
end
|
38
|
-
|
39
|
-
def valid_authorization
|
40
|
-
encoded_authorization = Base64.encode64(
|
41
|
-
"#{MaitreD::Heroku.id}:#{MaitreD::Heroku.password}"
|
42
|
-
)
|
43
|
-
"Basic #{encoded_authorization}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
class MaitreD::Heroku::Listener
|
2
|
-
def provision(heroku_id, plan, callback_url, logplex_token, options)
|
3
|
-
#
|
4
|
-
end
|
5
|
-
|
6
|
-
def plan_change(resource_id, heroku_id, plan)
|
7
|
-
#
|
8
|
-
end
|
9
|
-
|
10
|
-
def deprovision(resource_id)
|
11
|
-
#
|
12
|
-
end
|
13
|
-
|
14
|
-
def single_sign_on(resource_id)
|
15
|
-
#
|
16
|
-
end
|
17
|
-
end
|
data/lib/maitre_d/opperator.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module MaitreD::Opperator
|
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.shared_secret
|
15
|
-
@shared_secret
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.shared_secret=(secret)
|
19
|
-
@shared_secret = secret
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
require 'maitre_d/opperator/api_helpers'
|
24
|
-
require 'maitre_d/opperator/api'
|
25
|
-
require 'maitre_d/opperator/listener'
|
@@ -1,25 +0,0 @@
|
|
1
|
-
class MaitreD::Opperator::API < Grape::API
|
2
|
-
helpers MaitreD::Opperator::APIHelpers
|
3
|
-
|
4
|
-
before { authenticate! }
|
5
|
-
|
6
|
-
resources :instances do
|
7
|
-
post do
|
8
|
-
MaitreD::Opperator.listener.new.provision params[:features]
|
9
|
-
end
|
10
|
-
|
11
|
-
delete ':id' do
|
12
|
-
MaitreD::Opperator.listener.new.deprovision params[:id]
|
13
|
-
end
|
14
|
-
|
15
|
-
put ':id' do
|
16
|
-
MaitreD::Opperator.listener.new.change_plan params[:id], params[:features]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
resource :plan_warning do
|
21
|
-
put ':id' do
|
22
|
-
#
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,94 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Broadstack Provisioning API' do
|
4
|
-
let(:authorisation) { "Basic #{Base64.encode64('foo:bar')}" }
|
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%40broadstack.com',
|
12
|
-
:broadstack_id => 'app123@broadstack.com'
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
16
|
-
it "returns a 401 if the HTTP authorisation does not match" do
|
17
|
-
post '/broadstack/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 '/broadstack/resources', params, {'HTTP_AUTHORIZATION' => authorisation}
|
25
|
-
|
26
|
-
json_response['id'].should == '123'
|
27
|
-
end
|
28
|
-
|
29
|
-
it "returns the resource configuration" do
|
30
|
-
post '/broadstack/resources', params, {'HTTP_AUTHORIZATION' => authorisation}
|
31
|
-
|
32
|
-
json_response['config'].should == {'FOO_PROVISIONED' => "true"}
|
33
|
-
end
|
34
|
-
|
35
|
-
it "returns a custom message" do
|
36
|
-
post '/broadstack/resources', params, {'HTTP_AUTHORIZATION' => authorisation}
|
37
|
-
|
38
|
-
json_response['message'].should == 'Add-on provisioned!'
|
39
|
-
end
|
40
|
-
|
41
|
-
it "returns the region if it exists" do
|
42
|
-
post '/broadstack/resources', params.merge(:region => 'us-west'),
|
43
|
-
{'HTTP_AUTHORIZATION' => authorisation}
|
44
|
-
|
45
|
-
json_response['region'].should == 'us-west'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'Changing Plans' do
|
50
|
-
let(:params) {
|
51
|
-
{:broadstack_id => 'app123@broadstack.com', :plan => 'premium'}
|
52
|
-
}
|
53
|
-
|
54
|
-
it "returns a 401 if the HTTP authorisation does not match" do
|
55
|
-
put '/broadstack/resources/7', params,
|
56
|
-
{'HTTP_AUTHORIZATION' => 'Basic foobarbaz'}
|
57
|
-
|
58
|
-
response.status.should == 401
|
59
|
-
end
|
60
|
-
|
61
|
-
it "returns the new resource configuration" do
|
62
|
-
put '/broadstack/resources/7', params, {'HTTP_AUTHORIZATION' => authorisation}
|
63
|
-
|
64
|
-
json_response['config'].should == {'FOO_PROVISIONED' => "false"}
|
65
|
-
end
|
66
|
-
|
67
|
-
it "returns a custom message" do
|
68
|
-
put '/broadstack/resources/7', params, {'HTTP_AUTHORIZATION' => authorisation}
|
69
|
-
|
70
|
-
json_response['message'].should == 'Add-on upgraded or downgraded.'
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe 'Deprovisioning' do
|
75
|
-
it "returns a 401 if the HTTP authorisation does not match" do
|
76
|
-
delete '/broadstack/resources/28', {},
|
77
|
-
{'HTTP_AUTHORIZATION' => 'Basic foobarbaz'}
|
78
|
-
|
79
|
-
response.status.should == 401
|
80
|
-
end
|
81
|
-
|
82
|
-
it "returns with a status of 200" do
|
83
|
-
delete '/broadstack/resources/28', {}, {'HTTP_AUTHORIZATION' => authorisation}
|
84
|
-
|
85
|
-
response.status.should == 200
|
86
|
-
end
|
87
|
-
|
88
|
-
it "returns a custom message" do
|
89
|
-
delete '/broadstack/resources/28', {}, {'HTTP_AUTHORIZATION' => authorisation}
|
90
|
-
|
91
|
-
json_response['message'].should == 'Add-on removed.'
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|