rhc 1.1.11 → 1.2.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.
Files changed (45) hide show
  1. data/features/cartridge.feature +14 -1
  2. data/features/domain.feature +1 -1
  3. data/features/lib/rhc_helper.rb +3 -3
  4. data/features/lib/rhc_helper/app.rb +11 -3
  5. data/features/lib/rhc_helper/cartridge.rb +8 -0
  6. data/features/lib/rhc_helper/domain.rb +8 -15
  7. data/features/lib/rhc_helper/httpify.rb +11 -6
  8. data/features/lib/rhc_helper/runnable.rb +43 -7
  9. data/features/sshkey.feature +3 -4
  10. data/features/step_definitions/application_steps.rb +5 -5
  11. data/features/step_definitions/cartridge_steps.rb +12 -0
  12. data/features/step_definitions/client_steps.rb +3 -2
  13. data/features/step_definitions/sshkey_steps.rb +3 -3
  14. data/features/support/assumptions.rb +11 -11
  15. data/features/support/before_hooks.rb +23 -5
  16. data/features/support/env.rb +14 -4
  17. data/lib/rhc-common.rb +5 -2
  18. data/lib/rhc/cartridge_helpers.rb +7 -1
  19. data/lib/rhc/command_runner.rb +8 -4
  20. data/lib/rhc/commands.rb +6 -0
  21. data/lib/rhc/commands/app.rb +15 -7
  22. data/lib/rhc/commands/base.rb +3 -3
  23. data/lib/rhc/commands/cartridge.rb +78 -2
  24. data/lib/rhc/commands/port-forward.rb +137 -24
  25. data/lib/rhc/exceptions.rb +23 -8
  26. data/lib/rhc/helpers.rb +25 -4
  27. data/lib/rhc/output_helpers.rb +23 -0
  28. data/lib/rhc/rest.rb +38 -19
  29. data/lib/rhc/rest/base.rb +7 -3
  30. data/lib/rhc/rest/cartridge.rb +10 -1
  31. data/lib/rhc/usage_templates/command_help.erb +12 -12
  32. data/lib/rhc/usage_templates/command_syntax_help.erb +1 -1
  33. data/lib/rhc/usage_templates/help.erb +3 -3
  34. data/lib/rhc/usage_templates/missing_help.erb +1 -1
  35. data/lib/rhc/version.rb +1 -5
  36. data/lib/rhc/wizard.rb +4 -32
  37. data/spec/rest_spec_helper.rb +18 -4
  38. data/spec/rhc/commands/cartridge_spec.rb +91 -0
  39. data/spec/rhc/commands/domain_spec.rb +6 -2
  40. data/spec/rhc/commands/port-forward_spec.rb +95 -54
  41. data/spec/rhc/commands/snapshot_spec.rb +5 -0
  42. data/spec/rhc/rest_spec.rb +23 -2
  43. data/spec/rhc/wizard_spec.rb +9 -12
  44. data/spec/spec_helper.rb +5 -0
  45. metadata +228 -224
@@ -46,13 +46,13 @@ module RHC
46
46
  end
47
47
 
48
48
  class DeprecatedError < RuntimeError; end
49
-
49
+
50
50
  class KeyFileNotExistentException < Exception
51
51
  def initialize(message="SSH Key file not found")
52
52
  super message, 128
53
53
  end
54
54
  end
55
-
55
+
56
56
  class KeyFileAccessDeniedException < Exception
57
57
  def initialize(message = "Insufficient acces to SSH Key file")
58
58
  super message, 128
@@ -65,12 +65,6 @@ module RHC
65
65
  end
66
66
  end
67
67
 
68
- class ScaledApplicationsNotSupportedException < Exception
69
- def initialize(message="Scaled applications not supported")
70
- super message, 128
71
- end
72
- end
73
-
74
68
  class PermissionDeniedException < Exception
75
69
  def initialize(message="Permission denied")
76
70
  super message, 129
@@ -112,4 +106,25 @@ module RHC
112
106
  super message, 1
113
107
  end
114
108
  end
