core: allow multiple private keys [GH-907]

This commit is contained in:
Mitchell Hashimoto 2013-11-25 15:45:39 -08:00
parent d08e3f7ab3
commit 45e09eb677
7 changed files with 52 additions and 14 deletions

View File

@ -23,6 +23,8 @@ IMPROVEMENTS:
`--no-color` mode globally. [GH-2261]
- core: box URL and add date is tracked and shown if `-i` flag is
specified for `vagrant box list` [GH-2327]
- core: Multiple SSH keys can be specified with `config.ssh.private_key_path`
[GH-907]
- commands/init: Add `--output` option for specifing output path, or
"-" for stdin. [GH-1364]
- commands/provision: Add `--no-parallel` option to disable provider

View File

@ -299,8 +299,15 @@ module Vagrant
end
end
# Setup the keys
if !info[:private_key_path].is_a?(Array)
info[:private_key_path] = [info[:private_key_path]]
end
# Expand the private key path relative to the root path
info[:private_key_path] = File.expand_path(info[:private_key_path], @env.root_path)
info[:private_key_path].map! do |path|
File.expand_path(path, @env.root_path)
end
# Return the final compiled SSH info data
info

View File

@ -70,7 +70,7 @@ module Vagrant
:host => ssh_info[:host],
:port => ssh_info[:port],
:username => ssh_info[:username],
:key_path => ssh_info[:private_key_path]
:key_path => ssh_info[:private_key_path].join(", ")
end
raise Errors::SSHUnavailable
@ -85,7 +85,7 @@ module Vagrant
:host => ssh_info[:host],
:port => ssh_info[:port],
:username => ssh_info[:username],
:key_path => ssh_info[:private_key_path]
:key_path => ssh_info[:private_key_path].join(", ")
end
end
@ -116,7 +116,11 @@ module Vagrant
end
# If we're not in plain mode, attach the private key path.
command_options += ["-i", options[:private_key_path].to_s] if !plain_mode
if !plain_mode
options[:private_key_path].each do |path|
command_options += ["-i", path.to_s]
end
end
if ssh_info[:forward_x11]
# Both are required so that no warnings are shown regarding X11

View File

@ -167,7 +167,7 @@ module VagrantPlugins
:auth_methods => ["none", "publickey", "hostbased", "password"],
:config => false,
:forward_agent => ssh_info[:forward_agent],
:keys => [ssh_info[:private_key_path]],
:keys => ssh_info[:private_key_path],
:keys_only => true,
:paranoid => false,
:port => ssh_info[:port],
@ -175,7 +175,9 @@ module VagrantPlugins
}
# Check that the private key permissions are valid
Vagrant::Util::SSH.check_key_permissions(Pathname.new(ssh_info[:private_key_path]))
ssh_info[:private_key_path].each do |path|
Vagrant::Util::SSH.check_key_permissions(Pathname.new(path))
end
# Connect to SSH, giving it a few tries
connection = nil

View File

@ -18,6 +18,10 @@ module VagrantPlugins
@port = nil if @port == UNSET_VALUE
@private_key_path = nil if @private_key_path == UNSET_VALUE
@username = nil if @username == UNSET_VALUE
if @private_key_path && !@private_key_path.is_a?(Array)
@private_key_path = [@private_key_path]
end
end
# NOTE: This is _not_ a valid config validation method, since it
@ -28,9 +32,15 @@ module VagrantPlugins
def validate(machine)
errors = _detected_errors
if @private_key_path && \
!File.file?(File.expand_path(@private_key_path, machine.env.root_path))
errors << I18n.t("vagrant.config.ssh.private_key_missing", :path => @private_key_path)
if @private_key_path
@private_key_path.each do |raw_path|
path = File.expand_path(raw_path, machine.env.root_path)
if !File.file?(path)
errors << I18n.t(
"vagrant.config.ssh.private_key_missing",
path: raw_path)
end
end
end
errors

View File

@ -331,14 +331,22 @@ describe Vagrant::Machine do
it "should return the provider private key if given" do
provider_ssh_info[:private_key_path] = "/foo"
instance.ssh_info[:private_key_path].should == "/foo"
instance.ssh_info[:private_key_path].should == ["/foo"]
end
it "should return the configured SSH key path if set" do
provider_ssh_info[:private_key_path] = nil
instance.config.ssh.private_key_path = "/bar"
instance.ssh_info[:private_key_path].should == "/bar"
instance.ssh_info[:private_key_path].should == ["/bar"]
end
it "should return the array of SSH keys if set" do
provider_ssh_info[:private_key_path] = nil
instance.config.ssh.private_key_path = ["/foo", "/bar"]
instance.ssh_info[:private_key_path].should ==
["/foo", "/bar"]
end
context "expanding path relative to the root path" do
@ -346,7 +354,7 @@ describe Vagrant::Machine do
provider_ssh_info[:private_key_path] = "~/foo"
instance.ssh_info[:private_key_path].should ==
File.expand_path("~/foo", env.root_path)
[File.expand_path("~/foo", env.root_path)]
end
it "should with the config private key path" do
@ -354,7 +362,7 @@ describe Vagrant::Machine do
instance.config.ssh.private_key_path = "~/bar"
instance.ssh_info[:private_key_path].should ==
File.expand_path("~/bar", env.root_path)
[File.expand_path("~/bar", env.root_path)]
end
end
@ -362,7 +370,8 @@ describe Vagrant::Machine do
provider_ssh_info[:private_key_path] = nil
instance.config.ssh.private_key_path = nil
instance.ssh_info[:private_key_path].should == instance.env.default_private_key_path.to_s
instance.ssh_info[:private_key_path].should ==
[instance.env.default_private_key_path.to_s]
end
end
end

View File

@ -43,6 +43,10 @@ that ships with Vagrant, since that is what public boxes use. If you make
your own custom box with a custom SSH key, this should point to that
private key.
You can also specify multiple private keys by setting this to be an array.
This is useful, for example, if you use the default private key to bootstrap
the machine, but replace it with perhaps a more secure key later.
<hr>
`config.ssh.forward_agent` - If `true`, agent forwarding over SSH