rhc 0.98.16 → 1.0.4

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 (94) hide show
  1. data/bin/rhc +7 -49
  2. data/bin/rhc-app +14 -3
  3. data/bin/rhc-chk +16 -16
  4. data/bin/rhc-create-app +2 -0
  5. data/bin/rhc-create-domain +1 -2
  6. data/bin/rhc-ctl-app +12 -3
  7. data/bin/rhc-ctl-domain +1 -2
  8. data/bin/rhc-domain +1 -2
  9. data/bin/rhc-domain-info +1 -2
  10. data/bin/rhc-port-forward +1 -2
  11. data/bin/rhc-snapshot +3 -0
  12. data/bin/rhc-sshkey +1 -2
  13. data/bin/rhc-tail-files +1 -1
  14. data/bin/rhc-user-info +1 -3
  15. data/features/application.feature +4 -1
  16. data/features/domain.feature +0 -4
  17. data/features/geared_application.feature +11 -0
  18. data/features/lib/rhc_helper/app.rb +16 -5
  19. data/features/lib/rhc_helper/cartridge.rb +25 -9
  20. data/features/lib/rhc_helper/commandify.rb +34 -7
  21. data/features/lib/rhc_helper/domain.rb +2 -2
  22. data/features/lib/rhc_helper/httpify.rb +24 -14
  23. data/features/lib/rhc_helper/persistable.rb +1 -1
  24. data/features/lib/rhc_helper/sshkey.rb +11 -7
  25. data/features/lib/rhc_helper.rb +5 -3
  26. data/features/multiple_cartridge.feature +1 -1
  27. data/features/scaled_application.feature +48 -0
  28. data/features/sshkey.feature +37 -31
  29. data/features/step_definitions/application_steps.rb +18 -7
  30. data/features/step_definitions/cartridge_steps.rb +29 -3
  31. data/features/step_definitions/domain_steps.rb +2 -2
  32. data/features/step_definitions/sshkey_steps.rb +34 -34
  33. data/features/support/assumptions.rb +21 -9
  34. data/features/support/before_hooks.rb +24 -6
  35. data/features/support/env.rb +45 -19
  36. data/lib/rhc/cartridge_helper.rb +27 -0
  37. data/lib/rhc/cli.rb +1 -1
  38. data/lib/rhc/command_runner.rb +31 -3
  39. data/lib/rhc/commands/alias.rb +38 -0
  40. data/lib/rhc/commands/app.rb +478 -0
  41. data/lib/rhc/commands/base.rb +42 -12
  42. data/lib/rhc/commands/cartridge.rb +189 -0
  43. data/lib/rhc/commands/domain.rb +11 -49
  44. data/lib/rhc/commands/port-forward.rb +0 -1
  45. data/lib/rhc/commands/setup.rb +2 -1
  46. data/lib/rhc/commands/snapshot.rb +118 -0
  47. data/lib/rhc/commands/sshkey.rb +24 -38
  48. data/lib/rhc/commands/tail.rb +24 -0
  49. data/lib/rhc/commands/threaddump.rb +16 -0
  50. data/lib/rhc/commands.rb +33 -7
  51. data/lib/rhc/config.rb +28 -12
  52. data/lib/rhc/context_helper.rb +19 -5
  53. data/lib/rhc/core_ext.rb +86 -0
  54. data/lib/rhc/exceptions.rb +44 -0
  55. data/lib/rhc/git_helper.rb +59 -0
  56. data/lib/rhc/helpers.rb +86 -5
  57. data/lib/rhc/output_helpers.rb +213 -0
  58. data/lib/rhc/rest/application.rb +134 -67
  59. data/lib/rhc/rest/base.rb +48 -0
  60. data/lib/rhc/rest/cartridge.rb +40 -44
  61. data/lib/rhc/rest/client.rb +127 -59
  62. data/lib/rhc/rest/domain.rb +29 -39
  63. data/lib/rhc/rest/gear_group.rb +10 -0
  64. data/lib/rhc/rest/key.rb +8 -23
  65. data/lib/rhc/rest/user.rb +8 -24
  66. data/lib/rhc/rest.rb +22 -11
  67. data/lib/rhc/ssh_key_helpers.rb +47 -0
  68. data/lib/rhc/usage_templates/help.erb +0 -1
  69. data/lib/rhc/version.rb +3 -3
  70. data/lib/rhc/wizard.rb +123 -225
  71. data/lib/rhc-common.rb +43 -62
  72. data/spec/rest_spec_helper.rb +159 -36
  73. data/spec/rhc/cli_spec.rb +29 -1
  74. data/spec/rhc/command_spec.rb +32 -35
  75. data/spec/rhc/commands/alias_spec.rb +123 -0
  76. data/spec/rhc/commands/app_spec.rb +414 -0
  77. data/spec/rhc/commands/cartridge_spec.rb +342 -0
  78. data/spec/rhc/commands/domain_spec.rb +8 -8
  79. data/spec/rhc/commands/setup_spec.rb +17 -6
  80. data/spec/rhc/commands/snapshot_spec.rb +140 -0
  81. data/spec/rhc/commands/sshkey_spec.rb +26 -4
  82. data/spec/rhc/commands/tail_spec.rb +34 -0
  83. data/spec/rhc/commands/threaddump_spec.rb +83 -0
  84. data/spec/rhc/config_spec.rb +39 -13
  85. data/spec/rhc/context_spec.rb +51 -0
  86. data/spec/rhc/helpers_spec.rb +52 -12
  87. data/spec/rhc/rest_application_spec.rb +16 -3
  88. data/spec/rhc/rest_client_spec.rb +144 -36
  89. data/spec/rhc/rest_spec.rb +1 -1
  90. data/spec/rhc/wizard_spec.rb +133 -232
  91. data/spec/spec_helper.rb +4 -3
  92. metadata +56 -31
  93. data/features/support/ssh.sh +0 -2
  94. data/spec/rhc/common_spec.rb +0 -49
