(#8697) Introduce extra_args setting for ssh configs

Prior to this commit, there was no way to add additional ssh arguments
within a Vagrantfile for a given vagrant machine. This commit introduces
a new option extra_args that allows users to pass in a single argument
or an array of flags that will be added onto the ssh command.
This commit is contained in:
Brian Cain 2017-08-16 16:09:28 -07:00
parent 40d5c28f3f
commit ffec0ff8d9
6 changed files with 65 additions and 0 deletions

View File

@ -442,6 +442,7 @@ module Vagrant
info[:username] ||= @config.ssh.default.username
info[:compression] ||= @config.ssh.default.compression
info[:dsa_authentication] ||= @config.ssh.default.dsa_authentication
info[:extra_args] ||= @config.ssh.default.extra_args
# We set overrides if they are set. These take precedence over
# provider-returned data.
@ -453,6 +454,7 @@ module Vagrant
info[:dsa_authentication] = @config.ssh.dsa_authentication
info[:username] = @config.ssh.username if @config.ssh.username
info[:password] = @config.ssh.password if @config.ssh.password
info[:extra_args] = @config.ssh.extra_args if @config.ssh.extra_args
# We also set some fields that are purely controlled by Varant
info[:forward_agent] = @config.ssh.forward_agent

View File

@ -167,6 +167,12 @@ module Vagrant
#
# Without having extra_args be last, the user loses this ability
command_options += ["-o", "ForwardAgent=yes"] if ssh_info[:forward_agent]
# Note about :extra_args
# ssh_info[:extra_args] comes from a machines ssh config in a Vagrantfile,
# where as opts[:extra_args] comes from running the ssh command
command_options += Array(ssh_info[:extra_args]) if ssh_info[:extra_args]
command_options.concat(opts[:extra_args]) if opts[:extra_args]
# Build up the host string for connecting

View File

@ -11,6 +11,7 @@ module VagrantPlugins
attr_accessor :paranoid
attr_accessor :compression
attr_accessor :dsa_authentication
attr_accessor :extra_args
def initialize
@host = UNSET_VALUE
@ -23,6 +24,7 @@ module VagrantPlugins
@paranoid = UNSET_VALUE
@compression = UNSET_VALUE
@dsa_authentication = UNSET_VALUE
@extra_args = UNSET_VALUE
end
def finalize!
@ -36,6 +38,7 @@ module VagrantPlugins
@paranoid = false if @paranoid == UNSET_VALUE
@compression = true if @compression == UNSET_VALUE
@dsa_authentication = true if @dsa_authentication == UNSET_VALUE
@extra_args = nil if @extra_args == UNSET_VALUE
if @private_key_path && !@private_key_path.is_a?(Array)
@private_key_path = [@private_key_path]

View File

@ -793,6 +793,17 @@ describe Vagrant::Machine do
it "paranoid should be default" do
expect(instance.ssh_info[:paranoid]).to be(false)
end
it "extra_args should be nil" do
expect(instance.ssh_info[:extra_args]).to be(nil)
end
it "extra_args should be set" do
instance.config.ssh.extra_args = ["-L", "127.1.2.7:8008:127.1.2.7:8008"]
expect(instance.ssh_info[:extra_args]).to eq(["-L", "127.1.2.7:8008:127.1.2.7:8008"])
end
it "extra_args should be set as an array" do
instance.config.ssh.extra_args = "-6"
expect(instance.ssh_info[:extra_args]).to eq("-6")
end
it "keys_only should be overridden" do
instance.config.ssh.keys_only = false
expect(instance.ssh_info[:keys_only]).to be(false)

View File

@ -162,6 +162,42 @@ describe Vagrant::Util::SSH do
end
end
context "when extra_args is provided as an array" do
let(:ssh_info) {{
host: "localhost",
port: 2222,
username: "vagrant",
private_key_path: [temporary_file],
extra_args: ["-L", "8008:localhost:80"]
}}
it "enables agent forwarding options" do
allow(Vagrant::Util::SafeExec).to receive(:exec).and_return(nil)
expect(described_class.exec(ssh_info)).to eq(nil)
expect(Vagrant::Util::SafeExec).to have_received(:exec)
.with("ssh", "vagrant@localhost", "-p", "2222", "-o", "LogLevel=FATAL", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-o", "IdentityFile=#{ssh_info[:private_key_path][0]}", "-L", "8008:localhost:80")
end
end
context "when extra_args is provided as a string" do
let(:ssh_info) {{
host: "localhost",
port: 2222,
username: "vagrant",
private_key_path: [temporary_file],
extra_args: "-6"
}}
it "enables agent forwarding options" do
allow(Vagrant::Util::SafeExec).to receive(:exec).and_return(nil)
expect(described_class.exec(ssh_info)).to eq(nil)
expect(Vagrant::Util::SafeExec).to have_received(:exec)
.with("ssh", "vagrant@localhost", "-p", "2222", "-o", "LogLevel=FATAL", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-o", "IdentityFile=#{ssh_info[:private_key_path][0]}", "-6")
end
end
context "with subprocess enabled" do
let(:ssh_info) {{
host: "localhost",

View File

@ -157,3 +157,10 @@ default to `true` and `Compression=yes` will be enabled with ssh.
`config.ssh.dsa_authentication` - If `false`, this setting will not include
`DSAAuthentication` when ssh'ing into a machine. If this is not set, it will
default to `true` and `DSAAuthentication=yes` will be used with ssh.
`config.ssh.extra_args` - This settings value is passed directly into the
ssh executable. This allows you to pass any arbitrary commands to do things such
as reverse tunneling down into the ssh program. These options can either be
single flags set as strings such as `"-6"` for IPV6 or an array of arguments
such as `["-L", "8008:localhost:80"]` for enabling a tunnel from host port 8008
to port 80 on guest.