rhc 1.3.8 → 1.4.7

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.
@@ -1,4 +1,3 @@
1
- require 'dnsruby'
2
1
  require 'rhc/rest'
3
2
 
4
3
  module RHCHelper
@@ -9,21 +8,16 @@ module RHCHelper
9
8
  extend Runnable
10
9
  extend Commandify
11
10
  extend API
12
- include Dnsruby
13
11
 
14
12
  class << self
15
13
  attr_reader :domain_output, :domain_show_output, :exitcode
16
14
  end
17
15
 
18
16
  def self.unique_namespace(prefix)
19
- namepace = nil
20
- begin
21
- # Loop until we find a unique namespace
22
- chars = ("1".."9").to_a
23
- namespace = prefix + Array.new(8, '').collect{chars[rand(chars.size)]}.join
24
-
25
- end while reserved?(namespace)
26
- namespace
17
+ # TODO: Due to DNS changes with the model refactor,
18
+ # the namespace is not checked here - see #reserved?
19
+ chars = ("1".."9").to_a
20
+ prefix + Array.new(8, '').collect{chars[rand(chars.size)]}.join
27
21
  end
28
22
 
29
23
  def self.create_if_needed(prefix="test")
@@ -61,14 +55,11 @@ module RHCHelper
61
55
  end
62
56
 
63
57
  def self.reserved?(namespace=$namespace)
64
- # If we get a response, then the namespace is reserved
65
- # An exception means that it is available
66
- begin
67
- Dnsruby::Resolver.new.query("#{namespace}.#{$domain}", Dnsruby::Types::TXT)
68
- return true
69
- rescue
70
- return false
71
- end
58
+ # With the recent model refactoring, we no longer create
59
+ # TXT DNS records.
60
+ # Here, we return 'true', since this is the only code that is
61
+ # used in 'Then' clauses of 2 Cucumber scenarios.
62
+ true
72
63
  end
73
64
  end
74
65
  end
@@ -34,7 +34,7 @@ Feature: Scaled Application Operations
34
34
 
35
35
  Examples:
36
36
  | cart | type | value |
37
- | php-5.3 | min | 3 |
37
+ | php-5.3 | min | 1 |
38
38
  | php-5.3 | max | 5 |
39
39
  | php-5.3 | max | -1 |
40
40
 
@@ -32,7 +32,7 @@ Then /^the (.+) cartridge should be (.*)$/ do |name,status|
32
32
  when :stopped
33
33
  "(.+) stopped"
34
34
  when :removed
35
- "Cartridge '#{name}' cannot be found in application"
35
+ "There are no cartridges that match '#{name}'"
36
36
  else
37
37
  raise "Unrecognized status type #{status}"
38
38
  end
data/lib/rhc.rb CHANGED
@@ -12,12 +12,15 @@ require 'rhc/core_ext'
12
12
 
13
13
  module RHC
14
14
  autoload :Auth, 'rhc/auth'
15
+ autoload :CartridgeHelpers, 'rhc/cartridge_helpers'
15
16
  autoload :CommandRunner, 'rhc/command_runner'
16
17
  autoload :Commands, 'rhc/commands'
17
18
  autoload :Config, 'rhc/config'
19
+ autoload :GitHelpers, 'rhc/git_helpers'
18
20
  autoload :Helpers, 'rhc/helpers'
19
21
  autoload :HelpFormatter, 'rhc/help_formatter'
20
22
  autoload :Rest, 'rhc/rest'
23
+ autoload :SSHHelpers, 'rhc/ssh_helpers'
21
24
  autoload :TarGz, 'rhc/tar_gz'
22
25
  autoload :VERSION, 'rhc/version'
23
26
  end
@@ -1,40 +1,98 @@
1
1
  module RHC
2
2
  module CartridgeHelpers
3
3
 
4
- def find_cartridge(rest_obj, cartridge_name, type="embedded")
5
- carts = find_cartridges(rest_obj, [cartridge_name], type)
4
+ protected
5
+ def check_cartridges(names, opts={}, &block)
6
+ cartridge_names = Array(names).map{ |s| s.strip if s && s.length > 0 }.compact
7
+ from = opts[:from] || all_cartridges
6
8
 
