winrm 1.8.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -11
  3. data/.rubocop.yml +26 -22
  4. data/.travis.yml +11 -12
  5. data/Gemfile +3 -9
  6. data/LICENSE +202 -202
  7. data/README.md +232 -215
  8. data/Rakefile +34 -36
  9. data/Vagrantfile +6 -9
  10. data/WinrmAppveyor.psm1 +31 -31
  11. data/appveyor.yml +51 -51
  12. data/bin/rwinrm +97 -97
  13. data/changelog.md +86 -86
  14. data/lib/winrm.rb +39 -42
  15. data/lib/winrm/connection.rb +82 -0
  16. data/lib/winrm/connection_opts.rb +87 -0
  17. data/lib/winrm/{exceptions/exceptions.rb → exceptions.rb} +76 -57
  18. data/lib/winrm/http/response_handler.rb +96 -82
  19. data/lib/winrm/http/transport.rb +424 -435
  20. data/lib/winrm/http/transport_factory.rb +68 -0
  21. data/lib/winrm/output.rb +59 -43
  22. data/lib/winrm/psrp/create_pipeline.xml.erb +167 -0
  23. data/lib/winrm/psrp/fragment.rb +70 -0
  24. data/lib/winrm/psrp/init_runspace_pool.xml.erb +224 -0
  25. data/lib/winrm/psrp/message.rb +130 -0
  26. data/lib/winrm/psrp/message_data.rb +41 -0
  27. data/lib/winrm/psrp/message_data/base.rb +49 -0
  28. data/lib/winrm/psrp/message_data/error_record.rb +68 -0
  29. data/lib/winrm/psrp/message_data/pipeline_host_call.rb +32 -0
  30. data/lib/winrm/psrp/message_data/pipeline_output.rb +49 -0
  31. data/lib/winrm/psrp/message_data/runspacepool_host_call.rb +32 -0
  32. data/lib/winrm/psrp/message_data/runspacepool_state.rb +39 -0
  33. data/lib/winrm/psrp/message_data/session_capability.rb +36 -0
  34. data/lib/winrm/psrp/message_defragmenter.rb +62 -0
  35. data/lib/winrm/psrp/message_factory.rb +75 -0
  36. data/lib/winrm/psrp/message_fragmenter.rb +60 -0
  37. data/lib/winrm/psrp/powershell_output_decoder.rb +120 -0
  38. data/lib/winrm/psrp/receive_response_reader.rb +93 -0
  39. data/lib/winrm/psrp/session_capability.xml.erb +7 -0
  40. data/lib/winrm/psrp/uuid.rb +40 -0
  41. data/lib/winrm/shells/base.rb +175 -0
  42. data/lib/winrm/shells/cmd.rb +65 -0
  43. data/lib/winrm/shells/power_shell.rb +201 -0
  44. data/lib/winrm/shells/retryable.rb +45 -0
  45. data/lib/winrm/shells/shell_factory.rb +50 -0
  46. data/lib/winrm/version.rb +7 -7
  47. data/lib/winrm/wsmv/base.rb +59 -0
  48. data/lib/winrm/wsmv/cleanup_command.rb +61 -0
  49. data/lib/winrm/wsmv/close_shell.rb +50 -0
  50. data/lib/winrm/wsmv/command.rb +101 -0
  51. data/lib/winrm/wsmv/command_output.rb +76 -0
  52. data/lib/winrm/wsmv/command_output_decoder.rb +55 -0
  53. data/lib/winrm/wsmv/configuration.rb +46 -0
  54. data/lib/winrm/wsmv/create_pipeline.rb +66 -0
  55. data/lib/winrm/wsmv/create_shell.rb +119 -0
  56. data/lib/winrm/wsmv/header.rb +203 -0
  57. data/lib/winrm/wsmv/init_runspace_pool.rb +95 -0
  58. data/lib/winrm/wsmv/iso8601_duration.rb +60 -0
  59. data/lib/winrm/wsmv/keep_alive.rb +68 -0
  60. data/lib/winrm/wsmv/receive_response_reader.rb +128 -0
  61. data/lib/winrm/wsmv/send_data.rb +68 -0
  62. data/lib/winrm/wsmv/soap.rb +51 -0
  63. data/lib/winrm/wsmv/wql_query.rb +79 -0
  64. data/lib/winrm/wsmv/write_stdin.rb +88 -0
  65. data/preamble +17 -17
  66. data/{spec → tests/integration}/auth_timeout_spec.rb +18 -16
  67. data/{spec → tests/integration}/cmd_spec.rb +104 -102
  68. data/{spec → tests/integration}/config-example.yml +16 -19
  69. data/{spec → tests/integration}/issue_59_spec.rb +26 -23
  70. data/tests/integration/powershell_spec.rb +154 -0
  71. data/{spec → tests/integration}/spec_helper.rb +65 -73
  72. data/{spec → tests/integration}/transport_spec.rb +99 -139
  73. data/{spec → tests/integration}/wql_spec.rb +16 -14
  74. data/{spec → tests}/matchers.rb +60 -74
  75. data/tests/spec/configuration_spec.rb +93 -0
  76. data/tests/spec/connection_spec.rb +39 -0
  77. data/{spec → tests/spec}/exception_spec.rb +50 -50
  78. data/tests/spec/http/transport_factory_spec.rb +68 -0
  79. data/tests/spec/http/transport_spec.rb +44 -0
  80. data/{spec → tests/spec}/output_spec.rb +127 -110
  81. data/tests/spec/psrp/fragment_spec.rb +62 -0
  82. data/tests/spec/psrp/message_data/base_spec.rb +13 -0
  83. data/tests/spec/psrp/message_data/error_record_spec.rb +41 -0
  84. data/tests/spec/psrp/message_data/pipeline_host_call_spec.rb +25 -0
  85. data/tests/spec/psrp/message_data/pipeline_output_spec.rb +32 -0
  86. data/tests/spec/psrp/message_data/runspace_pool_host_call_spec.rb +25 -0
  87. data/tests/spec/psrp/message_data/runspacepool_state_spec.rb +16 -0
  88. data/tests/spec/psrp/message_data/session_capability_spec.rb +30 -0
  89. data/tests/spec/psrp/message_data_spec.rb +35 -0
  90. data/tests/spec/psrp/message_defragmenter_spec.rb +47 -0
  91. data/tests/spec/psrp/message_fragmenter_spec.rb +105 -0
  92. data/tests/spec/psrp/powershell_output_decoder_spec.rb +84 -0
  93. data/tests/spec/psrp/psrp_message_spec.rb +70 -0
  94. data/tests/spec/psrp/recieve_response_reader_spec.rb +154 -0
  95. data/tests/spec/psrp/uuid_spec.rb +28 -0
  96. data/{spec → tests/spec}/response_handler_spec.rb +61 -61
  97. data/tests/spec/shells/base_spec.rb +202 -0
  98. data/tests/spec/shells/cmd_spec.rb +75 -0
  99. data/tests/spec/shells/powershell_spec.rb +175 -0
  100. data/tests/spec/spec_helper.rb +47 -0
  101. data/tests/spec/stubs/clixml/error_record.xml.erb +84 -0
  102. data/{spec → tests/spec}/stubs/responses/get_command_output_response.xml.erb +13 -13
  103. data/tests/spec/stubs/responses/get_command_output_response_not_done.xml.erb +10 -0
  104. data/tests/spec/stubs/responses/get_powershell_keepalive_response.xml.erb +10 -0
  105. data/tests/spec/stubs/responses/get_powershell_output_response.xml.erb +12 -0
  106. data/tests/spec/stubs/responses/get_powershell_output_response_not_done.xml.erb +9 -0
  107. data/{spec → tests/spec}/stubs/responses/open_shell_v1.xml +19 -19
  108. data/{spec → tests/spec}/stubs/responses/open_shell_v2.xml +20 -20
  109. data/{spec → tests/spec}/stubs/responses/soap_fault_v1.xml +36 -36
  110. data/{spec → tests/spec}/stubs/responses/soap_fault_v2.xml +42 -42
  111. data/{spec → tests/spec}/stubs/responses/wmi_error_v2.xml +41 -41
  112. data/tests/spec/wsmv/cleanup_command_spec.rb +22 -0
  113. data/tests/spec/wsmv/close_shell_spec.rb +17 -0
  114. data/{spec → tests/spec/wsmv}/command_output_decoder_spec.rb +37 -37
  115. data/tests/spec/wsmv/command_output_spec.rb +45 -0
  116. data/tests/spec/wsmv/command_spec.rb +19 -0
  117. data/tests/spec/wsmv/configuration_spec.rb +17 -0
  118. data/tests/spec/wsmv/create_pipeline_spec.rb +31 -0
  119. data/tests/spec/wsmv/create_shell_spec.rb +38 -0
  120. data/tests/spec/wsmv/init_runspace_pool_spec.rb +36 -0
  121. data/tests/spec/wsmv/keep_alive_spec.rb +21 -0
  122. data/tests/spec/wsmv/receive_response_reader_spec.rb +123 -0
  123. data/tests/spec/wsmv/send_data_spec.rb +30 -0
  124. data/tests/spec/wsmv/wql_query_spec.rb +13 -0
  125. data/tests/spec/wsmv/write_stdin_spec.rb +22 -0
  126. data/winrm.gemspec +42 -40
  127. metadata +140 -38
  128. data/.rspec +0 -3
  129. data/lib/winrm/command_executor.rb +0 -243
  130. data/lib/winrm/command_output_decoder.rb +0 -53
  131. data/lib/winrm/helpers/iso8601_duration.rb +0 -58
  132. data/lib/winrm/helpers/powershell_script.rb +0 -42
  133. data/lib/winrm/soap_provider.rb +0 -39
  134. data/lib/winrm/winrm_service.rb +0 -550
  135. data/spec/command_executor_spec.rb +0 -475
  136. data/spec/issue_184_spec.rb +0 -67
  137. data/spec/powershell_spec.rb +0 -97
  138. data/spec/winrm_options_spec.rb +0 -76
  139. data/spec/winrm_primitives_spec.rb +0 -51
