summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Kantrowitz <noah@coderanger.net>2015-09-01 18:22:40 -0700
committerNoah Kantrowitz <noah@coderanger.net>2015-09-01 18:24:26 -0700
commitb63f742a826be3b97e9eea34f725fbdbdfc87aa8 (patch)
treee30680d95ea24774841e70d55a830f489875e918
parentad8fd4d65b48519ac154ad9bf9774322b0c6d902 (diff)
downloadchef-b63f742a826be3b97e9eea34f725fbdbdfc87aa8.tar.gz
Refactor knife ssh options stuff.
This allows most config options to work with the SSH gateway too. The most important of these is the identity file stuffs.
-rw-r--r--lib/chef/knife/ssh.rb74
1 files changed, 45 insertions, 29 deletions
diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb
index 68e01cf94f..a34e790c30 100644
--- a/lib/chef/knife/ssh.rb
+++ b/lib/chef/knife/ssh.rb
@@ -132,15 +132,18 @@ class Chef
if config[:ssh_gateway]
gw_host, gw_user = config[:ssh_gateway].split('@').reverse
gw_host, gw_port = gw_host.split(':')
- gw_opts = gw_port ? { :port => gw_port } : {}
+ gw_opts = session_options(gw_host, gw_port, gw_user)
- session.via(gw_host, gw_user || config[:ssh_user], gw_opts)
+ begin
+ # Try to connect with a key.
+ session.via(gw_host, gw_opts[:user], gw_opts)
+ rescue Net::SSH::AuthenticationFailed
+ prompt = "Enter the password for #{user}@#{gw_host}: "
+ gw_opts[:password] = prompt_for_password(prompt)
+ # Try again with a password.
+ session.via(gw_host, user, gw_opts)
+ end
end
- rescue Net::SSH::AuthenticationFailed
- user = gw_user || config[:ssh_user]
- prompt = "Enter the password for #{user}@#{gw_host}: "
- gw_opts.merge!(:password => prompt_for_password(prompt))
- session.via(gw_host, user, gw_opts)
end
def configure_session
@@ -204,32 +207,45 @@ class Chef
list
end
- def session_from_list(list)
- list.each do |item|
- host, ssh_port = item
- Chef::Log.debug("Adding #{host}")
- session_opts = {}
-
- ssh_config = Net::SSH.configuration_for(host)
-
+ # Net::SSH session options hash for global options. These should be
+ # options that will apply to the gateway connection in addition to the
+ # main one.
+ #
+ # @since 12.5.0
+ # @param host [String] Hostname for this session.
+ # @param port [String] SSH port for this session.
+ # @param user [String] Optional username for this session.
+ # @return [Hash<Symbol, Object>]
+ def session_options(host, port, user=nil)
+ ssh_config = Net::SSH.configuration_for(host)
+ {}.tap do |opts|
# Chef::Config[:knife][:ssh_user] is parsed in #configure_user and written to config[:ssh_user]
- user = config[:ssh_user] || ssh_config[:user]
- hostspec = user ? "#{user}@#{host}" : host
- session_opts[:keys] = File.expand_path(config[:identity_file]) if config[:identity_file]
- session_opts[:keys_only] = true if config[:identity_file]
- session_opts[:password] = config[:ssh_password] if config[:ssh_password]
- session_opts[:forward_agent] = config[:forward_agent]
- session_opts[:port] = config[:ssh_port] ||
- ssh_port || # Use cloud port if available
- Chef::Config[:knife][:ssh_port] ||
- ssh_config[:port]
- session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
-
+ opts[:user] = user || config[:ssh_user] || ssh_config[:user]
+ if config[:identity_file]
+ opts[:keys] = File.expand_path(config[:identity_file])
+ opts[:keys_only] = true
+ end
+ opts[:forward_agent] = config[:forward_agent] || ssh_config[:forward_agent]
+ opts[:port] = port || ssh_config[:port]
+ opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
if !config[:host_key_verify]
- session_opts[:paranoid] = false
- session_opts[:user_known_hosts_file] = "/dev/null"
+ opts[:paranoid] = false
+ opts[:user_known_hosts_file] = '/dev/null'
end
+ end
+ end
+ def session_from_list(list)
+ list.each do |item|
+ host, ssh_port = item
+ Chef::Log.debug("Adding #{host}")
+ session_opts = session_options(host, ssh_port)
+ # Handle port overrides for the main connection.
+ session_opts[:port] = Chef::Config[:knife][:ssh_port] if Chef::Config[:knife][:ssh_port]
+ session_opts[:port] = config[:ssh_port] if config[:ssh_port]
+ # Create the hostspec.
+ hostspec = session_opts[:user] ? "#{session_opts[:user]}@#{host}" : host
+ # Connect a new session on the multi.
session.use(hostspec, session_opts)
@longest = host.length if host.length > @longest