rhc 1.4.8 → 1.5.13

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.
Files changed (65) hide show
  1. data/features/application.feature +1 -0
  2. data/features/lib/rhc_helper/app.rb +5 -3
  3. data/features/lib/rhc_helper/commandify.rb +2 -1
  4. data/features/step_definitions/application_steps.rb +2 -1
  5. data/features/support/env.rb +4 -1
  6. data/lib/rhc/auth/basic.rb +18 -13
  7. data/lib/rhc/auth/token.rb +98 -0
  8. data/lib/rhc/auth/token_store.rb +51 -0
  9. data/lib/rhc/auth.rb +3 -1
  10. data/lib/rhc/command_runner.rb +1 -0
  11. data/lib/rhc/commands/account.rb +47 -1
  12. data/lib/rhc/commands/alias.rb +2 -4
  13. data/lib/rhc/commands/app.rb +23 -18
  14. data/lib/rhc/commands/authorization.rb +93 -0
  15. data/lib/rhc/commands/base.rb +11 -3
  16. data/lib/rhc/commands/cartridge.rb +8 -16
  17. data/lib/rhc/commands/git_clone.rb +2 -3
  18. data/lib/rhc/commands/port_forward.rb +10 -11
  19. data/lib/rhc/commands/setup.rb +4 -1
  20. data/lib/rhc/commands/snapshot.rb +4 -3
  21. data/lib/rhc/commands/tail.rb +3 -4
  22. data/lib/rhc/commands/threaddump.rb +1 -2
  23. data/lib/rhc/commands.rb +37 -3
  24. data/lib/rhc/config.rb +10 -1
  25. data/lib/rhc/context_helper.rb +5 -1
  26. data/lib/rhc/core_ext.rb +10 -0
  27. data/lib/rhc/exceptions.rb +0 -12
  28. data/lib/rhc/git_helpers.rb +12 -0
  29. data/lib/rhc/helpers.rb +31 -1
  30. data/lib/rhc/output_helpers.rb +19 -3
  31. data/lib/rhc/rest/api.rb +2 -1
  32. data/lib/rhc/rest/application.rb +5 -4
  33. data/lib/rhc/rest/authorization.rb +10 -0
  34. data/lib/rhc/rest/base.rb +6 -1
  35. data/lib/rhc/rest/client.rb +243 -122
  36. data/lib/rhc/rest/domain.rb +0 -15
  37. data/lib/rhc/rest/gear_group.rb +0 -1
  38. data/lib/rhc/rest/mock.rb +118 -16
  39. data/lib/rhc/rest/user.rb +0 -1
  40. data/lib/rhc/rest.rb +28 -8
  41. data/lib/rhc/ssh_helpers.rb +5 -2
  42. data/lib/rhc/tar_gz.rb +16 -5
  43. data/lib/rhc/usage_templates/help.erb +1 -1
  44. data/lib/rhc/wizard.rb +54 -10
  45. data/spec/coverage_helper.rb +9 -0
  46. data/spec/rhc/auth_spec.rb +229 -22
  47. data/spec/rhc/cli_spec.rb +15 -0
  48. data/spec/rhc/command_spec.rb +100 -8
  49. data/spec/rhc/commands/account_spec.rb +75 -1
  50. data/spec/rhc/commands/app_spec.rb +23 -5
  51. data/spec/rhc/commands/authorization_spec.rb +120 -0
  52. data/spec/rhc/commands/domain_spec.rb +2 -2
  53. data/spec/rhc/commands/git_clone_spec.rb +24 -0
  54. data/spec/rhc/commands/port_forward_spec.rb +22 -23
  55. data/spec/rhc/commands/server_spec.rb +2 -2
  56. data/spec/rhc/commands/setup_spec.rb +12 -0
  57. data/spec/rhc/config_spec.rb +7 -3
  58. data/spec/rhc/helpers_spec.rb +62 -9
  59. data/spec/rhc/rest_application_spec.rb +24 -0
  60. data/spec/rhc/rest_client_spec.rb +66 -56
  61. data/spec/rhc/rest_spec.rb +11 -2
  62. data/spec/rhc/wizard_spec.rb +61 -12
  63. data/spec/spec_helper.rb +125 -42
  64. data/spec/wizard_spec_helper.rb +1 -0
  65. metadata +9 -3