7
- if carts.length == 0
8
- valid_carts = rest_obj.cartridges.collect { |c| c.name if c.type == type }.compact
9
-
10
- msg = if RHC::Rest::Application === rest_obj
11
- "Cartridge '#{cartridge_name}' cannot be found in application '#{rest_obj.name}'."
12
- else
13
- "Cartridge '#{cartridge_name}' is not a valid cartridge name."
14
- end
15
-
16
- unless valid_carts.empty?
17
- msg += " Valid cartridges are (#{valid_carts.join(', ')})."
9
+ cartridge_names.map do |name|
10
+ name = name.downcase
11
+ from.find{ |c| c.name.downcase == name } ||
12
+ begin
13
+ carts = from.select{ |c| match_cart(c, name) }
14
+ if carts.empty?
15
+ paragraph { list_cartridges(from) }
16
+ raise RHC::CartridgeNotFoundException, "There are no cartridges that match '#{name}'."
17
+ elsif carts.length == 1
18
+ use_cart(carts.first, name)
19
+ else
20
+ carts.sort!.instance_variable_set(:@for, name)
21
+ carts
22
+ end
23
+ end
24
+ end.tap do |carts|
25
+ yield carts if block_given?
26
+ end.each do |carts|
27
+ if carts.is_a? Array
28
+ name = carts.instance_variable_get(:@for)
29
+ paragraph { list_cartridges(carts) }
30
+ raise RHC::MultipleCartridgesException, "There are multiple cartridges matching '#{name}'. Please provide the short name of the correct cart."
31
+ end
18
32
  end
33
+ end
19
34
 
