Module: RHC::SSHHelpers
- Included in:
- Commands::App, Commands::Snapshot, Commands::Ssh, Commands::Sshkey, Commands::Tail, DeploymentHelpers, Wizard
- Defined in:
- lib/rhc/ssh_helpers.rb
Defined Under Namespace
Classes: MultipleGearTask
Instance Method Summary collapse
-
#check_ssh_executable!(path) ⇒ Object
return supplied ssh executable, if valid (executable, searches $PATH).
- #exe?(executable) ⇒ Boolean
- #fingerprint_for_default_key ⇒ Object
- #fingerprint_for_local_key(key) ⇒ Object
-
#generate_ssh_key_ruby(type = "RSA", bits = 2048, comment = "ProtonBox-Key") ⇒ Object
Public: Generate an SSH key and store it in ~/.ssh/id_rsa.
-
#has_ssh? ⇒ Boolean
return whether or not SSH is installed.
- #run_on_gears(command, gears, opts = {}, &block) ⇒ Object
- #ssh_command_for_op(operation) ⇒ Object
-
#ssh_key_triple_for(key) ⇒ Object
for an SSH public key specified by ‘key’, return a triple [type, content, comment] which is basically the space-separated list of the SSH public key content.
- #ssh_key_triple_for_default_key ⇒ Object
-
#ssh_keygen_fallback(path) ⇒ Object
For Net::SSH versions (< 2.0.11) that does not have Net::SSH::KeyFactory.load_public_key, we drop to shell to get the key’s fingerprint.
-
#ssh_ruby(host, username, command, compression = false, request_pty = false, &block) ⇒ Object
Public: Run ssh command on remote host.
-
#ssh_send_file_ruby(host, username, command, filename) ⇒ Object
Public: Run ssh command on remote host and pipe the specified file contents to the command input.
-
#ssh_send_url_ruby(host, username, command, content_url) ⇒ Object
Public: Run ssh command on remote host and pipe the specified url contents to the command input.
-
#ssh_version ⇒ Object
check the version of SSH that is installed.
- #table_from_gears(command, groups, opts = {}, &block) ⇒ Object
Instance Method Details
#check_ssh_executable!(path) ⇒ Object
return supplied ssh executable, if valid (executable, searches $PATH). if none was supplied, return installed ssh, if any.
356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/rhc/ssh_helpers.rb', line 356 def check_ssh_executable!(path) if not path raise RHC::InvalidSSHExecutableException.new("No system SSH available. Please use the --ssh option to specify the path to your SSH executable, or install SSH.") unless has_ssh? 'ssh' else bin_path = path.split(' ').first raise RHC::InvalidSSHExecutableException.new("SSH executable '#{bin_path}' does not exist.") unless File.exist?(bin_path) or exe?(bin_path) raise RHC::InvalidSSHExecutableException.new("SSH executable '#{bin_path}' is not executable.") unless File.executable?(bin_path) or exe?(bin_path) path end end |
#exe?(executable) ⇒ Boolean
286 287 288 289 290 |
# File 'lib/rhc/ssh_helpers.rb', line 286 def exe?(executable) ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory| File.executable?(File.join(directory, executable.to_s)) end end |
#fingerprint_for_default_key ⇒ Object
317 318 319 |
# File 'lib/rhc/ssh_helpers.rb', line 317 def fingerprint_for_default_key fingerprint_for_local_key(RHC::Config.ssh_pub_key_file_path) end |
#fingerprint_for_local_key(key) ⇒ Object
304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/rhc/ssh_helpers.rb', line 304 def fingerprint_for_local_key(key) Net::SSH::KeyFactory.load_public_key(key).fingerprint rescue NoMethodError, NotImplementedError => e ssh_keygen_fallback key nil rescue OpenSSL::PKey::PKeyError, Net::SSH::Exception => e error e. nil rescue => e debug e. nil end |
#generate_ssh_key_ruby(type = "RSA", bits = 2048, comment = "ProtonBox-Key") ⇒ Object
Public: Generate an SSH key and store it in ~/.ssh/id_rsa
type - The String type RSA or DSS. bits - The Integer value for number of bits. comment - The String comment for the key
Examples
generate_ssh_key_ruby
# => /home/user/.ssh/id_rsa.pub
Returns nil on failure or public key location as a String on success
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/rhc/ssh_helpers.rb', line 261 def generate_ssh_key_ruby(type="RSA", bits = 2048, comment = "ProtonBox-Key") key = RHC::Vendor::SSHKey.generate(:type => type, :bits => bits, :comment => comment) ssh_dir = RHC::Config.ssh_dir priv_key = RHC::Config.ssh_priv_key_file_path pub_key = RHC::Config.ssh_pub_key_file_path if File.exists?(priv_key) say "SSH key already exists: #{priv_key}. Reusing..." return nil else unless File.exists?(ssh_dir) FileUtils.mkdir_p(ssh_dir) File.chmod(0700, ssh_dir) end File.open(priv_key, 'w') {|f| f.write(key.private_key)} File.chmod(0600, priv_key) File.open(pub_key, 'w') {|f| f.write(key.ssh_public_key)} ssh_add end pub_key end |
#has_ssh? ⇒ Boolean
return whether or not SSH is installed
344 345 346 347 348 349 350 351 352 |
# File 'lib/rhc/ssh_helpers.rb', line 344 def has_ssh? @has_ssh ||= begin @ssh_version = nil ssh_version $?.success? rescue false end end |
#run_on_gears(command, gears, opts = {}, &block) ⇒ Object
135 136 137 138 |
# File 'lib/rhc/ssh_helpers.rb', line 135 def run_on_gears(command, gears, opts={}, &block) debug "Executing #{command} on each of #{gears.inspect}" MultipleGearTask.new(command, gears, {:limit => .limit, :always_prefix => .always_prefix, :raw => .raw}.merge(opts)).run(&block) end |
#ssh_command_for_op(operation) ⇒ Object
146 147 148 149 150 |
# File 'lib/rhc/ssh_helpers.rb', line 146 def ssh_command_for_op(operation) #case operation raise RHC::OperationNotSupportedException, "The operation #{operation} is not supported." #end end |
#ssh_key_triple_for(key) ⇒ Object
for an SSH public key specified by ‘key’, return a triple
- type, content, comment
-
which is basically the space-separated list of the SSH public key content
324 325 326 327 328 329 330 331 332 |
# File 'lib/rhc/ssh_helpers.rb', line 324 def ssh_key_triple_for(key) begin IO.read(key).chomp.split rescue Errno::ENOENT => e raise ::RHC::KeyFileNotExistentException.new("File '#{key}' does not exist.") rescue Errno::EACCES => e raise ::RHC::KeyFileAccessDeniedException.new("Access denied to '#{key}'.") end end |
#ssh_key_triple_for_default_key ⇒ Object
334 335 336 |
# File 'lib/rhc/ssh_helpers.rb', line 334 def ssh_key_triple_for_default_key ssh_key_triple_for(RHC::Config.ssh_pub_key_file_path) end |
#ssh_keygen_fallback(path) ⇒ Object
For Net::SSH versions (< 2.0.11) that does not have Net::SSH::KeyFactory.load_public_key, we drop to shell to get the key’s fingerprint
295 296 297 298 299 300 301 302 |
# File 'lib/rhc/ssh_helpers.rb', line 295 def ssh_keygen_fallback(path) fingerprint = `ssh-keygen -lf #{path} 2>&1`.split(' ')[1] if $?.exitstatus != 0 error "Unable to compute SSH public key finger print for #{path}" end fingerprint end |
#ssh_ruby(host, username, command, compression = false, request_pty = false, &block) ⇒ Object
Public: Run ssh command on remote host
host - The String of the remote hostname to ssh to. username - The String username of the remote user to ssh as. command - The String command to run on the remote host. compression - Use compression in ssh, set to false if sending files. request_pty - Request for pty, set to false when pipe a file. block - Will yield this block and send the channel if provided.
Examples
ssh_ruby('myapp-t.protonbox.me',
'109745632b514e9590aa802ec015b074',
'pboxsh tail -f $PROTONBOX_LOG_DIR/*"')
# => true
Returns true on success
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/rhc/ssh_helpers.rb', line 169 def ssh_ruby(host, username, command, compression=false, request_pty=false, &block) debug "Opening Net::SSH connection to #{host}, #{username}, #{command}" exit_status = 0 Net::SSH.start(host, username, :compression => compression) do |session| #:nocov: channel = session.open_channel do |channel| if request_pty channel.request_pty do |ch, success| say "pty could not be obtained" unless success end end channel.exec(command) do |ch, success| channel.on_data do |ch, data| print data end channel.on_extended_data do |ch, type, data| print data end channel.on_close do |ch| debug "Terminating ... " end channel.on_request("exit-status") do |ch, data| exit_status = data.read_long end yield channel if block_given? channel.eof! end end session.loop #:nocov: end raise RHC::SSHCommandFailed.new(exit_status) if exit_status != 0 rescue Errno::ECONNREFUSED => e debug_error e raise RHC::SSHConnectionRefused.new(host, username) rescue Net::SSH::AuthenticationFailed => e debug_error e raise RHC::SSHAuthenticationFailed.new(host, username) rescue SocketError => e debug_error e raise RHC::ConnectionFailed, "The connection to #{host} failed: #{e.}" end |
#ssh_send_file_ruby(host, username, command, filename) ⇒ Object
Public: Run ssh command on remote host and pipe the specified file contents to the command input
host - The String of the remote hostname to ssh to. username - The String username of the remote user to ssh as. command - The String command to run on the remote host. filename - The String path to file to send.
221 222 223 224 225 226 227 228 229 230 |
# File 'lib/rhc/ssh_helpers.rb', line 221 def ssh_send_file_ruby(host, username, command, filename) filename = File.(filename) ssh_ruby(host, username, command) do |channel| File.open(filename, 'rb') do |file| file.chunk(1024) do |chunk| channel.send_data chunk end end end end |
#ssh_send_url_ruby(host, username, command, content_url) ⇒ Object
Public: Run ssh command on remote host and pipe the specified url contents to the command input
host - The String of the remote hostname to ssh to. username - The String username of the remote user to ssh as. command - The String command to run on the remote host. content_url - The url with the content to pipe to command.
240 241 242 243 244 245 246 247 |
# File 'lib/rhc/ssh_helpers.rb', line 240 def ssh_send_url_ruby(host, username, command, content_url) content_url = URI.parse(URI.encode(content_url.to_s)) ssh_ruby(host, username, command) do |channel| HTTPClient.new.get_content(content_url) do |chunk| channel.send_data chunk end end end |
#ssh_version ⇒ Object
check the version of SSH that is installed
339 340 341 |
# File 'lib/rhc/ssh_helpers.rb', line 339 def ssh_version @ssh_version ||= `ssh -V 2>&1`.strip end |
#table_from_gears(command, groups, opts = {}, &block) ⇒ Object
140 141 142 143 144 |
# File 'lib/rhc/ssh_helpers.rb', line 140 def table_from_gears(command, groups, opts={}, &block) cells = run_on_gears(command, groups, {:as => :table}.merge(opts), &block) cells.each{ |r| r.concat(r.pop.first.split(opts[:split_cells_on])) } if !block_given? && opts[:split_cells_on] say table cells, opts unless .raw end |