@@ -1,14 +1,26 @@
1
1
  require 'base64'
2
2
  require 'rhc/json'
3
+ require 'rhc/rest/base'
4
+ require 'rhc/helpers'
5
+ require 'uri'
3
6
 
4
7
  module RHC
5
8
  module Rest
6
- class Client
7
- include Rest
8
- def initialize(end_point, username, password, debug=false)
9
- # use mydebug for legacy reasons
10
- @mydebug = @mydebug || debug
11
- logger.debug "Connecting to #{end_point}" if @mydebug
9
+ class Client < Base
10
+ include RHC::Helpers
11
+
12
+ attr_reader :server_api_versions, :client_api_versions
13
+ # Keep the list of supported API versions here
14
+ # The list may not necessarily be sorted; we will select the last
15
+ # matching one supported by the server.
16
+ # See #api_version_negotiated
17
+ CLIENT_API_VERSIONS = [1.0, 1.1, 1.2]
18
+
19
+ def initialize(end_point, username, password, use_debug=false, preferred_api_versions = CLIENT_API_VERSIONS)
20
+ @debug = use_debug
21
+ @end_point = end_point
22
+ @server_api_versions = []
23
+ debug "Connecting to #{end_point}"
12
24
 
13
25
  credentials = nil
14
26
  userpass = "#{username}:#{password}"
@@ -21,100 +33,114 @@ module RHC
21
33
  # :nocov:
22
34
  @@headers["Authorization"] = "Basic #{credentials}"
23
35
  @@headers["User-Agent"] = RHC::Helpers.user_agent rescue nil
24
- #first get the API
25
36
  RestClient.proxy = ENV['http_proxy']
26
- request = new_request(:url => end_point, :method => :get, :headers => @@headers)
37
+
38
+ # API version negotiation
27
39
  begin