109
+
110
+ =begin
111
+ # Commenting this out for US2438
112
+ class AdditionalStorageArgumentsException < Exception
113
+ def initialize(message="Only one storage action can be performed at a time.")
114
+ super message, 1
115
+ end
116
+ end
117
+
118
+ class AdditionalStorageValueException < Exception
119
+ def initialize(message="The amount format must be a number, optionally followed by 'GB' (ex.: 5GB)")
120
+ super message, 1
121
+ end
122
+ end
123
+
124
+ class AdditionalStorageRemoveException < Exception
125
+ def initialize(message="The amount of additional storage to be removed exceeds the total amount in use. Add the -f flag to override.")
126
+ super message, 1
127
+ end
128
+ end
129
+ =end
115
130
  end
@@ -3,6 +3,7 @@ require 'rhc/version'
3
3
  require 'rhc/config'
4
4
  require 'rhc/commands'
5
5
  require 'rhc/output_helpers'
6
+ require 'rbconfig'
6
7
 
7
8
  require 'resolv'
8
9
 
@@ -83,6 +84,7 @@ module RHC
83
84
  global_option '-d', '--debug', "Turn on debugging"
84
85
 
85
86
  global_option('--timeout seconds', Integer, 'Set the timeout in seconds for network commands') do |value|
87
+ abort(color("Timeout must be a positive integer",:red)) unless value > 0
86
88
  # FIXME: Refactor so we don't have to use a global var here
87
89
  $rest_timeout = value
88
90
  end
@@ -164,19 +166,27 @@ module RHC
164
166
  count == 1 ? "#{count} #{s}" : "#{count} #{s}s"
165
167
  end
166
168
 
169
+ # given an array of arrays "items", construct an array of strings that can
170
+ # be used to print in tabular form.
167
171
  def table(items, opts={}, &block)
168
172
  items = items.map &block if block_given?
169
- columns = []
170
- max = items.each do |item|
173
+ widths = []
174
+ items.each do |item|
171
175
  item.each_with_index do |s, i|
172
176
  item[i] = s.to_s
173
- columns[i] = [columns[i] || 0, s.length].max if s.respond_to?(:length)
177
+ widths[i] = [widths[i] || 0, s.length].max if s.respond_to?(:length)
174
178
  end
175
179
  end
176
180
  align = opts[:align] || []
177
181
  join = opts[:join] || ' '
182
+ if opts[:header]
183
+ sep = opts[:separator] || "="
184
+ ary = Array.new(opts[:header].length)
185
+ items.unshift ary.each_with_index {|obj, idx| ary[idx] = sep.to_s * (widths[idx] || 1)}
186
+ items.unshift(opts[:header])
187
+ end
178
188
  items.map do |item|
179
- item.each_with_index.map{ |s,i| s.send((align[i] == :right ? :rjust : :ljust), columns[i], ' ') }.join(join).strip
189
+ item.each_with_index.map{ |s,i| s.send((align[i] == :right ? :rjust : :ljust), widths[i], ' ') }.join(join).strip
180
190
  end
181
191
  end
182
192
 
@@ -314,6 +324,7 @@ module RHC
314
324
  def jruby? ; RUBY_PLATFORM =~ /java/i end
315
325
  def windows? ; RUBY_PLATFORM =~ /win(32|dows|ce)|djgpp|(ms|cyg|bcc)win|mingw32/i end
316
326
  def unix? ; !jruby? && !windows? end
327
+ def mac? ; RbConfig::CONFIG['host_os'] =~ /^darwin/ end
317
328
 
318
329
  # common SSH key display format in ERB
319
330
  def ssh_key_display_format
@@ -335,5 +346,15 @@ Fingerprint: <%= key.fingerprint %>
335
346
  dns.getresources(host, Resolv::DNS::Resource::IN::A).any?
336
347
  # :nocov:
337
348
  end
349
+
350
+ def hosts_file_contains?(host)
351
+ # :nocov:
352
+ resolver = Resolv::Hosts.new
353
+ begin
354
+ resolver.getaddress host
355
+ rescue Resolv::ResolvError
356
+ end
357
+ # :nocov:
358
+ end
338
359
  end