@@ -6,7 +6,183 @@ require 'httpclient'
6
6
 
7
7
  module RHC
8
8
  module Rest
9
+
10
+ MAX_RETRIES = 5
11
+
12
+ #
13
+ # These are methods that belong to the API object but are
14
+ # callable from the client for convenience.
15
+ #
16
+ module ApiMethods
17
+ def add_domain(id)
18
+ debug "Adding domain #{id}"
19
+ @domains = nil
20
+ api.rest_method "ADD_DOMAIN", :id => id
21
+ end
22
+
23
+ def domains
24
+ debug "Getting all domains"
25
+ @domains ||= api.rest_method "LIST_DOMAINS"
26
+ end
27
+
28
+ def cartridges
29
+ debug "Getting all cartridges"
30
+ @cartridges ||= api.rest_method("LIST_CARTRIDGES", nil, :lazy_auth => true)
31
+ end
32
+
33
+ def user
34
+ debug "Getting user info"
35
+ @user ||= api.rest_method "GET_USER"
36
+ end
37
+
38
+ def sshkeys
39
+ debug "Finding all keys for #{user.login}"
40
+ user.keys
41
+ end
42
+
43
+ def add_key(name, key, content)
44
+ debug "Adding key #{key} for #{user.login}"
45
+ user.add_key name, key, content
46
+ end
47
+
48
+ def delete_key(name)
49
+ debug "Deleting key '#{name}'"
50
+ key = find_key(name)
51
+ key.destroy
52
+ end
53
+
54
+ #Find Domain by namesapce
55
+ def find_domain(id)
56
+ debug "Finding domain #{id}"
57
+ domains.each { |domain| return domain if domain.id == id }
58
+
59
+ raise DomainNotFoundException.new("Domain #{id} not found")
60
+ end
61
+
62
+ def find_application(domain, application, options={})
63
+ response = request({
64
+ :url => link_show_application_by_domain_name(domain, application),
65
+ :method => "GET",
66
+ :payload => options
67
+ })
68
+ end
69
+
70
+ def find_application_gear_groups(domain, application, options={})
71
+ response = request({
72
+ :url => link_show_application_by_domain_name(domain, application, "gear_groups"),
73
+ :method => "GET",
74
+ :payload => options
75
+ })
76
+ end
77
+
78
+ def link_show_application_by_domain_name(domain, application, *args)
79
+ [
80
+ api.links['LIST_DOMAINS']['href'],
81
+ domain,
82
+ "applications",
83
+ application,
84
+ ].concat(args).map{ |s| URI.escape(s) }.join("/")
85
+ end
86
+
87
+ #Find Cartridge by name or regex
88
+ def find_cartridges(name)
89
+ debug "Finding cartridge #{name}"
90
+ if name.is_a?(Hash)
91
+ regex = name[:regex]
92
+ type = name[:type]
93
+ name = name[:name]
94
+ end
95
+
96
+ filtered = Array.new
97
+ cartridges.each do |cart|
98
+ if regex
99
+ filtered.push(cart) if cart.name.match(regex) and (type.nil? or cart.type == type)
100
+ else
101
+ filtered.push(cart) if (name.nil? or cart.name == name) and (type.nil? or cart.type == type)
102
+ end
103
+ end
104
+ return filtered
105
+ end
106
+
107
+ #find Key by name
108
+ def find_key(name)
109
+ debug "Finding key #{name}"
110
+ user.find_key(name) or raise RHC::KeyNotFoundException.new("Key #{name} does not exist")
111
+ end
112
+
113
+ def sshkeys
114
+ logger.debug "Finding all keys for #{user.login}" if @mydebug
115
+ user.keys
116
+ end
117
+
118
+ def add_key(name, key, content)
119
+ logger.debug "Adding key #{key} for #{user.login}" if @mydebug
120
+ user.add_key name, key, content
121
+ end
122
+
123
+ def delete_key(name)
124
+ logger.debug "Deleting key '#{name}'" if @mydebug
125
+ key = find_key(name)
126
+ key.destroy
127
+ end
128
+
129
+ def supports_sessions?
130
+ api.supports? 'ADD_AUTHORIZATION'
131
+ end
132
+
133
+ def authorizations
134
+ raise AuthorizationsNotSupported unless supports_sessions?
135
+ api.rest_method 'LIST_AUTHORIZATIONS'
136
+ end
137
+
138
+ #
139
+ # Returns nil if creating sessions is not supported, raises on error, otherwise
140
+ # returns an Authorization object.
141
+ #
142
+ def new_session(options={})
143
+ if supports_sessions?
144
+ api.rest_method('ADD_AUTHORIZATION', {
145
+ :scope => 'session',
146
+ :note => "RHC/#{RHC::VERSION::STRING} (from #{Socket.gethostname rescue 'unknown'} on #{RUBY_PLATFORM})",
147
+ :reuse => true
148
+ }, options)
149
+ end
150
+ end
151
+
152
+ def add_authorization(options={})
153
+ raise AuthorizationsNotSupported unless supports_sessions?
154
+ api.rest_method('ADD_AUTHORIZATION', options, options)
155
+ end
156
+
157
+ def delete_authorizations
158
+ raise AuthorizationsNotSupported unless supports_sessions?
159
+ api.rest_method('LIST_AUTHORIZATIONS', nil, {:method => :delete})
160
+ end
161
+
162
+ def delete_authorization(token)
163
+ raise AuthorizationsNotSupported unless supports_sessions?
164
+ api.rest_method('SHOW_AUTHORIZATION', nil, {:method => :delete, :params => {':id' => token}})
165
+ end
166
+
167
+ def authorization_scope_list
168
+ raise AuthorizationsNotSupported unless supports_sessions?
169
+ link = api.links['ADD_AUTHORIZATION']
170
+ scope = link['optional_params'].find{ |h| h['name'] == 'scope' }
171
+ scope['description'].scan(/(?!\n)\*(.*?)\n(.*?)(?:\n|\Z)/m).inject([]) do |h, (a, b)|
172
+ h << [a.strip, b.strip] if a.present? && b.present?
173
+ h
174
+ end
175
+ end
176
+
177
+ def logout
178
+ #TODO logout
179
+ debug "Logout/Close client"
180
+ end
181
+ alias :close :logout
182
+ end
183
+
9
184
  class Client < Base
