class Bosh::Cli::Command::Ssh
Public Instance Methods
cleanup(*args)
click to toggle source
# File lib/cli/commands/ssh.rb, line 71 def cleanup(*args) job, index, args = JobCommandArgs.new(args).to_a if args.size > 0 err("SSH cleanup doesn't accept any extra args") end manifest = prepare_deployment_manifest(show_state: true) say("Cleaning up ssh artifacts from #{job}/#{index}") director.cleanup_ssh(manifest.name, job, "^#{SSH_USER_PREFIX}", [index]) end
scp(*args)
click to toggle source
# File lib/cli/commands/ssh.rb, line 51 def scp(*args) job, index, args = JobCommandArgs.new(args).to_a upload = options[:upload] download = options[:download] if (upload && download) || (upload.nil? && download.nil?) err('Please specify either --upload or --download') end manifest = prepare_deployment_manifest(show_state: true) if args.size != 2 err('Please enter valid source and destination paths') end say("Executing file operations on job #{job}") perform_operation(upload ? :upload : :download, manifest.name, job, index, args) end
shell(*args)
click to toggle source
# File lib/cli/commands/ssh.rb, line 21 def shell(*args) if args.size > 0 job, id, command = JobCommandArgs.new(args).to_a else command = '' job, id = prompt_for_job_and_index end manifest = prepare_deployment_manifest(show_state: true) if command.empty? setup_interactive_shell(manifest.name, job, id) else say("Executing `#{command.join(' ')}' on #{job}/#{id}") perform_operation(:exec, manifest.name, job, id, command) end end
Private Instance Methods
encrypt_password(plain_text)
click to toggle source
# File lib/cli/commands/ssh.rb, line 95 def encrypt_password(plain_text) return unless plain_text @salt_charset ||= get_salt_charset salt = '' 8.times do salt << @salt_charset[rand(@salt_charset.size)] end plain_text.crypt(salt) end
get_salt_charset()
click to toggle source
# File lib/cli/commands/ssh.rb, line 85 def get_salt_charset charset = [] charset.concat(('a'..'z').to_a) charset.concat(('A'..'Z').to_a) charset.concat(('0'..'9').to_a) charset << '.' charset << '/' charset end
perform_operation(operation, deployment_name, job, index, args)
click to toggle source
# File lib/cli/commands/ssh.rb, line 200 def perform_operation(operation, deployment_name, job, index, args) password = options[:default_password] || '' setup_ssh(deployment_name, job, index, password) do |sessions, gateway, ssh_session| sessions.each do |session| unless session['status'] == 'success' && session['ip'] err("Failed to set up SSH on #{job}/#{index}: #{session.inspect}") end with_ssh(session['ip'], ssh_session, gateway) do |ssh| case operation when :exec nl say("#{job}/#{session['index']}") say(ssh.exec!(args.join(' '))) when :upload ssh.scp.upload!(args[0], args[1]) when :download file = File.basename(args[0]) path = "#{args[1]}/#{file}.#{job}.#{session['index']}" ssh.scp.download!(args[0], path) say("Downloaded file to #{path}".make_green) else err("Unknown operation #{operation}") end end end end end
setup_interactive_shell(deployment_name, job, id)
click to toggle source
@param [String] job Job name @param [Integer] index Job index
# File lib/cli/commands/ssh.rb, line 169 def setup_interactive_shell(deployment_name, job, id) password = options[:default_password] || '' setup_ssh(deployment_name, job, id, password) do |sessions, gateway, ssh_session| session = sessions.first unless session['status'] == 'success' && session['ip'] err("Failed to set up SSH on #{job}/#{id}: #{session.inspect}") end say("Starting interactive shell on job #{job}/#{id}") skip_strict_host_key_checking = options[:strict_host_key_checking] =~ (/(no|false)$/i) ? '-o StrictHostKeyChecking=no' : '-o StrictHostKeyChecking=yes' private_key_option = ssh_session.ssh_private_key_option if gateway port = gateway.open(session['ip'], 22) known_host_option = ssh_session.ssh_known_host_option(port) ssh_session_pid = Process.spawn('ssh', "#{ssh_session.user}@localhost", '-p', port.to_s, private_key_option, skip_strict_host_key_checking, known_host_option) Process.waitpid(ssh_session_pid) gateway.close(port) else known_host_option = ssh_session.ssh_known_host_option(nil) ssh_session_pid = Process.spawn('ssh', "#{ssh_session.user}@#{session['ip']}", private_key_option, skip_strict_host_key_checking, known_host_option) Process.waitpid(ssh_session_pid) end end end
setup_ssh(deployment_name, job, id, password) { |sessions, gateway, ssh_session| ... }
click to toggle source
@param [String] job @param [Integer] index @param [optional,String] password
# File lib/cli/commands/ssh.rb, line 108 def setup_ssh(deployment_name, job, id, password) say("Target deployment is `#{deployment_name}'") nl say('Setting up ssh artifacts') ssh_session = SSHSession.new status, task_id = director.setup_ssh( deployment_name, job, id, ssh_session.user, ssh_session.public_key, encrypt_password(password)) unless status == :done err("Failed to set up SSH: see task #{task_id} log for details") end sessions = JSON.parse(director.get_task_result_log(task_id)) unless sessions && sessions.kind_of?(Array) && sessions.size > 0 err("Error setting up ssh, check task #{task_id} log for more details") end sessions.each do |session| unless session.kind_of?(Hash) err("Unexpected SSH session info: #{session.inspect}. " + "Please check task #{task_id} log for more details") end end ssh_session.set_host_session(sessions.first) begin if options[:gateway_host] || (!options[:no_gateway] && sessions.first["gateway_host"]) require 'net/ssh/gateway' gw_host = options[:gateway_host] || sessions.first["gateway_host"] gw_user = options[:gateway_user] || sessions.first["gateway_user"] || ENV['USER'] gw_options = {} gw_options[:keys] = [options[:gateway_identity_file]] if options[:gateway_identity_file] begin gateway = Net::SSH::Gateway.new(gw_host, gw_user, gw_options) rescue Net::SSH::AuthenticationFailed err("Authentication failed with gateway #{gw_host} and user #{gw_user}.") end else gateway = nil end yield sessions, gateway, ssh_session ensure nl say('Cleaning up ssh artifacts') ssh_session.cleanup indices = sessions.map { |session| session['id'] || session['index'] } director.cleanup_ssh(deployment_name, job, "^#{ssh_session.user}$", indices) gateway.shutdown! if gateway end end
with_ssh(ip, ssh_session, gateway = nil) { |ssh| ... }
click to toggle source
@param [String] user @param [String] ip @param [optional, Net::SSH::Gateway] gateway @yield [Net::SSH]
# File lib/cli/commands/ssh.rb, line 234 def with_ssh(ip, ssh_session, gateway = nil) require 'net/scp' options = { :keys => ssh_session.ssh_private_key_path } if gateway gateway.ssh(ip, ssh_session.user, options) { |ssh| yield ssh } else require 'net/ssh' known_host_path = ssh_session.ssh_known_host_path(nil) if known_host_path.length > 0 options[:user_known_hosts_file] = known_host_path end Net::SSH.start(ip, ssh_session.user, options) { |ssh| yield ssh } end end