class Kitchen::Transport::Ssh

A Transport which uses the SSH protocol to execute commands and transfer files.

@author Fletcher Nichol <fnichol@nichol.ca>

Public Instance Methods

cleanup!() click to toggle source

(see Base#cleanup!)

# File lib/kitchen/transport/ssh.rb, line 104
def cleanup!
  if @connection
    string_to_mask = "[SSH] shutting previous connection #{@connection}"
    masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
    logger.debug(masked_string)
    @connection.close
    @connection = @connection_options = nil
  end
end
connection(state, &block) click to toggle source

(see Base#connection)

# File lib/kitchen/transport/ssh.rb, line 93
def connection(state, &block)
  options = connection_options(config.to_hash.merge(state))

  if @connection && @connection_options == options
    reuse_connection(&block)
  else
    create_new_connection(options, &block)
  end
end
finalize_config!(instance) click to toggle source
Calls superclass method Kitchen::Configurable#finalize_config!
# File lib/kitchen/transport/ssh.rb, line 77
def finalize_config!(instance)
  super

  # zlib was never a valid value and breaks in net-ssh >= 2.10
  # TODO: remove these backwards compatiable casts in 2.0
  case config[:compression]
  when "zlib"
    config[:compression] = "zlib@openssh.com"
  when "none"
    config[:compression] = false
  end

  self
end

Private Instance Methods

connection_options(data) click to toggle source

Builds the hash of options needed by the Connection object on construction.

@param data [Hash] merged configuration and mutable state data @return [Hash] hash of connection options @api private rubocop:disable Metrics/MethodLength, Metrics/AbcSize

# File lib/kitchen/transport/ssh.rb, line 469
def connection_options(data)
  opts = {
    logger: logger,
    user_known_hosts_file: "/dev/null",
    hostname: data[:hostname],
    port: data[:port],
    username: data[:username],
    compression: data[:compression],
    compression_level: data[:compression_level],
    keepalive: data[:keepalive],
    keepalive_interval: data[:keepalive_interval],
    keepalive_maxcount: data[:keepalive_maxcount],
    timeout: data[:connection_timeout],
    connection_retries: data[:connection_retries],
    connection_retry_sleep: data[:connection_retry_sleep],
    max_ssh_sessions: data[:max_ssh_sessions],
    max_wait_until_ready: data[:max_wait_until_ready],
    ssh_gateway: data[:ssh_gateway],
    ssh_gateway_username: data[:ssh_gateway_username],
    ssh_gateway_port: data[:ssh_gateway_port],
  }

  if data[:ssh_key] && !data[:password]
    opts[:keys_only] = true
    opts[:keys] = Array(data[:ssh_key])
    opts[:auth_methods] = ["publickey"]
  end

  if data[:ssh_http_proxy]
    options_http_proxy = {}
    options_http_proxy[:user] = data[:ssh_http_proxy_user]
    options_http_proxy[:password] = data[:ssh_http_proxy_password]
    opts[:proxy] = Net::SSH::Proxy::HTTP.new(data[:ssh_http_proxy], data[:ssh_http_proxy_port], options_http_proxy)
  end

  if data[:ssh_key_only]
    opts[:auth_methods] = ["publickey"]
  end

  opts[:password] = data[:password]           if data.key?(:password)
  opts[:forward_agent] = data[:forward_agent] if data.key?(:forward_agent)
  opts[:verbose] = data[:verbose].to_sym      if data.key?(:verbose)

  # disable host key verification. The hash key and value to use
  # depend on the version of net-ssh in use
  opts[verify_host_key_option] = verify_host_key_value

  opts
end
create_new_connection(options, &block) click to toggle source

Creates a new SSH Connection instance and save it for potential future reuse.

@param options [Hash] connection options @return [Ssh::Connection] an SSH Connection instance @api private

# File lib/kitchen/transport/ssh.rb, line 556
def create_new_connection(options, &block)
  cleanup!
  @connection_options = options
  @connection = Kitchen::Transport::Ssh::Connection.new(options, &block)
end
reuse_connection() { |connection| ... } click to toggle source

Return the last saved SSH connection instance.

@return [Ssh::Connection] an SSH Connection instance @api private

# File lib/kitchen/transport/ssh.rb, line 566
def reuse_connection
  string_to_mask = "[SSH] reusing existing connection #{@connection}"
  masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
  logger.debug(masked_string)
  yield @connection if block_given?
  @connection
end
verify_host_key_option() click to toggle source

Returns the correct host-key-verification option key to use depending on what version of net-ssh is in use. In net-ssh <= 4.1, the supported parameter is `paranoid` but in 4.2, it became `verify_host_key`

`verify_host_key` does not work in <= 4.1, and `paranoid` throws deprecation warnings in >= 4.2.

While the “right thing” to do would be to pin train's dependency on net-ssh to ~> 4.2, this will prevent InSpec from being used in Chef v12 because of it pinning to a v3 of net-ssh.

# File lib/kitchen/transport/ssh.rb, line 531
def verify_host_key_option
  current_net_ssh = Net::SSH::Version::CURRENT
  new_option_version = Net::SSH::Version[4, 2, 0]

  current_net_ssh >= new_option_version ? :verify_host_key : :paranoid
end
verify_host_key_value() click to toggle source

Returns the correct host-key-verification option value to use depending on what version of net-ssh is in use. In net-ssh <= 5, the supported parameter is false but in 5.0, it became `:never`

# File lib/kitchen/transport/ssh.rb, line 543
def verify_host_key_value
  current_net_ssh = Net::SSH::Version::CURRENT
  new_option_version = Net::SSH::Version[5, 0, 0]

  current_net_ssh >= new_option_version ? :never : false
end