Provider API to return SSH info, must implement `ssh_info`.

Since SSH is such a critical part of Vagrant, each provider must
implement a method that returns the proper way to SSH into the machine.
This commit is contained in:
Mitchell Hashimoto 2012-08-05 12:41:05 -07:00
parent 9db982f7a4
commit 1a2a8b49c0
4 changed files with 155 additions and 1 deletions

View File

@ -116,6 +116,60 @@ module Vagrant
@id = value
end
# This returns the SSH info for accessing this machine. This SSH info
# is queried from the underlying provider. This method returns `nil` if
# the machine is not ready for SSH communication.
#
# The structure of the resulting hash is guaranteed to contain the
# following structure, although it may return other keys as well
# not documented here:
#
# {
# :host => "1.2.3.4",
# :port => "22",
# :username => "mitchellh",
# :private_key_path => "/path/to/my/key"
# }
#
# Note that Vagrant makes no guarantee that this info works or is
# correct. This is simply the data that the provider gives us or that
# is configured via a Vagrantfile. It is still possible after this
# point when attempting to connect via SSH to get authentication
# errors.
#
# @return [Hash] SSH information.
def ssh_info
# First, ask the provider for their information. If the provider
# returns nil, then the machine is simply not ready for SSH, and
# we return nil as well.
info = @provider.ssh_info
return nil if info.nil?
# Delete out the nil entries.
info.dup.each do |key, value|
info.delete(key) if value.nil?
end
# Next, we default some fields if they weren't given to us by
# the provider.
info[:host] = @config.ssh.host if @config.ssh.host
info[:port] = @config.ssh.port if @config.ssh.port
info[:username] = @config.ssh.username if @config.ssh.username
# We also set some fields that are purely controlled by Varant
info[:forward_agent] = @config.ssh.forward_agent
info[:forward_x11] = @config.ssh.forward_x11
# Set the private key path. If a specific private key is given in
# the Vagrantfile we set that. Otherwise, we use the default (insecure)
# private key, but only if the provider didn't give us one.
info[:private_key_path] = @config.ssh.private_key_path if @config.ssh.private_key_path
info[:private_key_path] = @env.default_private_key_path if !info[:private_key_path]
# Return the final compiled SSH info data
info
end
# Returns the state of this machine. The state is queried from the
# backing provider, so it can be any arbitrary symbol.
#

View File

@ -21,6 +21,31 @@ module Vagrant
nil
end
# This should return a hash of information that explains how to
# SSH into the machine. If the machine is not at a point where
# SSH is even possible, then `nil` should be returned.
#
# The general structure of this returned hash should be the
# following:
#
# {
# :host => "1.2.3.4",
# :port => "22",
# :username => "mitchellh",
# :private_key_path => "/path/to/my/key"
# }
#
# **Note:** Vagrant only supports private key based authentication,
# mainly for the reason that there is no easy way to exec into an
# `ssh` prompt with a password, whereas we can pass a private key
# via commandline.
#
# @return [Hash] SSH information. For the structure of this hash
# read the accompanying documentation for this method.
def ssh_info
nil
end
# This should return the state of the machine within this provider.
# The state can be any symbol.
#

View File

@ -11,7 +11,7 @@ describe Vagrant::Machine do
obj
end
let(:box) { Object.new }
let(:config) { Object.new }
let(:config) { env.config.global }
let(:env) do
# We need to create a Vagrantfile so that this test environment
# has a proper root path
@ -175,6 +175,73 @@ describe Vagrant::Machine do
end
end
describe "ssh info" do
describe "with the provider returning nil" do
it "should return nil if the provider returns nil" do
provider.should_receive(:ssh_info).and_return(nil)
instance.ssh_info.should be_nil
end
end
describe "with the provider returning data" do
let(:provider_ssh_info) { {} }
before(:each) do
provider.should_receive(:ssh_info).and_return(provider_ssh_info)
end
[:host, :port, :username].each do |type|
it "should return the provider data if not configured in Vagrantfile" do
provider_ssh_info[type] = "foo"
instance.config.ssh.send("#{type}=", nil)
instance.ssh_info[type].should == "foo"
end
it "should return the Vagrantfile value over the provider data if given" do
provider_ssh_info[type] = "foo"
instance.config.ssh.send("#{type}=", "bar")
instance.ssh_info[type].should == "bar"
end
end
it "should set the configured forward agent settings" do
provider_ssh_info[:forward_agent] = true
instance.config.ssh.forward_agent = false
instance.ssh_info[:forward_agent].should == false
end
it "should set the configured forward X11 settings" do
provider_ssh_info[:forward_x11] = true
instance.config.ssh.forward_x11 = false
instance.ssh_info[:forward_x11].should == false
end
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"
end
it "should return the configured SSH key path if set" do
provider_ssh_info[:private_key_path] = "foo"
instance.config.ssh.private_key_path = "bar"
instance.ssh_info[:private_key_path].should == "bar"
end
it "should return the default private key path if provider and config doesn't have one" 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
end
end
end
describe "state" do
it "should query state from the provider" do
state = :running

View File

@ -7,4 +7,12 @@ describe Vagrant::Plugin::V1::Provider do
it "should return nil by default for actions" do
instance.action(:whatever).should be_nil
end
it "should return nil by default for ssh info" do
instance.ssh_info.should be_nil
end
it "should return nil by default for state" do
instance.state.should be_nil
end
end