185
+ include ApiMethods
10
186
 
11
187
  # Keep the list of supported API versions here
12
188
  # The list may not necessarily be sorted; we will select the last
@@ -33,6 +209,12 @@ module RHC
33
209
  @preferred_api_versions ||= CLIENT_API_VERSIONS
34
210
  @debug ||= false
35
211
 
212
+ if options[:token]
213
+ self.headers[:authorization] = "Bearer #{options.delete(:token)}"
214
+ options.delete(:user)
215
+ options.delete(:password)
216
+ end
217
+
36
218
  @auth = options.delete(:auth)
37
219
 
38
220
  self.headers.merge!(options.delete(:headers)) if options[:headers]
@@ -45,17 +227,33 @@ module RHC
45
227
  @debug
46
228
  end
47
229
 
230
+ def url
231
+ @end_point
232
+ end
233
+
234
+ def api
235
+ @api ||= RHC::Rest::Api.new(self, @preferred_api_versions).tap do |api|
236
+ self.current_api_version = api.api_version_negotiated
237
+ end
238
+ end
239
+
240
+ def api_version_negotiated
241
+ api
242
+ current_api_version
243
+ end
244
+
48
245
  def request(options, &block)
49
- (0..(1.0/0.0)).each do |i|
246
+ (0..MAX_RETRIES).each do |i|
50
247
  begin
