rhc 1.2.7 → 1.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/bin/rhc +6 -8
  2. data/bin/rhc-chk +23 -10
  3. data/features/domain.feature +1 -1
  4. data/features/lib/rhc_helper.rb +3 -2
  5. data/features/lib/rhc_helper/api.rb +7 -0
  6. data/features/lib/rhc_helper/app.rb +8 -10
  7. data/features/lib/rhc_helper/domain.rb +2 -1
  8. data/features/lib/rhc_helper/runnable.rb +2 -24
  9. data/features/sshkey.feature +3 -3
  10. data/features/step_definitions/cartridge_steps.rb +6 -6
  11. data/features/step_definitions/client_steps.rb +0 -1
  12. data/features/step_definitions/sshkey_steps.rb +2 -2
  13. data/features/support/before_hooks.rb +0 -1
  14. data/features/support/env.rb +5 -3
  15. data/lib/rhc-common.rb +1 -1
  16. data/lib/rhc.rb +9 -8
  17. data/lib/rhc/auth.rb +3 -0
  18. data/lib/rhc/auth/basic.rb +54 -0
  19. data/lib/rhc/cartridge_helpers.rb +11 -5
  20. data/lib/rhc/cli.rb +4 -2
  21. data/lib/rhc/command_runner.rb +35 -30
  22. data/lib/rhc/commands.rb +127 -18
  23. data/lib/rhc/commands/account.rb +24 -0
  24. data/lib/rhc/commands/alias.rb +1 -1
  25. data/lib/rhc/commands/app.rb +210 -209
  26. data/lib/rhc/commands/apps.rb +22 -0
  27. data/lib/rhc/commands/base.rb +10 -77
  28. data/lib/rhc/commands/cartridge.rb +35 -35
  29. data/lib/rhc/commands/domain.rb +20 -13
  30. data/lib/rhc/commands/git_clone.rb +30 -0
  31. data/lib/rhc/commands/{port-forward.rb → port_forward.rb} +3 -3
  32. data/lib/rhc/commands/server.rb +28 -16
  33. data/lib/rhc/commands/setup.rb +18 -1
  34. data/lib/rhc/commands/snapshot.rb +4 -4
  35. data/lib/rhc/commands/sshkey.rb +4 -18
  36. data/lib/rhc/commands/tail.rb +32 -9
  37. data/lib/rhc/config.rb +168 -99
  38. data/lib/rhc/context_helper.rb +22 -9
  39. data/lib/rhc/core_ext.rb +41 -1
  40. data/lib/rhc/exceptions.rb +21 -5
  41. data/lib/rhc/git_helpers.rb +81 -0
  42. data/lib/rhc/help_formatter.rb +21 -1
  43. data/lib/rhc/helpers.rb +222 -87
  44. data/lib/rhc/output_helpers.rb +94 -110
  45. data/lib/rhc/rest.rb +15 -198
  46. data/lib/rhc/rest/api.rb +88 -0
  47. data/lib/rhc/rest/application.rb +29 -30
  48. data/lib/rhc/rest/attributes.rb +27 -0
  49. data/lib/rhc/rest/base.rb +29 -33
  50. data/lib/rhc/rest/cartridge.rb +42 -20
  51. data/lib/rhc/rest/client.rb +351 -89
  52. data/lib/rhc/rest/domain.rb +7 -13
  53. data/lib/rhc/rest/gear_group.rb +1 -1
  54. data/lib/rhc/rest/key.rb +7 -2
  55. data/lib/rhc/rest/mock.rb +609 -0
  56. data/lib/rhc/rest/user.rb +6 -2
  57. data/lib/rhc/{ssh_key_helpers.rb → ssh_helpers.rb} +58 -28
  58. data/lib/rhc/{targz.rb → tar_gz.rb} +0 -0
  59. data/lib/rhc/usage_templates/command_help.erb +4 -1
  60. data/lib/rhc/usage_templates/help.erb +24 -11
  61. data/lib/rhc/usage_templates/options_help.erb +14 -0
  62. data/lib/rhc/wizard.rb +283 -213
  63. data/spec/keys/example.pem +23 -0
  64. data/spec/keys/example_private.pem +27 -0
  65. data/spec/keys/server.pem +19 -0
  66. data/spec/rest_spec_helper.rb +3 -371
  67. data/spec/rhc/auth_spec.rb +226 -0
  68. data/spec/rhc/cli_spec.rb +41 -14
  69. data/spec/rhc/command_spec.rb +44 -15
  70. data/spec/rhc/commands/account_spec.rb +41 -0
  71. data/spec/rhc/commands/alias_spec.rb +16 -15
  72. data/spec/rhc/commands/app_spec.rb +115 -92
  73. data/spec/rhc/commands/apps_spec.rb +39 -0
  74. data/spec/rhc/commands/cartridge_spec.rb +134 -112
  75. data/spec/rhc/commands/domain_spec.rb +31 -86
  76. data/spec/rhc/commands/git_clone_spec.rb +56 -0
  77. data/spec/rhc/commands/{port-forward_spec.rb → port_forward_spec.rb} +27 -32
  78. data/spec/rhc/commands/server_spec.rb +28 -3
  79. data/spec/rhc/commands/setup_spec.rb +29 -11
  80. data/spec/rhc/commands/snapshot_spec.rb +4 -3
  81. data/spec/rhc/commands/sshkey_spec.rb +24 -56
  82. data/spec/rhc/commands/tail_spec.rb +26 -9
  83. data/spec/rhc/commands/threaddump_spec.rb +12 -11
  84. data/spec/rhc/config_spec.rb +211 -164
  85. data/spec/rhc/context_spec.rb +2 -0
  86. data/spec/rhc/helpers_spec.rb +242 -46
  87. data/spec/rhc/rest_application_spec.rb +42 -28
  88. data/spec/rhc/rest_client_spec.rb +110 -93
  89. data/spec/rhc/rest_spec.rb +220 -131
  90. data/spec/rhc/targz_spec.rb +1 -1
  91. data/spec/rhc/wizard_spec.rb +435 -624
  92. data/spec/spec.opts +1 -1
  93. data/spec/spec_helper.rb +140 -6
  94. data/spec/wizard_spec_helper.rb +326 -0
  95. metadata +163 -143
  96. data/lib/rhc/client.rb +0 -17
  97. data/lib/rhc/git_helper.rb +0 -59
