Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6547: allow_multiple_ssh_ports_and_usernames_in_capistrano_with_gateways_too.diff

File allow_multiple_ssh_ports_and_usernames_in_capistrano_with_gateways_too.diff, 7.1 kB (added by ezmobius, 2 years ago)
  • test/actor_test.rb

    old new  
    316316    @actor.foo 
    317317    assert_instance_of GatewayConnectionFactory, @actor.factory 
    318318  end 
     319   
     320  def test_establish_connection_uses_gateway_if_specified_with_username_and_port 
     321    @actor.configuration.gateway = "demo@10.example.com:8088" 
     322    @actor.define_task :foo, :roles => :db do 
     323      run "do this" 
     324    end 
     325    @actor.foo 
     326    assert_instance_of GatewayConnectionFactory, @actor.factory 
     327  end 
    319328 
    320329  def test_run_when_not_pretend 
    321330    @actor.define_task :foo do 
  • test/ssh_test.rb

    old new  
    4242      MockSSH.invocations.first[1][:auth_methods] 
    4343    assert_nil MockSSH.invocations.first[2] 
    4444  end 
     45   
     46  def test_explicit_ssh_ports_in_server_string_no_block 
     47    Net.const_during(:SSH, MockSSH) do 
     48      Capistrano::SSH.connect('demo.server.i:8088', @config) 
     49    end 
    4550 
     51    assert_equal 1, MockSSH.invocations.length 
     52    assert_equal 'demo.server.i', MockSSH.invocations.first[0] 
     53    assert_equal '8088', MockSSH.invocations.first[1][:port] 
     54    assert_equal 'demo', MockSSH.invocations.first[1][:username] 
     55  end 
     56   
     57  def test_explicit_ssh_username_in_server_string_no_block 
     58    Net.const_during(:SSH, MockSSH) do 
     59      Capistrano::SSH.connect('bob@demo.server.i', @config) 
     60    end 
     61 
     62    assert_equal 1, MockSSH.invocations.length 
     63    assert_equal 'demo.server.i', MockSSH.invocations.first[0] 
     64    assert_equal 22, MockSSH.invocations.first[1][:port] 
     65    assert_equal 'bob', MockSSH.invocations.first[1][:username] 
     66  end 
     67   
     68  def test_explicit_ssh_username_and_port_in_server_string_no_block 
     69    Net.const_during(:SSH, MockSSH) do 
     70      Capistrano::SSH.connect('bob@demo.server.i:8088', @config) 
     71    end 
     72 
     73    assert_equal 1, MockSSH.invocations.length 
     74    assert_equal 'demo.server.i', MockSSH.invocations.first[0] 
     75    assert_equal '8088', MockSSH.invocations.first[1][:port] 
     76    assert_equal 'bob', MockSSH.invocations.first[1][:username] 
     77  end 
     78 
    4679  def test_publickey_auth_succeeds_explicit_port_no_block 
    4780    Net.const_during(:SSH, MockSSH) do 
    4881      Capistrano::SSH.connect('demo.server.i', @config, 23) 
     
    5386    assert_nil MockSSH.invocations.first[2] 
    5487  end 
    5588 
     89 
     90  def test_explicit_ssh_ports_in_server_string_with_block 
     91    Net.const_during(:SSH, MockSSH) do 
     92      Capistrano::SSH.connect('demo.server.i:8088', @config) do |session| 
     93      end 
     94    end 
     95    assert_equal 'demo.server.i', MockSSH.invocations.first[0] 
     96    assert_equal '8088', MockSSH.invocations.first[1][:port] 
     97    assert_equal 1, MockSSH.invocations.length 
     98    assert_instance_of Proc, MockSSH.invocations.first[2] 
     99  end 
     100   
     101  def test_explicit_ssh_username_in_server_string_with_block 
     102    Net.const_during(:SSH, MockSSH) do 
     103      Capistrano::SSH.connect('bob@demo.server.i', @config) do |session| 
     104      end 
     105    end 
     106    assert_equal 'demo.server.i', MockSSH.invocations.first[0] 
     107    assert_equal 22, MockSSH.invocations.first[1][:port] 
     108    assert_equal 1, MockSSH.invocations.length 
     109    assert_equal 'bob', MockSSH.invocations.first[1][:username] 
     110    assert_instance_of Proc, MockSSH.invocations.first[2] 
     111  end 
     112   
     113  def test_explicit_ssh_username_and_port_in_server_string_with_block 
     114    Net.const_during(:SSH, MockSSH) do 
     115      Capistrano::SSH.connect('bob@demo.server.i:8088', @config) do |session| 
     116      end 
     117    end 
     118    assert_equal 'demo.server.i', MockSSH.invocations.first[0] 
     119    assert_equal '8088', MockSSH.invocations.first[1][:port] 
     120    assert_equal 1, MockSSH.invocations.length 
     121    assert_equal 'bob', MockSSH.invocations.first[1][:username] 
     122    assert_instance_of Proc, MockSSH.invocations.first[2] 
     123  end 
     124 
     125  def test_parse_server 
     126    assert_equal(['bob', 'demo.server.i', '8088'],  
     127                 Capistrano::SSH.parse_server("bob@demo.server.i:8088")) 
     128    assert_equal([nil, 'demo.server.i', '8088'],  
     129                 Capistrano::SSH.parse_server("demo.server.i:8088"))                  
     130    assert_equal(['bob', 'demo.server.i', nil],  
     131                 Capistrano::SSH.parse_server("bob@demo.server.i")) 
     132    assert_equal([nil, 'demo.server.i', nil],  
     133                 Capistrano::SSH.parse_server("demo.server.i")) 
     134  end   
     135 
    56136  def test_publickey_auth_succeeds_with_block 
    57137    Net.const_during(:SSH, MockSSH) do 
    58138      Capistrano::SSH.connect('demo.server.i', @config) do |session| 
  • lib/capistrano/ssh.rb

    old new  
    2727                        :password => password_value, 
    2828                        :port => port, 
    2929                        :auth_methods => methods.shift }.merge(config.ssh_options) 
     30                         
     31        user, server, port = parse_server(server)          
     32        ssh_options[:username] = user if user    
     33        ssh_options[:port] = port if port 
     34         
    3035        Net::SSH.start(server,ssh_options,&block) 
    3136      rescue Net::SSH::AuthenticationFailed 
    3237        raise if methods.empty? 
     
    3439        retry 
    3540      end 
    3641    end 
     42     
     43    # This regex is used for its byproducts, the $1-9 match vars. 
     44    # This regex will always match the ssh hostname and if there  
     45    # is a username or port they will be matched as well. This  
     46    # allows us to set the username and ssh port right in the  
     47    # server string:  "username@123.12.123.12:8088" 
     48    # This remains fully backwards compatible and can still be 
     49    # intermixed with the old way of doing things. usernames 
     50    # and ports will be used from the server string if present 
     51    # but they will fall back to the regular defaults when not 
     52    # present. Returns and array like: 
     53    # ['bob', 'demo.server.com', '8088'] 
     54    # will always at least return the server: 
     55    # [nil, 'demo.server.com', nil] 
     56    def self.parse_server(server) 
     57      server =~ /^(?:([^;,:=]+)@|)(.*?)(?::(\d+)|)$/ 
     58      [$1, $2, $3] 
     59    end   
    3760  end 
    3861end 
  • lib/capistrano/gateway.rb

    old new  
    6969    def connect_to(server) 
    7070      connection = nil 
    7171      @config.logger.trace "establishing connection to #{server} via gateway" 
    72       port = next_port 
     72      local_port = next_port 
    7373 
    7474      thread = Thread.new do 
    7575        begin 
    76           @session.forward.local(port, server, 22) 
    77           connection = SSH.connect('127.0.0.1', @config, port) 
     76          user, server, port = SSH.parse_server(server)    
     77          @config.ssh_options[:username] = user if user 
     78          remote_port = port || 22 
     79          @session.forward.local(local_port, server, remote_port) 
     80          connection = SSH.connect('127.0.0.1', @config, local_port) 
    7881          @config.logger.trace "connection to #{server} via gateway established" 
    7982        rescue Errno::EADDRINUSE 
    8083          port = next_port