28
- response = request.execute
29
- result = RHC::Json.decode(response)
30
- @links = request(request)
31
- rescue => e
32
- raise ResourceAccessException.new("Resource could not be accessed:#{e.message}")
40
+ debug "Client supports API versions #{preferred_api_versions.join(', ')}"
41
+ @client_api_versions = preferred_api_versions
42
+ default_request = new_request(:url => @end_point, :method => :get, :headers => @@headers)
43
+ @server_api_versions, links = api_info(default_request)
44
+ debug "Server supports API versions #{@server_api_versions.join(', ')}"
45
+
46
+ if api_version_negotiated
47
+ unless server_api_version_current?
48
+ debug "Client API version #{api_version_negotiated} is not current. Refetching API"
49
+ # need to re-fetch API
50
+ @@headers["Accept"] = "application/json; version=#{api_version_negotiated}"
51
+ req = new_request(:url => @end_point, :method => :get, :headers => @@headers)
52
+ @server_api_versions, links = api_info req
53
+ end
54
+ else
55
+ warn_about_api_versions
56
+ end
57
+ rescue Exception => e
58
+ raise ResourceAccessException.new("Failed to access resource: #{e.message}")
33
59
  end
60
+
61
+ super({:links => links}, use_debug)
34
62
  end
35
63
 
36
- #Add Domain
37
64
  def add_domain(id)
38
- logger.debug "Adding domain #{id}" if @mydebug
39
- url = @links['ADD_DOMAIN']['href']
40
- method = @links['ADD_DOMAIN']['method']
41
- payload = {:id => id}
42
- request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload)
43
- return request(request)
65
+ debug "Adding domain #{id}"
66
+ rest_method "ADD_DOMAIN", :id => id
44
67
  end
45
68
 
46
- #Get all Domain
47
69
  def domains
48
- logger.debug "Getting all domains" if @mydebug
49
- url = @links['LIST_DOMAINS']['href']
50
- method = @links['LIST_DOMAINS']['method']
51
- request = new_request(:url => url, :method => method, :headers => @@headers)
52
- return request(request)
70
+ debug "Getting all domains"
71
+ rest_method "LIST_DOMAINS"
72
+ end
73
+
74
+ def cartridges
75
+ debug "Getting all cartridges"
76
+ rest_method "LIST_CARTRIDGES"
77
+ end
78
+
79
+ def user
80
+ debug "Getting user info"
81
+ rest_method "GET_USER"
82
+ end
83
+
84
+ def sshkeys
85
+ debug "Finding all keys for #{user.login}"
86
+ user.keys
87
+ end
88
+
89
+ def add_key(name, key, content)
90
+ debug "Adding key #{key} for #{user.login}"
91
+ user.add_key name, key, content
92
+ end
93
+
94
+ def delete_key(name)
95
+ debug "Deleting key '#{name}'"
96
+ key = find_key(name)
97
+ key.destroy
53
98
  end
54
99
 
55
100
  #Find Domain by namesapce
56
101
  def find_domain(id)
57
- logger.debug "Finding domain #{id}" if @mydebug
102
+ debug "Finding domain #{id}"
58
103
  domains.each { |domain| return domain if domain.id == id }
59
104
 
60
105
  raise RHC::DomainNotFoundException.new("Domain #{id} does not exist")
61
106
  end
62
107
 
63
- #Get all Cartridge
64
- def cartridges
65
- logger.debug "Getting all cartridges" if @mydebug
66
- url = @links['LIST_CARTRIDGES']['href']
67
- method = @links['LIST_CARTRIDGES']['method']
68
- request = new_request(:url => url, :method => method, :headers => @@headers)
69
- return request(request)
70
- end
71
-
72
108
  #Find Cartridge by name or regex
73
109
  def find_cartridges(name)
74
- logger.debug "Finding cartridge #{name}" if @mydebug
75
- regex = nil
110
+ debug "Finding cartridge #{name}"
76
111
  if name.is_a?(Hash)
77
- name = name[:name] if name[:name]
78
- regex = name[:regex] if name[:regex]
112
+ regex = name[:regex]
113
+ type = name[:type]
114
+ name = name[:name]
79
115
  end
80
116
 
81
117
  filtered = Array.new
82
118
  cartridges.each do |cart|
83
119
  if regex
84
- filtered.push(cart) if cart.name.match(regex)
120
+ filtered.push(cart) if cart.name.match(regex) and (type.nil? or cart.type == type)
85
121
  else
86
- filtered.push(cart) if cart.name == name
122
+ filtered.push(cart) if (name.nil? or cart.name == name) and (type.nil? or cart.type == type)
87
123
  end
88
124
  end
89
125
  return filtered
90
126
  end
91
127
 