@@ -1,9 +1,7 @@
1
- require 'rhc/rest/base'
2
-
3
1
  module RHC
4
2
  module Rest
5
3
  class Domain < Base
6
- attr_reader :id
4
+ define_attr :id
7
5
 
8
6
  #Add Application to this domain
9
7
  # options
@@ -18,23 +16,19 @@ module RHC
18
16
  options.each do |key, value|
19
17
  payload[key] = value
20
18
  end
21
- timeout = nil
22
- if options[:scale]
23
- timeout = 300 # 5 minute timeout for scalable app
24
- end
25
-
26
- rest_method "ADD_APPLICATION", payload, timeout
19
+ options = {:timeout => options[:scale] && 0 || nil}
20
+ rest_method "ADD_APPLICATION", payload, options
27
21
  end
28
22
 
29
- def applications
23
+ def applications(options = {})
30
24
  debug "Getting all applications for domain #{id}"
31
- rest_method "LIST_APPLICATIONS"
25
+ rest_method "LIST_APPLICATIONS", options
32
26
  end
33
27
 
34
28
  def update(new_id)
35
29
  debug "Updating domain #{id} to #{new_id}"
36
30
  # 5 minute timeout as this may take time if there are a lot of apps
37
- rest_method "UPDATE", {:id => new_id}, 300
31
+ rest_method "UPDATE", {:id => new_id}, {:timeout => 0}
38
32
  end
39
33
  alias :save :update
40
34
 
@@ -53,7 +47,7 @@ module RHC
53
47
 
54
48
  debug "Finding application :name => #{name}, :framework => #{framework}"
55
49
  applications.each do |app|
56
- return app if (name.nil? or app.name == name) and (framework.nil? or app.framework == framework)
50
+ return app if (name.nil? or app.name.downcase == name.downcase) and (framework.nil? or app.framework == framework)
57
51
  end
58
52
 
59
53
  raise RHC::ApplicationNotFoundException.new("Application #{name} does not exist")
@@ -4,7 +4,7 @@ module RHC
4
4
  module Rest
5
5
  class GearGroup < Base
6
6
  include Rest
7
- attr_reader :gears, :cartridges
7
+ define_attr :gears, :cartridges
8
8
  end
9
9
  end
10
10
  end
@@ -3,7 +3,7 @@ require 'rhc/rest/base'
3
3
  module RHC
4
4
  module Rest
5
5
  class Key < Base
