Skip to content

Commit

Permalink
Merge pull request #122 from chef/winrm-v2
Browse files Browse the repository at this point in the history
Use winrm v2 implementation
  • Loading branch information
chris-rock authored Sep 4, 2016
2 parents a2704f6 + 3fd4fad commit 560b159
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 35 deletions.
12 changes: 9 additions & 3 deletions lib/train/extras/command_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# author: Christoph Hartmann

require 'base64'
require 'winrm'
require 'train/errors'

module Train::Extras
Expand Down Expand Up @@ -114,15 +113,22 @@ def run(script)
# especially in local mode, we cannot be sure that we get a Powershell
# we may just get a `cmd`.
# TODO: we may want to opt for powershell.exe -command instead of `encodeCommand`
"powershell -encodedCommand #{WinRM::PowershellScript.new(safe_script(script)).encoded}"
"powershell -encodedCommand #{encoded(safe_script(script))}"
end

# reused from https://github.com/WinRb/WinRM/blob/master/lib/winrm/command_executor.rb
# suppress the progress stream from leaking to stderr
def safe_script(script)
"$ProgressPreference='SilentlyContinue';" + script
end

# Encodes the script so that it can be passed to the PowerShell
# --EncodedCommand argument.
# @return [String] The UTF-16LE base64 encoded script
def encoded(script)
encoded_script = safe_script(script).encode('UTF-16LE', 'UTF-8')
Base64.strict_encode64(encoded_script)
end

def to_s
'PowerShell CommandWrapper'
end
Expand Down
6 changes: 3 additions & 3 deletions lib/train/transports/winrm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def validate_options(opts)
opts[:endpoint] = "#{scheme}://#{opts[:host]}:#{port}/#{path}"
end

WINRM_FS_SPEC_VERSION = '~> 0.3'.freeze
WINRM_FS_SPEC_VERSION = '~> 1.0'.freeze

# Builds the hash of options needed by the Connection object on
# construction.
Expand All @@ -100,12 +100,12 @@ def validate_options(opts)
def connection_options(opts)
{
logger: logger,
winrm_transport: :negotiate,
transport: :negotiate,
disable_sspi: false,
basic_auth_only: false,
endpoint: opts[:endpoint],
user: opts[:user],
pass: opts[:password],
password: opts[:password],
rdp_port: opts[:rdp_port],
connection_retries: opts[:connection_retries],
connection_retry_sleep: opts[:connection_retry_sleep],
Expand Down
19 changes: 8 additions & 11 deletions lib/train/transports/winrm_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ class Train::Transports::WinRM
class Connection < BaseConnection
def initialize(options)
super(options)
@endpoint = @options.delete(:endpoint)
@rdp_port = @options.delete(:rdp_port)
@winrm_transport = @options.delete(:winrm_transport)
@connection_retries = @options.delete(:connection_retries)
@connection_retry_sleep = @options.delete(:connection_retry_sleep)
@max_wait_until_ready = @options.delete(:max_wait_until_ready)
Expand All @@ -59,11 +57,11 @@ def run_command(command)
logger.debug("[WinRM] #{self} (#{command})")
out = ''

response = session.run_powershell_script(command) do |stdout, _|
response = session.run(command) do |stdout, _|
out << stdout if stdout
end

CommandResult.new(out, response.stderr, response[:exitcode])
CommandResult.new(out, response.stderr, response.exitcode)
end

# (see Base::Connection#login_command)
Expand Down Expand Up @@ -98,7 +96,7 @@ def wait_until_ready
end

def uri
"winrm://#{options[:user]}@#{@endpoint}:#{@rdp_port}"
"winrm://#{options[:user]}@#{options[:endpoint]}:#{@rdp_port}"
end

private
Expand All @@ -112,7 +110,7 @@ def uri
# Mac system
# @api private
def rdp_doc(opts = {})
host = URI.parse(@endpoint).host
host = URI.parse(options[:endpoint]).host
content = [
"full address:s:#{host}:#{@rdp_port}",
'prompt for credentials:i:1',
Expand All @@ -139,7 +137,7 @@ def file_transporter
def login_command_for_linux
args = %W( -u #{options[:user]} )
args += %W( -p #{options[:pass]} ) if options.key?(:pass)
args += %W( #{URI.parse(@endpoint).host}:#{@rdp_port} )
args += %W( #{URI.parse(options[:endpoint]).host}:#{@rdp_port} )
LoginCommand.new('rdesktop', args)
end

Expand Down Expand Up @@ -172,10 +170,9 @@ def session(retry_options = {})
retry_delay: @connection_retry_sleep.to_i,
}.merge(retry_options)

service_args = [@endpoint, @winrm_transport, options.merge(opts)]
@service = ::WinRM::WinRMWebService.new(*service_args)
@service = ::WinRM::Connection.new(options.merge(opts))
@service.logger = logger
@service.create_executor
@service.shell(:powershell)
end
end

Expand All @@ -184,7 +181,7 @@ def session(retry_options = {})
#
# @api private
def to_s
"#{@winrm_transport}::#{@endpoint}<#{options.inspect}>"
"<#{options.inspect}>"
end

class OS < OSCommon
Expand Down
16 changes: 0 additions & 16 deletions test/unit/extras/command_wrapper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,3 @@
lc.run(cmd).must_equal "echo #{bpw} | base64 --decode | #{sudo_command} -S #{cmd}"
end
end

describe 'powershell command' do
let(:cls) { Train::Extras::PowerShellCommand }
let(:cmd) { rand.to_s }
let(:backend) {
backend = Train::Transports::Mock.new.connection
backend.mock_os({ family: 'windows' })
backend
}

it 'wraps commands in powershell' do
lc = cls.new(backend, {})
tmp =
lc.run(cmd).must_equal "powershell -encodedCommand #{WinRM::PowershellScript.new('$ProgressPreference=\'SilentlyContinue\';' + cmd).encoded}"
end
end
4 changes: 2 additions & 2 deletions train.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Gem::Specification.new do |spec|
# 1.9 support is no longer needed here or for Inspec
spec.add_dependency 'net-ssh', '>= 2.9', '< 4.0'
spec.add_dependency 'net-scp', '~> 1.2'
spec.add_dependency 'winrm', '~> 1.6'
spec.add_dependency 'winrm-fs', '~> 0.3'
spec.add_dependency 'winrm', '~> 2.0'
spec.add_dependency 'winrm-fs', '~> 1.0'
spec.add_dependency 'docker-api', '~> 1.26'

spec.add_development_dependency 'mocha', '~> 1.1'
Expand Down

0 comments on commit 560b159

Please sign in to comment.