339
360
  end
@@ -101,6 +101,8 @@ module RHC
101
101
  header cart.name do
102
102
  display_cart_properties(cart,properties) if properties
103
103
  display_cart_scaling_info(cart) if cart.scalable?
104
+ # Commenting this out for US2438
105
+ # display_cart_storage_info(cart) if cart.additional_gear_storage > 0
104
106
  display_no_info("cartridge") unless @table_displayed
105
107
  end
106
108
  end
@@ -122,6 +124,22 @@ module RHC
122
124
  get_properties(cart,:current_scale,:scales_from,:scales_to)
123
125
  end
124
126
 
127
+ =begin
128
+ # Commenting this out for US2438
129
+ def display_cart_storage_info(cart, title="Storage Info")
130
+ say_table \
131
+ title,
132
+ get_properties(cart,:base_gear_storage,:additional_gear_storage)
133
+ end
134
+
135
+ def display_cart_storage_list(carts)
136
+ carts.each do |cart|
137
+ puts
138
+ display_cart_storage_info(cart, cart.display_name)
139
+ end
140
+ end
141
+ =end
142
+
125
143
  #---------------------------
126
144
  # Misc information
127
145
  #---------------------------
@@ -174,6 +192,11 @@ module RHC
174
192
  date(value)
175
193
  when :scales_from,:scales_to
176
194
  (value == -1 ? "available gears" : value)
195
+ =begin
196
+ # Commenting this out for US2438
197
+ when :base_gear_storage,:additional_gear_storage
198
+ ((value.nil? or value == 0) ? "None" : "#{value}GB")
199
+ =end
177
200
  when :aliases
178
201
  value.join ' '
179
202
  else
@@ -101,19 +101,19 @@ module RHC
101
101
  when 'domains'
102
102
  domains = Array.new
103
103
  data.each do |domain_json|
104
- domains.push(Domain.new(domain_json, @debug))
104
+ domains.push(Domain.new(domain_json, debug?))
105
105
  end
106
106
  return domains
107
107
  when 'domain'
108
- return Domain.new(data, @debug)
108
+ return Domain.new(data, debug?)
109
109
  when 'applications'
110
110
  apps = Array.new
111
111
  data.each do |app_json|
112
- apps.push(Application.new(app_json, @debug))
112
+ apps.push(Application.new(app_json, debug?))
113
113
  end
114
114
  return apps
115
115
  when 'application'
116
- app = Application.new(data, @debug)
116
+ app = Application.new(data, debug?)
117
117
  result['messages'].each do |message|
118
118
  app.add_message(message['text']) if message['field'].nil? or message['field'] == 'result'
119
119
  end
@@ -121,25 +121,25 @@ module RHC
121
121
  when 'cartridges'
122
122
  carts = Array.new
123
123
  data.each do |cart_json|
124
- carts.push(Cartridge.new(cart_json, @debug))
124
+ carts.push(Cartridge.new(cart_json, debug?))
125
125
  end
126
126
  return carts
127
127
  when 'cartridge'
128
- return Cartridge.new(data, @debug)
128
+ return Cartridge.new(data, debug?)
129
129
  when 'user'
130
- return User.new(data, @debug)
130
+ return User.new(data, debug?)
131
131
  when 'keys'
132
132
  keys = Array.new
133
133
  data.each do |key_json|
134
- keys.push(Key.new(key_json, @debug))
134
+ keys.push(Key.new(key_json, debug?))
135
135
  end
136
136
  return keys
137
137
  when 'key'
138
- return Key.new(data, @debug)
138
+ return Key.new(data, debug?)
139
139
  when 'gear_groups'
140
140
  gears = Array.new
141
141
  data.each do |gear_json|
142
- gears.push(GearGroup.new(gear_json, @debug))
142
+ gears.push(GearGroup.new(gear_json, debug?))
143
143
  end
144
144
  return gears
145
145
  else
