diff --git a/lib/rhc/commands/ssh.rb b/lib/rhc/commands/ssh.rb index d6e4b60f0..20995ffa4 100644 --- a/lib/rhc/commands/ssh.rb +++ b/lib/rhc/commands/ssh.rb @@ -15,6 +15,8 @@ class Ssh < Base You may run a specific SSH command by passing one or more arguments, or use a different SSH executable or pass options to SSH with the '--ssh' option. + + A dedicated private key can be passed to SSH with the '--key' option. To use the '--ssh' flag with an SSH executable path containing a space, wrap the executable path with double quotes: @@ -24,6 +26,7 @@ class Ssh < Base takes_application :argument => true argument :command, "Command to run in the application's SSH session", ['--command COMMAND'], :type => :list, :optional => true option ["--ssh PATH"], "Path to your SSH executable or additional options" + option ["--key KEY"], "Private KEY to use for the SSH connections. Requires a private key." option ["--gears"], "Execute this command on all gears in the app. Requires a command." option ["--limit INTEGER"], "Limit the number of simultaneous SSH connections opened with --gears (default: 5).", :type => Integer, :default => 5 option ["--raw"], "Output only the data returned by each host, no hostname prefix." @@ -42,8 +45,12 @@ def run(_, command) $stderr.puts "Connecting to #{rest_app.ssh_string.to_s} ..." unless command.present? debug "Using user specified SSH: #{options.ssh}" if options.ssh - - command_line = [RHC::Helpers.split_path(ssh), ('-vv' if debug?), rest_app.ssh_string.to_s, command].flatten.compact + debug "Using user specified SSH Private Key: #{options.key}" if options.key + if options.key + command_line = [RHC::Helpers.split_path(ssh), ('-vv' if debug?), rest_app.ssh_string.to_s, "-i", options.key, command].flatten.compact + else + command_line = [RHC::Helpers.split_path(ssh), ('-vv' if debug?), rest_app.ssh_string.to_s, command].flatten.compact + end debug "Invoking Kernel.exec with #{command_line.inspect}" Kernel.send(:exec, *command_line) diff --git a/spec/rhc/commands/ssh_spec.rb b/spec/rhc/commands/ssh_spec.rb index 8a74b9082..3465b89c6 100644 --- a/spec/rhc/commands/ssh_spec.rb +++ b/spec/rhc/commands/ssh_spec.rb @@ -171,6 +171,32 @@ end end + describe 'app ssh custom private key' do + let(:arguments) { ['app', 'ssh', 'app1', '--key', 'valid_private_key'] } + + context 'when custom private key is valid' do + before(:each) do + @domain = rest_client.add_domain("mockdomain") + @domain.add_application("app1", "mock_type") + Kernel.should_receive(:exec).with("ssh", "fakeuuidfortestsapp1@127.0.0.1", "-i", "valid_private_key").and_return(0) + #subject.class.any_instance.stub(:discover_git_executable).and_return('git') + end + it { run_output.should match("Connecting to fakeuuidfortestsapp") } + it { expect{ run }.to exit_with_code(0) } + end + + context 'when custom private key does not exist' do + let(:arguments) { ['app', 'ssh', 'app1', '--key', 'nonexistent_private_key'] } + it { expect { run }.to exit_with_code(1) } + end + + context 'when custom private key is inaccessible' do + let(:arguments) { ['app', 'ssh', 'app1', '--key', 'inaccessible_private_key'] } + it { expect { run }.to exit_with_code(1) } + end + + end + describe 'app ssh custom ssh with spaces and arguments' do let(:arguments) { ['app', 'ssh', 'app1', '--ssh', '"/path/to /ssh" --with_custom_flag'] } context 'when custom ssh does not exist as a path' do