92
- #Get User info
93
- def user
94
- url = @links['GET_USER']['href']
95
- method = @links['GET_USER']['method']
96
- request = new_request(:url => url, :method => method, :headers => @@headers)
97
- return request(request)
98
- end
99
-
100
128
  #find Key by name
101
129
  def find_key(name)
102
- logger.debug "Finding key #{name}" if @mydebug
103
- user.keys.each { |key| return key if key.name == name }
104
-
105
- raise RHC::KeyNotFoundException.new("Key #{name} does not exist")
130
+ debug "Finding key #{name}"
131
+ user.find_key(name) or raise RHC::KeyNotFoundException.new("Key #{name} does not exist")
106
132
  end
107
-
133
+
108
134
  def sshkeys
109
135
  logger.debug "Finding all keys for #{user.login}" if @mydebug
110
136
  user.keys
111
137
  end
112
-
138
+
113
139
  def add_key(name, key, content)
114
140
  logger.debug "Adding key #{key} for #{user.login}" if @mydebug
115
141
  user.add_key name, key, content
116
142
  end
117
-
143
+
118
144
  def delete_key(name)
119
145
  logger.debug "Deleting key '#{name}'" if @mydebug
120
146
  key = find_key(name)
@@ -123,10 +149,52 @@ module RHC
123
149
 
124
150
  def logout
125
151
  #TODO logout
126
- logger.debug "Logout/Close client" if @mydebug
152
+ debug "Logout/Close client"
127
153
  end
128
154
  alias :close :logout
155
+
156
+
157
+ ### API version related methods
158
+ def api_version_match?
159
+ ! api_version_negotiated.nil?
160
+ end
161
+
162
+ # return the API version that the server and this client can agree on
163
+ def api_version_negotiated
164
+ client_api_versions.reverse. # choose the last API version listed
165
+ detect { |v| @server_api_versions.include? v }
166
+ end
167
+
168
+ def client_api_version_current?
169
+ current_client_api_version == api_version_negotiated
170
+ end
171
+
172
+ def current_client_api_version
173
+ client_api_versions.last
174
+ end
175
+
176
+ def server_api_version_current?
177
+ @server_api_versions && @server_api_versions.max == api_version_negotiated
178
+ end
179
+
180
+ def warn_about_api_versions
181
+ if !api_version_match?
182
+ warn "WARNING: API version mismatch. This client supports #{client_api_versions.join(', ')} but
183
+ server at #{URI.parse(@end_point).host} supports #{@server_api_versions.join(', ')}."
184
+ warn "The client version may be outdated; please consider updating 'rhc'. We will continue, but you may encounter problems."
185
+ end
186
+ end
187
+
188
+ def debug?
189
+ @debug
190
+ end
191
+
192
+ private
193
+ # execute +req+ with RestClient, and return [server_api_versions, links]
194
+ def api_info(req)
195
+ json_response = ::RHC::Json.decode(req.execute)
196
+ [ json_response['supported_api_versions'], json_response['data'] ]
197
+ end
129
198
  end
130
-
131
199
  end
132
200
  end
@@ -1,23 +1,19 @@
1
+ require 'rhc/rest/base'
2
+
1
3
  module RHC
2
4
  module Rest
3
- class Domain
4
- include Rest
5
+ class Domain < Base
5
6
  attr_reader :id
6
- def initialize(args)
7
- @id = args[:id] || args["id"]
8
- @links = args[:links] || args["links"]
9
- end
10
7
 
11
8
  #Add Application to this domain
12
9
  # options
13
10
  # cartrdige
14
11
  # template
15
12
  # scale
16
- # node_profile
13
+ # gear_profile
17
14
  def add_application(name, options)
18
- logger.debug "Adding application #{name} to domain #{self.id}" if @mydebug
19
- url = @links['ADD_APPLICATION']['href']
20
- method = @links['ADD_APPLICATION']['method']
15
+ debug "Adding application #{name} to domain #{id}"
16
+
21
17
  payload = {:name => name}
22
18
  options.each do |key, value|
23
19
  payload[key] = value
@@ -26,48 +22,42 @@ module RHC
26
22
  if options[:scale]