@@ -150,14 +150,20 @@ module RHC
150
150
  def new_request(options)
151
151
  # user specified timeout takes presidence
152
152
  options[:timeout] = $rest_timeout || options[:timeout]
153
- options[:open_timeout] ||= 4
153
+ options[:open_timeout] ||= (options[:timeout] || 4)
154
154
 
155
155
  RestClient::Request.new options
156
156
  end
157
157
 
158
158
  def request(request, &block)
159
+ tried = 0
159
160
  begin
160
- response = request.execute
161
+ debug "Request: #{request.inspect}" if debug?
162
+ begin
163
+ response = request.execute
164
+ ensure
165
+ debug "Response: #{response.inspect}" rescue nil if debug?
166
+ end
161
167
  #set cookie
162
168
  rh_sso = response.cookies['rh_sso']
163
169
  if not rh_sso.nil?
@@ -169,17 +175,30 @@ module RHC
169
175
  parse_response(response) unless response.nil? or response.code == 204
170
176
  end
171
177
  rescue RestClient::RequestTimeout => e
172
- raise TimeoutException.new("Connection to server timed out. It is possible the operation finished without being able to report success. Use 'rhc domain show' or 'rhc app status' to check the status of your applications.")
178
+ raise TimeoutException.new(
179
+ "Connection to server timed out. "\
180
+ "It is possible the operation finished without being able "\
181
+ "to report success. Use 'rhc domain show' or 'rhc app show' "\
182
+ "to see the status of your applications.")
173
183
  rescue RestClient::ServerBrokeConnection => e
174
- raise ConnectionException.new("Connection to server got interrupted: #{e.message}")
184
+ raise ConnectionException.new(
185
+ "Connection to server got interrupted: #{e.message}")
186
+ rescue RestClient::BadGateway => e
187
+ debug "ERROR: Received bad gateway from server, will retry once if this is a GET" if debug?
188
+ retry if (tried += 1) < 2 && request.method.to_s.upcase == "GET"
189
+ raise ConnectionException.new(
190
+ "An error occurred while communicating with the server (#{e.message}). This problem may only be temporary."\
191
+ "#{RestClient.proxy.present? ? " Check that you have correctly specified your proxy server '#{RestClient.proxy}' as well as your OpenShift server '#{request.url}'." : " Check that you have correctly specified your OpenShift server '#{request.url}'."}")
175
192
  rescue RestClient::ExceptionWithResponse => e
176
193
  process_error_response(e.response, request.url)
177
194
  rescue SocketError => e
178
- raise ConnectionException.new("Unable to connect to the server (#{e.message})."\
179
- "#{RestClient.proxy.present? ? " Check that you have correctly specified your proxy server '#{RestClient.proxy}' as well as your OpenShift server '#{request.url}'." : " Check that you have correctly specified your OpenShift server '#{request.url}'."}")
195
+ raise ConnectionException.new(
196
+ "Unable to connect to the server (#{e.message})."\
197
+ "#{RestClient.proxy.present? ? " Check that you have correctly specified your proxy server '#{RestClient.proxy}' as well as your OpenShift server '#{request.url}'." : " Check that you have correctly specified your OpenShift server '#{request.url}'."}")
180
198
  rescue => e
181
- logger.debug e.backtrace.join("\n ") if @debug
182
- raise ResourceAccessException.new("Failed to access resource: #{e.message}")
199
+ logger.debug e.backtrace.join("\n ") if debug?
200
+ raise ResourceAccessException.new(
201
+ "Failed to access resource: #{e.message}")
183
202
  end
184
203
  end
185
204
 
@@ -199,7 +218,7 @@ module RHC
199
218
  result = RHC::Json.decode(response)
200
219
  messages = Array(result['messages'])
201
220
  rescue => e
202
- logger.debug "Response did not include a message from server: #{e.message}" if @debug
221
+ logger.debug "Response did not include a message from server: #{e.message}" if debug?
203
222
  parse_error = generic_error(url)
204
223
  end
205
224
  case response.code
@@ -18,9 +18,14 @@ module RHC
18
18
  @messages << msg
