ey_services_fake 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/ey_services_fake.gemspec +23 -0
- data/lib/ey_services_fake/mock_backend.rb +151 -0
- data/lib/ey_services_fake/mocking_bird_service.rb +122 -0
- data/lib/ey_services_fake/models.rb +64 -0
- data/lib/ey_services_fake/reacharound_awsm.rb +155 -0
- data/lib/ey_services_fake/tresfiestas_fake.rb +134 -0
- data/lib/ey_services_fake/tresfiestas_fake_rack_app.rb +156 -0
- data/lib/ey_services_fake/url_generator.rb +37 -0
- data/lib/ey_services_fake/version.rb +3 -0
- metadata +104 -0
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ey_services_fake/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ey_services_fake"
|
7
|
+
s.version = EyServicesFake::VERSION
|
8
|
+
s.authors = ["Jacob Burkhart & Josh Lane"]
|
9
|
+
s.email = ["jacob@engineyard.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{A fake for use when writting tests against the ey_services_api}
|
12
|
+
s.description = %q{A fake for use when writting tests against the ey_services_api}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ey_services_fake"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency "sinatra"
|
22
|
+
s.add_dependency "cubbyhole", ">= 0.2.0"
|
23
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module EyServicesFake
|
2
|
+
class MockBackend
|
3
|
+
|
4
|
+
def self.tresfiestas_fake
|
5
|
+
require 'ey_services_fake/tresfiestas_fake'
|
6
|
+
TresfiestasFake
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.setup!(actors = {})
|
10
|
+
unless actors[:awsm]
|
11
|
+
require 'ey_services_fake/reacharound_awsm'
|
12
|
+
actors[:awsm] = ReacharoundAwsm.new
|
13
|
+
end
|
14
|
+
unless actors[:service_provider]
|
15
|
+
require 'ey_services_fake/mocking_bird_service'
|
16
|
+
actors[:service_provider] = MockingBirdService.new
|
17
|
+
end
|
18
|
+
unless actors[:tresfiestas]
|
19
|
+
actors[:tresfiestas] = tresfiestas_fake.new
|
20
|
+
end
|
21
|
+
new(actors)
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(actors)
|
25
|
+
@actors = actors
|
26
|
+
end
|
27
|
+
|
28
|
+
def actor(role)
|
29
|
+
@actors[role] or raise "No actor registered as #{role}, I have #{@actors.keys.inspect}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def reset!
|
33
|
+
@actors.values.each do |v|
|
34
|
+
v.reset!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def awsm
|
39
|
+
awsm_hash = actor(:tresfiestas).find_awsm
|
40
|
+
unless awsm_hash
|
41
|
+
awsm_hash = actor(:tresfiestas).create_awsm(actor(:awsm).base_url, actor(:awsm).app)
|
42
|
+
actor(:awsm).setup(awsm_hash[:auth_id], awsm_hash[:auth_key], actor(:tresfiestas).base_url, actor(:tresfiestas).app)
|
43
|
+
end
|
44
|
+
awsm_hash
|
45
|
+
end
|
46
|
+
|
47
|
+
def partner
|
48
|
+
partner_hash = actor(:tresfiestas).find_partner(sso_user)
|
49
|
+
unless partner_hash
|
50
|
+
partner_hash = actor(:tresfiestas).create_partner(sso_user, actor(:service_provider).base_url, actor(:service_provider).app)
|
51
|
+
@actors.values.each do |actor|
|
52
|
+
if actor.respond_to?(:service_provider_setup)
|
53
|
+
actor.service_provider_setup(partner_hash[:auth_id], partner_hash[:auth_key], actor(:service_provider).base_url, actor(:service_provider).app)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
actor(:service_provider).setup(partner_hash[:auth_id], partner_hash[:auth_key], actor(:tresfiestas).base_url, actor(:tresfiestas).app)
|
57
|
+
end
|
58
|
+
partner_hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def service
|
62
|
+
partner_hash = self.partner
|
63
|
+
service_hash = actor(:tresfiestas).find_service(partner_hash[:id])
|
64
|
+
unless service_hash
|
65
|
+
actor(:service_provider).register_service(partner_hash[:registration_url])
|
66
|
+
service_hash = actor(:tresfiestas).find_service(partner_hash[:id])
|
67
|
+
end
|
68
|
+
service_hash.merge(:partner => partner_hash)
|
69
|
+
end
|
70
|
+
|
71
|
+
def sso_user
|
72
|
+
actor(:awsm).sso_user #allows for nils (some implementations of AWSM may decide this is ok)
|
73
|
+
end
|
74
|
+
|
75
|
+
def sso_account
|
76
|
+
awsm #need to have setup awsm before you can create accounts!
|
77
|
+
sso_user_something = sso_user #the sso_user is a somehting, not necessarily a hash
|
78
|
+
sso_account_hash = actor(:awsm).find_sso_account(sso_user_something)
|
79
|
+
unless sso_account_hash
|
80
|
+
sso_account_hash = actor(:awsm).create_sso_account(sso_user_something)
|
81
|
+
end
|
82
|
+
sso_account_hash
|
83
|
+
end
|
84
|
+
|
85
|
+
def service_enablement
|
86
|
+
sso_account_hash = self.sso_account
|
87
|
+
service_hash = self.service
|
88
|
+
unless actor(:tresfiestas).service_available_for_account?(service_hash[:id], sso_account_hash[:id])
|
89
|
+
actor(:tresfiestas).make_service_available_for_account(service_hash[:id], sso_account_hash[:id])
|
90
|
+
end
|
91
|
+
{
|
92
|
+
:service => service_hash,
|
93
|
+
:sso_account => sso_account_hash,
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def service_account
|
98
|
+
service_enablement_hash = self.service_enablement
|
99
|
+
sso_account_hash = service_enablement_hash[:sso_account]
|
100
|
+
service_hash = service_enablement_hash[:service]
|
101
|
+
service_account_hash = actor(:tresfiestas).find_service_account(service_hash[:id], sso_account_hash[:id])
|
102
|
+
unless service_account_hash
|
103
|
+
actor(:awsm).enable_service(service_hash[:id], sso_account_hash[:id])
|
104
|
+
service_account_hash = actor(:tresfiestas).find_service_account(service_hash[:id], sso_account_hash[:id])
|
105
|
+
end
|
106
|
+
service_account_hash.merge(:name => sso_account_hash[:name], :service => service_hash, :sso_account => sso_account_hash)
|
107
|
+
end
|
108
|
+
|
109
|
+
def destroy_service_account
|
110
|
+
actor(:awsm).disable_service(service_account[:id])
|
111
|
+
end
|
112
|
+
|
113
|
+
def app_deployment
|
114
|
+
app_deployment_hash = actor(:awsm).find_app_deployment(sso_account[:id])
|
115
|
+
unless app_deployment_hash
|
116
|
+
actor(:awsm).create_app_deployment(sso_account[:id], "myapp", "myenv", "production")
|
117
|
+
app_deployment_hash = actor(:awsm).find_app_deployment(sso_account[:id])
|
118
|
+
end
|
119
|
+
app_deployment_hash
|
120
|
+
end
|
121
|
+
|
122
|
+
def provisioned_service
|
123
|
+
service_account_hash = self.service_account
|
124
|
+
sso_account_hash = service_account_hash[:sso_account]
|
125
|
+
app_deployment_hash = self.app_deployment
|
126
|
+
provisioned_service_hash = actor(:tresfiestas).find_provisioned_service(service_account_hash[:id], app_deployment_hash[:id])
|
127
|
+
unless provisioned_service_hash
|
128
|
+
actor(:awsm).provision_service(sso_account_hash[:id], service_account_hash[:id], app_deployment_hash[:id])
|
129
|
+
provisioned_service_hash = actor(:tresfiestas).find_provisioned_service(service_account_hash[:id], app_deployment_hash[:id])
|
130
|
+
end
|
131
|
+
provisioned_service_hash.merge(:service_account => service_account_hash, :app_deployment => app_deployment_hash)
|
132
|
+
end
|
133
|
+
|
134
|
+
def destroy_provisioned_service
|
135
|
+
actor(:awsm).deprovision_service(provisioned_service[:id])
|
136
|
+
end
|
137
|
+
|
138
|
+
def latest_invoice
|
139
|
+
actor(:tresfiestas).latest_invoice
|
140
|
+
end
|
141
|
+
|
142
|
+
def latest_status_message
|
143
|
+
actor(:tresfiestas).latest_status_message
|
144
|
+
end
|
145
|
+
|
146
|
+
def send_message(message_url, message_type, message_subject, message_body = nil)
|
147
|
+
actor(:service_provider).send_message(message_url, message_type, message_subject, message_body)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module EyServicesFake
|
4
|
+
class MockingBirdService
|
5
|
+
class Application < Sinatra::Base
|
6
|
+
enable :raise_errors
|
7
|
+
disable :dump_errors
|
8
|
+
disable :show_exceptions
|
9
|
+
|
10
|
+
delete '/api/1/some_provisioned_service' do
|
11
|
+
{}.to_json
|
12
|
+
end
|
13
|
+
|
14
|
+
delete '/api/1/some_service_account' do
|
15
|
+
{}.to_json
|
16
|
+
end
|
17
|
+
|
18
|
+
post '/api/1/service_accounts_callback' do
|
19
|
+
service_account = EY::ServicesAPI::ServiceAccountCreation.from_request(request.body.read)
|
20
|
+
standard_response_params = MockingBirdService.service_account_creation_params
|
21
|
+
EY::ServicesAPI::ServiceAccountResponse.new(
|
22
|
+
:provisioned_services_url => standard_response_params[:provisioned_services_url],
|
23
|
+
:url => standard_response_params[:url],
|
24
|
+
:configuration_url => standard_response_params[:configuration_url],
|
25
|
+
:configuration_required => standard_response_params[:configuration_required],
|
26
|
+
:message => EY::ServicesAPI::Message.new(:message_type => "status", :subject => "some messages")
|
27
|
+
).to_hash.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
post '/api/1/provisioned_services_callback' do
|
31
|
+
provisioned_service = EY::ServicesAPI::ProvisionedServiceCreation.from_request(request.body.read)
|
32
|
+
standard_response_params = MockingBirdService.service_provisioned_params
|
33
|
+
EY::ServicesAPI::ProvisionedServiceResponse.new(
|
34
|
+
:url => standard_response_params[:url],
|
35
|
+
:vars => standard_response_params[:vars],
|
36
|
+
:configuration_required => false,
|
37
|
+
:configuration_url => standard_response_params[:configuration_url],
|
38
|
+
:message => EY::ServicesAPI::Message.new(:message_type => "status", :subject => "some provisioned service messages")
|
39
|
+
).to_hash.to_json
|
40
|
+
end
|
41
|
+
|
42
|
+
get '/sso/some_service_account' do
|
43
|
+
"SSO Hello Service Account"
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/sso/some_provisioned_service' do
|
47
|
+
"SSO Hello Provisioned Service"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def reset!
|
52
|
+
#no-op
|
53
|
+
end
|
54
|
+
|
55
|
+
def app
|
56
|
+
Application
|
57
|
+
end
|
58
|
+
|
59
|
+
def setup(auth_id, auth_key, base_url = nil, backend = nil)
|
60
|
+
require 'ey_services_api'
|
61
|
+
connection = EY::ServicesAPI.setup!(:auth_id => auth_id, :auth_key => auth_key)
|
62
|
+
if backend
|
63
|
+
connection.backend = backend
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def base_url
|
68
|
+
self.class.base_url
|
69
|
+
end
|
70
|
+
def self.base_url
|
71
|
+
"http://mock.service/"
|
72
|
+
end
|
73
|
+
|
74
|
+
def registration_params
|
75
|
+
self.class.registration_params
|
76
|
+
end
|
77
|
+
def self.registration_params
|
78
|
+
{
|
79
|
+
:name => "Mocking Bird",
|
80
|
+
:description => "a mock service",
|
81
|
+
:service_accounts_url => "#{base_url}api/1/service_accounts_callback",
|
82
|
+
:home_url => "#{base_url}",
|
83
|
+
:terms_and_conditions_url => "#{base_url}terms",
|
84
|
+
:vars => ["SOME_ENV_VAR", "OTHER_VAR"]
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def service_account_creation_params
|
89
|
+
self.class.service_account_creation_params
|
90
|
+
end
|
91
|
+
def self.service_account_creation_params
|
92
|
+
{
|
93
|
+
:provisioned_services_url => "#{base_url}api/1/provisioned_services_callback",
|
94
|
+
:url => "#{base_url}api/1/some_service_account",
|
95
|
+
:configuration_url => "#{base_url}sso/some_service_account",
|
96
|
+
:configuration_required => false
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def service_provisioned_params
|
101
|
+
self.class.service_provisioned_params
|
102
|
+
end
|
103
|
+
def self.service_provisioned_params
|
104
|
+
{
|
105
|
+
:vars => {"SOME_ENV_VAR" => "value", "OTHER_VAR" => "blah"},
|
106
|
+
:configuration_url => "#{base_url}sso/some_provisioned_service",
|
107
|
+
:configuration_required => false,
|
108
|
+
:url => "#{base_url}api/1/some_provisioned_service",
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
def register_service(registration_url)
|
113
|
+
EY::ServicesAPI.connection.register_service(registration_url, MockingBirdService.registration_params)
|
114
|
+
end
|
115
|
+
|
116
|
+
def send_message(message_url, message_type, message_subject, message_body)
|
117
|
+
message = EY::ServicesAPI::Message.new(:message_type => message_type, :subject => message_subject, :body => message_body)
|
118
|
+
EY::ServicesAPI.connection.send_message(message_url, message)
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'cubbyhole/base'
|
2
|
+
|
3
|
+
module EyServicesFake
|
4
|
+
class Model < Cubbyhole::Base
|
5
|
+
def self.inherited(klass)
|
6
|
+
decendants << klass
|
7
|
+
end
|
8
|
+
def self.nuke_all
|
9
|
+
decendants.map(&:nuke)
|
10
|
+
end
|
11
|
+
def self.backend
|
12
|
+
@backend ||= Hash.new
|
13
|
+
end
|
14
|
+
def self.decendants
|
15
|
+
@decendants ||= []
|
16
|
+
end
|
17
|
+
def self.belongs_to(model, name, key)
|
18
|
+
search_context = self.to_s.split("::")
|
19
|
+
search_context.pop
|
20
|
+
search_context = eval(search_context.join("::").to_s)
|
21
|
+
self.class_eval do
|
22
|
+
define_method(name) do
|
23
|
+
klass = search_context.const_get(model)
|
24
|
+
klass.all.find{|s| self.send(key).to_i == s.id.to_i }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def self.has_many(model, name, key)
|
29
|
+
search_context = self.to_s.split("::")
|
30
|
+
search_context.pop
|
31
|
+
search_context = eval(search_context.join("::").to_s)
|
32
|
+
self.class_eval do
|
33
|
+
define_method(name) do
|
34
|
+
klass = search_context.const_get(model)
|
35
|
+
Cubbyhole::Collection.new(klass.all.select{|s| s.send(key).to_s == self.id.to_s })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
class Partner < Model
|
41
|
+
has_many :Service, :services, :partner_id
|
42
|
+
end
|
43
|
+
class Service < Model
|
44
|
+
has_many :ServiceEnablement, :service_enablements, :service_id
|
45
|
+
has_many :ServiceAccount, :service_accounts, :service_id
|
46
|
+
belongs_to :Partner, :partner, :partner_id
|
47
|
+
end
|
48
|
+
class ServiceAccount < Model
|
49
|
+
has_many :ProvisionedService, :provisioned_services, :service_account_id
|
50
|
+
has_many :Message, :messages, :service_account_id
|
51
|
+
belongs_to :Service, :service, :service_id
|
52
|
+
end
|
53
|
+
class ProvisionedService < Model
|
54
|
+
has_many :Message, :messages, :provisioned_service_id
|
55
|
+
belongs_to :ServiceAccount, :service_account, :service_account_id
|
56
|
+
end
|
57
|
+
class ServiceEnablement < Model; end
|
58
|
+
class Invoice < Model; end
|
59
|
+
class Message < Model
|
60
|
+
belongs_to :ServiceAccount, :service_account, :service_account_id
|
61
|
+
belongs_to :ProvisionedService, :provisioned_service, :provisioned_service_id
|
62
|
+
end
|
63
|
+
class Awsm < Model; end
|
64
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'ey_services_fake/models'
|
3
|
+
|
4
|
+
module EyServicesFake
|
5
|
+
class ReacharoundAwsm
|
6
|
+
class Application < Sinatra::Base
|
7
|
+
enable :raise_errors
|
8
|
+
disable :dump_errors
|
9
|
+
disable :show_exceptions
|
10
|
+
|
11
|
+
post '/dashboard_notifications_url' do
|
12
|
+
{}.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def app
|
18
|
+
Application
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset!
|
22
|
+
#no-op
|
23
|
+
end
|
24
|
+
|
25
|
+
def base_url
|
26
|
+
"http://cloud.engineyard.com"
|
27
|
+
end
|
28
|
+
|
29
|
+
class Account < EyServicesFake::Model; end
|
30
|
+
class AppDeployment < EyServicesFake::Model
|
31
|
+
belongs_to :App, :app, :app_id
|
32
|
+
belongs_to :Environment, :environment, :environment_id
|
33
|
+
end
|
34
|
+
class App < EyServicesFake::Model; end
|
35
|
+
class Environment < EyServicesFake::Model; end
|
36
|
+
class User < EyServicesFake::Model
|
37
|
+
has_many :Account, :accounts, :owner_id
|
38
|
+
end
|
39
|
+
|
40
|
+
def service_provider_setup(auth_id, auth_key, service_provider_url, service_provider_rackapp)
|
41
|
+
@connection = EY::ApiHMAC::BaseConnection.new(auth_id, auth_key).tap{|c| c.backend = service_provider_rackapp}
|
42
|
+
end
|
43
|
+
def setup(auth_id, auth_key, tresfiestas_url, tresfiestas_rackapp)
|
44
|
+
#ignored... we don't talk to tresfiestas, we talk to service_provider
|
45
|
+
end
|
46
|
+
|
47
|
+
def sso_user
|
48
|
+
the_one_email = "the-one-user@example.com"
|
49
|
+
User.first(:email => the_one_email) || User.create(:email => the_one_email)
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_sso_account(sso_user)
|
53
|
+
account = sso_user.accounts.first
|
54
|
+
account && {
|
55
|
+
:id => account.id,
|
56
|
+
:name => account.name,
|
57
|
+
}
|
58
|
+
end
|
59
|
+
def create_sso_account(sso_user)
|
60
|
+
Account.create(:owner_id => sso_user.id, :name => 'some-account')
|
61
|
+
find_sso_account(sso_user)
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_app_deployment(sso_account_id)
|
65
|
+
app_deployment = AppDeployment.first(:account_id => sso_account_id)
|
66
|
+
app_deployment && {
|
67
|
+
:id => app_deployment.id,
|
68
|
+
:app => {
|
69
|
+
:name => app_deployment.app.name,
|
70
|
+
},
|
71
|
+
:environment => {
|
72
|
+
:name => app_deployment.environment.name,
|
73
|
+
:framework_env => app_deployment.environment.framework_env,
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
def create_app_deployment(sso_account_id, app_name, env_name, framework_env)
|
78
|
+
app = App.create(:name => app_name)
|
79
|
+
env = Environment.create(:name => env_name, :framework_env => framework_env)
|
80
|
+
AppDeployment.create(:account_id => sso_account_id, :app_id => app.id, :environment_id => env.id)
|
81
|
+
end
|
82
|
+
|
83
|
+
#Normal implmentations of AWSM would not be posting to service_accounts_url;
|
84
|
+
#they would be posting to private API to say that they wish to create a service account
|
85
|
+
#but this is reacharound AWSM, and so it plays the role of tresfiestas internals here
|
86
|
+
# def enable_service(connection, sso_account, service_hash)
|
87
|
+
def enable_service(service_id, sso_account_id)
|
88
|
+
url_gen = EyServicesFake::URL_GEN
|
89
|
+
service_account = ServiceAccount.create(:sso_account_id => sso_account_id, :active => false, :service_id => service_id, :dashboard_notifications_url => "#{base_url}/dashboard_notifications_url")
|
90
|
+
service = Service.get(service_id)
|
91
|
+
creation_attributes = {
|
92
|
+
:name => Account.get(sso_account_id).name,
|
93
|
+
:url => url_gen.partner_service_account(service, service_account),
|
94
|
+
:messages_url => url_gen.messages(service, service_account),
|
95
|
+
:invoices_url => url_gen.invoices(service, service_account),
|
96
|
+
}
|
97
|
+
@connection.post(service.service_accounts_url, creation_attributes) do |result, location|
|
98
|
+
service_account.active = true
|
99
|
+
service_account.provisioned_services_url = result["service_account"]['provisioned_services_url']
|
100
|
+
service_account.configuration_url = result["service_account"]['configuration_url']
|
101
|
+
service_account.url = result["service_account"]['url']
|
102
|
+
service_account.configuration_required = result["service_account"]['configuration_required']
|
103
|
+
if result["message"] && result["message"]["message_type"]
|
104
|
+
Message.create(
|
105
|
+
:service_account_id => service_account.id,
|
106
|
+
:message_type => result["message"]["message_type"],
|
107
|
+
:subject => result["message"]["subject"],
|
108
|
+
:body => result["message"]["body"])
|
109
|
+
end
|
110
|
+
service_account.save
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def disable_service(service_account_id)
|
115
|
+
service_account = ServiceAccount.get(service_account_id)
|
116
|
+
@connection.delete(service_account.url)
|
117
|
+
end
|
118
|
+
|
119
|
+
def provision_service(sso_account_id, service_account_id, app_deployment_id)
|
120
|
+
url_gen = EyServicesFake::URL_GEN
|
121
|
+
provisioned_service = ProvisionedService.create(:app_deployment_id => app_deployment_id.to_i, :active => false, :service_account_id => service_account_id.to_i, :dashboard_notifications_url => "#{base_url}/dashboard_notifications_url")
|
122
|
+
service_account_object = ServiceAccount.get(service_account_id)
|
123
|
+
app_deployment = AppDeployment.get(app_deployment_id)
|
124
|
+
app = app_deployment.app
|
125
|
+
environment = app_deployment.environment
|
126
|
+
provision_attribtues = {
|
127
|
+
:url => url_gen.partner_provisioned_service(service_account_object, provisioned_service),
|
128
|
+
:messages_url => url_gen.messages(service_account_object.service, service_account_object, provisioned_service),
|
129
|
+
:app => {:id => app.id, :name => app.name},
|
130
|
+
:environment => {:id => environment.id, :name => environment.name, :framework_env => environment.framework_env},
|
131
|
+
}
|
132
|
+
@connection.post(service_account_object.provisioned_services_url, provision_attribtues) do |result, location|
|
133
|
+
provisioned_service.active = true
|
134
|
+
provisioned_service.vars = result['provisioned_service']["vars"]
|
135
|
+
provisioned_service.configuration_url = result['provisioned_service']["configuration_url"]
|
136
|
+
provisioned_service.configuration_required = result['provisioned_service']["configuration_required"]
|
137
|
+
provisioned_service.url = result['provisioned_service']["url"]
|
138
|
+
if result["message"] && result["message"]["message_type"]
|
139
|
+
Message.create(
|
140
|
+
:provisioned_service_id => provisioned_service.id,
|
141
|
+
:message_type => result["message"]["message_type"],
|
142
|
+
:subject => result["message"]["subject"],
|
143
|
+
:body => result["message"]["body"])
|
144
|
+
end
|
145
|
+
provisioned_service.save
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def deprovision_service(provisioned_service_id)
|
150
|
+
provisioned_service = ProvisionedService.get(provisioned_service_id)
|
151
|
+
@connection.delete(provisioned_service.url)
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'ey_services_fake/url_generator'
|
2
|
+
require 'ey_services_fake/models'
|
3
|
+
require 'ey_services_fake/tresfiestas_fake_rack_app'
|
4
|
+
|
5
|
+
module EyServicesFake
|
6
|
+
BASE_URL = "http://services.engineyard.com"
|
7
|
+
URL_GEN = EyServicesFake::UrlGenerator.new(BASE_URL)
|
8
|
+
|
9
|
+
class TresfiestasFake
|
10
|
+
|
11
|
+
def reset!
|
12
|
+
Model.nuke_all
|
13
|
+
end
|
14
|
+
|
15
|
+
def base_url
|
16
|
+
BASE_URL
|
17
|
+
end
|
18
|
+
|
19
|
+
def app
|
20
|
+
TresfiestasFakeRackApp
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_awsm
|
24
|
+
awsm_object = Awsm.first
|
25
|
+
awsm_object && {
|
26
|
+
:id => awsm_object.id,
|
27
|
+
:auth_id => awsm_object.auth_id,
|
28
|
+
:auth_key => awsm_object.auth_key,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_awsm(awsm_base_url, awsm_app)
|
33
|
+
Awsm.create(:auth_id => "789eef", :auth_key => "009abb")
|
34
|
+
app.awsm_connection = EY::ApiHMAC::BaseConnection.new("789eef", "009abb")
|
35
|
+
app.awsm_connection.backend = awsm_app
|
36
|
+
find_awsm
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_partner(sso_user)
|
40
|
+
partner_object = Partner.first
|
41
|
+
partner_object && {
|
42
|
+
:id => partner_object.id,
|
43
|
+
:auth_id => partner_object.auth_id,
|
44
|
+
:auth_key => partner_object.auth_key,
|
45
|
+
:registration_url => URL_GEN.service_registration(partner_object),
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_partner(sso_user, partner_base_url, partner_app)
|
50
|
+
Partner.create(:auth_id => "123edf", :auth_key => "abc456")
|
51
|
+
app.partner_connection = EY::ApiHMAC::BaseConnection.new("123edf", "abc456")
|
52
|
+
app.partner_connection.backend = partner_app
|
53
|
+
find_partner(sso_user)
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_service(partner_id)
|
57
|
+
partner_object = Partner.get!(partner_id)
|
58
|
+
service_object = partner_object.services.first
|
59
|
+
service_object && {
|
60
|
+
:id => service_object.id,
|
61
|
+
:name => service_object.name,
|
62
|
+
:service_accounts_url => service_object.service_accounts_url
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def service_available_for_account?(service_id, sso_account_id)
|
67
|
+
Service.get(service_id).service_enablements.first(:sso_account_id => sso_account_id)
|
68
|
+
end
|
69
|
+
|
70
|
+
def make_service_available_for_account(service_id, sso_account_id)
|
71
|
+
ServiceEnablement.create(:service_id => service_id.to_i, :sso_account_id => sso_account_id.to_i, :reason => "test")
|
72
|
+
end
|
73
|
+
|
74
|
+
def find_service_account(service_id, sso_account_id)
|
75
|
+
service_object = Service.get(service_id)
|
76
|
+
service_account_object = service_object.service_accounts.first(:sso_account_id => sso_account_id)
|
77
|
+
service_account_object && {
|
78
|
+
:id => service_account_object.id,
|
79
|
+
:url => URL_GEN.partner_service_account(service_object, service_account_object),
|
80
|
+
:messages_url => URL_GEN.messages(service_object, service_account_object),
|
81
|
+
:invoices_url => URL_GEN.invoices(service_object, service_account_object),
|
82
|
+
:pushed_service_account => {
|
83
|
+
:provisioned_services_url => service_account_object.provisioned_services_url,
|
84
|
+
:configuration_url => service_account_object.configuration_url,
|
85
|
+
:url => service_account_object.url,
|
86
|
+
:configuration_required => service_account_object.configuration_required,
|
87
|
+
}
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
def find_provisioned_service(service_account_id, app_deployment_id)
|
92
|
+
service_account = ServiceAccount.get(service_account_id)
|
93
|
+
provisioned_service = service_account.provisioned_services.first(:app_deployment_id => app_deployment_id)
|
94
|
+
provisioned_service && {
|
95
|
+
:id => provisioned_service.id,
|
96
|
+
:url => URL_GEN.partner_provisioned_service(service_account, provisioned_service),
|
97
|
+
:messages_url => URL_GEN.messages(service_account.service, service_account, provisioned_service),
|
98
|
+
:pushed_provisioned_service => {
|
99
|
+
:vars => provisioned_service.vars,
|
100
|
+
:configuration_url => provisioned_service.configuration_url,
|
101
|
+
:configuration_required => provisioned_service.configuration_required,
|
102
|
+
:url => provisioned_service.url
|
103
|
+
}
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def latest_invoice
|
108
|
+
invoice = Invoice.last
|
109
|
+
{
|
110
|
+
:total_amount_cents => invoice.total_amount_cents,
|
111
|
+
:line_item_description => invoice.line_item_description,
|
112
|
+
:service_account_id => invoice.service_account_id,
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def latest_status_message
|
117
|
+
if message = Message.last(:message_type => "status")
|
118
|
+
to_return = {
|
119
|
+
:id => message.id,
|
120
|
+
:subject => message.subject,
|
121
|
+
:body => message.body
|
122
|
+
}
|
123
|
+
if message.respond_to?(:service_account) && message.service_account
|
124
|
+
to_return[:service_account_id] = message.service_account.id
|
125
|
+
end
|
126
|
+
if message.respond_to?(:provisioned_service) && message.provisioned_service
|
127
|
+
to_return[:provisioned_service_id] = message.provisioned_service.id
|
128
|
+
end
|
129
|
+
to_return
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module EyServicesFake
|
4
|
+
class TresfiestasFakeRackApp < Sinatra::Base
|
5
|
+
enable :raise_errors
|
6
|
+
disable :dump_errors
|
7
|
+
disable :show_exceptions
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :partner_connection
|
11
|
+
attr_accessor :awsm_connection
|
12
|
+
end
|
13
|
+
|
14
|
+
################
|
15
|
+
# External API #
|
16
|
+
################
|
17
|
+
|
18
|
+
get '/api/1/partners/:partner_id/services' do |partner_id|
|
19
|
+
partner = Partner.get!(partner_id)
|
20
|
+
to_return = []
|
21
|
+
partner.services.each do |service|
|
22
|
+
to_return << {"service" => service.attributes.merge('url' => URL_GEN.service(service)) }
|
23
|
+
end
|
24
|
+
to_return.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
#TODO: auth!
|
28
|
+
post '/api/1/partners/:partner_id/services' do |partner_id|
|
29
|
+
partner = Partner.get!(partner_id)
|
30
|
+
service_json = JSON.parse(request.body.read)["service"]
|
31
|
+
if service_json["name"].to_s.empty?
|
32
|
+
status 400
|
33
|
+
{:error_messages => ["Name can't be blank"]}.to_json
|
34
|
+
else
|
35
|
+
service = Service.create(service_json.merge(:partner_id => partner.id))
|
36
|
+
status 201
|
37
|
+
headers 'Location' => URL_GEN.service(service)
|
38
|
+
{}.to_json
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
get '/api/1/partners/:partner_id/services/:service_id' do |partner_id, service_id|
|
43
|
+
partner = Partner.get!(partner_id)
|
44
|
+
if service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
|
45
|
+
{"service" => service.attributes}.to_json
|
46
|
+
else
|
47
|
+
status 404
|
48
|
+
{}.to_json
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
put '/api/1/partners/:partner_id/services/:service_id' do |partner_id, service_id|
|
53
|
+
partner = Partner.get!(partner_id)
|
54
|
+
service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
|
55
|
+
update_params = JSON.parse(request.body.read)["service"]
|
56
|
+
if update_params.key?("name") && update_params["name"].to_s.empty?
|
57
|
+
status 400
|
58
|
+
{:error_messages => ["Name can't be blank"]}.to_json
|
59
|
+
else
|
60
|
+
service.update_attributes(update_params)
|
61
|
+
{}.to_json
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
delete '/api/1/partners/:partner_id/services/:service_id' do |partner_id, service_id|
|
66
|
+
partner = Partner.get!(partner_id)
|
67
|
+
service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
|
68
|
+
service.destroy
|
69
|
+
{}.to_json
|
70
|
+
end
|
71
|
+
|
72
|
+
put '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id' do |partner_id, service_id, service_account_id|
|
73
|
+
partner = Partner.get!(partner_id)
|
74
|
+
service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
|
75
|
+
service_account = service.service_accounts.detect{ |sa| sa.id.to_s == service_account_id.to_s }
|
76
|
+
service_account_atts = JSON.parse(request.body.read)["service_account"]
|
77
|
+
service_account.update_attributes(service_account_atts)
|
78
|
+
{}.to_json
|
79
|
+
end
|
80
|
+
|
81
|
+
post '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id/invoices' do |partner_id, service_id, service_account_id|
|
82
|
+
invoice_params = JSON.parse(request.body.read)["invoice"]
|
83
|
+
unless invoice_params['total_amount_cents'].is_a?(Fixnum)
|
84
|
+
status 400
|
85
|
+
return {:error_messages => ["Total Amount Cents must be an integer"]}.to_json
|
86
|
+
end
|
87
|
+
if invoice_params["line_item_description"].to_s.empty?
|
88
|
+
status 400
|
89
|
+
return {:error_messages => ["Line item description can't be blank"]}.to_json
|
90
|
+
end
|
91
|
+
if invoice_params['total_amount_cents'] < 0
|
92
|
+
status 400
|
93
|
+
return {:error_messages => ["Total amount cents must be greater than or equal to 0"]}.to_json
|
94
|
+
end
|
95
|
+
Invoice.create(invoice_params.merge(:service_account_id => service_account_id.to_i))
|
96
|
+
{}.to_json
|
97
|
+
end
|
98
|
+
|
99
|
+
post '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id/messages' do |partner_id, service_id, service_account_id|
|
100
|
+
message_params = JSON.parse(request.body.read)["message"]
|
101
|
+
message_type = message_params['message_type']
|
102
|
+
subject = message_params['subject']
|
103
|
+
body = message_params['body']
|
104
|
+
|
105
|
+
if subject.to_s.empty?
|
106
|
+
status 400
|
107
|
+
return {:error_messages => ["Subject can't be blank."]}.to_json
|
108
|
+
end
|
109
|
+
|
110
|
+
unless ['status', 'notification', 'alert'].include? message_type
|
111
|
+
status 400
|
112
|
+
return {:error_messages => ['Message type must be one of: status, notification or alert']}.to_json
|
113
|
+
end
|
114
|
+
|
115
|
+
service_account = ServiceAccount.get(service_account_id)
|
116
|
+
message = Message.create(message_params.merge(:service_account_id => service_account.id))
|
117
|
+
self.class.awsm_connection.post(service_account.dashboard_notifications_url, {
|
118
|
+
:notification => {:subject => subject, :body => body},
|
119
|
+
:message_type => message_type,
|
120
|
+
:configuration_possible => !!service_account.configuration_url,
|
121
|
+
:service_name => service_account.service.name,
|
122
|
+
:service_id => service_account.service_id})
|
123
|
+
{}.to_json
|
124
|
+
end
|
125
|
+
|
126
|
+
post '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id/provisioned_service/:provisioned_service_id/messages' do |partner_id, service_id, service_account_id, provisioned_service_id|
|
127
|
+
message_params = JSON.parse(request.body.read)["message"]
|
128
|
+
subject = message_params['subject']
|
129
|
+
message_type = message_params['message_type']
|
130
|
+
body = message_params['body']
|
131
|
+
|
132
|
+
if subject.to_s.empty?
|
133
|
+
status 400
|
134
|
+
return {:error_messages => ["Subject can't be blank."]}.to_json
|
135
|
+
end
|
136
|
+
|
137
|
+
unless ['status', 'notification', 'alert'].include? message_type
|
138
|
+
status 400
|
139
|
+
return {:error_messages => ['Message type must be one of: status, notification or alert']}.to_json
|
140
|
+
end
|
141
|
+
|
142
|
+
message = Message.create(message_params.merge(:provisioned_service_id => provisioned_service_id.to_i))
|
143
|
+
provisioned_service = ProvisionedService.get(provisioned_service_id)
|
144
|
+
service_account = provisioned_service.service_account
|
145
|
+
message = Message.create(message_params.merge(:provisioned_service_id => provisioned_service.id))
|
146
|
+
self.class.awsm_connection.post(provisioned_service.dashboard_notifications_url, {
|
147
|
+
:notification => {:subject => subject, :body => body},
|
148
|
+
:message_type => message_type,
|
149
|
+
:configuration_possible => !!provisioned_service.configuration_url,
|
150
|
+
:service_name => service_account.service.name,
|
151
|
+
:provisionable_service_id => provisioned_service.id})
|
152
|
+
{}.to_json
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module EyServicesFake
|
2
|
+
class UrlGenerator
|
3
|
+
|
4
|
+
def initialize(base_url)
|
5
|
+
@base_url = base_url
|
6
|
+
end
|
7
|
+
|
8
|
+
def service_registration(partner)
|
9
|
+
"#{@base_url}/api/1/partners/#{partner.id}/services"
|
10
|
+
end
|
11
|
+
|
12
|
+
def service(service)
|
13
|
+
"#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def partner_service_account(service, service_account)
|
17
|
+
"#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def messages(service, service_account, provisioned_service = nil)
|
21
|
+
if provisioned_service
|
22
|
+
"#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}/provisioned_service/#{provisioned_service.id}/messages"
|
23
|
+
else
|
24
|
+
"#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}/messages"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def invoices(service, service_account)
|
29
|
+
"#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}/invoices"
|
30
|
+
end
|
31
|
+
|
32
|
+
def partner_provisioned_service(service_account, provisioned_service)
|
33
|
+
"#{@base_url}/api/1/service_accounts/#{service_account.id}/provisioned_service/#{provisioned_service.id}"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ey_services_fake
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jacob Burkhart & Josh Lane
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-06 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: sinatra
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: cubbyhole
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 23
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 2
|
46
|
+
- 0
|
47
|
+
version: 0.2.0
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
description: A fake for use when writting tests against the ey_services_api
|
51
|
+
email:
|
52
|
+
- jacob@engineyard.com
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- .gitignore
|
61
|
+
- ey_services_fake.gemspec
|
62
|
+
- lib/ey_services_fake/mock_backend.rb
|
63
|
+
- lib/ey_services_fake/mocking_bird_service.rb
|
64
|
+
- lib/ey_services_fake/models.rb
|
65
|
+
- lib/ey_services_fake/reacharound_awsm.rb
|
66
|
+
- lib/ey_services_fake/tresfiestas_fake.rb
|
67
|
+
- lib/ey_services_fake/tresfiestas_fake_rack_app.rb
|
68
|
+
- lib/ey_services_fake/url_generator.rb
|
69
|
+
- lib/ey_services_fake/version.rb
|
70
|
+
homepage: ""
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
requirements: []
|
97
|
+
|
98
|
+
rubyforge_project: ey_services_fake
|
99
|
+
rubygems_version: 1.8.10
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: A fake for use when writting tests against the ey_services_api
|
103
|
+
test_files: []
|
104
|
+
|