winrm 1.8.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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