19
19
  end
20
20
 
21
+ protected
22
+ def debug?
23
+ @debug
24
+ end
25
+
21
26
  private
22
- def debug(msg)
23
- logger.debug(msg) if @debug
27
+ def debug(msg, obj=nil)
28
+ logger.debug("#{msg}#{obj ? " #{obj}" : ''}") if debug?
24
29
  end
25
30
 
26
31
  def rest_method(link_name, payload={}, timeout=nil)
@@ -28,7 +33,6 @@ module RHC
28
33
  method = links[link_name]['method']
29
34
 
30
35
  request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload, :timeout => timeout)
31
- debug "Request: #{request.inspect}"
32
36
  request(request)
33
37
  end
34
38
 
@@ -3,7 +3,7 @@ require 'rhc/rest/base'
3
3
  module RHC
4
4
  module Rest
5
5
  class Cartridge < Base
6
- attr_reader :type, :name, :display_name, :properties, :status_messages, :scales_to, :scales_from, :scales_with, :current_scale
6
+ attr_reader :type, :name, :display_name, :properties, :status_messages, :scales_to, :scales_from, :scales_with, :current_scale, :base_gear_storage, :additional_gear_storage
7
7
  def initialize(args, use_debug=false)
8
8
  @properties = {}
9
9
  props = args[:properties] || args["properties"] || []
@@ -13,6 +13,10 @@ module RHC
13
13
  @properties[:"#{p['type']}"] = category
14
14
  end
15
15
 
16
+ # Make sure that additional gear storage is an integer
17
+ # TODO: This should probably be fixed in the broker
18
+ args['additional_gear_storage'] = args['additional_gear_storage'].to_i rescue 0
19
+
16
20
  super
17
21
  end
18
22
 
@@ -63,6 +67,11 @@ module RHC
63
67
  rest_method "UPDATE", values
64
68
  end
65
69
 
70
+ def set_storage(values)
71
+ debug "Setting additional storage: #{values[:additional_gear_storage]}GB"
72
+ rest_method "UPDATE", values
73
+ end
74
+
66
75
  def connection_info
67
76
  info = property(:cart_data, :connection_url) || property(:cart_data, :job_url) || property(:cart_data, :monitoring_url)
68
77
  info ? (info["value"] || '').rstrip : nil
@@ -1,13 +1,7 @@
1
- Usage: rhc <%= @command.name %> <%= @command.syntax %>
1
+ Usage: <%= Array(program :name).first %> <%= @command.name %> <%= @command.syntax %>
2
2
 
3
3
  <%= @command.description || @command.summary %>
4
- <% unless @actions.nil? or @actions.empty? -%>
5
-
6
- List of Actions
7
- <% for action in @actions -%>
8
- <%= "%-18s %s\n" % [action[:name], action[:summary]] -%>
9
- <% end -%>
10
- <% end -%>
4
+ <% if @actions.blank? -%>
11
5
  <% unless @command.options.blank? or @command.options.all?{ |o| o[:hide] } -%>
12
6
 
13
7
  Options for <%= @command.name %>
@@ -20,8 +14,14 @@ Global Options
20
14
  <% for option in @global_options -%><% next if option[:hide] -%>
21
15
  <%= "%-25s %s\n" % [option[:switches].join(', '), option[:description]] -%>
22
16
  <% end -%>
23
- <%#-
24
- Other Attrs we may wish to use:
17
+ <% else -%>
25
18
 
26
- * @examples - for description, command in @examples
27
- -%>
19
+ List of Actions
20
+ <% for action in @actions -%>
21
+ <%= "%-18s %s\n" % [action[:name], action[:summary]] -%>
22
+ <% end -%>
23
+ <% if @command.default_action? -%>
24
+
25
+ The default action for this resource is '<%= @command.default_action %>'
26
+ <% end -%>
27
+ <% end -%>
@@ -1,4 +1,4 @@
1
- Usage: rhc <%= @command.name %> <%= @command.syntax %>
1
+ Usage: <%= Array(program :name).first %> <%= @command.name %><%= " #{@command.syntax}" if @command.syntax %>
2
2
  <% unless @command.options.blank? or @command.options.all?{ |o| o[:hide] } -%>
