Skip to content
Browse files

Allow :gateway to be set to an array, in which case a chain of tunnel…

…s is created
  • Loading branch information...
1 parent f6d3442 commit 5b60cc4e3f88bd4d29b404b9b616941d11079648 @kerryb kerryb committed with jamis Aug 25, 2008
Showing with 37 additions and 11 deletions.
  1. +2 −0 CHANGELOG.rdoc
  2. +12 −6 lib/capistrano/configuration/connections.rb
  3. +23 −5 test/configuration/connections_test.rb
View
2 CHANGELOG.rdoc
@@ -1,5 +1,7 @@
== (unreleased)
+* Allow :gateway to be set to an array, in which case a chain of tunnels is created [Kerry Buckley]
+
* Allow HOSTS spec to override even non-existent roles [Mike Bailey]
* Sort releases via "ls -xt" instead of "ls -x" to allow for custom release names [Yan Pritzker]
View
18 lib/capistrano/configuration/connections.rb
@@ -23,21 +23,27 @@ def connect_to(server)
class GatewayConnectionFactory #:nodoc:
def initialize(gateway, options)
- Thread.abort_on_exception = true
- server = ServerDefinition.new(gateway)
-
@options = options
- @gateway = SSH.connection_strategy(server, options) do |host, user, connect_options|
+ @options[:logger].debug "Creating gateway using #{[*gateway].join(', ')}" if @options[:logger]
+ Thread.abort_on_exception = true
+ @gateways = [*gateway].collect { |g| ServerDefinition.new(g) }
+ tunnel = SSH.connection_strategy(@gateways[0], @options) do |host, user, connect_options|
Net::SSH::Gateway.new(host, user, connect_options)
end
+ @gateway = (@gateways[1..-1]).inject(tunnel) do |tunnel, destination|
+ @options[:logger].debug "Creating tunnel to #{destination}" if @options[:logger]
+ local_host = ServerDefinition.new("127.0.0.1", :user => destination.user, :port => tunnel.open(destination.host, (destination.port || 22)))
+ SSH.connection_strategy(local_host, @options) do |host, user, connect_options|
+ Net::SSH::Gateway.new(host, user, connect_options)
+ end
+ end
end
-
+
def connect_to(server)
@options[:logger].debug "establishing connection to `#{server}' via gateway" if @options[:logger]
local_host = ServerDefinition.new("127.0.0.1", :user => server.user, :port => @gateway.open(server.host, server.port || 22))
session = SSH.connect(local_host, @options)
session.xserver = server
- @options[:logger].trace "connected: `#{server}' (via gateway)" if @options[:logger]
session
end
end
View
28 test/configuration/connections_test.rb
@@ -58,18 +58,36 @@ def test_default_connection_factory_honors_config_options
assert_equal :session, @config.connection_factory.connect_to(server)
end
- def test_connection_factory_should_return_gateway_instance_if_gateway_variable_is_set
- @config.values[:gateway] = "j@capistrano"
- Net::SSH::Gateway.expects(:new).with("capistrano", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ def test_should_connect_through_gateway_if_gateway_variable_is_set
+ @config.values[:gateway] = "j@gateway"
+ Net::SSH::Gateway.expects(:new).with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
end
def test_connection_factory_as_gateway_should_honor_config_options
- @config.values[:gateway] = "capistrano"
+ @config.values[:gateway] = "gateway"
@config.values.update(@ssh_options)
- Net::SSH::Gateway.expects(:new).with("capistrano", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
end
+
+ def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_an_array
+ @config.values[:gateway] = ["j@gateway1", "k@gateway2"]
+ gateway1 = mock
+ Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(gateway1)
+ gateway1.expects(:open).returns(65535)
+ Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
+ end
+
+ def test_connection_factory_as_gateway_should_share_gateway_between_connections
+ @config.values[:gateway] = "j@gateway"
+ Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ Capistrano::SSH.stubs(:connect).returns(stub_everything)
+ assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
+ @config.establish_connections_to(server("capistrano"))
+ @config.establish_connections_to(server("another"))
+ end
def test_establish_connections_to_should_accept_a_single_nonarray_parameter
Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.returns(:success)

0 comments on commit 5b60cc4

Please sign in to comment.
Something went wrong with that request. Please try again.