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,177 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rhc/coverage_helper'
4
-
5
- require 'rhc-common'
6
-
7
- RHC::Helpers.deprecated_command('rhc sshkey',true)
8
-
9
- #
10
- # print help
11
- #
12
- def p_usage(exit_code = 255)
13
- rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
14
- puts <<USAGE
15
-
16
- Usage: rhc sshkey (<command> | --help) [<args>]
17
- Manage multiple keys for the registered rhcloud user.
18
-
19
- List of commands
20
- list Display all the SSH keys for the user account
21
- add Add SSH key to the user account
22
- update Update SSH key for the user account
23
- remove Remove SSH key from the user account
24
-
25
- List of arguments
26
- -l|--rhlogin rhlogin OpenShift login (#{rhlogin})
27
- -p|--password password Password (optional, will prompt)
28
- -i|--identifier key-name User-specified identifier for the key
29
- -k|--ssh key-filepath SSH public key filepath
30
- -d|--debug Print Debug info
31
- -h|--help Show Usage info
32
- --config path Path of alternate config file
33
- --timeout # Timeout, in seconds, for the session
34
-
35
- USAGE
36
- exit exit_code
37
- end
38
-
39
-
40
- def validate_args(val_id=true)
41
- # If provided a config path, check it
42
- RHC::Config.check_cpath($opt)
43
-
44
- # Pull in configs from files
45
- $libra_server = get_var('libra_server')
46
- debug = get_var('debug') == 'false' ? nil : get_var('debug')
47
-
48
- $opt['rhlogin'] = get_var('default_rhlogin') unless $opt['rhlogin']
49
- p_usage if !RHC::check_rhlogin($opt['rhlogin'])
50
-
51
- debug = $opt["debug"] ? true : false
52
- RHC::debug(debug)
53
-
54
- p_usage if val_id && !RHC::check_key($opt['identifier'])
55
-
56
- RHC::timeout($opt["timeout"], get_var('timeout'))
57
- RHC::connect_timeout($opt["timeout"], get_var('timeout'))
58
- $password = $opt['password'] ? $opt['password'] : RHC::get_password
59
- end
60
-
61
- def remove_key
62
- validate_args(true)
63
-
64
- data = {}
65
- data[:rhlogin] = $opt['rhlogin']
66
- data[:key_name] = $opt['identifier']
67
- data[:action] = 'remove-key'
68
-
69
- url = URI.parse("https://#{$libra_server}/broker/ssh_keys")
70
- handle_key_mgmt_response(url, data, $password)
71
- end
72
-
73
- def show_key_list
74
- validate_args(false)
75
-
76
- ssh_keys = RHC::get_ssh_keys($libra_server, $opt['rhlogin'], $password, RHC::Config.default_proxy)
77
- additional_ssh_keys = ssh_keys['keys']
78
-
79
- puts ""
80
- puts "SSH keys"
81
- puts "========"
82
-
83
- # first list the primary key
84
- puts " Name: default"
85
- puts " Type: #{ssh_keys['ssh_type']}"
86
- puts "Fingerprint: #{ssh_keys['fingerprint']}"
87
- #puts " Key: #{ssh_keys['ssh_key']}"
88
- puts ""
89
-
90
- # now list the additional keys
91
- if additional_ssh_keys && additional_ssh_keys.kind_of?(Hash)
92
- additional_ssh_keys.each do |name, keyval|
93
- puts " Name: #{name}"
94
- puts " Type: #{keyval['type']}"
95
- puts "Fingerprint: #{keyval['fingerprint']}"
96
- #puts " Key: #{keyval['key']}"
97
- puts ""
98
- end
99
- end
100
- end
101
-
102
- begin
103
- argv_c = ARGV.clone
104
-
105
- if ARGV[0] =~ /^(add|update)$/
106
- ARGV.shift
107
- opts = GetoptLong.new(
108
- ["--debug", "-d", GetoptLong::NO_ARGUMENT],
109
- ["--help", "-h", GetoptLong::NO_ARGUMENT],
110
- ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
111
- ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
112
- ["--identifier", "-i", GetoptLong::REQUIRED_ARGUMENT],
113
- ["--ssh", "-k", GetoptLong::REQUIRED_ARGUMENT],
114
- ["--config", GetoptLong::REQUIRED_ARGUMENT],
115
- ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
116
- )
117
- elsif ARGV[0] =~ /^remove$/
118
- ARGV.shift
119
- opts = GetoptLong.new(
120
- ["--debug", "-d", GetoptLong::NO_ARGUMENT],
121
- ["--help", "-h", GetoptLong::NO_ARGUMENT],
122
- ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
123
- ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
124
- ["--identifier", "-i", GetoptLong::REQUIRED_ARGUMENT],
125
- ["--config", GetoptLong::REQUIRED_ARGUMENT],
126
- ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
127
- )
128
- elsif ARGV[0] =~ /^list$/
129
- ARGV.shift
130
- opts = GetoptLong.new(
131
- ["--debug", "-d", GetoptLong::NO_ARGUMENT],
132
- ["--help", "-h", GetoptLong::NO_ARGUMENT],
133
- ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
134
- ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
135
- ["--config", GetoptLong::REQUIRED_ARGUMENT],
136
- ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
137
- )
138
- else
139
- opts = GetoptLong.new(
140
- ["--help", "-h", GetoptLong::NO_ARGUMENT]
141
- )
142
- unless ARGV[0] =~ /^(help|-h|--help)$/
143
- puts "Missing or invalid command!"
144
- # just exit at this point
145
- # printing the usage description will be handled in the rescue
146
- exit 255
147
- end
148
- end
149
-
150
- $opt = {}
151
- opts.each do |o, a|
152
- $opt[o[2..-1]] = a.to_s
153
- end
154
-
155
- rescue Exception => e
156
- p_usage
157
- end
158
-
159
- p_usage 0 if $opt["help"]
160
-
161
- case argv_c[0]
162
- when "add", "update"
163
- validate_args(true)
164
- add_or_update_key(argv_c[0], $opt['identifier'], $opt['ssh'],
165
- $opt['rhlogin'], $password)
166
- when "remove"
167
- remove_key
168
- when "list", nil
169
- show_key_list
170
- when "-h", "--help", "help", nil
171
- p_usage 0
172
- else
173
- puts "Invalid command!"
174
- p_usage
175
- end
176
-
177
- exit 0
@@ -1,133 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rhc/coverage_helper'
4
-
5
- require 'rhc-common'
6
- require 'base64'
7
-
8
- #
9
- # print help
10
- #
11
- def p_usage(exit_code = 255)
12
- rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
13
- puts <<USAGE
14
-
15
- Usage: #{$0}
16
- Tail the logs of an application
17
-
18
- -l|--rhlogin rhlogin OpenShift login (#{rhlogin})
19
- -a|--app Target application (required)
20
- -f|--files File glob relative to app (default <application_name>/logs/*) (optional)
21
- -o|--opts Options to pass to the server-side (linux based) tail command (-f is implicit. See the linux tail man page full list of options.) (Ex: --opts '-n 100')
22
- -p|--password password Password (optional, will prompt)
23
- -d|--debug Print Debug info
24
- -h|--help Show Usage info
25
- --config path Path of alternate config file
26
- --timeout # Timeout, in seconds, for the session
27
-
28
- USAGE
29
- exit exit_code
30
- end
31
-
32
- begin
33
- opts = GetoptLong.new(
34
- ["--debug", "-d", GetoptLong::NO_ARGUMENT],
35
- ["--help", "-h", GetoptLong::NO_ARGUMENT],
36
- ["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
37
- ["--opts", "-o", GetoptLong::REQUIRED_ARGUMENT],
38
- ["--files", "-f", GetoptLong::REQUIRED_ARGUMENT],
39
- ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
40
- ["--config", GetoptLong::REQUIRED_ARGUMENT],
41
- ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
42
- ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
43
- )
44
- opt = {}
45
- opts.each do |o, a|
46
- opt[o[2..-1]] = a.to_s
47
- end
48
- rescue Exception => e
49
- #puts e.message
50
- p_usage
51
- end
52
-
53
- # If provided a config path, check it
54
- RHC::Config.check_cpath(opt)
55
-
56
- # Pull in configs from files
57
- libra_server = get_var('libra_server')
58
- debug = get_var('debug') == 'false' ? nil : get_var('debug')
59
-
60
- p_usage 0 if opt['help']
61
-
62
- p_usage if !opt['app'] || 0 != ARGV.length
63
-
64
- debug = true if opt['debug']
65
-
66
- RHC::debug(debug)
67
-
68
- RHC::timeout(opt["timeout"], get_var('timeout'))
69
- RHC::connect_timeout(opt["timeout"], get_var('timeout'))
70
-
71
- opt['rhlogin'] = get_var('default_rhlogin') unless opt['rhlogin']
72
-
73
- if !RHC::check_rhlogin(opt['rhlogin'])
74
- p_usage
75
- end
76
-
77
- password = opt['password']
78
- if !password
79
- password = RHC::get_password
80
- end
81
-
82
- user_info = RHC::get_user_info(libra_server, opt['rhlogin'], password, RHC::Config.default_proxy, false)
83
-
84
- app = opt['app']
85
-
86
- unless user_info['app_info'][app]
87
- puts
88
- puts "Could not find app '#{opt['app']}'. Please run rhc-domain-info to get a list"
89
- puts "of your current running applications"
90
- puts
91
- exit 101
92
- end
93
-
94
- opt['files'] = "*/log*/*" unless opt['files']
95
- file_glob = "#{opt['files']}"
96
- app_uuid = user_info['app_info'][app]['uuid']
97
- namespace = user_info['user_info']['domains'][0]['namespace']
98
- rhc_domain = user_info['user_info']['rhc_domain']
99
-
100
- # -t to force PTY and avoid daemons
101
- # Red Hat OpenShift: https://bugzilla.redhat.com/show_bug.cgi?id=726646
102
- # OpenSSH https://bugzilla.mindrot.org/show_bug.cgi?id=396
103
-
104
- remote_cmd = "tail#{opt['opts'] ? ' --opts ' + Base64::encode64(opt['opts']).chomp : ''} #{file_glob}"
105
- ssh_cmd = "ssh -t #{app_uuid}@#{app}-#{namespace}.#{rhc_domain} '#{remote_cmd}'"
106
-
107
- puts "Attempting to tail files: #{file_glob}"
108
- puts "Use ctl + c to stop"
109
- puts ssh_cmd if debug
110
- begin
111
- if opt['files'] == 'system-messages'
112
- RHC::ctl_app(libra_server, RHC::Config.default_proxy, opt['app'], opt['rhlogin'], password,
113
- 'system-messages', false, nil, nil)
114
- else
115
- ssh_ruby("#{app}-#{namespace}.#{rhc_domain}", app_uuid, remote_cmd)
116
- end
117
- rescue Interrupt
118
- puts
119
- puts "Terminating..."
120
- exit 0
121
- rescue SocketError => e
122
- puts
123
- puts "Could not connect: #{e.message}"
124
- puts
125
- puts "DEBUG: #{e.debug}" if debug
126
- puts "You can try to run this manually if you have ssh installed: "
127
- puts
128
- puts ssh_cmd
129
- puts
130
- exit 1
131
- end
132
- # this should never happen
133
- exit 1
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- args = ""
4
- ARGV.each do|a|
5
- if a.to_s.strip.length == 0; a = "'#{a}'" end
6
- args += " #{a}"
7
- end
8
-
9
- system("rhc-domain-info #{args} 2>&1")
10
- retcode = $?.exitstatus
11
-
12
- exit retcode
@@ -1,1205 +0,0 @@
1
- require 'rubygems' # Will eventually be removed when this file is deprecated
2
- require 'fileutils'
3
- require 'getoptlong'
4
- require 'net/http'
5
- require 'net/https'
6
- require 'net/ssh'
7
- require 'rhc/vendor/sshkey'
8
- require 'resolv'
9
- require 'uri'
10
- require 'highline/import'
11
- require 'rhc'
12
- require 'rhc/rest'
13
- require 'rhc/helpers'
14
- require 'rhc/config'
15
- require 'rhc/wizard'
16
- require 'rhc/tar_gz'
17
- require 'rhc/json'
18
-
19
- module RHC
20
-
21
- DEFAULT_MAX_LENGTH = 16
22
- APP_NAME_MAX_LENGTH = 32
23
- MAX_RETRIES = 7
24
- DEFAULT_DELAY = 2.0
25
- API = "1.1.3"
26
- PATTERN_VERSION=/\A\d+\.\d+\.\d+\z/
27
- @read_timeout = 120
28
- @connect_timeout = 20
29
- @mydebug = false
30
- @@api_version = "?.?.?"
31
-
32
- # reset lines
33
- # \r moves the cursor to the beginning of line
34
- # ANSI escape code to clear line from cursor to end of line
35
- # "\e" is an alternative to "\033"
36
- # cf. http://en.wikipedia.org/wiki/ANSI_escape_code
37
- CLEAR_LINE = "\r" + "\e[0K"
38
-
39
- DEBUG_INGORE_KEYS = {
40
- 'result' => nil,
41
- 'debug' => nil,
42
- 'exit_code' => nil,
43
- 'messages' => nil,
44
- 'data' => nil,
45
- 'api' => nil
46
- }
47
-
48
- def self.timeout(*vals)
49
- vals.each do |val|
50
- if val
51
- unless val.to_i > 0
52
- puts 'Timeout must be specified as a number greater than 0'
53
- exit 1
54
- end
55
- @read_timeout = [val.to_i, @read_timeout].max
56
- return @read_timeout
57
- end
58
- end
59
- end
60
-
61
- def self.connect_timeout(*vals)
62
- vals.each do |val|
63
- if val
64
- unless val.to_i > 0
65
- puts 'Timeout must be specified as a number greater than 0'
66
- exit 1
67
- end
68
- @connect_timeout = [val.to_i, @connect_timeout].max
69
- return @connect_timeout
70
- end
71
- end
72
- end
73
-
74
- def self.debug(bool)
75
- @mydebug = bool
76
- end
77
-
78
- def self.update_server_api_v(dict)
79
- if !dict['api'].nil? && (dict['api'] =~ PATTERN_VERSION)
80
- @@api_version = dict['api']
81
- end
82
- end
83
-
84
- def self.check_version
85
- if @@api_version =~ PATTERN_VERSION
86
- if API != @@api_version
87
- puts "\nNOTICE: Client API version (#{API}) does not match the server (#{@@api_version}).\nThough requests may succeed, you should consider updating your client tools.\n\n"
88
- end
89
- end
90
- end
91
-
92
- def self.delay(time, adj=DEFAULT_DELAY)
93
- (time*=adj).to_int
94
- end
95
-
96
- def self.json_encode(data)
97
- RHC::Json.encode(data)
98
- end
99
-
100
- def self.json_decode(json)
101
- RHC::Json.decode(json)
102
- end
103
-
104
- def self.generate_json(data)
105
- data['api'] = API
106
- json = json_encode(data)
107
- json
108
- end
109
-
110
- def self.get_cartridges_list(libra_server, net_http, cart_type="standalone", print_result=nil)
111
- puts "Obtaining list of cartridges (please excuse the delay)..."
112
- data = {'cart_type' => cart_type}
113
- if @mydebug
114
- data[:debug] = true
115
- end
116
- print_post_data(data)
117
- json_data = generate_json(data)
118
-
119
- url = URI.parse("https://#{libra_server}/broker/cartlist")
120
- response = http_post(net_http, url, json_data, "none")
121
-
122
- unless response.code == '200'
123
- print_response_err(response)
124
- return []
125
- end
126
- begin
127
- json_resp = json_decode(response.body)
128
- rescue RHC::JsonError
129
- exit 1
130
- end
131
- update_server_api_v(json_resp)
132
- if print_result
133
- print_response_success(json_resp)
134
- end
135
- begin
136
- carts = (json_decode(json_resp['data']))['carts']
137
- rescue RHC::JsonError
138
- exit 1
139
- end
140
- carts
141
- end
142
-
143
- def self.get_cartridge_listing(carts, sep, libra_server, net_http, cart_type="standalone", print_result=nil)
144
- carts = get_cartridges_list(libra_server, net_http, cart_type, print_result) if carts.nil?
145
- carts.join(sep)
146
- end
147
-
148
-
149
- # Invalid chars (") ($) (^) (<) (>) (|) (%) (/) (;) (:) (,) (\) (*) (=) (~)
150
- def self.check_rhlogin(rhlogin)
151
- if rhlogin
152
- if rhlogin =~ /["\$\^<>\|%\/;:,\\\*=~]/
153
- puts 'OpenShift login may not contain any of these characters: (\") ($) (^) (<) (>) (|) (%) (/) (;) (:) (,) (\) (*) (=) (~)'
154
- return false
155
- end
156
- else
157
- puts "OpenShift login is required"
158
- return false
159
- end
160
- true
161
- end
162
-
163
- def self.check_app(app)
164
- check_field(app, 'application', APP_NAME_MAX_LENGTH)
165
- end
166
-
167
- def self.check_namespace(namespace)
168
- check_field(namespace, 'namespace', DEFAULT_MAX_LENGTH)
169
- end
170
-
171
- def self.check_key(keyname)
172
- check_field(keyname, 'key name', DEFAULT_MAX_LENGTH, /[^0-9a-zA-Z]/,
173
- 'contains invalid characters! Only alpha-numeric characters allowed.')
174
- end
175
-
176
- def self.check_field(field, type, max=0, val_regex=/[^0-9a-zA-Z]/,
177
- regex_failed_error='contains non-alphanumeric characters!')
178
- if field
179
- if field =~ val_regex
180
- say "#{type} " + regex_failed_error
181
- return false
182
- end
183
- if max != 0 && field.length > max
184
- say "maximum #{type} size is #{max} characters"
185
- return false
186
- end
187
- else
188
- say "#{type} is required"
189
- return false
190
- end
191
- field
192
- end
193
-
194
- def self.print_post_data(h)
195
- if (@mydebug)
196
- puts 'Submitting form:'
197
- h.each do |k,v|
198
- if k.to_s != 'password'
199
- puts "#{k.to_s}: #{v.to_s}"
200
- else
201
- print 'password: '
202
- for i in (1..v.length)
203
- print 'X'
204
- end
205
- puts ''
206
- end
207
- end
208
- end
209
- end
210
-
211
- def self.get_user_info(libra_server, rhlogin, password, net_http, print_result, not_found_message=nil)
212
- data = {'rhlogin' => rhlogin}
213
- if @mydebug
214
- data[:debug] = true
215
- end
216
- print_post_data(data)
217
- json_data = generate_json(data)
218
-
219
- url = URI.parse("https://#{libra_server}/broker/userinfo")
220
- response = http_post(net_http, url, json_data, password)
221
-
222
- unless response.code == '200'
223
- if response.code == '404'
224
- if not_found_message
225
- puts not_found_message
226
- else
227
- puts "A user with rhlogin '#{rhlogin}' does not have a registered domain. Be sure to run 'rhc domain create' before using the other rhc tools."
228
- end
229
- exit 99
230
- elsif response.code == '401'
231
- puts "Invalid user credentials"
232
- exit 97
233
- else
234
- print_response_err(response)
235
- end
236
- exit 1
237
- end
238
- begin
239
- json_resp = json_decode(response.body)
240
- rescue RHC::JsonError
241
- exit 1
242
- end
243
- update_server_api_v(json_resp)
244
- if print_result
245
- print_response_success(json_resp)
246
- end
247
- begin
248
- user_info = json_decode(json_resp['data'].to_s)
249
- rescue RHC::JsonError
250
- exit 1
251
- end
252
- user_info
253
- end
254
-
255
- # Public: Get a list of ssh keys
256
- #
257
- # type - The String type RSA or DSS.
258
- # libra_server - The String DNS for the broker
259
- # rhlogin - The String login name
260
- # password - The String password for login
261
- # net_http - The NET::HTTP Object to use
262
- #
263
- # Examples
264
- #
265
- # RHC::get_ssh_keys('openshift.redhat.com',
266
- # 'mylogin@example.com',
267
- # 'mypassword',
268
- # RHC::Config.default_proxy)
269
- # # => { "ssh_type" => "ssh-rsa",
270
- # "ssh_key" => "AAAAB3NzaC1yc2EAAAADAQAB....",
271
- # "fingerprint" => "ea:08:e3:c7:e3:c3:8e:6a:66:34:65:e4:56:f4:3e:ff"}
272
- #
273
- # FIXME! Exits on failure! Should return something instead
274
- #
275
- # Returns Hash on success or exits on failure
276
- def self.get_ssh_keys(libra_server, rhlogin, password, net_http)
277
- data = {'rhlogin' => rhlogin, 'action' => 'list-keys'}
278
- if @mydebug
279
- data[:debug] = true
280
- end
281
- print_post_data(data)
282
- json_data = generate_json(data)
283
-
284
- url = URI.parse("https://#{libra_server}/broker/ssh_keys")
285
- response = http_post(net_http, url, json_data, password)
286
-
287
- unless response.code == '200'
288
- if response.code == '401'
289
- puts "Invalid user credentials"
290
- exit 97
291
- else
292
- print_response_err(response)
293
- end
294
- exit 1
295
- end
296
- begin
297
- json_resp = json_decode(response.body)
298
- rescue RHC::JsonError
299
- exit 1
300
- end
301
- update_server_api_v(json_resp)
302
- begin
303
- ssh_keys = (json_decode(json_resp['data'].to_s))
304
- rescue RHC::JsonError
305
- exit 1
306
- end
307
-
308
- # Inject public fingerprint into key.
309
- begin
310
- if ssh_keys['ssh_type'].nil? or ssh_keys['ssh_type'].empty?
311
- ssh_keys['fingerprint'] = nil
312
- else
313
- ssh_keys['fingerprint'] = \
314
- Net::SSH::KeyFactory.load_data_public_key(
315
- "#{ssh_keys['ssh_type']} #{ssh_keys['ssh_key']}").fingerprint
316
- end
317
- rescue NoMethodError
318
- #older net/ssh (mac for example)
319
- tempfile = `mktemp /tmp/openshift.XXXXXXXX`
320
- `echo "#{ssh_keys['ssh_type']} #{ssh_keys['ssh_key']}" > #{tempfile}`
321
- ssh_keys['fingerprint'] = `ssh-keygen -lf #{tempfile}`.split(' ')[1]
322
- rescue Net::SSH::Exception, NotImplementedError, OpenSSL::PKey::PKeyError
323
- # Could be a new unsupported key type or invalid data on the server
324
- ssh_keys['fingerprint'] = 'Key type is not recognized. Please check this key is valid.'
325
- end
326
-
327
- if ssh_keys['keys'] && ssh_keys['keys'].kind_of?(Hash)
328
- ssh_keys['keys'].each do |name, keyval|
329
- type = keyval['type']
330
- key = keyval['key']
331
- begin
332
- ssh_keys['keys'][name]['fingerprint'] = \
333
- Net::SSH::KeyFactory.load_data_public_key(
334
- "#{type} #{key}").fingerprint
335
- rescue NoMethodError
336
- #older net/ssh (mac for example)
337
- tempfile = `mktemp /tmp/openshift.XXXXXXXX`
338
- `echo "#{type} #{key}" > #{tempfile}`
339
- ssh_keys['keys'][name]['fingerprint'] = `ssh-keygen -lf #{tempfile}`.split(' ')[1]
340
- rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
341
- # Could be a new unsupported key type or invalid data on the server
342
- ssh_keys['keys'][name]['fingerprint'] = 'Key type is not recognized. Please check this key is valid.'
343
- end
344
- end
345
- end
346
- ssh_keys
347
- end
348
-
349
- def self.get_password
350
- password = nil
351
- begin
352
- password = ask_password
353
- rescue Interrupt
354
- puts "\n"
355
- exit 1
356
- end
357
- puts "\n"
358
- password
359
- end
360
-
361
- def self.http_post(http, url, json_data, password)
362
- req = http::Post.new(url.path)
363
-
364
- puts "Contacting #{url.scheme}://#{url.host}" if @mydebug
365
- req.set_form_data({'json_data' => json_data, 'password' => password})
366
- req['User-Agent'] = RHC::Helpers.user_agent
367
-
368
- http = http.new(url.host, url.port)
369
- http.open_timeout = @connect_timeout
370
- http.read_timeout = @read_timeout
371
- if url.scheme == "https"
372
- http.use_ssl = true
373
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
374
- end
375
- begin
376
- response = http.start {|http| http.request(req)}
377
- if response.code == '404' && response.content_type == 'text/html'
378
- # TODO probably want to remove this at some point
379
- puts "!!!! WARNING !!!! WARNING !!!! WARNING !!!!"
380
- puts "RHCloud server not found. You might want to try updating your rhc client tools."
381
- exit 218
382
- end
383
- response
384
- rescue Exception => e
385
- puts "There was a problem communicating with the server. Response message: #{e.message}"
386
- puts "If you were disconnected it is possible the operation finished without being able to report success."
387
- puts "You can use 'rhc domain show' and 'rhc app show --state' to learn about the status of your user and application(s)."
388
- exit 219
389
- end
390
- end
391
-
392
- def self.print_response_err(response)
393
- puts "Problem reported from server. Response code was #{response.code}."
394
- if (!@mydebug)
395
- puts "Re-run with -d for more information."
396
- end
397
- exit_code = 1
398
- if response.class.inspect == "Struct::FakeResponse"
399
- print_response_message(response.body)
400
- elsif response.content_type == 'application/json'
401
- begin
402
- json_resp = json_decode(response.body)
403
- exit_code = print_json_body(json_resp)
404
- rescue RHC::JsonError
405
- exit_code = 1
406
- end
407
- elsif @mydebug
408
- puts "HTTP response from server is #{response.body}"
409
- end
410
- exit exit_code.nil? ? 666 : exit_code
411
- end
412
-
413
- def self.print_response_messages(json_resp)
414
- messages = json_resp['messages']
415
- print_response_message(messages)
416
- end
417
-
418
- def self.print_response_message(message)
419
- if (message && !message.empty?)
420
- puts ''
421
- puts 'MESSAGES:'
422
- puts message
423
- puts ''
424
- end
425
- end
426
-
427
- def self.print_response_success(json_resp, print_result=false)
428
- if @mydebug
429
- print "Response from server:"
430
- $stdout.flush
431
- print_json_body(json_resp, print_result)
432
- elsif print_result
433
- print_json_body(json_resp)
434
- else
435
- print_response_messages(json_resp)
436
- end
437
- end
438
-
439
- def self.print_json_body(json_resp, print_result=true)
440
- print_response_messages(json_resp)
441
- exit_code = json_resp['exit_code']
442
- if @mydebug
443
- if json_resp['debug']
444
- puts ''
445
- puts 'DEBUG:'
446
- puts json_resp['debug']
447
- puts ''
448
- puts "Exit Code: #{exit_code}"
449
- if (json_resp.length > 3)
450
- json_resp.each do |k,v|
451
- if !DEBUG_INGORE_KEYS.has_key?(k)
452
- puts "#{k.to_s}: #{v.to_s}"
453
- end
454
- end
455
- end
456
- end
457
- if json_resp['api']
458
- puts "API version: #{json_resp['api']}"
459
- end
460
- end
461
- if print_result && json_resp['result']
462
- puts ''
463
- puts 'RESULT:'
464
- puts json_resp['result']
465
- puts ''
466
- end
467
- exit_code
468
- end
469
-
470
- #
471
- # Check if host exists
472
- #
473
- def self.hostexist?(host)
474
- RHC::Helpers.host_exists?(host)
475
- end
476
-
477
- def self.create_app(libra_server, net_http, user_info, app_name, app_type, rhlogin, password, repo_dir=nil, no_dns=false, no_git=false, is_embedded_jenkins=false, gear_size='small',scale=false)
478
-
479
- # Need to have a fake HTTPResponse object for passing to print_reponse_err
480
- # May already be initialized if called from another piece of code
481
- # FIXME: remove this requirement when refactoring rhc
482
- begin
483
- Struct::FakeResponse
484
- rescue NameError
485
- Struct.new('FakeResponse',:body,:code,:content_type)
486
- end
487
-
488
- domains = user_info['user_info']['domains']
489
- if domains.empty?
490
- emessage = "Please create a domain with 'rhc domain create -n <namespace>' before creating applications."
491
- print_response_err(Struct::FakeResponse.new(emessage,403))
492
- end
493
- namespace = domains[0]['namespace']
494
- puts "Creating application: #{app_name} in #{namespace}"
495
- data = {:cartridge => app_type,
496
- :action => 'configure',
497
- :node_profile => gear_size,
498
- :app_name => app_name,
499
- :rhlogin => rhlogin
500
- }
501
- if @mydebug
502
- data[:debug] = true
503
- end
504
-
505
- # Need to use the new REST API for scaling apps
506
- # We'll need to then get the new application using the existing
507
- # API in order to access the rest of the logic in this function
508
- if scale
509
- end_point = "https://#{libra_server}/broker/rest/api"
510
- client = RHC::Rest::Client.new(end_point, rhlogin, password)
511
-
512
- domain = client.find_domain(user_info['user_info']['domains'][0]['namespace'])
513
-
514
- namespace = domain.id
515
- # Catch errors
516
- begin
517
- application = domain.add_application(app_name,{:cartridge => app_type, :scale => true, :gear_profile => gear_size})
518
-
519
- # Variables that are needed for the rest of the function
520
- app_uuid = application.uuid
521
- result = "Successfully created application: #{app_name}"
522
-
523
- # health check path now returned by the API
524
- health_check_path = application.health_check_path
525
-
526
- puts "DEBUG: '#{app_name}' creation returned success." if @mydebug
527
- rescue RHC::Rest::ConnectionException, RHC::Rest::ResourceAccessException => e
528
- print_response_err(Struct::FakeResponse.new(e.message,e.code))
529
- rescue RHC::Rest::ValidationException => e
530
- validation_error_code = (e.code.nil?) ? 406 : e.code
531
- print_response_err(Struct::FakeResponse.new(e.message, validation_error_code))
532
- rescue RHC::Rest::ServerErrorException => e
533
- error_code = (e.code.nil?) ? 500 : e.code
534
- print_response_err(Struct::FakeResponse.new(e.message, error_code))
535
- end
536
- else
537
- json_data = generate_json(data)
538
-
539
- url = URI.parse("https://#{libra_server}/broker/cartridge")
540
- response = http_post(net_http, url, json_data, password)
541
-
542
- if response.code == '200'
543
- json_resp = json_decode(response.body)
544
- print_response_success(json_resp)
545
- json_data = json_decode(json_resp['data'])
546
- health_check_path = json_data['health_check_path']
547
- app_uuid = json_data['uuid']
548
- result = json_resp['result']
549
- puts "DEBUG: '#{app_name}' creation returned success." if @mydebug
550
- else
551
- print_response_err(response)
552
- end
553
- end
554
-
555
- #
556
- # At this point, we need to register a handler to guarantee app
557
- # cleanup on any exceptions or calls to exit
558
- #
559
- at_exit do
560
- unless $!.nil? || $!.is_a?(SystemExit) && $!.success?
561
- puts "Cleaning up application"
562
- destroy_app(libra_server, net_http, app_name, rhlogin, password)
563
- end
564
- end
565
-
566
- rhc_domain = user_info['user_info']['rhc_domain']
567
-
568
- fqdn = "#{app_name}-#{namespace}.#{rhc_domain}"
569
-
570
- loop = 0
571
- #
572
- # Confirm that the host exists in DNS
573
- #
574
- unless no_dns
575
- puts "Now your new domain name is being propagated worldwide (this might take a minute)..."
576
-
577
- # Allow DNS to propogate
578
- sleep 15
579
-
580
- # Now start checking for DNS
581
- sleep_time = 2
582
- while loop < MAX_RETRIES && !hostexist?(fqdn)
583
- sleep sleep_time
584
- loop+=1
585
- print CLEAR_LINE + " retry # #{loop} - Waiting for DNS: #{fqdn}"
586
- $stdout.flush
587
- sleep_time = delay(sleep_time)
588
- end
589
- end
590
-
591
- # if we have executed print statements, then move to the next line
592
- if loop > 0
593
- puts
594
- end
595
-
596
- # construct the Git URL
597
- git_url = "ssh://#{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain}/~/git/#{app_name}.git/"
598
-
599
- # If the hostname couldn't be resolved, print out the git URL
600
- # and exit cleanly. This will help solve issues where DNS times
601
- # out in APAC, etc on resolution.
602
- if loop >= MAX_RETRIES
603
- puts <<WARNING
604
-
605
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
606
- WARNING: We were unable to lookup your hostname (#{fqdn})
607
- in a reasonable amount of time. This can happen periodically and will just
608
- take an extra minute or two to propagate depending on where you are in the
609
- world. Once you are able to access your application in a browser, you can then
610
- clone your git repository.
611
-
612
- Application URL: http://#{fqdn}
613
-
614
- Git Repository URL: #{git_url}
615
-
616
- Git Clone command:
617
- git clone #{git_url} #{repo_dir}
618
-
619
- If you can't get your application '#{app_name}' running in the browser, you can
620
- also try destroying and recreating the application as well using:
621
-
622
- rhc app destroy -a #{app_name} -l #{rhlogin}
623
-
624
- If this doesn't work for you, let us know in the forums or in IRC and we'll
625
- make sure to get you up and running.
626
-
627
- Forums: https://openshift.redhat.com/community/forums/openshift
628
-
629
- IRC: #openshift (on Freenode)
630
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
631
-
632
- WARNING
633
- exit 0
634
- end
635
-
636
- #
637
- # Pull new repo locally
638
- #
639
-
640
- unless no_git
641
- puts "Pulling new repo down" if @mydebug
642
-
643
- quiet = (@mydebug ? ' ' : '--quiet ')
644
- puts "git clone #{quiet}#{git_url} #{repo_dir}" if @mydebug
645
- git_clone = %x[git clone #{quiet} #{git_url} #{repo_dir} 2>&1]
646
- if $?.exitstatus != 0
647
-
648
- if RHC::Helpers.windows?
649
-
650
- `nslookup #{app_name}-#{namespace}.#{rhc_domain}`
651
- windows_nslookup = $?.exitstatus == 0
652
- `ping #{app_name}-#{namespace}.#{rhc_domain} -n 2`
653
- windows_ping = $?.exitstatus == 0
654
-
655
- if windows_nslookup and !windows_ping # this is related to BZ #826769
656
- puts <<WINSOCKISSUE
657
-
658
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
659
- WARNING: We were unable to lookup your hostname (#{fqdn})
660
- in a reasonable amount of time. This can happen periodically and will just
661
- take up to 10 extra minutes to propagate depending on where you are in the
662
- world. This may also be related to an issue with Winsock on Windows [1][2].
663
- We recommend you wait a few minutes then clone your git repository manually.
664
-
665
- Git Clone command:
666
- git clone #{git_url} #{repo_dir}
667
-
668
- [1] http://support.microsoft.com/kb/299357
669
- [2] http://support.microsoft.com/kb/811259
670
-
671
- If this doesn't work for you, let us know in the forums or in IRC and we'll
672
- make sure to get you up and running.
673
-
674
- Forums: https://openshift.redhat.com/community/forums/openshift
675
-
676
- IRC: #openshift (on Freenode)
677
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
678
-
679
- WINSOCKISSUE
680
- exit 0
681
- end
682
- end
683
- puts "Error in git clone"
684
- puts git_clone
685
- exit 216
686
- end
687
- else
688
- if is_embedded_jenkins
689
- # if this is a jenkins client application to be embedded,
690
- # then print this message only in debug mode
691
- if @mydebug
692
- puts "
693
- Note: There is a git repo for your Jenkins application '#{app_name}'
694
- but it isn't being downloaded as part of this process. In most cases
695
- it isn't needed but you can always clone it later.
696
-
697
- "
698
- end
699
- else
700
- puts <<IMPORTANT
701
-
702
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
703
- IMPORTANT: Since the -n flag was specified, no local repo has been created.
704
- This means you can't make changes to your published application until after
705
- you clone the repo yourself. See the git url below for more information.
706
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
707
-
708
- IMPORTANT
709
- end
710
- end
711
-
712
- #
713
- # At this point, we need to register a handler to guarantee git
714
- # repo cleanup on any exceptions or calls to exit
715
- #
716
- unless no_git
717
- at_exit do
718
- unless $!.nil? || $!.is_a?(SystemExit) && $!.success?
719
- puts "Cleaning up git repo"
720
- FileUtils.rm_rf repo_dir
721
- end
722
- end
723
- end
724
- return {:app_name => app_name,
725
- :fqdn => fqdn,
726
- :health_check_path => health_check_path,
727
- :git_url => git_url,
728
- :repo_dir => repo_dir,
729
- :result => result
730
- }
731
- end
732
-
733
- #
734
- # An application is considered available if the health check URL unambiguously returns a 1 or 0.
735
- # Otherwise, if the root URL for the app successfully returns content it is also considered
736
- # successful. In the future, applications that do not expose a public web interface will need
737
- # a more advanced check mechanism, or the check should not prevent creation.
738
- #
739
- def self.check_app_available(net_http, app_name, fqdn, health_check_path, result, git_url, repo_dir, no_git)
740
-
741
- available = MAX_RETRIES.times.any? do |i|
742
- sleep i * DEFAULT_DELAY
743
-
744
- puts "Checking if the application is available ##{i+1}"
745
- if health_check_path and !health_check_path.empty?
746
- value = open("http://#{fqdn}/#{health_check_path}").read[0,1] rescue nil
747
- # TODO: I should be typed exception ApplicationHealthFailure
748
- raise "ERROR: The application was unable to start. Please report this issue via the forums or IRC or file a bug through our public bug tracker." if value == '0'
749
- next true if value == '1'
750
- end
751
- open("http://#{fqdn}") rescue nil
752
- end
753
-
754
- if available
755
- puts "Application #{app_name} is available at: http://#{fqdn}/"
756
- puts " Git URL: #{git_url}"
757
-
758
- if @mydebug
759
- unless no_git
760
- puts "To make changes to '#{app_name}', commit to #{repo_dir}/."
761
- else
762
- puts <<LOOKSGOOD
763
- To make changes to '#{app_name}', you must first clone it with:
764
- git clone #{git_url}
765
-
766
- LOOKSGOOD
767
- puts "Then run 'git push' to update your OpenShift space."
768
- end
769
- end
770
- if result && !result.empty?
771
- puts "#{result}"
772
- end
773
- true
774
- else
775
- puts "Application is not available"
776
- false
777
- end
778
- rescue StandardError => e
779
- puts e
780
- false
781
- end
782
-
783
- def self.destroy_app(libra_server, net_http, app_name, rhlogin, password)
784
- json_data = generate_json(
785
- {:action => 'deconfigure',
786
- :app_name => app_name,
787
- :rhlogin => rhlogin
788
- })
789
- url = URI.parse("https://#{libra_server}/broker/cartridge")
790
- http_post(net_http, url, json_data, password)
791
- end
792
-
793
- def self.ctl_app(libra_server, net_http, app_name, rhlogin, password, action, embedded=false, framework=nil, server_alias=nil, print_result=true)
794
- data = {:action => action,
795
- :app_name => app_name,
796
- :rhlogin => rhlogin
797
- }
798
-
799
- data[:server_alias] = server_alias if server_alias
800
- if framework
801
- data[:cartridge] = framework
802
- end
803
-
804
- if @mydebug
805
- data[:debug] = true
806
- end
807
-
808
- json_data = generate_json(data)
809
-
810
- url = nil
811
- if embedded
812
- url = URI.parse("https://#{libra_server}/broker/embed_cartridge")
813
- else
814
- url = URI.parse("https://#{libra_server}/broker/cartridge")
815
- end
816
- response = http_post(net_http, url, json_data, password)
817
-
818
- if response.code == '200'
819
- json_resp = json_decode(response.body)
820
- print_response_success(json_resp, print_result || @mydebug)
821
- else
822
- print_response_err(response)
823
- end
824
- json_decode(response.body)
825
- end
826
-
827
- def self.snapshot_create(rhc_domain, namespace, app_name, app_uuid, filename, debug=false)
828
-
829
- ssh_cmd = "ssh #{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain} 'snapshot' > #{filename}"
830
- puts "Pulling down a snapshot to #{filename}..."
831
- puts ssh_cmd if debug
832
- puts
833
-
834
- begin
835
-
836
- if ! RHC::Helpers.windows?
837
- output = `#{ssh_cmd}`
838
- if $?.exitstatus != 0
839
- puts output
840
- puts "Error in trying to save snapshot. You can try to save manually by running:"
841
- puts
842
- puts ssh_cmd
843
- puts
844
- return 1
845
- end
846
- else
847
- Net::SSH.start("#{app_name}-#{namespace}.#{rhc_domain}", app_uuid) do |ssh|
848
- File.open(filename, 'wb') do |file|
849
- ssh.exec! "snapshot" do |channel, stream, data|
850
- if stream == :stdout
851
- file.write(data)
852
- else
853
- puts data if debug
854
- end
855
- end
856
- end
857
- end
858
- end
859
- rescue Exception => e
860
- puts e.backtrace if debug
861
- puts "Error in trying to save snapshot. You can try to save manually by running:"
862
- puts
863
- puts ssh_cmd
864
- puts
865
- return 1
866
- end
867
- true
868
- end
869
-
870
- def self.snapshot_restore(rhc_domain, namespace, app_name, app_uuid, filename, debug=false)
871
- if File.exists? filename
872
-
873
- include_git = RHC::Helpers.windows? ? false : RHC::TarGz.contains(filename, './*/git')
874
-
875
- ssh_cmd = "cat #{filename} | ssh #{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain} 'restore#{include_git ? ' INCLUDE_GIT' : ''}'"
876
- puts "Restoring from snapshot #{filename}..."
877
- puts ssh_cmd if debug
878
- puts
879
-
880
- begin
881
- if ! RHC::Helpers.windows?
882
- output = `#{ssh_cmd}`
883
- if $?.exitstatus != 0
884
- puts output
885
- puts "Error in trying to restore snapshot. You can try to restore manually by running:"
886
- puts
887
- puts ssh_cmd
888
- puts
889
- return 1
890
- end
891
- else
892
- ssh = Net::SSH.start("#{app_name}-#{namespace}.#{rhc_domain}", app_uuid)
893
- ssh.open_channel do |channel|
894
- channel.exec("restore#{include_git ? ' INCLUDE_GIT' : ''}") do |ch, success|
895
- channel.on_data do |ch, data|
896
- puts data
897
- end
898
- channel.on_extended_data do |ch, type, data|
899
- puts data
900
- end
901
- channel.on_close do |ch|
902
- puts "Terminating..."
903
- end
904
- File.open(filename, 'rb') do |file|
905
- file.chunk(1024) do |chunk|
906
- channel.send_data chunk
907
- end
908
- end
909
- channel.eof!
910
- end
911
- end
912
- ssh.loop
913
- end
914
- rescue Exception => e
915
- puts e.backtrace
916
- puts "Error in trying to restore snapshot. You can try to restore manually by running:"
917
- puts
918
- puts ssh_cmd
919
- puts
920
- return 1
921
- end
922
-
923
- else
924
- puts "Archive not found: #{filename}"
925
- return 255
926
- end
927
- true
928
- end
929
-
930
- end
931
-
932
- # provide a hook for performing actions before rhc-* commands exit
933
- at_exit {
934
- # ensure client tools are up to date
935
- RHC::check_version
936
- }
937
-
938
- #
939
- # Config paths... /etc/openshift/express.conf or $GEM/conf/express.conf -> ~/.openshift/express.conf
940
- #
941
- # semi-private: Just in case we rename again :)
942
- @opts_config_path = nil
943
- @conf_name = 'express.conf'
944
- _linux_cfg = '/etc/openshift/' + @conf_name
945
- _gem_cfg = File.join(File.expand_path(File.dirname(__FILE__) + "/../conf"), @conf_name)
946
- @home_conf = File.expand_path('~/.openshift')
947
- @local_config_path = File.join(@home_conf, @conf_name)
948
- @config_path = File.exists?(_linux_cfg) ? _linux_cfg : _gem_cfg
949
- @home_dir=File.expand_path("~")
950
-
951
- local_config_path = File.expand_path(@local_config_path)
952
-
953
- #
954
- # Check for proxy environment
955
- #
956
-
957
- @http = RHC::Config.default_proxy
958
-
959
- def config_path
960
- return @opts_config_path ? @opts_config_path : @local_config_path
961
- end
962
-
963
- def config
964
- return @opts_config ? @opts_config : @local_config
965
- end
966
-
967
- def ask_password
968
- return ask("Password: ") { |q|
969
- q.echo = '*'
970
- q.whitespace = :chomp
971
- }
972
- end
973
-
974
- def kfile_not_found
975
- puts <<KFILE_NOT_FOUND
976
- Your SSH keys are created either by running ssh-keygen (password optional)
977
- or by having the 'rhc domain create' command do it for you. If you created
978
- them on your own (or want to use an existing keypair), be sure to paste
979
- your public key into the express console at http://www.openshift.com.
980
- The client tools use the value of 'ssh_key_file' in express.conf to find
981
- your key followed by the defaults of id_rsa[.pub] and then
982
- id_rsa[.pub].
983
- KFILE_NOT_FOUND
984
-
985
- #exit 212
986
- end
987
-
988
- def get_kfile(check_exists=true)
989
- ssh_key_file = get_var('ssh_key_file')
990
- if ssh_key_file
991
- if (File.basename(ssh_key_file) == ssh_key_file)
992
- kfile = "#{ENV['HOME']}/.ssh/#{ssh_key_file}"
993
- else
994
- kfile = File.expand_path(ssh_key_file)
995
- end
996
- else
997
- kfile = "#{ENV['HOME']}/.ssh/id_rsa"
998
- end
999
- if check_exists && !File.exists?(kfile)
1000
- if ssh_key_file
1001
- puts "WARNING: Unable to find '#{kfile}' referenced in express.conf."
1002
- kfile_not_found
1003
- else
1004
- kfile = "#{ENV['HOME']}/.ssh/id_rsa"
1005
- if !File.exists?(kfile)
1006
- puts "WARNING: Unable to find ssh key file."
1007
- kfile_not_found
1008
- end
1009
- end
1010
- end
1011
- return kfile
1012
- end
1013
-
1014
- def get_kpfile(kfile, check_exists=true)
1015
- kpfile = kfile + '.pub'
1016
- if check_exists && !File.exists?(kpfile)
1017
- puts "WARNING: Unable to find '#{kpfile}'"
1018
- kfile_not_found
1019
- end
1020
- return kpfile
1021
- end
1022
-
1023
- # Add a new namespace to configs
1024
- def self.add_rhlogin_config(rhlogin, uuid)
1025
- config_path = RHC::Config.local_config_path
1026
- f = open(File.expand_path(config_path), 'a')
1027
- unless RHC::Config['default_rhlogin']
1028
- f.puts("# Default rhlogin to use if none is specified")
1029
- f.puts("default_rhlogin=#{rhlogin}")
1030
- f.puts("")
1031
- end
1032
- f.close
1033
- end
1034
-
1035
- # Public: Handle response message when updating keys
1036
- #
1037
- # url - The Object URI::HTTPS
1038
- # data - The Hash representation of the data response
1039
- # password - The String password for the user
1040
- #
1041
- # Examples
1042
- #
1043
- # handle_key_mgmt_response(
1044
- # URI.parse('https://openshift.redhat.com/broker/ssh_keys'),
1045
- # {
1046
- # :rhlogin=>"rhnlogin@example.com",
1047
- # :key_name=>"default",
1048
- # :action=>"update-key",
1049
- # :ssh=>"AAAAB3NzaC1yc2EAAAADAQABAAAAgQCrXG5c.....",
1050
- # :key_type=>"ssh-rsa"},
1051
- # 'mypass')
1052
- # # => nil
1053
- #
1054
- # Returns nil on Success and RHC::http object on failure
1055
- def handle_key_mgmt_response(url, data, password)
1056
- RHC::print_post_data(data)
1057
- json_data = RHC::generate_json(data)
1058
-
1059
- response = RHC::http_post(RHC::Config.default_proxy, url, json_data, password)
1060
-
1061
- if response.code == '200'
1062
- begin
1063
- json_resp = RHC::json_decode(response.body)
1064
- RHC::update_server_api_v(json_resp)
1065
- RHC::print_response_success(json_resp)
1066
- puts "Success"
1067
- return
1068
- rescue RHC::JsonError
1069
- RHC::print_response_err(response)
1070
- end
1071
- else
1072
- RHC::print_response_err(response)
1073
- end
1074
- puts "Failure"
1075
- return response
1076
- end
1077
-
1078
- # Public: Add or upload an ssh key
1079
- #
1080
- # type - The String type RSA or DSS.
1081
- # command - The String value 'add' or 'update'
1082
- # identifier - The String value to identify the key
1083
- # pub_key_file_path - The String file path of the public key
1084
- # rhlogin - The String login to the broker
1085
- # password- The String password for the user
1086
- #
1087
- # Examples
1088
- #
1089
- # generate_ssh_key_ruby('add', 'newkeyname', '~/.ssh/id_rsa',
1090
- # 'mylogin', 'mypass')
1091
- # # => /home/user/.ssh/id_rsa.pub
1092
- #
1093
- # Returns nil on success or HTTP object on failure
1094
- def add_or_update_key(command, identifier, pub_key_file_path, rhlogin, password)
1095
-
1096
- # Read user public ssh key
1097
- if pub_key_file_path
1098
- if File.readable?(pub_key_file_path)
1099
- begin
1100
- ssh_keyfile_contents = File.open(pub_key_file_path).gets.chomp.split(' ')
1101
- ssh_key = ssh_keyfile_contents[1]
1102
- ssh_key_type = ssh_keyfile_contents[0]
1103
- rescue Exception => e
1104
- puts "Invalid public keyfile format! Please specify a valid user public keyfile."
1105
- exit 1
1106
- end
1107
- else
1108
- puts "Unable to read user public keyfile #{pub_key_file_path}"
1109
- exit 1
1110
- end
1111
- else # create key
1112
- key_name = identifier
1113
- puts "Generating ssh key pair for user '#{key_name}' in the dir '#{Dir.pwd}/'"
1114
- # REMOVED in favor of generate_ssh_key_ruby: system("ssh-keygen -t rsa -f '#{key_name}'")
1115
- ssh_pub_key_file = generate_ssh_key_ruby()
1116
- ssh_keyfile_contents = File.open(ssh_pub_key_file).gets.chomp.split(' ')
1117
- ssh_key = ssh_keyfile_contents[1]
1118
- ssh_key_type = ssh_keyfile_contents[0]
1119
- end
1120
-
1121
- data = {}
1122
- data[:rhlogin] = rhlogin
1123
- data[:key_name] = identifier
1124
- data[:ssh] = ssh_key
1125
- data[:action] = 'add-key'
1126
- data[:key_type] = ssh_key_type
1127
-
1128
- if command == 'add'
1129
- data[:action] = 'add-key'
1130
- elsif command == 'update'
1131
- data[:action] = 'update-key'
1132
- end
1133
-
1134
- url = URI.parse("https://#{RHC::Config['libra_server']}/broker/ssh_keys")
1135
- handle_key_mgmt_response(url, data, password)
1136
- end
1137
-
1138
-
1139
- # Public: Generate an SSH key and store it in ~/.ssh/id_rsa
1140
- #
1141
- # type - The String type RSA or DSS.
1142
- # bits - The Integer value for number of bits.
1143
- # comment - The String comment for the key
1144
- #
1145
- # Examples
1146
- #
1147
- # generate_ssh_key_ruby()
1148
- # # => /home/user/.ssh/id_rsa.pub
1149
- #
1150
- # Returns nil on failure or public key location as a String on success
1151
- def generate_ssh_key_ruby(type="RSA", bits = 1024, comment = "OpenShift-Key")
1152
- key = RHC::Vendor::SSHKey.generate(:type => type,
1153
- :bits => bits,
1154
- :comment => comment)
1155
- ssh_dir = "#{RHC::Config.home_dir}/.ssh"
1156
- if File.exists?("#{ssh_dir}/id_rsa")
1157
- puts "SSH key already exists: #{ssh_dir}/id_rsa. Reusing..."
1158
- return nil
1159
- else
1160
- unless File.exists?(ssh_dir)
1161
- FileUtils.mkdir_p(ssh_dir)
1162
- File.chmod(0700, ssh_dir)
1163
- end
1164
- File.open("#{ssh_dir}/id_rsa", 'w') {|f| f.write(key.private_key)}
1165
- File.chmod(0600, "#{ssh_dir}/id_rsa")
1166
- File.open("#{ssh_dir}/id_rsa.pub", 'w') {|f| f.write(key.ssh_public_key)}
1167
- end
1168
- "#{ssh_dir}/id_rsa.pub"
1169
- end
1170
-
1171
- # Public: Run ssh command on remote host
1172
- #
1173
- # host - The String of the remote hostname to ssh to.
1174
- # username - The String username of the remote user to ssh as.
1175
- # command - The String command to run on the remote host.
1176
- #
1177
- # Examples
1178
- #
1179
- # ssh_ruby('myapp-t.rhcloud.com',
1180
- # '109745632b514e9590aa802ec015b074',
1181
- # 'rhcsh tail -f $OPENSHIFT_LOG_DIR/*"')
1182
- # # => true
1183
- #
1184
- # Returns true on success
1185
- def ssh_ruby(host, username, command)
1186
- Net::SSH.start(host, username) do |session|
1187
- session.open_channel do |channel|
1188
- channel.request_pty do |ch, success|
1189
- puts "pty could not be obtained" unless success
1190
- end
1191
-
1192
- channel.on_data do |ch, data|
1193
- #puts "[#{file}] -> #{data}"
1194
- puts data
1195
- end
1196
- channel.exec command
1197
- end
1198
- session.loop
1199
- end
1200
- end
1201
-
1202
- # Public: legacy convinience function for getting config keys
1203
- def get_var(key)
1204
- RHC::Config[key]
1205
- end