test-kitchen / test-kitchen

Test Kitchen is an integration tool for developing and testing infrastructure code and software on isolated target platforms
Other
1.86k stars 583 forks source link

kitchen login, password prompt #1461

Closed guskovd closed 5 years ago

guskovd commented 5 years ago

It seems that kitchen login does not use the password option

D      [local command] BEGIN (docker >> /dev/null 2>&1)
D      [local command] END (0m0.04s)
D      Login command: ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=VERBOSE -p 22 vagrant@172.17.0.2 (Options: {})
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
Password:

kitchen converge - OK

 --> kitchen converge  default-macos -l debug
-----> Starting Kitchen (v1.23.2)
D      [local command] BEGIN (docker >> /dev/null 2>&1)
D      [local command] END (0m0.05s)
-----> Converging <default-macos>...
       Preparing files for transfer
D      Creating local sandbox in /tmp/default-macos-sandbox-20180910-22271-1hw4v6s
       Preparing data
D      Using data from /home/guskov/prog/openstack-dev/states/qemu/data
       Preparing script
       No provisioner script file specified, skipping
       Transferring files to <default-macos>
D      TIMING: scp async upload (Kitchen::Transport::Ssh)
D      [SSH] opening connection to vagrant@172.17.0.2<{:user_known_hosts_file=>"/dev/null", :port=>22, :compression=>false, :compression_level=>0, :keepalive=>true, :keepalive_interval=>60, :timeout=>15, :password=>"vagrant", :verify_host
_key=>false}>                                                                                                                                                                                                                                
D      TIMING: scp async upload (Kitchen::Transport::Ssh) took (0m0.28s)
D      Transfer complete
D      Attempting to execute command - try 1 of 1.
D      [SSH] vagrant@172.17.0.2<{:user_known_hosts_file=>"/dev/null", :port=>22, :compression=>false, :compression_level=>0, :keepalive=>true, :keepalive_interval=>60, :timeout=>15, :password=>"vagrant", :verify_host_key=>false, :logger=>
#<Logger:0x0000000002bf16a0 @level=4, @progname=nil, @default_formatter=#<Logger::Formatter:0x0000000002bf1628 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x0000000002bf15d8 @shift_period_suffix=nil, @shift_size=nil
, @shift_age=nil, @filename=nil, @dev=#<IO:<STDERR>>, @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x0000000002bf1588>>>, :password_prompt=>#<Net::SSH::Prompt:0x0000000002bf1560>, :user=>"vagrant"}> (sh -c '                  
TEST_KITCHEN="1"; export TEST_KITCHEN
/tmp/kitchen/data/provision.sh
')
       hello
       Downloading files from <default-macos>
D      Download complete
D      Cleaning up local sandbox in /tmp/default-macos-sandbox-20180910-22271-1hw4v6s
       Finished converging <default-macos> (0m0.34s).
D      [SSH] shutting previous connection vagrant@172.17.0.2<{:user_known_hosts_file=>"/dev/null", :port=>22, :compression=>false, :compression_level=>0, :keepalive=>true, :keepalive_interval=>60, :timeout=>15, :password=>"vagrant", :veri
fy_host_key=>false, :logger=>#<Logger:0x0000000002bf16a0 @level=4, @progname=nil, @default_formatter=#<Logger::Formatter:0x0000000002bf1628 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x0000000002bf15d8 @shift_perio
d_suffix=nil, @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDERR>>, @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x0000000002bf1588>>>, :password_prompt=>#<Net::SSH::Prompt:0x0000000002bf1560>, :user=>"vagrant"}
>                                                                                                                                                                                                                                            
-----> Kitchen is finished. (0m0.43s)
guskovd commented 5 years ago

kitchen diagnose default-macos

    transport:
      compression: false
      compression_level: 0
      connection_retries: 5
      connection_retry_sleep: 1
      connection_timeout: 15
      keepalive: true
      keepalive_interval: 60
      kitchen_root: "/home/guskov/prog/openstack-dev/states/qemu"
      log_level: :info
      max_ssh_sessions: 9
      max_wait_until_ready: 600
      name: ssh
      password: vagrant
      port: 22
      ssh_gateway: 
      ssh_gateway_port: 22
      ssh_gateway_username: 
      ssh_http_proxy: 
      ssh_http_proxy_password: 
      ssh_http_proxy_port: 
      ssh_http_proxy_user: 
      ssh_key: 
      test_base_path: "/home/guskov/prog/openstack-dev/states/qemu/test/integration"
      username: vagrant
guskovd commented 5 years ago

By the code, login_command does not use Net::SSH, which allows to bypass the interactive input of the password. I do not really understand how this should work without sshpass / Net::SSH

guskovd commented 5 years ago

my dirty workaround:

lib/kitchen/transport/ssh_patch.rb:

require 'kitchen/transport/ssh'

module Kitchen
  module Transport
    # Wrapped exception for any internally raised SSH-related errors.
    class Ssh < Kitchen::Transport::Base
      class Connection < Kitchen::Transport::Base::Connection
        def login_command
          args  = %w{ -o UserKnownHostsFile=/dev/null }
          args += %w{ -o StrictHostKeyChecking=no }
          args += %w{ -o IdentitiesOnly=yes } if options[:keys]
          args += %W{ -o LogLevel=#{logger.debug? ? 'VERBOSE' : 'ERROR'} }
          if options.key?(:forward_agent)
            args += %W{ -o ForwardAgent=#{options[:forward_agent] ? 'yes' : 'no'} }
          end
          if ssh_gateway
            gateway_command = "ssh -q #{ssh_gateway_username}@#{ssh_gateway} nc #{hostname} #{port}"
            args += %W{ -o ProxyCommand=#{gateway_command} -p #{ssh_gateway_port} }
          end
          Array(options[:keys]).each { |ssh_key| args += %W{ -i #{ssh_key} } }
          args += %W{ -p #{port} }
          args += %W{ #{username}@#{hostname} }

          if options[:password]
            LoginCommand.new("sshpass", ["-p", options[:password], "ssh"] + args)
          else
            LoginCommand.new("ssh", args)
          end
        end
      end
    end
  end
end

and in .kitchen.yml:

<% require_relative 'lib/kitchen/transport/ssh_patch.rb' %>
cheeseplus commented 5 years ago

What driver are you using?

It appears from the output that you're using kitchen-vagrant in which case Vagrant presumes base boxes have an SSH key already added. This isn't to say we can't make login friendlier in some respects but it generally follows how the drivers operate and almost all of them expect ssh keys.

guskovd commented 5 years ago

In our infrastructure I use kitchen-openstack, kitchen-qemu and kitchen-docker. In some cases it is quite inconvenient to use keys, for example when working with windows and macos images. They are not very well compatible with cloud-init / nocloud So I would like to use a password.

coderanger commented 5 years ago

I don't think we want to make Kitchen reliant on sshpass as an external tool. So my vote is that you can use passwords just fine, but that kitchen login won't be automatic. You can use kitchen exec for single, non-interactive commands, which runs via Kitchen's transport layer and so will work without having to type something in.

cheeseplus commented 5 years ago

kitchen login has never worked for Windows as there is no expected shell, it drops an RDP file so that's moot. For MacOS I know this works because I build images for Chef internally and the standard method of making a key available for Vagrant work exactly as expected.

That is to say, if you want to do things your own way and disregard the standard Vagrant guidance for building boxes that's your call but we're not going to change the tool to support something explicitly recommended against without very good reason.

guskovd commented 5 years ago

I do not understand why you can call mstsc.exe from test-kitchen: https://github.com/test-kitchen/test-kitchen/blob/9c771433645495500f0c6da21927208826ec8d5d/lib/kitchen/transport/winrm.rb#L318 but you can not use sshpass.

coderanger commented 5 years ago

That's a standard program included with Windows (at least Windows Server) and more importantly there isn't really much of an option or I would happily change that to be more generic :) Conversely sshpass is not generally installed on most machines and this addresses a very niche use case.

guskovd commented 5 years ago

kitchen login has never worked for Windows as there is no expected shell, it drops an RDP file so that's moot. For MacOS I know this works because I build images for Chef internally and the standard method of making a key available for Vagrant work exactly as expected.

I'm using cygwin + ssh. kitchen converge works great. kitchen login - no

coderanger commented 5 years ago

"for Windows" he meant Windows test instances, not Windows workstations. The OS of the workstation is mostly moot, though we do change which RDP client is used by default based on the workstation OS.

guskovd commented 5 years ago

Here is another example of use. kitchen-transport-rsync uses the login_command method. https://github.com/unibet/kitchen-transport-rsync/blob/d6b60ddbfdc1f08d72fd5a49d0b048627b80c285/lib/kitchen/transport/rsync.rb#L42 It seems that their plugin works with my patch

coderanger commented 5 years ago

Sure, you can certainly move this sshpass support into your own plugin. Going to close this out.

guskovd commented 5 years ago

In my opinion, where to write warning to user: "install sshpass", if it is not installed and drop to enter password

guskovd commented 5 years ago

In my opinion, where to write warning to user: "install sshpass", if it is not installed and drop to enter password

If I make a merge-request with this approach, do you accept?

cheeseplus commented 5 years ago

No, this goes against how most drivers operate and doesn't solve a general problem - this solves only a specific problem for yourself that is because you're not baking the boxes/base images with keys which is fairly standard practice at this point.

As @coderanger mentions, you can write your own plugin to do this but it's not something we intend to support for all the reasons given.

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.