6
- attr_reader :name, :type, :content
6
+ define_attr :name, :type, :content
7
7
 
8
8
  def update(type, content)
9
9
  debug "Updating key #{self.name}"
@@ -17,13 +17,18 @@ module RHC
17
17
  alias :delete :destroy
18
18
 
19
19
  def fingerprint
20
- begin
20
+ @fingerprint ||= begin
21
21
  public_key = Net::SSH::KeyFactory.load_data_public_key("#{type} #{content}")
22
22
  public_key.fingerprint
23
23
  rescue NotImplementedError, OpenSSL::PKey::PKeyError => e
24
24
  'Invalid key'
25
25
  end
26
26
  end
27
+
28
+ def visible_to_ssh?
29
+ Net::SSH::Authentication::Agent.connect.identities.
30
+ find{ |i| fingerprint == i.fingerprint }.present? rescue false
31
+ end
27
32
  end
28
33
  end
29
34
  end
@@ -0,0 +1,609 @@
1
+ require "rhc/rest"
2
+
3
+ module RHC::Rest::Mock
4
+
5
+ def self.start
6
+ RHC::Helpers.warn "Running in mock mode"
7
+ MockRestClient.new.tap do |c|
8
+ d = c.add_domain("test1")
9
+ app = d.add_application('app1', 'carttype1')
10
+ app.cartridges[0].display_name = "A display name"
11
+ app.add_cartridge('mockcart2')
12
+ app2 = d.add_application('app2', 'carttype2', true)
13
+ end
14
+ end
15
+
16
+ module Helpers
17
+
18
+ def mock_user
19
+ "test_user"
20
+ end
21
+
22
+ def mock_user_auth
23
+ respond_to?(:user_auth) ? self.user_auth : {:user => username, :password => password}
24
+ end
25
+
26
+ def stub_api_request(method, uri, with_auth=true)
27
+ stub_request(method, mock_href(uri, with_auth)).
28
+ with(&user_agent_header)
29
+ end
30
+
31
+ def stub_api(auth=false)
32
+ stub_api_request(:get, 'broker/rest/api', auth).
33
+ to_return({
34
+ :body => {
35
+ :data => mock_response_links(mock_real_client_links),
36
+ :supported_api_versions => [1.0, 1.1, 1.2, 1.3],
37
+ }.to_json
38
+ })
39
+ end
40
+ def stub_user(auth=mock_user_auth)
41
+ stub_api_request(:get, 'broker/rest/user', auth).to_return(simple_user(username))
42
+ end
43
+ def stub_create_default_key
44
+ stub_api_request(:post, 'broker/rest/user/keys', mock_user_auth).
45
+ with(:body => hash_including({:name => 'default', :type => 'ssh-rsa'})).
46
+ to_return({:status => 201, :body => {}.to_json})
47
+ end
48
+ def stub_update_key(name)
49
+ stub_api_request(:put, "broker/rest/user/keys/#{name}", mock_user_auth).
50
+ with(:body => hash_including({:type => 'ssh-rsa'})).
51
+ to_return({:status => 200, :body => {}.to_json})
52
+ end
53
+ def stub_create_domain(name)
54
+ stub_api_request(:post, 'broker/rest/domains', mock_user_auth).
55
+ with(:body => hash_including({:id => name})).
56
+ to_return(new_domain(name))
57
+ end
58
+ def stub_no_keys
59
+ stub_api_request(:get, 'broker/rest/user/keys', mock_user_auth).to_return(no_keys)
60
+ end
61
+ def stub_mock_ssh_keys(name='test')
62
+ stub_api_request(:get, 'broker/rest/user/keys', mock_user_auth).
63
+ to_return({
64
+ :body => {
65
+ :type => 'keys',
66
+ :data => [
67
+ {
68
+ :name => name,
69
+ :type => pub_key.split[0],
70
+ :content => pub_key.split[1],
71
+ # :links => mock_response_links([
72
+ # ['UPDATE', "broker/rest/user/keys/#{name}", 'put']
73
+ # ]),
74
+ }
75
+ ],
76
+ }.to_json
77
+ })
78
+ end
79
+ def stub_one_key(name)
80
+ stub_api_request(:get, 'broker/rest/user/keys', mock_user_auth).
81
+ to_return({
82
+ :body => {
83
+ :type => 'keys',
84
+ :data => [
85
+ {
86
+ :name => name,
87
+ :type => 'ssh-rsa',
88
+ :content => rsa_key_content_public,
89
+ :links => mock_response_links([
90
+ ['UPDATE', "broker/rest/user/keys/#{name}", 'put']
91
+ ]),
92
+ }
93
+ ],
94
+ }.to_json
95
+ })
96
+ end
97
+ def stub_no_domains
98
+ stub_api_request(:get, 'broker/rest/domains', mock_user_auth).to_return(no_domains)
99
+ end
100
+ def stub_one_domain(name)
101
+ stub_api_request(:get, 'broker/rest/domains', mock_user_auth).
102
+ to_return({
103
+ :body => {
104
+ :type => 'domains',
105
+ :data => [{:id => name, :links => mock_response_links([
106
+ ['LIST_APPLICATIONS', "broker/rest/domains/#{name}/applications", 'get']
107
+ ])}],
108
+ }.to_json
109
+ })
110
+ end
111
+ def stub_one_application(domain_name, name)
112
+ stub_api_request(:get, "broker/rest/domains/#{domain_name}/applications", mock_user_auth).
113
+ to_return({
114
+ :body => {
115
+ :type => 'applications',
116
+ :data => [{
117
+ :domain_id => domain_name,
118
+ :id => 1,
119
+ :name => name,
120
+ :app_url => "http://#{name}-#{domain_name}.rhcloud.com",
121
+ :links => mock_response_links([
122
+ ]),
123
+ }],
124
+ }.to_json
125
+ })
126
+ end
127
+ def stub_simple_carts
128
+ stub_api_request(:get, 'broker/rest/cartridges', mock_user_auth).to_return(simple_carts)
129
+ end
130
+
131
+ def define_exceptional_test_on_wizard
132
+ RHC::Wizard.module_eval <<-EOM
133
+ private
134
+ def test_and_raise
135
+ raise
136
+ end
137
+ EOM
138
+ end
139
+
140
+ def no_keys
141
+ empty_response_list('keys')
142
+ end
143
+ def no_domains
144
+ empty_response_list('domains')
145
+ end
146
+
147
+ def empty_response_list(type)
148
+ {
149
+ :body => {
150
+ :type => type,
151
+ :data => [],
152
+ }.to_json
153
+ }
154
+ end
155
+
156
+ def new_domain(name)
157
+ {
158
+ :status => 201,
159
+ :body => {
160
+ :type => 'domain',
161
+ :data => {
162
+ :id => name,
163
+ :links => mock_response_links([
164
+ ])
165
+ },
166
+ }.to_json
167
+ }
168
+ end
169
+ def simple_carts
170
+ {
171
+ :body => {
172
+ :type => 'cartridges',
173
+ :data => [
174
+ {:name => 'mock_standalone_cart-1', :type => 'standalone', :tags => ['cartridge'], :display_name => 'Mock1 Cart'},
175
+ {:name => 'mock_standalone_cart-2', :type => 'standalone', :description => 'Mock2 description'},
176
+ {:name => 'mock_embedded_cart-1', :type => 'embedded', :tags => ['scheduled'], :display_name => 'Mock1 Embedded Cart'},
177
+ ],
178
+ }.to_json
179
+ }
180
+ end
181
+ def simple_user(login)
182
+ {
183
+ :body => {
184
+ :type => 'user',
185
+ :data => {
186
+ :login => login,
187
+ :plan_id => respond_to?(:user_plan_id) ? self.user_plan_id : nil,
188
+ :consumed_gears => respond_to?(:user_consumed_gears) ? self.user_consumed_gears : 0,
189
+ :max_gears => respond_to?(:user_max_gears) ? self.user_max_gears : 3,
190
+ :capabilities => respond_to?(:user_capabilities) ? self.user_capabilities : {:gear_sizes => ['small', 'medium']},
191
+ :links => mock_response_links([
192
+ ['ADD_KEY', "broker/rest/user/keys", 'POST'],
193
+ ['LIST_KEYS', "broker/rest/user/keys", 'GET'],
194
+ ])
195
+ },
196
+ }.to_json
197
+ }
198
+ end
199
+
200
+ def mock_pass
201
+ "test pass"
202
+ end
203
+
204
+ def mock_uri
205
+ "test.domain.com"
206
+ end
207
+
208
+ # Creates consistent hrefs for testing
209
+ def mock_href(relative="", with_auth=false)
210
+ server = respond_to?(:server) ? self.server : mock_uri
211
+ uri_string =
212
+ if with_auth == true
213
+ username = respond_to?(:username) ? self.username : mock_user
214
+ password = respond_to?(:password) ? self.password : mock_pass
215
+ "#{username}:#{password}@#{mock_uri}"
216
+ elsif with_auth
217
+ "#{with_auth[:user]}:#{with_auth[:password]}@#{server}"
218
+ else
219
+ server
220
+ end
221
+ "https://#{uri_string}/#{relative}"
222
+ end
223
+
224
+ # This formats link lists for JSONification
225
+ def mock_response_links(links)
226
+ link_set = {}
227
+ links.each do |link|
228
+ operation = link[0]
229
+ href = link[1]
230
+ method = link[2]
231
+ # Note that the 'relative' key/value pair below is a convenience for testing;
232
+ # this is not used by the API classes.
233
+ link_set[operation] = { 'href' => mock_href(href), 'method' => method, 'relative' => href }
234
+ end
235
+ return link_set
236
+ end
237
+
238
+ def mock_app_links(domain_id='test_domain',app_id='test_app')
239
+ [['ADD_CARTRIDGE', "domains/#{domain_id}/apps/#{app_id}/carts/add", 'post'],
240
+ ['LIST_CARTRIDGES', "domains/#{domain_id}/apps/#{app_id}/carts/", 'get' ],
241
+ ['GET_GEAR_GROUPS', "domains/#{domain_id}/apps/#{app_id}/gear_groups", 'get' ],
242
+ ['START', "domains/#{domain_id}/apps/#{app_id}/start", 'post'],
243
+ ['STOP', "domains/#{domain_id}/apps/#{app_id}/stop", 'post'],
244
+ ['RESTART', "domains/#{domain_id}/apps/#{app_id}/restart", 'post'],
245
+ ['THREAD_DUMP', "domains/#{domain_id}/apps/#{app_id}/event", 'post'],
246
+ ['ADD_ALIAS', "domains/#{domain_id}/apps/#{app_id}/event", 'post'],
247
+ ['REMOVE_ALIAS', "domains/#{domain_id}/apps/#{app_id}/event", 'post'],
248
+ ['DELETE', "domains/#{domain_id}/apps/#{app_id}/delete", 'post']]
249
+ end
250
+
251
+ def mock_cart_links(domain_id='test_domain',app_id='test_app',cart_id='test_cart')
252
+ [['START', "domains/#{domain_id}/apps/#{app_id}/carts/#{cart_id}/start", 'post'],
253
+ ['STOP', "domains/#{domain_id}/apps/#{app_id}/carts/#{cart_id}/stop", 'post'],
254
+ ['RESTART', "domains/#{domain_id}/apps/#{app_id}/carts/#{cart_id}/restart", 'post'],
255
+ ['DELETE', "domains/#{domain_id}/apps/#{app_id}/carts/#{cart_id}/delete", 'post']]
256
+ end
257
+
258
+ def mock_client_links
259
+ [['GET_USER', 'user/', 'get' ],
260
+ ['ADD_DOMAIN', 'domains/add', 'post'],
261
+ ['LIST_DOMAINS', 'domains/', 'get' ],
262
+ ['LIST_CARTRIDGES', 'cartridges/', 'get' ]]
263
+ end
264
+ def mock_real_client_links
265
+ [['GET_USER', "broker/rest/user", 'GET'],
266
+ ['LIST_DOMAINS', "broker/rest/domains", 'GET'],
267
+ ['ADD_DOMAIN', "broker/rest/domains", 'POST'],
268
+ ['LIST_CARTRIDGES', "broker/rest/cartridges", 'GET'],
269
+ ]
270
+ end
271
+
272
+ def mock_domain_links(domain_id='test_domain')
273
+ [['ADD_APPLICATION', "domains/#{domain_id}/apps/add", 'post'],
274
+ ['LIST_APPLICATIONS', "domains/#{domain_id}/apps/", 'get' ],
275
+ ['UPDATE', "domains/#{domain_id}/update", 'post'],
276
+ ['DELETE', "domains/#{domain_id}/delete", 'post']]
277
+ end
278
+
279
+ def mock_key_links(key_id='test_key')
280
+ [['UPDATE', "user/keys/#{key_id}/update", 'post'],
281
+ ['DELETE', "user/keys/#{key_id}/delete", 'post']]
282
+ end
283
+
284
+ def mock_user_links
285
+ [['ADD_KEY', 'user/keys/add', 'post'],
286
+ ['LIST_KEYS', 'user/keys/', 'get' ]]
287
+ end
288
+
289
+ def mock_cartridge_response(cart_count=1)
290
+ carts = []
291
+ while carts.length < cart_count
292
+ carts << {
293
+ :name => "mock_cart_#{carts.length}",
294
+ :type => "mock_cart_#{carts.length}_type",
295
+ :links => mock_response_links(mock_cart_links('mock_domain','mock_app',"mock_cart_#{carts.length}"))
296
+ }
297
+ end
298
+
299
+ carts = carts[0] if cart_count == 1
300
+ type = cart_count == 1 ? 'cartridge' : 'cartridges'
301
+
302
+ return {
303
+ :body => {
304
+ :type => type,
305
+ :data => carts
306
+ }.to_json,
307
+ :status => 200
308
+ }
309
+ end
310
+
311
+ def mock_gear_groups_response()
312
+ groups = [{}]
313
+ type = 'gear_groups'
314
+
315
+ return {
316
+ :body => {
317
+ :type => type,
318
+ :data => groups
319
+ }.to_json,
320
+ :status => 200
321
+ }
322
+ end
323
+ end
324
+
325
+ class MockRestClient < RHC::Rest::Client
326
+ include Helpers
327
+
328
+ def initialize(config=RHC::Config)
329
+ obj = self
330
+ if RHC::Rest::Client.respond_to?(:stub)
331
+ RHC::Rest::Client.stub(:new) { obj }
332
+ else
333
+ RHC::Rest::Client.instance_eval do
334
+ @obj = obj
335
+ def new(*args)
336
+ @obj
337
+ end
338
+ end
339
+ end
340
+ @domains = []
341
+ @user = MockRestUser.new(client, config.username)
342
+ @api = MockRestApi.new(client, config)
343
+ end
344
+
345
+ def api
346
+ @api
347
+ end
348
+
349
+ def user
350
+ @user
351
+ end
352
+
353
+ def domains
354
+ @domains
355
+ end
356
+
357
+ def cartridges
358
+ [MockRestCartridge.new(self, "mock_cart-1", "embedded"), # code should sort this to be after standalone
359
+ MockRestCartridge.new(self, "mock_standalone_cart-1", "standalone"),
360
+ MockRestCartridge.new(self, "mock_standalone_cart-2", "standalone"),
361
+ MockRestCartridge.new(self, "mock_unique_standalone_cart-1", "standalone"),
362
+ MockRestCartridge.new(self, "jenkins-1.4", "standalone"),
363
+ MockRestCartridge.new(self, "mock_cart-2", "embedded"),
364
+ MockRestCartridge.new(self, "unique_mock_cart-1", "embedded"),
365
+ MockRestCartridge.new(self, "jenkins-client-1.4", "embedded")]
366
+ end
367
+
368
+ def add_domain(id)
369
+ d = MockRestDomain.new(self, id)
370
+ @domains << d
371
+ d
372
+ end
373
+
374
+ def sshkeys
375
+ @user.keys
376
+ end
377
+
378
+ def add_key(name, type, content)
379
+ @user.add_key(name, type, content)
380
+ end
381
+
382
+ def delete_key(name)
383
+ @user.keys.delete_if { |key| key.name == name }
384
+ end
385
+ end
386
+
387
+ class MockRestApi < RHC::Rest::Api
388
+ include Helpers
389
+
390
+ def initialize(client, config)
391
+ @client = client
392
+ @client_api_versions = RHC::Rest::Client::CLIENT_API_VERSIONS
393
+ @server_api_versions = @client_api_versions
394
+ self.attributes = {:links => mock_response_links(mock_client_links)}
395
+ end
396
+ end
397
+
398
+ class MockRestUser < RHC::Rest::User
399
+ include Helpers
400
+ def initialize(client, login)
401
+ super({}, client)
402
+ @login = login
403
+ @keys = [
404
+ MockRestKey.new(client, 'mockkey1', 'ssh-rsa', 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDNK8xT3O+kSltmCMsSqBfAgheB3YFJ9Y0ESJnFjFASVxH70AcCQAgdQSD/r31+atYShJdP7f0AMWiQUTw2tK434XSylnZWEyIR0V+j+cyOPdVQlns6D5gPOnOtweFF0o18YulwCOK8Q1H28GK8qyWhLe0FcMmxtKbbQgaVRvQdXZz4ThzutCJOyJm9xVb93+fatvwZW76oLLvfFJcJSOK2sgW7tJM2A83bm4mwixFDF7wO/+C9WA+PgPKJUIjvy1gZjBhRB+3b58vLOnYhPOgMNruJwzB+wJ3pg8tLJEjxSbHyyoi6OqMBs4BVV7LdzvwTDxEjcgtHVvaVNXgO5iRX'),
405
+ MockRestKey.new(client, 'mockkey2', 'ssh-dsa', 'AAAAB3NzaC1kc3MAAACBAPaaFj6Xjrjd8Dc4AAkJe0HigqaXMxj/87xHoV+nPgerHIceJWhPUWdW40lSASrgpAV9Eq4zzD+L19kgYdbMw0vSX5Cj3XtNOsow9MmMxFsYjTxCv4eSs/rLdGPaYZ5GVRPDu8tN42Bm8lj5o+ky3HzwW+mkQMZwcADQIgqtn6QhAAAAFQCirDfIMf/JoMOFf8CTnsTKWw/0zwAAAIAIQp6t2sLIp1d2TBfd/qLjOJA10rPADcnhBzWB/cd/oFJ8a/2nmxeSPR5Ov18T6itWqbKwvZw2UC0MrXoYbgcfVNP/ym1bCd9rB5hu1sg8WO4JIxA/47PZooT6PwTKVxHuENEzQyJL2o6ZJq+wuV0taLvm6IaM5TAZuEJ2p4TC/gAAAIBpLcVXZREa7XLY55nyidt/+UC+PxpjhPHOHbzL1OvWEaumN4wcJk/JZPppgXX9+WDkTm1SD891U0cXnGMTP0OZOHkOUHF2ZcfUe7p9kX4WjHs0OccoxV0Lny6MC4DjalJyaaEbijJHSUX3QlLcBOlPHJWpEpvWQ9P8AN4PokiGzA==')
406
+ ]
407
+ end
408
+
409
+ def keys
410
+ @keys
411
+ end
412
+
413
+ def add_key(name, type, content)
414
+ @keys << MockRestKey.new(client, name, type, content)
415
+ end
416
+ end
417
+
418
+ class MockRestDomain < RHC::Rest::Domain
419
+ include Helpers
420
+ def initialize(client, id)
421
+ super({}, client)
422
+ @id = id
423
+ @applications = []
424
+ self.attributes = {:links => mock_response_links(mock_domain_links('mock_domain_0'))}
425
+ end
426
+
427
+ def update(id)
428
+ @id = id
429
+ self
430
+ end
431
+
432
+ def destroy
433
+ raise RHC::Rest::ClientErrorException.new("Applications must be empty.") unless @applications.empty?
434
+ client.domains.delete_if { |d| d.id == @id }
435
+
436
+ @applications = nil
437
+ end
438
+
439
+ def add_application(name, type=nil, scale=nil, gear_profile='default', git_url=nil)
440
+ if type.is_a?(Hash)
441
+ scale = type[:scale]
442
+ gear_profile = type[:gear_profile]
443
+ git_url = type[:initial_git_url]
444
+ type = Array(type[:cartridges] || type[:cartridge])
445
+ end
446
+ a = MockRestApplication.new(client, name, type, self, scale, gear_profile, git_url)
447
+ builder = @applications.find{ |app| app.cartridges.map(&:name).any?{ |s| s =~ /^jenkins-[\d\.]+$/ } }
448
+ a.building_app = builder.name if builder
449
+ @applications << a
450
+ a.add_message("Success")
451
+ a
452
+ end
453
+
454
+ def applications(*args)
455
+ @applications
456
+ end
457
+ end
458
+
459
+ class MockRestGearGroup < RHC::Rest::GearGroup
460
+ include Helpers
461
+ def initialize(client=nil)
462
+ super({}, client)
463
+ @cartridges = [{'name' => 'fake_geargroup_cart-0.1'}]
464
+ @gears = [{'state' => 'started', 'id' => 'fakegearid'}]
465
+ end
466
+ end
467
+
468
+ class MockRestApplication < RHC::Rest::Application
469
+ include Helpers
470
+ def fakeuuid
471
+ "fakeuuidfortests#{@name}"
472
+ end
473
+
474
+ def initialize(client, name, type, domain, scale=nil, gear_profile='default', initial_git_url=nil)
475
+ super({}, client)
476
+ @name = name
477
+ @domain = domain
478
+ @cartridges = []
479
+ @creation_time = Date.new(2000, 1, 1).strftime('%Y-%m-%dT%H:%M:%S%z')
480
+ @uuid = fakeuuid
481
+ @initial_git_url = initial_git_url
482
+ @git_url = "git:fake.foo/git/#{@name}.git"
483
+ @app_url = "https://#{@name}-#{@domain.id}.fake.foo/"
484
+ @ssh_url = "ssh://#{@uuid}@127.0.0.1"
485
+ @aliases = []
486
+ @gear_profile = gear_profile
487
+ if scale
488
+ @scalable = true
489
+ end
490
+ self.attributes = {:links => mock_response_links(mock_app_links('mock_domain_0', 'mock_app_0')), :messages => []}
491
+ self.gear_count = 5
492
+ types = Array(type)
493
+ cart = add_cartridge(types.first, false) if types.first
494
+ if scale
495
+ cart.supported_scales_to = (cart.scales_to = -1)
496
+ cart.supported_scales_from = (cart.scales_from = 2)
497
+ cart.current_scale = 2
498
+ cart.scales_with = "haproxy-1.4"
499
+ prox = add_cartridge('haproxy-1.4')
500
+ prox.collocated_with = [types.first]
501
+ end
502
+ types.drop(1).each{ |c| add_cartridge(c, false) }
503
+ @framework = types.first
504
+ end
505
+
506
+ def destroy
507
+ @domain.applications.delete self
508
+ end
509
+
510
+ def add_cartridge(name, embedded=true)
511
+ type = embedded ? "embedded" : "standalone"
512
+ c = MockRestCartridge.new(client, name, type, self)
513
+ c.properties << {'name' => 'prop1', 'value' => 'value1', 'description' => 'description1' }
514
+ @cartridges << c
515
+ c.messages << "Cartridge added with properties"
516
+ c
517
+ end
518
+
519
+ def gear_groups
520
+ # we don't have heavy interaction with gear groups yet so keep this simple
521
+ @gear_groups ||= [MockRestGearGroup.new(client)]
522
+ end
523
+
524
+ def cartridges
525
+ @cartridges
526
+ end
527
+
528
+ def start
529
+ @app
530
+ end
531
+
532
+ def stop(*args)
533
+ @app
534
+ end
535
+
536
+ def restart
537
+ @app
538
+ end
539
+
540
+ def reload
541
+ @app
542
+ end
543
+
544
+ def tidy
545
+ @app
546
+ end
547
+ end
548
+
549
+ class MockRestCartridge < RHC::Rest::Cartridge
550
+ include Helpers
551
+ def initialize(client, name, type, app=nil, properties=[{'type' => 'cart_data', 'name' => 'connection_url', 'value' => "http://fake.url" }])
552
+ super({}, client)
553
+ @name = name
554
+ @type = type
555
+ @app = app
556
+ @properties = properties.each(&:stringify_keys!)
557
+ @status_messages = [{"message" => "started", "gear_id" => "123"}]
558
+ @scales_from = 1
559
+ @scales_to = 1
560
+ @current_scale = 1
561
+ @gear_profile = 'small'
562
+ end
563
+
564
+ def destroy
565
+ @app.cartridges.delete self
566
+ end
567
+
568
+ def status
569
+ @status_messages
570
+ end
571
+
572
+ def start
573
+ @status_messages = [{"message" => "started", "gear_id" => "123"}]
574
+ @app
575
+ end
576
+
577
+ def stop
578
+ @status_messages = [{"message" => "stopped", "gear_id" => "123"}]
579
+ @app
580
+ end
581
+
582
+ def restart
583
+ @status_messages = [{"message" => "started", "gear_id" => "123"}]
584
+ @app
585
+ end
586
+
587
+ def reload
588
+ @app
589
+ end
590
+
591
+ def set_scales(values)
592
+ values.delete_if{|k,v| v.nil? }
593
+ @scales_from = values[:scales_from] if values[:scales_from]
594
+ @scales_to = values[:scales_to] if values[:scales_to]
595
+ self
596
+ end
597
+ end
598
+
599
+ class MockRestKey < RHC::Rest::Key
600
+ include Helpers
601
+ def initialize(client, name, type, content)
602
+ super({}, client)
603
+ @name = name
604
+ @type = type
605
+ @content = content
606
+ end
607
+ end
608
+ end
609
+