51
248
  client, args = new_request(options.dup)
249
+ auth = options[:auth] || self.auth
52
250
 
53
- #debug "Request: #{client.object_id} #{args.inspect}\n-------------" if debug?
251
+ debug "Request #{args[0].to_s.upcase} #{args[1]}" if debug?
54
252
  response = client.request(*(args << true))
55
- #debug "Response: #{response.status} #{response.headers.inspect}\n#{response.content}\n-------------" if debug? && response
253
+ debug " code #{response.status}" if debug? && response
56
254
 
57
255
  next if retry_proxy(response, i, args, client)
58
- auth.retry_auth?(response) and redo if auth
256
+ auth.retry_auth?(response, self) and next if auth
59
257
  handle_error!(response, args[1], client) unless response.ok?
60
258
 
61
259
  break (if block_given?
@@ -68,7 +266,7 @@ module RHC
68
266
  debug "Response: #{e.res.status} #{e.res.headers.inspect}\n#{e.res.content}\n-------------" if debug?
69
267
 
70
268
  next if retry_proxy(e.res, i, args, client)
71
- auth.retry_auth?(e.res) and redo if auth
269
+ auth.retry_auth?(e.res, self) and next if auth
72
270
  handle_error!(e.res, args[1], client)
73
271
  end
74
272
  raise ConnectionException.new(
@@ -134,122 +332,14 @@ module RHC
134
332
  end
135
333
  end
136
334
 
137
- def url
138
- @end_point
139
- end
140
-
141
- def api
142
- @api ||= RHC::Rest::Api.new(self, @preferred_api_versions)
143
- end
144
-
145
- def api_version_negotiated
146
- api.api_version_negotiated
147
- end
148
-
149
- ################################################
150
- # Delegate methods to API, should be moved there
151
- # and then simply passed through.
152
-
153
- def add_domain(id)
154
- debug "Adding domain #{id}"
155
- @domains = nil
156
- api.rest_method "ADD_DOMAIN", :id => id
157
- end
158
-
159
- def domains
160
- debug "Getting all domains"
161
- @domains ||= api.rest_method "LIST_DOMAINS"
162
- end
163
-
164
- def cartridges
165
- debug "Getting all cartridges"
166
- @cartridges ||= api.rest_method("LIST_CARTRIDGES", nil, :lazy_auth => true)
167
- end
168
-
169
- def user
170
- debug "Getting user info"
171
- @user ||= api.rest_method "GET_USER"
172
- end
173
-
174
- def sshkeys
175
- debug "Finding all keys for #{user.login}"
176
- user.keys
177
- end
178
-
179
- def add_key(name, key, content)
180
- debug "Adding key #{key} for #{user.login}"
181
- user.add_key name, key, content
182
- end
183
-
184
- def delete_key(name)
185
- debug "Deleting key '#{name}'"
186
- key = find_key(name)
187
- key.destroy
188
- end
189
-
190
- #Find Domain by namesapce
191
- def find_domain(id)
192
- debug "Finding domain #{id}"
193
- domains.each { |domain| return domain if domain.id == id }
194
-
195
- raise RHC::DomainNotFoundException.new("Domain #{id} does not exist")
196
- end
197
-
198
- #Find Cartridge by name or regex
199
- def find_cartridges(name)
200
- debug "Finding cartridge #{name}"
201
- if name.is_a?(Hash)
202
- regex = name[:regex]
203
- type = name[:type]
204
- name = name[:name]
205
- end
206
-
207
- filtered = Array.new
208
- cartridges.each do |cart|
209
- if regex
210
- filtered.push(cart) if cart.name.match(regex) and (type.nil? or cart.type == type)
211
- else
212
- filtered.push(cart) if (name.nil? or cart.name == name) and (type.nil? or cart.type == type)
213
- end
214
- end
215
- return filtered
216
- end
217
-
218
- #find Key by name
219
- def find_key(name)
220
- debug "Finding key #{name}"
221
- user.find_key(name) or raise RHC::KeyNotFoundException.new("Key #{name} does not exist")
222
- end
223
-
224
- def sshkeys
225
- logger.debug "Finding all keys for #{user.login}" if @mydebug
226
- user.keys
227
- end
228
-
229
- def add_key(name, key, content)
230
- logger.debug "Adding key #{key} for #{user.login}" if @mydebug
231
- user.add_key name, key, content
232
- end
233
-
234
- def delete_key(name)
235
- logger.debug "Deleting key '#{name}'" if @mydebug
236
- key = find_key(name)
237
- key.destroy
238
- end
239
-
240
- def logout
241
- #TODO logout
242
- debug "Logout/Close client"
243
- end
244
- alias :close :logout
245
-
246
335
  protected
247
336
  include RHC::Helpers
248
337
 
249
338
  attr_reader :auth
339
+ attr_accessor :current_api_version
250
340
  def headers
251
341
  @headers ||= {
252
- 'Accept' => 'application/json',
342
+ :accept => :json
253
343
  }
254
344
  end
255
345
 
@@ -303,18 +393,30 @@ module RHC
303
393
  def new_request(options)
304
394
  options.reverse_merge!(self.options)
305
395
 
396
+ options[:connect_timeout] ||= options[:timeout] || 120
397
+ options[:receive_timeout] ||= options[:timeout] || 0
398
+ options[:send_timeout] ||= options[:timeout] || 0
399
+ options[:timeout] = nil
400
+
401
+ if auth = options[:auth] || self.auth
402
+ auth.to_request(options)
403
+ end
404
+
306
405
  headers = (self.headers.to_a + (options.delete(:headers) || []).to_a).inject({}) do |h,(k,v)|
307
406
  v = "application/#{v}" if k == :accept && v.is_a?(Symbol)
308
407
  h[k.to_s.downcase.gsub(/_/, '-')] = v
309
408
  h
310
409
  end
311
410
 
312
- options[:connect_timeout] ||= options[:timeout] || 120
313
- options[:receive_timeout] ||= options[:timeout] || 0
314
- options[:send_timeout] ||= options[:timeout] || 0
315
- options[:timeout] = nil
411
+ user = options.delete(:user)
412
+ password = options.delete(:password)
413
+ if user
414
+ headers['Authorization'] ||= "Basic #{["#{user}:#{password}"].pack('m').tr("\n", '')}"
415
+ end
316
416
 
317
- auth.to_request(options) if auth
417
+ modifiers = []
418
+ version = options.delete(:api_version) || current_api_version
419
+ modifiers << ";version=#{version}" if version
318
420
 
319
421
  query = options.delete(:query) || {}
320
422
  payload = options.delete(:payload)
@@ -324,11 +426,18 @@ module RHC
324
426
  else
325
427
  headers['content-type'] ||= begin
326
428
  payload = payload.to_json unless payload.nil? || payload.is_a?(String)
327
- 'application/json'
429
+ "application/json#{modifiers.join}"
328
430
  end
329
431
  end
330
432
  query = nil if query.blank?
331
433
 
434
+ if headers['accept'] && modifiers.present?
435
+ headers['accept'] << modifiers.join
436
+ end
437
+
438
+ # remove all unnecessary options
439
+ options.delete(:lazy_auth)
440
+
332
441
  args = [options.delete(:method), options.delete(:url), query, payload, headers, true]
333
442
  [httpclient_for(options), args]
334
443
  end
@@ -360,6 +469,10 @@ module RHC
360
469
  data.map{ |json| Domain.new(json, self) }
361
470
  when 'domain'
362
471
  Domain.new(data, self)
472
+ when 'authorization'
473
+ Authorization.new(data, self)
474
+ when 'authorizations'
475
+ data.map{ |json| Authorization.new(json, self) }
363
476
  when 'applications'
364
477
  data.map{ |json| Application.new(json, self) }
365
478
  when 'application'
@@ -388,7 +501,7 @@ module RHC
388
501
  "The server did not respond correctly. This may be an issue "\
389
502
  "with the server configuration or with your connection to the "\
390
503
  "server (such as a Web proxy or firewall)."\
391
- "#{client.proxy.present? ? " Please verify that your proxy server is working correctly (#{client.proxy}) and that you can access the OpenShift server #{url}" : "Please verify that you can access the OpenShift server #{url}"}"
504
+ "#{client.proxy.present? ? " Please verify that your proxy server is working correctly (#{client.proxy}) and that you can access the OpenShift server #{url}" : " Please verify that you can access the OpenShift server #{url}"}"
392
505
  end
393
506
 
394
507
  def handle_error!(response, url, client)
@@ -414,6 +527,14 @@ module RHC
414
527
  when 403
415
528
  raise RequestDeniedException, messages_to_error(messages) || "You are not authorized to perform this operation."
416
529
  when 404
530
+ if messages.length == 1
531
+ case messages.first['exit_code']
532
+ when 127
533
+ raise DomainNotFoundException, messages_to_error(messages) || generic_error_message(url, client)
534
+ when 101
535
+ raise ApplicationNotFoundException, messages_to_error(messages) || generic_error_message(url, client)
536
+ end
537
+ end
417
538
  raise ResourceNotFoundException, messages_to_error(messages) || generic_error_message(url, client)
418
539
  when 409
419
540
  raise_generic_error(url, client) if messages.empty?
@@ -44,21 +44,6 @@ module RHC
44
44
  rest_method "DELETE", :force => force
45
45
  end
46
46
  alias :delete :destroy
47
-
48
- def find_application(name, options={})
49
- if name.is_a?(Hash)
50
- options = name.merge(options)
51
- name = options[:name]
52
- end
53
- framework = options[:framework]
54
-
55
- debug "Finding application :name => #{name}, :framework => #{framework}"
56
- applications.each do |app|
57
- return app if (name.nil? or app.name.downcase == name.downcase) and (framework.nil? or app.framework == framework)
58
- end
59
-
60
- raise RHC::ApplicationNotFoundException.new("Application #{name} does not exist")
61
- end
62
47
  end
63
48
  end
64
49
  end
@@ -3,7 +3,6 @@ require 'rhc/rest/base'
3
3
  module RHC
4
4
  module Rest
5
5
  class GearGroup < Base
6
- include Rest
7
6
  define_attr :gears, :cartridges
8
7
  end
9
8
  end
data/lib/rhc/rest/mock.rb CHANGED
@@ -15,6 +15,10 @@ module RHC::Rest::Mock
15
15
 
16
16
  module Helpers
17
17
 
18
+ def mock_date_1
19
+ '2013-02-21T01:00:01Z'
20
+ end
21
+
18
22
  def mock_user
19
23
  "test_user"
20
24
  end
@@ -23,16 +27,33 @@ module RHC::Rest::Mock
23
27
  respond_to?(:user_auth) ? self.user_auth : {:user => username, :password => password}
24
28
  end
25
29
 
30
+ def credentials_for(with_auth)
31
+ if with_auth == true
32
+ [respond_to?(:username) ? self.username : mock_user, respond_to?(:password) ? self.password : mock_pass]
33
+ elsif with_auth
34
+ with_auth.values_at(:user, :password)
35
+ end
36
+ end
37
+
38
+ def expect_authorization(with_auth)
39
+ username, password = credentials_for(with_auth)
40
+ lambda{ |r|
41
+ !username || (r.headers['Authorization'] == "Basic #{["#{username}:#{password}"].pack('m').tr("\n", '')}")
42
+ }
43
+ end
44
+
26
45
  def stub_api_request(method, uri, with_auth=true)
27
- stub_request(method, mock_href(uri, with_auth)).
28
- with(&user_agent_header)
46
+ api = stub_request(method, mock_href(uri, with_auth))
47
+ api.with(&lambda{ |r| request.headers['Authorization'] == "Bearer #{with_auth[:token]}" }) if with_auth.respond_to?(:[]) && with_auth[:token]
48
+ api.with(&expect_authorization(with_auth))
49
+ api.with(&user_agent_header)
29
50
  end
30
51
 
31
- def stub_api(auth=false)
52
+ def stub_api(auth=false, authorizations=false)
32
53
  stub_api_request(:get, 'broker/rest/api', auth).
33
54
  to_return({
34
55
  :body => {
35
- :data => mock_response_links(mock_real_client_links),
56
+ :data => mock_response_links(authorizations ? mock_api_with_authorizations : mock_real_client_links),
36
57
  :supported_api_versions => [1.0, 1.1, 1.2, 1.3],
37
58
  }.to_json
38
59
  })
@@ -64,6 +85,37 @@ module RHC::Rest::Mock
64
85
  with(:body => hash_including({:id => name})).
65
86
  to_return(new_domain(name))
66
87
  end
88
+ def stub_authorizations
89
+ stub_api_request(:get, 'broker/rest/user/authorizations', mock_user_auth).
90
+ to_return({
91
+ :status => 200,
92
+ :body => {
93
+ :type => 'authorizations',
94
+ :data => [
95
+ {
96
+ :note => 'an_authorization',
97
+ :token => 'a_token_value',
98
+ :created_at => mock_date_1,
99
+ :expires_in_seconds => 60,
100
+ :scopes => 'session read'
101
+ }
102
+ ]
103
+ }.to_json
104
+ })
105
+ end
106
+ def stub_delete_authorizations
107
+ stub_api_request(:delete, 'broker/rest/user/authorizations', mock_user_auth).
108
+ to_return(:status => 204)
109
+ end
110
+ def stub_delete_authorization(token)
111
+ stub_api_request(:delete, "broker/rest/user/authorizations/#{token}", mock_user_auth).
112
+ to_return(:status => 204)
113
+ end
114
+ def stub_add_authorization(params)
115
+ stub_api_request(:post, 'broker/rest/user/authorizations', mock_user_auth).
116
+ with(:body => hash_including(params)).
117
+ to_return(new_authorization(params))
118
+ end
67
119
  def stub_no_keys
68
120
  stub_api_request(:get, 'broker/rest/user/keys', mock_user_auth).to_return(no_keys)
69
121
  end
@@ -118,7 +170,7 @@ module RHC::Rest::Mock
118
170
  }.to_json
119
171
  })
120
172
  end
121
- def stub_one_application(domain_name, name)
173
+ def stub_one_application(domain_name, name, *args)
122
174
  stub_api_request(:get, "broker/rest/domains/#{domain_name}/applications", mock_user_auth).
123
175
  to_return({
124
176
  :body => {
@@ -133,7 +185,26 @@ module RHC::Rest::Mock
133
185
  }],
134
186
  }.to_json
135
187
  })
