maitre_d 0.4.0 → 0.5.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 +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
|