@@ -1,23 +1,26 @@
1
- # encoding: UTF-8
2
- describe 'issue 59', integration: true do
3
- before(:all) do
4
- @winrm = winrm_connection
5
- end
6
-
7
- describe 'long running script without output' do
8
- let(:logged_output) { StringIO.new }
9
- let(:logger) { Logging.logger(logged_output) }
10
-
11
- it 'should not error' do
12
- @winrm.set_timeout(1)
13
- @winrm.logger = logger
14
-
15
- out = @winrm.powershell('$ProgressPreference="SilentlyContinue";sleep 3; Write-Host "Hello"')
16
-
17
- expect(out).to have_exit_code 0
18
- expect(out).to have_stdout_match(/Hello/)
19
- expect(out).to have_no_stderr
20
- expect(logged_output.string).to match(/retrying receive request/)
21
- end
22
- end
23
- end
1
+ # encoding: UTF-8
2
+ require_relative 'spec_helper'
3
+
4
+ describe 'issue 59' do
5
+ describe 'long running script without output' do
6
+ let(:logged_output) { StringIO.new }
7
+ let(:logger) { Logging.logger(logged_output) }
8
+
9
+ before do
10
+ opts = connection_opts.dup
11
+ opts[:operation_timeout] = 1
12
+ conn = WinRM::Connection.new(opts)
13
+ conn.logger = logger
14
+ @powershell = conn.shell(:powershell)
15
+ end
16
+
17
+ it 'should not error' do
18
+ out = @powershell.run('$ProgressPreference="SilentlyContinue";sleep 3; Write-Host "Hello"')
19
+
20
+ expect(out).to have_exit_code 0
21
+ expect(out).to have_stdout_match(/Hello/)
22
+ expect(out).to have_no_stderr
23
+ expect(logged_output.string).to match(/retrying receive request/)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,154 @@
1
+ # encoding: UTF-8
2
+ require_relative 'spec_helper'
3
+
4
+ describe 'winrm client powershell' do
5
+ before(:all) do
6
+ @powershell = winrm_connection.shell(:powershell)
7
+ end
8
+
9
+ describe 'ipconfig' do
10
+ subject(:output) { @powershell.run('ipconfig') }
11
+ it { should have_exit_code 0 }
12
+ it { should have_stdout_match(/Windows IP Configuration/) }
13
+ it { should have_no_stderr }
14
+ end
15
+
16
+ describe 'exit' do
17
+ subject(:output) { @powershell.run('exit 5') }
18
+ it { should have_exit_code 5 }
19
+ end
20
+
21
+ describe 'echo \'hello world\' using apostrophes' do
22
+ subject(:output) { @powershell.run("echo 'hello world'") }
23
+ it { should have_exit_code 0 }
24
+ it { should have_stdout_match(/hello world/) }
25
+ it { should have_no_stderr }
26
+ end
27
+
28
+ describe 'handling special XML characters' do
29
+ subject(:output) { @powershell.run("echo 'hello & <world>'") }
30
+ it { should have_exit_code 0 }
31
+ it { should have_stdout_match(/hello & <world>/) }
32
+ it { should have_no_stderr }
33
+ end
34
+
35
+ describe 'dir with incorrect argument /z' do
36
+ subject(:output) { @powershell.run('dir /z') }
37
+ it { should have_stderr_match(/Cannot find path/) }
38
+ it { should have_no_stdout }
39
+ end
40
+
41
+ describe 'Math area calculation' do
42
+ subject(:output) do
43
+ @powershell.run <<-EOH
44
+ $diameter = 4.5
45
+ $area = [Math]::pow([Math]::PI * ($diameter/2), 2)
46
+ Write-Host $area
47
+ EOH
48
+ end
49
+ it { should have_exit_code 0 }
50
+ it { should have_stdout_match(/49.9648722805149/) }
51
+ it { should have_no_stderr }
52
+ end
53
+
54
+ describe 'ipconfig with a block' do
55
+ subject(:stdout) do
56
+ outvar = ''
57
+ @powershell.run('ipconfig') do |stdout, _stderr|
58
+ outvar << stdout
59
+ end
60
+ outvar
61
+ end
62
+ it { should match(/Windows IP Configuration/) }
63
+ end
64
+
65
+ describe 'capturing output from Write-Host and Write-Error' do
66
+ subject(:output) do
67
+ script = <<-eos
68
+ Write-Host 'Hello'
69
+ $host.ui.WriteErrorLine(', world!')
70
+ eos
71
+
72
+ @captured_stdout = ''
73
+ @captured_stderr = ''
74
+ @powershell.run(script) do |stdout, stderr|
75
+ @captured_stdout << stdout if stdout
76
+ @captured_stderr << stderr if stderr
77
+ end
78
+ end
79
+
80
+ it 'should have stdout' do
81
+ expect(output.stdout).to eq("Hello\r\n")
82
+ expect(output.stdout).to eq(@captured_stdout)
83
+ end
84
+
85
+ it 'should have stderr' do
86
+ expect(output.stderr).to eq(", world!\r\n")
87
+ expect(output.stderr).to eq(@captured_stderr)
88
+ end
89
+
90
+ it 'should have output' do
91
+ expect(output.output).to eq("Hello\r\n, world!\r\n")
92
+ end
93
+ end
94
+
95
+ describe 'capturing output from pipeline followed by Host' do
96
+ subject(:output) do
97
+ script = <<-eos
98
+ Write-Output 'output'
99
+ $host.UI.Writeline('host')
100
+ eos
101
+
102
+ @captured_stdout = ''
103
+ @captured_stderr = ''
104
+ @powershell.run(script) do |stdout, stderr|
105
+ @captured_stdout << stdout if stdout
106
+ @captured_stderr << stderr if stderr
107
+ end
108
+ end
109
+
110
+ it 'should print from the pipeline first' do
111
+ expect(output.stdout).to start_with("output\r\n")
112
+ end
113
+
114
+ it 'should write to host last' do
115
+ expect(output.stdout).to end_with("host\r\n")
116
+ end
117
+ end
118
+
119
+ describe 'it should handle utf-8 characters' do
120
+ subject(:output) { @powershell.run('echo "✓1234-äöü"') }
121
+ it { should have_exit_code 0 }
122
+ it { should have_stdout_match(/✓1234-äöü/) }
123
+ end
124
+
125
+ describe 'output exceeds a single fragment' do
126
+ subject(:output) { @powershell.run('Write-Output $("a"*600000)') }
127
+ it { should have_exit_code 0 }
128
+ it 'has assebled the output' do
129
+ expect(output.stdout).to eq('a' * 600000 + "\r\n")
130
+ end
131
+ end
132
+
133
+ describe 'command exceeds a single fragment' do
134
+ subject(:output) { @powershell.run("$var='#{'a' * 600000}';Write-Output 'long var'") }
135
+ it { should have_exit_code 0 }
136
+ it 'has sent the output' do
137
+ expect(output.stdout).to eq("long var\r\n")
138
+ end
139
+ end
140
+
141
+ describe 'reading pipeline messages' do
142
+ subject(:messages) { @powershell.send_pipeline_command('ipconfig') }
143
+
144
+ it 'returns multiple messages' do
145
+ expect(messages.length).to be > 1
146
+ end
147
+ it 'first message is pipeline output' do
148
+ expect(messages.first.type).to eq(WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output])
149
+ end
150
+ it 'last message is pipeline state' do
151
+ expect(messages.last.type).to eq(WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_state])
152
+ end
153
+ end
154
+ end
@@ -1,73 +1,65 @@
1
- # encoding: UTF-8
2
- require 'rubygems'
3
- require 'bundler/setup'
4
- require 'winrm'
5
- require 'json'
6
- require_relative 'matchers'
7
-
8
- # Creates a WinRM connection for integration tests
9
- module ConnectionHelper
10
- # rubocop:disable AbcSize
11
- def winrm_connection
12
- winrm = WinRM::WinRMWebService.new(
13
- config[:endpoint], config[:auth_type].to_sym, config[:options])
14
- winrm.logger.level = :error
15
- winrm
16
- end
17
- # rubocop:enable AbcSize
18
-
19
- def config
20
- @config ||= begin
21
- cfg = symbolize_keys(YAML.load(File.read(winrm_config_path)))
22
- cfg[:options].merge!(basic_auth_only: true) unless cfg[:auth_type].eql? :kerberos
23
- merge_environment!(cfg)
24
- cfg
25
- end
26
- end
27
-
28
- def merge_environment!(config)
29
- merge_config_option_from_environment(config, 'user')
30
- merge_config_option_from_environment(config, 'pass')
31
- merge_config_option_from_environment(config, 'no_ssl_peer_verification')
32
- if ENV['use_ssl_peer_fingerprint']
33
- config[:options][:ssl_peer_fingerprint] = ENV['winrm_cert']
34
- end
35
- config[:endpoint] = ENV['winrm_endpoint'] if ENV['winrm_endpoint']
36
- end
37
-
38
- def merge_config_option_from_environment(config, key)
39
- env_key = 'winrm_' + key
40
- config[:options][key.to_sym] = ENV[env_key] if ENV[env_key]
41
- end
42
-
43
- def winrm_config_path
44
- # Copy config-example.yml to config.yml and edit for your local configuration
45
- path = File.expand_path("#{File.dirname(__FILE__)}/config.yml")
46
- unless File.exist?(path)
47
- # user hasn't done this, so use sane defaults for unit tests
48
- path = File.expand_path("#{File.dirname(__FILE__)}/config-example.yml")
49
- end
50
- path
51
- end
52
-
53
- # rubocop:disable Metrics/MethodLength
54
- def symbolize_keys(hash)
55
- hash.each_with_object({}) do |(key, value), result|
56
- new_key = case key
57
- when String then key.to_sym
58
- else key
59
- end
60
- new_value = case value
61
- when Hash then symbolize_keys(value)
62
- else value
63
- end
64
- result[new_key] = new_value
65
- result
66
- end
67
- end
68
- # rubocop:enable Metrics/MethodLength
69
- end
70
-
71
- RSpec.configure do |config|
72
- config.include(ConnectionHelper)
73
- end
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'winrm'
5
+ require 'json'
6
+ require_relative '../matchers'
7
+
8
+ # Creates a WinRM connection for integration tests
9
+ module ConnectionHelper
10
+ def winrm_connection
11
+ WinRM::Connection.new(connection_opts)
12
+ end
13
+
14
+ def connection_opts
15
+ @config ||= begin
16
+ cfg = symbolize_keys(YAML.load(File.read(winrm_config_path)))
17
+ merge_environment(cfg)
18
+ end
19
+ end
20
+
21
+ def merge_environment(config)
22
+ merge_config_option_from_environment(config, 'user')
23
+ merge_config_option_from_environment(config, 'password')
24
+ merge_config_option_from_environment(config, 'no_ssl_peer_verification')
25
+ if ENV['use_ssl_peer_fingerprint']
26
+ config[:ssl_peer_fingerprint] = ENV['winrm_cert']
27
+ end
28
+ config[:endpoint] = ENV['winrm_endpoint'] if ENV['winrm_endpoint']
29
+ config
30
+ end
31
+
32
+ def merge_config_option_from_environment(config, key)
33
+ env_key = 'winrm_' + key
34
+ config[key.to_sym] = ENV[env_key] if ENV[env_key]
35
+ end
36
+
37
+ def winrm_config_path
38
+ # Copy config-example.yml to config.yml and edit for your local ConnectionOpts
39
+ path = File.expand_path("#{File.dirname(__FILE__)}/config.yml")
40
+ unless File.exist?(path)
41
+ # user hasn't done this, so use sane defaults for unit tests
42
+ path = File.expand_path("#{File.dirname(__FILE__)}/config-example.yml")
43
+ end
44
+ path
45
+ end
46
+
47
+ def symbolize_keys(hash)
48
+ hash.each_with_object({}) do |(key, value), result|
49
+ new_key = case key
50
+ when String then key.to_sym
51
+ else key
52
+ end
53
+ new_value = case value
54
+ when Hash then symbolize_keys(value)
55
+ else value
56
+ end
57
+ result[new_key] = new_value
58
+ result
59
+ end
60
+ end
61
+ end
62
+
63
+ RSpec.configure do |config|
64
+ config.include(ConnectionHelper)
65
+ end
@@ -1,139 +1,99 @@
1
- # encoding: UTF-8
2
- require 'rubyntlm'
3
- require 'winrm/http/transport'
4
-
5
- describe WinRM::HTTP::HttpNegotiate, unit: true do
6
- describe '#init' do
7
- let(:endpoint) { 'some_endpoint' }
8
- let(:domain) { 'some_domain' }
9
- let(:user) { 'some_user' }
10
- let(:password) { 'some_password' }
11
- let(:options) { {} }
12
-
13
- context 'user is not domain prefixed' do
14
- it 'does not pass a domain to the NTLM client' do
15
- expect(Net::NTLM::Client).to receive(:new).with(user, password, options)
16
- WinRM::HTTP::HttpNegotiate.new(endpoint, user, password, options)
17
- end
18
- end
19
-
20
- context 'user is domain prefixed' do
21
- it 'passes prefixed domain to the NTLM client' do
22
- expect(Net::NTLM::Client).to receive(:new) do |passed_user, passed_password, passed_options|
23
- expect(passed_user).to eq user
24
- expect(passed_password).to eq password
25
- expect(passed_options[:domain]).to eq domain
26
- end
27
- WinRM::HTTP::HttpNegotiate.new(endpoint, "#{domain}\\#{user}", password, options)
28
- end
29
- end
30
-
31
- context 'option is passed with a domain' do
32
- let(:options) { { domain: domain } }
33
-
34
- it 'passes domain option to the NTLM client' do
35
- expect(Net::NTLM::Client).to receive(:new) do |passed_user, passed_password, passed_options|
36
- expect(passed_user).to eq user
37
- expect(passed_password).to eq password
38
- expect(passed_options[:domain]).to eq domain
39
- end
40
- WinRM::HTTP::HttpNegotiate.new(endpoint, user, password, options)
41
- end
42
- end
43
- end
44
- end
45
-
46
- describe 'WinRM connection', integration: true do
47
- let(:winrm_connection) do
48
- endpoint = config[:endpoint].dup
49
- if auth_type == :ssl
50
- endpoint.sub!('5985', '5986')
51
- endpoint.sub!('http', 'https')
52
- end
53
- winrm = WinRM::WinRMWebService.new(
54
- endpoint, auth_type, options)
55
- winrm.logger.level = :error
56
- winrm
57
- end
58
- let(:options) do
59
- opts = {}
60
- opts[:user] = config[:options][:user]
61
- opts[:pass] = config[:options][:pass]
62
- opts[:basic_auth_only] = basic_auth_only
63
- opts[:no_ssl_peer_verification] = no_ssl_peer_verification
64
- opts[:ssl_peer_fingerprint] = ssl_peer_fingerprint
65
- opts[:client_cert] = user_cert
66
- opts[:client_key] = user_key
67
- opts
68
- end
69
- let(:basic_auth_only) { false }
70
- let(:no_ssl_peer_verification) { false }
71
- let(:ssl_peer_fingerprint) { nil }
72
- let(:user_cert) { nil }
73
- let(:user_key) { nil }
74
-
75
- subject(:output) do
76
- executor = winrm_connection.create_executor
77
- executor.run_cmd('ipconfig')
78
- end
79
-
80
- shared_examples 'a valid_connection' do
81
- it 'has a 0 exit code' do
82
- expect(subject).to have_exit_code 0
83
- end
84
-
85
- it 'includes command output' do
86
- expect(subject).to have_stdout_match(/Windows IP Configuration/)
87
- end
88
-
89
- it 'has no errors' do
90
- expect(subject).to have_no_stderr
91
- end
92
- end
93
-
94
- context 'HttpPlaintext' do
95
- let(:basic_auth_only) { true }
96
- let(:auth_type) { :plaintext }
97
-
98
- it_behaves_like 'a valid_connection'
99
- end
100
-
101
- context 'HttpNegotiate' do
102
- let(:auth_type) { :negotiate }
103
-
104
- it_behaves_like 'a valid_connection'
105
- end
106
-
107
- context 'BasicAuthSSL', skip: ENV['winrm_cert'].nil? do
108
- let(:basic_auth_only) { true }
109
- let(:auth_type) { :ssl }
110
- let(:no_ssl_peer_verification) { true }
111
-
112
- it_behaves_like 'a valid_connection'
113
- end
114
-
115
- context 'ClientCertAuthSSL', skip: ENV['user_cert'].nil? do
116
- let(:auth_type) { :ssl }
117
- let(:no_ssl_peer_verification) { true }
118
- let(:user_cert) { ENV['user_cert'] }
119
- let(:user_key) { ENV['user_key'] }
120
-
121
- before { options[:pass] = nil }
122
-
123
- it_behaves_like 'a valid_connection'
124
- end
125
-
126
- context 'Negotiate over SSL', skip: ENV['winrm_cert'].nil? do
127
- let(:auth_type) { :ssl }
128
- let(:no_ssl_peer_verification) { true }
129
-
130
- it_behaves_like 'a valid_connection'
131
- end
132
-
133
- context 'SSL fingerprint', skip: ENV['winrm_cert'].nil? do
134
- let(:auth_type) { :ssl }
135
- let(:ssl_peer_fingerprint) { ENV['winrm_cert'] }
136
-
137
- it_behaves_like 'a valid_connection'
138
- end
139
- end
1
+ # encoding: UTF-8
2
+ require_relative 'spec_helper'
3
+
4
+ describe 'WinRM connection' do
5
+ let(:connection) do
6
+ endpoint = connection_opts[:endpoint].dup
7
+ if auth_type == :ssl
8
+ endpoint.sub!('5985', '5986')
9
+ endpoint.sub!('http', 'https')
10
+ end
11
+ conn_options = {
12
+ transport: auth_type,
13
+ endpoint: endpoint
14
+ }.merge(options)
15
+ WinRM::Connection.new(conn_options).shell(:cmd)
16
+ end
17
+ let(:options) do
18
+ opts = {}
19
+ opts[:user] = connection_opts[:user]
20
+ opts[:password] = connection_opts[:password]
21
+ opts[:basic_auth_only] = basic_auth_only
22
+ opts[:no_ssl_peer_verification] = no_ssl_peer_verification
23
+ opts[:ssl_peer_fingerprint] = ssl_peer_fingerprint
24
+ opts[:client_cert] = user_cert
25
+ opts[:client_key] = user_key
26
+ opts
27
+ end
28
+ let(:basic_auth_only) { false }
29
+ let(:no_ssl_peer_verification) { false }
30
+ let(:ssl_peer_fingerprint) { nil }
31
+ let(:user_cert) { nil }
32
+ let(:user_key) { nil }
33
+
34
+ subject(:output) { connection.run('ipconfig') }
35
+
36
+ after(:each) do
37
+ connection.close
38
+ end
39
+
40
+ shared_examples 'a valid_connection' do
41
+ it 'has a 0 exit code' do
42
+ expect(subject).to have_exit_code 0
43
+ end
44
+
45
+ it 'includes command output' do
46
+ expect(subject).to have_stdout_match(/Windows IP Configuration/)
47
+ end
48
+
49
+ it 'has no errors' do
50
+ expect(subject).to have_no_stderr
51
+ end
52
+ end
53
+
54
+ context 'HttpPlaintext' do
55
+ let(:basic_auth_only) { true }
56
+ let(:auth_type) { :plaintext }
57
+
58
+ it_behaves_like 'a valid_connection'
59
+ end
60
+
61
+ context 'HttpNegotiate' do
62
+ let(:auth_type) { :negotiate }
63
+
64
+ it_behaves_like 'a valid_connection'
65
+ end
66
+
67
+ context 'BasicAuthSSL', skip: ENV['winrm_cert'].nil? do
68
+ let(:basic_auth_only) { true }
69
+ let(:auth_type) { :ssl }
70
+ let(:no_ssl_peer_verification) { true }
71
+
72
+ it_behaves_like 'a valid_connection'
73
+ end
74
+
75
+ context 'ClientCertAuthSSL', skip: ENV['user_cert'].nil? do
76
+ let(:auth_type) { :ssl }
77
+ let(:no_ssl_peer_verification) { true }
78
+ let(:user_cert) { ENV['user_cert'] }
79
+ let(:user_key) { ENV['user_key'] }
80
+
81
+ before { options[:pass] = nil }
82
+
83
+ it_behaves_like 'a valid_connection'
84
+ end
85
+
86
+ context 'Negotiate over SSL', skip: ENV['winrm_cert'].nil? do
87
+ let(:auth_type) { :ssl }
88
+ let(:no_ssl_peer_verification) { true }
89
+
90
+ it_behaves_like 'a valid_connection'
91
+ end
92
+
93
+ context 'SSL fingerprint', skip: ENV['winrm_cert'].nil? do
94
+ let(:auth_type) { :ssl }
95
+ let(:ssl_peer_fingerprint) { ENV['winrm_cert'] }
96
+
97
+ it_behaves_like 'a valid_connection'
98
+ end
99
+ end