188
+ stub_relative_application(domain_name,name, *args)
136
189
  end
190
+
191
+ def stub_relative_application(domain_name, app_name, body = {}, status = 200)
192
+ url = client_links['LIST_DOMAINS']['relative'] rescue "broker/rest/domains"
193
+ stub_api_request(:any, "#{url}/#{domain_name}/applications/#{app_name}").
194
+ to_return({
195
+ :body => {
196
+ :type => 'application',
197
+ :data => {
198
+ :domain_id => domain_name,
199
+ :name => app_name,
200
+ :id => 1,
201
+ :links => mock_response_links(mock_app_links(domain_name,app_name)),
202
+ }
203
+ }.merge(body).to_json,
204
+ :status => status
205
+ })
206
+ end
207
+
137
208
  def stub_simple_carts
138
209
  stub_api_request(:get, 'broker/rest/cartridges', mock_user_auth).to_return(simple_carts)
139
210
  end
@@ -206,6 +277,22 @@ module RHC::Rest::Mock
206
277
  }.to_json
207
278
  }
208
279
  end
280
+ def new_authorization(params)
281
+ {
282
+ :status => 201,
283
+ :body => {
284
+ :type => 'authorization',
285
+ :data => {
286
+ :note => params[:note],
287
+ :token => 'a_token_value',
288
+ :scopes => (params[:scope] || "userinfo").gsub(/,/, ' '),
289
+ :expires_in => (params[:expires_in] || 60).to_i,
290
+ :expires_in_seconds => (params[:expires_in] || 60).to_i,
291
+ :created_at => mock_date_1,
292
+ },
293
+ }.to_json
294
+ }
295
+ end
209
296
 