27
23
  timeout = 300 # 5 minute timeout for scalable app
28
24
  end
29
- request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload, :timeout => timeout)
30
- return request(request)
31
- end
32
25
 
33
- #Get all Application for this domain
34
- def applications
35
- logger.debug "Getting all applications for domain #{self.id}" if @mydebug
36
- url = @links['LIST_APPLICATIONS']['href']
37
- method = @links['LIST_APPLICATIONS']['method']
38
- request = new_request(:url => url, :method => method, :headers => @@headers)
39
- return request(request)
26
+ rest_method "ADD_APPLICATION", payload, timeout
40
27
  end
41
28
 
42
- def find_application(name)
43
- logger.debug "Finding application #{name}" if @mydebug
44
- applications.each { |app| return app if app.name == name }
45
-
46
- raise RHC::ApplicationNotFoundException.new("Application #{name} does not exist")
29
+ def applications
30
+ debug "Getting all applications for domain #{id}"
31
+ rest_method "LIST_APPLICATIONS"
47
32
  end
48
33
 
49
- #Update Domain
50
34
  def update(new_id)
51
- logger.debug "Updating domain #{self.id} to #{new_id}" if @mydebug
52
- url = @links['UPDATE']['href']
53
- method = @links['UPDATE']['method']
54
- payload = {:id => new_id}
35
+ debug "Updating domain #{id} to #{new_id}"
55
36
  # 5 minute timeout as this may take time if there are a lot of apps
56
- request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload, :timeout=> 300)
57
- return request(request)
37
+ rest_method "UPDATE", {:id => new_id}, 300
58
38
  end
59
39
  alias :save :update
60
40
 
61
- #Delete Domain
62
41
  def destroy(force=false)
63
- logger.debug "Deleting domain #{self.id}" if @mydebug
64
- url = @links['DELETE']['href']
65
- method = @links['DELETE']['method']
66
- payload = {:force => force}
67
- request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload)
68
- return request(request)
42
+ debug "Deleting domain #{id}"
43
+ rest_method "DELETE", :force => force
69
44
  end
70
45
  alias :delete :destroy
46
+
47
+ def find_application(name, options={})
48
+ if name.is_a?(Hash)
49
+ options = name.merge(options)
50
+ name = options[:name]
51
+ end
52
+ framework = options[:framework]
53
+
54
+ debug "Finding application :name => #{name}, :framework => #{framework}"
55
+ applications.each do |app|
56
+ return app if (name.nil? or app.name == name) and (framework.nil? or app.framework == framework)
57
+ end
58
+
59
+ raise RHC::ApplicationNotFoundException.new("Application #{name} does not exist")
60
+ end
71
61
  end
72
62
  end
73
63
  end
@@ -0,0 +1,10 @@
1
+ require 'rhc/rest/base'
2
+
3
+ module RHC
4
+ module Rest
5
+ class GearGroup < Base
6
+ include Rest
7
+ attr_reader :gears, :cartridges
8
+ end
9
+ end
10
+ end
data/lib/rhc/rest/key.rb CHANGED
@@ -1,35 +1,21 @@
1
+ require 'rhc/rest/base'
2
+
1
3
  module RHC
2
4
  module Rest
3
- class Key
4
- include Rest
5
+ class Key < Base
5
6
  attr_reader :name, :type, :content
6
- def initialize(args)
7
- @name = args[:name] || args["name"]
8
- @type = args[:type] || args["type"]
9
- @content = args[:content] || args["content"]
10
- @links = args[:links] || args["links"]
11
- end
12
7
 
13
- # Update Key
14
8
  def update(type, content)
15
- logger.debug "Updating key #{self.name}" if @mydebug
16
- url = @links['UPDATE']['href']
17
- method = @links['UPDATE']['method']
18
- payload = {:type => type, :content => content}
19
- request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload)
20
- return request(request)
9
+ debug "Updating key #{self.name}"
10
+ rest_method "UPDATE", :type => type, :content => content
21
11
  end
22
12
 
23
- #Delete Key
24
13
  def destroy