3
3
  Pass '--help' to see the full list of options
4
4
  <% end -%>
@@ -1,5 +1,5 @@
1
- Usage: <%= program :name %> (<resource> | --help) [<action>] [<args>]
2
- <%= program :description %>
1
+ Usage: <%= Array(program :name).first %> <resource> [<action>] [--help] [<args>]
2
+ <%= Array(program :description).first %>
3
3
 
4
4
  List of Commands and Resources
5
5
  <% for name, command in @commands.sort -%>
@@ -13,7 +13,7 @@ Global Options
13
13
  <% end -%>
14
14
  <%- end -%>
15
15
 
16
- See '<%= program :name %> help <resource>' for more specifics on each resource or command.
16
+ See '<%= Array(program :name).first %> help <resource>' for more specifics on each resource or command.
17
17
  <% if program :help -%>
18
18
  <% for title, body in program(:help) %>
19
19
  <%= $terminal.color title.to_s.upcase, :bold %>:
@@ -1 +1 @@
1
- See '<%= program :name %> help' for a list of available commands.
1
+ See '<%= Array(program :name).first %> help' for a list of available commands.
@@ -1,9 +1,5 @@
1
1
  module RHC
2
2
  module VERSION #:nocov:
3
- MAJOR = 1
4
- MINOR = 1
5
- MICRO = 11
6
- #PRE = ''
7
- STRING = [MAJOR,MINOR,MICRO].compact.join('.')
3
+ STRING = Gem.loaded_specs['rhc'].version.to_s rescue '0.0.0'
8
4
  end
9
5
  end
@@ -59,20 +59,10 @@ module RHC
59
59
  private
60
60
 
61
61
  def greeting_stage
62
- paragraph do
63
- say "Starting Interactive Setup for OpenShift's command line interface"
64
- end
65
-
66
- paragraph do
67
- say "It looks like you have not configured or used OpenShift " \
68
- "client tools on this computer. " \
69
- "We'll help you configure the client tools with a few quick questions. " \
70
- "You can skip this in the future by copying your configuration files to other machines you use to manage your OpenShift account:"
71
- end
62
+ info "OpenShift Client Tools (RHC) Setup Wizard"
72
63
 
73
64
  paragraph do
74
- say "#{@config_path}"
75
- say "#{RHC::Config.home_dir}/.ssh/"
65
+ say "This wizard will help you upload your SSH keys, set your application namespace, and check that other programs like Git are properly installed."
76
66
  end
77
67
 
78
68
  true
@@ -83,9 +73,9 @@ module RHC
83
73
  section(:top => 1, :bottom => -1) do
84
74
  if @config.has_opts? && @config.opts_login
85
75
  @username = @config.opts_login
86
- say "Using #{@username}, which was given on the command line"
76
+ say "Using #{@username}"
87
77
  else
88
- @username = ask("To connect to #{@libra_server} enter your OpenShift login (email or Red Hat login id): ") do |q|
78
+ @username = ask("Login to #{@libra_server}: ") do |q|
89
79
  q.default = RHC::Config.default_rhlogin
90
80
  end
91
81
  end
@@ -443,24 +433,6 @@ EOF
443
433
  super(config, login)
444
434
  end
445
435
 
446
- def greeting_stage
447
- paragraph do
448
- say "Starting Interactive Setup for OpenShift's command line interface"
449
- end
450
-
451
- paragraph do
452
- say "We'll help get you setup with just a couple of questions. " \
453
- "You can skip this in the future by copying your config's around:"
454
- end
455
-
456
- paragraph do
457
- say " #{@config_path}"
458
- say " #{RHC::Config.home_dir}/.ssh/"
459
- end
460
-
461
- true
462
- end
463
-
464
436
  def create_config_stage
465
437
  if File.exists? @config_path
466
438
  backup = "#{@config_path}.bak"