210
297
  def mock_pass
211
298
  "test pass"
@@ -218,16 +305,7 @@ module RHC::Rest::Mock
218
305
  # Creates consistent hrefs for testing
219
306
  def mock_href(relative="", with_auth=false)
220
307
  server = respond_to?(:server) ? self.server : mock_uri
221
- uri_string =
222
- if with_auth == true
223
- username = respond_to?(:username) ? self.username : mock_user
224
- password = respond_to?(:password) ? self.password : mock_pass
225
- "#{username}:#{password}@#{mock_uri}"
226
- elsif with_auth
227
- "#{with_auth[:user]}:#{with_auth[:password]}@#{server}"
228
- else
229
- server
230
- end
308
+ uri_string = server
231
309
  "https://#{uri_string}/#{relative}"
232
310
  end
233
311
 
@@ -242,7 +320,7 @@ module RHC::Rest::Mock
242
320
  # this is not used by the API classes.
243
321
  link_set[operation] = { 'href' => mock_href(href), 'method' => method, 'relative' => href }
244
322
  end
245
- return link_set
323
+ link_set
246
324
  end
247
325
 
248
326
  def mock_app_links(domain_id='test_domain',app_id='test_app')
@@ -278,6 +356,13 @@ module RHC::Rest::Mock
278
356
  ['LIST_CARTRIDGES', "broker/rest/cartridges", 'GET'],