25
- logger.debug "Deleting key #{self.name}" if @mydebug
26
- url = @links['DELETE']['href']
27
- method = @links['DELETE']['method']
28
- request = new_request(:url => url, :method => method, :headers => @@headers)
29
- return request(request)
14
+ debug "Deleting key #{self.name}"
15
+ rest_method "DELETE"
30
16
  end
31
17
  alias :delete :destroy
32
-
18
+
33
19
  def fingerprint
34
20
  begin
35
21
  public_key = Net::SSH::KeyFactory.load_data_public_key("#{type} #{content}")
@@ -37,7 +23,6 @@ module RHC
37
23
  rescue NotImplementedError, OpenSSL::PKey::PKeyError => e
38
24
  'Invalid key'
39
25
  end
40
-
41
26
  end
42
27
  end
43
28
  end
data/lib/rhc/rest/user.rb CHANGED
@@ -1,40 +1,24 @@
1
+ require 'rhc/rest/base'
2
+
1
3
  module RHC
2
4
  module Rest
3
- class User
4
- include Rest
5
+ class User < Base
5
6
  attr_reader :login
6
- def initialize(args)
7
- @login = args[:login] || args["login"]
8
- @links = args[:links] || args["links"]
9
- end
10
7
 
11
- #Add Key for this user
12
8
  def add_key(name, content, type)
13
- url = @links['ADD_KEY']['href']
14
- method = @links['ADD_KEY']['method']
15
- payload = {:name => name, :type => type, :content => content}
16
- request = new_request(:url => url, :method => method, :headers => @@headers, :payload => payload)
17
- return request(request)
9
+ debug "Add key #{name} of type #{type} for user #{login}"
10
+ rest_method "ADD_KEY", :name => name, :type => type, :content => content
18
11
  end
19
12
 
20
- #Get all Key for this user
21
13
  def keys
22
- url = @links['LIST_KEYS']['href']
23
- method = @links['LIST_KEYS']['method']
24
- request = new_request(:url => url, :method => method, :headers => @@headers)
25
- return request(request)
14
+ debug "Getting all keys for user #{login}"
15
+ rest_method "LIST_KEYS"
26
16
  end
27
17
 
28
18
  #Find Key by name
29
19
  def find_key(name)
30
- filtered = Array.new
31
- keys.each do |key|
32
20
  #TODO do a regex caomparison
33
- if key.name == name
34
- filtered.push(key)
35
- end
36
- end
37
- return filtered
21
+ keys.detect { |key| key.name == name }
38
22
  end
39
23
  end
40
24
  end
data/lib/rhc/rest.rb CHANGED
@@ -10,6 +10,7 @@ module RHC
10
10
  autoload :Domain, 'rhc/rest/domain'
11
11
  autoload :Key, 'rhc/rest/key'
12
12
  autoload :User, 'rhc/rest/user'
13
+ autoload :GearGroup, 'rhc/rest/gear_group'
13
14
 
14
15
  class Exception < RuntimeError
15
16
  attr_reader :code
@@ -100,39 +101,49 @@ module RHC
100
101
  when 'domains'
101
102
  domains = Array.new
102
103
  data.each do |domain_json|
103
- domains.push(Domain.new(domain_json))
104
+ domains.push(Domain.new(domain_json, @debug))
104
105
  end
105
106
  return domains
106
107
  when 'domain'
107
- return Domain.new(data)
108
+ return Domain.new(data, @debug)
108
109
  when 'applications'
109
110
  apps = Array.new
110
111
  data.each do |app_json|
111
- apps.push(Application.new(app_json))
112
+ apps.push(Application.new(app_json, @debug))
112
113
  end
113
114
  return apps
114
115
  when 'application'
115
- return Application.new(data)
116
+ app = Application.new(data, @debug)
117
+ result['messages'].each do |message|
118
+ app.add_message(message['text']) if message['field'].nil? or message['field'] == 'result'
119
+ end
120
+ return app
116
121
  when 'cartridges'
117
122
  carts = Array.new
118
123
  data.each do |cart_json|
119
- carts.push(Cartridge.new(cart_json))
124
+ carts.push(Cartridge.new(cart_json, @debug))
120
125
  end
121
126
  return carts
122
127
  when 'cartridge'
123
- return Cartridge.new(data)
128
+ return Cartridge.new(data, @debug)
124
129
  when 'user'