20
- raise RHC::CartridgeNotFoundException, msg
21
- elsif carts.length > 1
22
- msg = "Multiple cartridge versions match your criteria. Please specify one."
23
- carts.each { |cart| msg += "\n #{cart.name}" }
24
- raise RHC::MultipleCartridgesException, msg
35
+ def use_cart(cart, for_cartridge_name)
36
+ info "Using #{cart.name}#{cart.display_name ? " (#{cart.display_name})" : ''} for '#{for_cartridge_name}'"
37
+ cart
25
38
  end
26
39
 
27
- carts[0]
28
- end
40
+ def match_cart(cart, search)
41
+ search = search.to_s.downcase.gsub(/[_\-\s]/,' ')
42
+ [
43
+ cart.name,
44
+ cart.description,
45
+ (cart.tags || []).join(' '),
46
+ ].compact.any?{ |s| s.present? && s.downcase.gsub(/[_\-\s]/,' ').include?(search) }
47
+ end
29
48
 
30
- def find_cartridges(rest_obj, cartridge_list, type='embedded')
31
- rest_obj.find_cartridges :regex => cartridge_list.collect { |c| cart_regex c }.join('|'), :type => type
32
- end
49
+ def web_carts_only
50
+ lambda{ |cart|
51
+ next cart unless cart.is_a? Array
52
+ name = cart.instance_variable_get(:@for)
53
+ matching = cart.select(&:only_in_new?)
54
+ if matching.empty?
55
+ raise RHC::MultipleCartridgesException, "You must select only a single web cartridge. '#{name}' matches web cartridges."
56
+ elsif matching.size == 1
57
+ use_cart(matching.first, name)
58
+ else
59
+ matching.instance_variable_set(:@for, name)
60
+ matching
61
+ end
62
+ }
63
+ end
33
64
 
34
- private
65
+ def other_carts_only
66
+ lambda{ |cart|
67
+ next cart unless cart.is_a? Array
68
+ name = cart.instance_variable_get(:@for)
69
+ matching = cart.select{ |c| not c.only_in_new? }
70
+ if matching.empty?
71
+ raise RHC::MultipleCartridgesException, "You must select only a single web cartridge. '#{name}' matches web cartridges."
72
+ elsif matching.size == 1
73
+ use_cart(matching.first, name)
74
+ else
75
+ matching.instance_variable_set(:@for, name)
76
+ matching
77
+ end
78
+ }
79
+ end
35
80
 
36
- def cart_regex(cart)
37
- "^#{cart.rstrip}(-[0-9\.]+){0,1}$"
38
- end
81
+ def standalone_cartridges
82
+ @standalone_cartridges ||= all_cartridges.select{ |c| c.type == 'standalone' }
83
+ end
84
+ def not_standalone_cartridges
85
+ @not_standalone_cartridges ||= all_cartridges.select{ |c| c.type != 'standalone' }
86
+ end
87
+ def all_cartridges
88
+ @all_cartridges = rest_client.cartridges
89
+ end
90
+
91
+ def list_cartridges(cartridges)
92
+ carts = cartridges.map{ |c| [c.name, c.display_name || ''] }.sort{ |a,b| a[1].downcase <=> b[1].downcase }
93
+ carts.unshift ['==========', '=========']
94
+ carts.unshift ['Short Name', 'Full name']
95
+ say table(carts).join("\n")
96
+ end
39
97
  end
40
98
  end
@@ -89,7 +89,7 @@ module RHC
89
89
  1
90
90
  rescue RHC::Exception, RHC::Rest::Exception => e
91
91
  RHC::Helpers.error e.message
92
- e.code.nil? ? 128 : e.code
92
+ e.code.nil? ? 128 : [1, (e.code || 1).to_i].max
93
93
  end
94
94
  else
95
95
  run_active_command
@@ -51,7 +51,7 @@ module RHC::Commands
51
51
  argument :cartridges, "The web framework this application should use", ["-t", "--type cartridge"], :arg_type => :list
52
52
  #argument :additional_cartridges, "A list of other cartridges such as databases you wish to add. Cartridges can also be added later using 'rhc cartridge add'", [], :arg_type => :list
53
53
  def create(name, cartridges)
54
- cartridges = check_cartridges(cartridges)
54
+ cartridges = check_cartridges(cartridges, &require_one_web_cart)
55
55
 
56
56
  options.default \
57
57
  :dns => true,
@@ -278,6 +278,29 @@ module RHC::Commands
278
278
  0
279
279
  end
280
280
 
281
+ summary "SSH into the specified application"
282
+ syntax "<app> [--ssh path_to_ssh_executable]"
283
+ argument :app, "The name of the application you want to SSH into", ["-a", "--app app"], :context => :app_context
284
+ option ["--ssh PATH"], "Path to your SSH executable"
285
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
286
+ alias_action 'ssh', :root_command => true
287
+ def ssh(app_name)
288
+ raise ArgumentError, "No application specified" unless app_name.present?
289
+ raise OptionParser::InvalidOption, "No system SSH available. Please use the --ssh option to specify the path to your SSH executable, or install SSH." unless options.ssh or has_ssh?
290
+
291
+ domain = rest_client.find_domain(options.namespace)
292
+ app = domain.find_application(app_name)
293
+
294
+ say "Connecting to #{app.ssh_string.to_s} ..."
295
+ if options.ssh
296
+ debug "Using user specified SSH: #{options.ssh}"
297
+ Kernel.send(:system, "#{options.ssh} #{app.ssh_string.to_s}")
298
+ else
299
+ debug "Using system ssh"
300
+ Kernel.send(:system, "ssh #{app.ssh_string.to_s}")
301
+ end
302
+ end
303
+
281
304
  summary "DEPRECATED use 'show <app> --state' instead"
282
305
  syntax "<app> [--namespace namespace] [--app app]"
283
306
  argument :app, "The name of the application you are getting information on", ["-a", "--app app"], :context => :app_context
@@ -292,54 +315,26 @@ module RHC::Commands
292
315
  private
293
316
  include RHC::GitHelpers
294
317
  include RHC::CartridgeHelpers
295
-
296
- def check_sshkeys!
297
- RHC::SSHWizard.new(rest_client, config, options).run
298
- end
299
-
300
- def standalone_cartridges
301
- @standalone_cartridges ||= all_cartridges.select{ |c| c.type == 'standalone' }
302
- end
303
- def all_cartridges
304
- @all_cartridges = rest_client.cartridges
305
- end
306
-
307
- def check_cartridges(cartridge_names)
308
- cartridge_names = Array(cartridge_names).map{ |s| s.strip if s && s.length > 0 }.compact
309
-
310
- cartridge_names.map do |name|
311
- all_cartridges.find{ |c| c.name == name } ||
312
- begin
313
- matching_cartridges = all_cartridges.select{ |c| c.name.include?(name) }
314
- unless matching_cartridges.length == 1
315
- if matching_cartridges.present?
316
- paragraph { list_cartridges(matching_cartridges) }
317
- raise RHC::MultipleCartridgesException, "There are multiple web cartridges named '#{name}'. Please provide the short name of your desired cart." if matching_cartridges.present?
318
- else
319
- paragraph { list_cartridges(all_cartridges) }
320
- raise RHC::CartridgeNotFoundException, "There are no cartridges that match '#{name}'."
321
- end
322
- end
323
- use_cart(matching_cartridges.first, name)
324
- end
325
- end.tap do |carts|
326
- if carts.none?(&:only_in_new?)
327
- section(:bottom => 1){ list_cartridges }
318
+
319
+ def require_one_web_cart
320
+ lambda{ |carts|
321
+ match, ambiguous = carts.partition{ |c| not c.is_a?(Array) }
322
+ selected_web = match.any?(&:only_in_new?)
323
+ possible_web = ambiguous.flatten.any?(&:only_in_new?)
324
+ if not (selected_web or possible_web)
325
+ section(:bottom => 1){ list_cartridges(standalone_cartridges) }
328
326
  raise RHC::CartridgeNotFoundException, "Every application needs a web cartridge to handle incoming web requests. Please provide the short name of one of the carts listed above."
329
327
  end
330
- end
331
- end
332
-
333
- def use_cart(cart, for_cartridge_name)
334
- info "Using #{cart.name}#{cart.display_name ? " (#{cart.display_name})" : ''} for '#{for_cartridge_name}'"
335
- cart
328
+ if selected_web
329
+ carts.map! &other_carts_only
330
+ elsif possible_web
331
+ carts.map! &web_carts_only
332
+ end
333
+ }
336
334
  end
337
335
 
338
- def list_cartridges(cartridges=standalone_cartridges)
339
- carts = cartridges.map{ |c| [c.name, c.display_name || ''] }.sort{ |a,b| a[1].downcase <=> b[1].downcase }
340
- carts.unshift ['==========', '=========']
341
- carts.unshift ['Short Name', 'Full name']
342
- say table(carts).join("\n")
336
+ def check_sshkeys!
337
+ RHC::SSHWizard.new(rest_client, config, options).run
343
338
  end
344
339
 
345
340
  def app_action(app, action, *args)
@@ -363,7 +358,7 @@ module RHC::Commands
363
358
  rescue RHC::Rest::Exception => e
364
359
  if e.code == 109
365
360
  paragraph{ say "Valid cartridge types:" }
366
- paragraph{ list_cartridges }
361
+ paragraph{ list_cartridges(standalone_cartridges) }
367
362
  end
368
363
  raise
369
364
  end
@@ -422,18 +417,19 @@ module RHC::Commands
422
417
  Kernel.sleep 5
423
418
 
424
419
  # Now start checking for DNS
425
- for i in 0..MAX_RETRIES-1
426
- found = host_exists?(host) || hosts_file_contains?(host)
427
- break if found
420
+ host_found = hosts_file_contains?(host) or
421
+ 1.upto(MAX_RETRIES) { |i|
422
+ host_found = host_exists?(host)
423
+ break found if host_found
428
424
 
429
- say " retry # #{i+1} - Waiting for DNS: #{host}"
425
+ say " retry # #{i} - Waiting for DNS: #{host}"
430
426
  Kernel.sleep sleep_time.to_i
431
427
  sleep_time *= DEFAULT_DELAY_THROTTLE
432
- end
428
+ }
433
429
 
434
430
  debug "End checking for application dns @ '#{host} - found=#{found}'"
435
431
 
436
- found
432
+ host_found
437
433
  end
438
434
 
439
435
  def enable_jenkins?
@@ -461,6 +457,22 @@ module RHC::Commands
461
457
  # :nocov:
462
458
  end
463
459
 
460
+ # check the version of SSH that is installed
461
+ def ssh_version
462
+ @ssh_version ||= `ssh -V 2>&1`.strip
463
+ end
464
+
465
+ # return whether or not SSH is installed
466
+ def has_ssh?
467
+ @has_ssh ||= begin
468
+ @ssh_version = nil
469
+ ssh_version
470
+ $?.success?
471
+ rescue
472
+ false
473
+ end
474
+ end
475
+
464
476
  def windows_nslookup_bug?(rest_app)
465
477
  windows_nslookup = run_nslookup(rest_app.host)
466
478
  windows_ping = run_ping(rest_app.host)
@@ -15,7 +15,7 @@ module RHC::Commands
15
15
  carts = rest_client.cartridges.sort_by{ |c| "#{c.type == 'standalone' && 1}_#{c.tags.include?('experimental') ? 1 : 0}_#{(c.display_name || c.name).downcase}" }
16
16
 
17
17
  list = if options.verbose
18
- carts.map do |c|
18
+ carts.map do |c|
19
19
  name = c.display_name != c.name && "#{color(c.display_name, :cyan)} [#{c.name}]" || c.name
20
20
  tags = c.tags - RHC::Rest::Cartridge::HIDDEN_TAGS
21
21
  [
@@ -42,7 +42,7 @@ module RHC::Commands
42
42
  argument :cart_type, "The type of the cartridge you are adding (run 'rhc cartridge list' to obtain a list of available cartridges)", ["-c", "--cartridge cart_type"]
43
43
  alias_action :"app cartridge add", :root_command => true, :deprecated => true
44
44
  def add(cart_type)
45
- cart = find_cartridge rest_client, cart_type
45
+ cart = check_cartridges(cart_type, :from => not_standalone_cartridges).first
46
46
 
47
47
  say "Adding #{cart.name} to application '#{options.app}' ... "
48
48
 
@@ -67,7 +67,7 @@ module RHC::Commands
67
67
  def show(cartridge)
68
68
  rest_domain = rest_client.find_domain(options.namespace)
69
69
  rest_app = rest_domain.find_application(options.app)
70
- rest_cartridge = find_cartridge rest_app, cartridge, nil
70
+ rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
71
71
 
72
72
  display_cart(rest_cartridge)
73
73
 
@@ -85,7 +85,7 @@ module RHC::Commands
85
85
 
86
86
  rest_domain = rest_client.find_domain(options.namespace)
87
87
  rest_app = rest_domain.find_application(options.app)
88
- rest_cartridge = rest_app.find_cartridge cartridge, :type => "embedded"
88
+ rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
89
89
 
90
90
  confirm_action "Removing a cartridge is a destructive operation that may result in loss of data associated with the cartridge.\n\nAre you sure you wish to remove #{rest_cartridge.name} from '#{rest_app.name}'?"
91
91
 
@@ -103,9 +103,7 @@ module RHC::Commands
103
103
  option ["-a", "--app app"], "Application the cartridge", :context => :app_context, :required => true
104
104
  alias_action :"app cartridge start", :root_command => true, :deprecated => true
105
105
  def start(cartridge)
106
- cartridge_action cartridge, :start
107
-
108
- results { say "#{cartridge} started!" }
106
+ cartridge_action(cartridge, :start){ |_, c| results{ say "#{c.name} started" } }
109
107
  0
110
108
  end
111
109
 
@@ -116,9 +114,7 @@ module RHC::Commands
116
114
  option ["-a", "--app app"], "Application you the cartridge belongs to", :context => :app_context, :required => true
117
115
  alias_action :"app cartridge stop", :root_command => true, :deprecated => true
118
116
  def stop(cartridge)
119
- cartridge_action cartridge, :stop
120
-
121
- results { say "#{cartridge} stopped!" }
117
+ cartridge_action(cartridge, :stop){ |_, c| results{ say "#{c.name} stopped" } }
122
118
  0
123
119
  end
124
120
 
@@ -129,9 +125,7 @@ module RHC::Commands
129
125
  option ["-a", "--app app"], "Application the cartridge belongs to", :context => :app_context, :required => true
130
126
  alias_action :"app cartridge restart", :root_command => true, :deprecated => true
131
127
  def restart(cartridge)
132
- cartridge_action cartridge, :restart
133
-
134
- results { say "#{cartridge} restarted!" }
128
+ cartridge_action(cartridge, :restart){ |_, c| results{ say "#{c.name} restarted" } }
135
129
  0
136
130
  end
137
131
 
@@ -144,7 +138,7 @@ module RHC::Commands
144
138
  def status(cartridge)
145
139
  rest_domain = rest_client.find_domain(options.namespace)
146
140
  rest_app = rest_domain.find_application(options.app)
147
- rest_cartridge = find_cartridge(rest_app, cartridge)
141
+ rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
148
142
  results { rest_cartridge.status.each{ |msg| say msg['message'] } }
149
143
  0
150
144
  end
@@ -156,9 +150,7 @@ module RHC::Commands
156
150
  option ["-a", "--app app"], "Application the cartridge belongs to", :context => :app_context, :required => true
157
151
  alias_action :"app cartridge reload", :root_command => true, :deprecated => true
158
152
  def reload(cartridge)
159
- cartridge_action cartridge, :reload
160
-
161
- results { say "#{cartridge} config reloaded!" }
153
+ cartridge_action(cartridge, :reload){ |_, c| results{ say "#{c.name} reloaded" } }
162
154
  0
163
155
  end
164
156
 
@@ -174,7 +166,7 @@ module RHC::Commands
174
166
 
175
167
  rest_domain = rest_client.find_domain(options.namespace)
176
168
  rest_app = rest_domain.find_application(options.app)
177
- rest_cartridge = find_cartridge rest_app, cartridge, nil
169
+ rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
178
170
 
179
171
  raise RHC::CartridgeNotScalableException unless rest_cartridge.scalable?
180
172
 
@@ -191,8 +183,6 @@ module RHC::Commands
191
183
  0
192
184
  end
193
185
 
194
- =begin
195
- # Commenting this out for US2438
196
186
  summary 'View/manipulate storage on a cartridge'
197
187
  syntax '<cartridge> -a app [--show] [--add|--remove|--set amount] [--namespace namespace]'
198
188
  argument :cart_type, "The name of the cartridge", ["-c", "--cartridge cart_type"], :arg_type => :list
@@ -203,11 +193,8 @@ module RHC::Commands
203
193
  option ["--remove amount"], "Remove the indicated amount from the additional storage capacity"
204
194
  option ["--set amount"], "Set the specified amount of additional storage capacity"
205
195
  option ["-f", "--force"], "Force the action"
206
- def storage(cartridges)
207
- # Make sure that we are dealing with an array (-c param will only pass in a string)
208
- # BZ 883658
209
- cartridges = [cartridges].flatten
210
-
196
+ def storage(cartridge)
197
+ cartridges = Array(cartridge)
211
198
  rest_domain = rest_client.find_domain(options.namespace)
212
199
  rest_app = rest_domain.find_application(options.app)
213
200
 
@@ -227,8 +214,7 @@ module RHC::Commands
227
214
  if cartridges.length == 0
228
215
  display_cart_storage_list rest_app.cartridges
229
216
  else
230
- cartridges.each do |cartridge_name|
231
- cart = rest_app.find_cartridge(cartridge_name)
217
+ check_cartridges(cartridge, :from => rest_app.cartridges).each do |cart|
232
218
  display_cart_storage_info cart, cart.display_name
233
219
  end
234
220
  end
@@ -237,7 +223,7 @@ module RHC::Commands
237
223
  raise RHC::MultipleCartridgesException,
238
224
  'Exactly one cartridge must be specified for this operation' if cartridges.length != 1
239
225
 
240
- rest_cartridge = find_cartridge rest_app, cartridges.first, nil
226
+ rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
241
227
  amount = amount.match(/^(\d+)(GB)?$/i)
242
228
  raise RHC::AdditionalStorageValueException if amount.nil?
243
229
 
@@ -266,17 +252,18 @@ module RHC::Commands
266
252
 
267
253
  0
268
254
  end
269
- =end
270
255
 
271
256
  private
272
257
  include RHC::CartridgeHelpers
273
258
 
274
- def cartridge_action(cartridge, action)
259
+ def cartridge_action(cartridge, action, &block)
275
260
  rest_domain = rest_client.find_domain(options.namespace)
276
261
  rest_app = rest_domain.find_application(options.app)
277
- rest_cartridge = find_cartridge rest_app, cartridge
262
+ rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
278
263
  result = rest_cartridge.send action
279
- [result, rest_cartridge, rest_app, rest_domain]
264
+ resp = [result, rest_cartridge, rest_app, rest_domain]
265
+ yield resp if block_given?
266
+ resp
280
267
  end
281
268
  end
282
269
  end