279
357
  ]
280
358
  end
359
+ def mock_api_with_authorizations
360
+ mock_real_client_links.concat([
361
+ ['LIST_AUTHORIZATIONS', "broker/rest/user/authorizations", 'GET'],
362
+ ['ADD_AUTHORIZATION', "broker/rest/user/authorizations", 'POST'],
363
+ ['SHOW_AUTHORIZATION', "broker/rest/user/authorizations/:id", 'GET'],
364
+ ])
365
+ end
281
366
 
282
367
  def mock_domain_links(domain_id='test_domain')
283
368
  [['ADD_APPLICATION', "domains/#{domain_id}/apps/add", 'post'],
@@ -392,6 +477,23 @@ module RHC::Rest::Mock
392
477
  def delete_key(name)
393
478
  @user.keys.delete_if { |key| key.name == name }
394
479
  end
480
+
481
+ # Need to mock this since we are not registering HTTP requests when adding apps to the mock domain
482
+ def find_application(domain, name, options = {})
483
+ find_domain(domain).applications.each do |app|
484
+ return app if app.name.downcase == name.downcase
485
+ end
486
+
487
+ raise RHC::Rest::ApplicationNotFoundException.new("Application #{name} does not exist")
488
+ end
489
+
490
+ def find_application_gear_groups(domain, name, options = {})
491
+ find_domain(domain).applications.each do |app|
492
+ return app.gear_groups if app.name.downcase == name.downcase
493
+ end
494
+
495
+ raise RHC::Rest::ApplicationNotFoundException.new("Application #{name} does not exist")
496
+ end
395
497
  end
396
498
 
397
499
  class MockRestApi < RHC::Rest::Api
data/lib/rhc/rest/user.rb CHANGED
@@ -17,7 +17,6 @@ module RHC
17
17
 
18
18
  #Find Key by name
19
19
  def find_key(name)
20
- #TODO do a regex caomparison
21
20
  keys.detect { |key| key.name == name }
22
21
  end
23
22