125
- return User.new(data)
130
+ return User.new(data, @debug)
126
131
  when 'keys'
127
132
  keys = Array.new
128
133
  data.each do |key_json|
129
- keys.push(Key.new(key_json))
134
+ keys.push(Key.new(key_json, @debug))
130
135
  end
131
136
  return keys
132
137
  when 'key'
133
- return Key.new(data)
138
+ return Key.new(data, @debug)
139
+ when 'gear_groups'
140
+ gears = Array.new
141
+ data.each do |gear_json|
142
+ gears.push(GearGroup.new(gear_json, @debug))
143
+ end
144
+ return gears
134
145
  else
135
- data
146
+ data
136
147
  end
137
148
  end
138
149
 
@@ -212,7 +223,7 @@ module RHC
212
223
  when 500
213
224
  messages.each do |message|
214
225
  if message['severity'].upcase == "ERROR"
215
- raise ServerErrorException, message['text']
226
+ raise ServerErrorException.new(message['text'], message["exit_code"] ? message["exit_code"].to_i : nil)
216
227
  end
217
228
  end
218
229
  when 503
@@ -70,6 +70,53 @@ module RHC
70
70
  template.result(binding)
71
71
  end
72
72
 
73
+
74
+ # For Net::SSH versions (< 2.0.11) that does not have
75
+ # Net::SSH::KeyFactory.load_public_key, we drop to shell to get
76
+ # the key's fingerprint
77
+ def ssh_keygen_fallback(path)
78
+ fingerprint = `ssh-keygen -lf #{path} 2>&1`.split(' ')[1]
79
+
80
+ if $?.exitstatus != 0
81
+ error "Unable to compute SSH public key finger print for #{path}"
82
+ end
83
+ fingerprint
84
+ end
85
+
86
+ def fingerprint_for_local_key(key)
87
+ Net::SSH::KeyFactory.load_public_key(key).fingerprint
88
+ rescue NoMethodError, NotImplementedError => e
89
+ ssh_keygen_fallback key
90
+ return nil
91
+ # :nocov: no reason to cover this case
92
+ rescue OpenSSL::PKey::PKeyError, Net::SSH::Exception => e
93
+ error e.message
94
+ return nil
95
+ # :nocov:
96
+ end
97
+
98
+ def fingerprint_for_default_key
99
+ fingerprint_for_local_key RHC::Config::ssh_pub_key_file_path
100
+ end
101
+
102
+ # for an SSH public key specified by 'key', return a triple
103
+ # [type, content, comment]
104
+ # which is basically the space-separated list of the SSH public key content
105
+ def ssh_key_triple_for(key)
106
+ begin
107
+ file = File.open key
108
+ rescue Errno::ENOENT => e
109
+ raise ::RHC::KeyFileNotExistentException.new("File '#{key}' does not exist.")
110
+ rescue Errno::EACCES => e
111
+ raise ::RHC::KeyFileAccessDeniedException.new("Access denied to '#{key}'.")
112
+ end
113
+ file.gets.chomp.split
114
+ end
115
+
116
+ def ssh_key_triple_for_default_key
117
+ ssh_key_triple_for RHC::Config::ssh_pub_key_file_path
118
+ end
119
+
73
120
  private
74
121
 
75
122
  def ssh_add
@@ -2,7 +2,6 @@ Usage: <%= program :name %> (<resource> | --help) [<action>] [<args>]
2
2
  <%= program :description %>
3
3
 
4
4
  List of Commands and Resources
5
- app Manage applications within the OpenShift account.
6
5
  <% for name, command in @commands.sort -%>
7
6
  <%- unless alias? name or name == "help" or name.include?(" ") or command.summary.nil? -%> <%="%-18s %s\n" % [command.name, command.summary || command.description] %><%- end -%>
8
7
  <%- end -%>
data/lib/rhc/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module RHC
2
2
  module VERSION #:nocov:
3
- MAJOR = 0
4
- MINOR = 98
5
- MICRO = 16
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ MICRO = 4
6
6
  #PRE = ''
7
7
  STRING = [MAJOR,MINOR,MICRO].compact.join('.')
8
8
  end