def self.connection_strategy(server, options={}, &block)
methods = [ %w(publickey hostbased), %w(password keyboard-interactive) ]
password_value = nil
ssh_options = (options[:ssh_options] || {}).merge(server.options[:ssh_options] || {})
ssh_options = Net::SSH.configuration_for(server.host, ssh_options.fetch(:config, true)).merge(ssh_options)
ssh_options[:config] = false
ssh_options[:verbose] = :debug if options[:verbose] && options[:verbose] > 0
user = server.user || options[:user] || ssh_options[:username] ||
ssh_options[:user] || ServerDefinition.default_user
port = server.port || options[:port] || ssh_options[:port]
host = ssh_options.fetch(:host_name, server.host)
ssh_options[:port] = port if port
ssh_options.delete(:username)
ssh_options.delete(:user)
begin
connection_options = ssh_options.merge(
:password => password_value,
:auth_methods => ssh_options[:auth_methods] || methods.shift
)
yield host, user, connection_options
rescue Net::SSH::AuthenticationFailed
raise if methods.empty? || ssh_options[:auth_methods]
password_value = options[:password]
retry
end
end