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
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ # Copyright 2015 Matt Wrock <matt@mattwrock.com>
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require_relative '../exceptions'
19
+
20
+ module WinRM
21
+ module Shells
22
+ # Shell mixin for retrying an operation
23
+ module Retryable
24
+ RETRYABLE_EXCEPTIONS = lambda do
25
+ [
26
+ Errno::EACCES, Errno::EADDRINUSE, Errno::ECONNREFUSED, Errno::ETIMEDOUT,
27
+ Errno::ECONNRESET, Errno::ENETUNREACH, Errno::EHOSTUNREACH, ::WinRM::WinRMWSManFault,
28
+ ::WinRM::WinRMHTTPTransportError, ::WinRM::WinRMAuthorizationError,
29
+ HTTPClient::KeepAliveDisconnected, HTTPClient::ConnectTimeoutError
30
+ ].freeze
31
+ end
32
+
33
+ # Retries the operation a specified number of times with a delay between
34
+ # @param retries [Fixnum] The number of times to retry
35
+ # @param delay [Fixnum] The number of seconds to wait between retry attempts
36
+ def retryable(retries, delay)
37
+ yield
38
+ rescue *RETRYABLE_EXCEPTIONS.call
39
+ raise unless (retries -= 1) > 0
40
+ sleep(delay)
41
+ retry
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'base'
18
+ require_relative 'cmd'
19
+ require_relative 'power_shell'
20
+
21
+ module WinRM
22
+ module Shells
23
+ # Factory for creating concrete shell instances
24
+ class ShellFactory
25
+ # Creates a new ShellFactory instance
26
+ # @param connection_opts [ConnectionOpts] The WinRM connection options
27
+ # @param transport [HttpTransport] The WinRM SOAP transport for sending messages
28
+ # @param logger [Logger] The logger to log messages to
29
+ def initialize(connection_opts, transport, logger)
30
+ @connection_opts = connection_opts
31
+ @transport = transport
32
+ @logger = logger
33
+ end
34
+
35
+ # Creates a new shell instance based off the shell_type
36
+ # @param shell_type [Symbol] The shell type :cmd or :powershell
37
+ # @return The ready to use shell instance
38
+ def create_shell(shell_type)
39
+ type = shell_type.to_s.capitalize.to_sym
40
+ if Shells.constants.include?(type)
41
+ WinRM::Shells.const_get(type).new(@connection_opts, @transport, @logger)
42
+ else
43
+ message = "#{type} is not a valid WinRM shell type. " \
44
+ 'Expected either :cmd, :powershell or pluggable shell.'
45
+ raise WinRM::InvalidShellError, message
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,7 +1,7 @@
1
- # encoding: UTF-8
2
-
3
- # WinRM module
4
- module WinRM
5
- # The version of the WinRM library
6
- VERSION = '1.8.1'
7
- end
1
+ # encoding: UTF-8
2
+
3
+ # WinRM module
4
+ module WinRM
5
+ # The version of the WinRM library
6
+ VERSION = '2.0.0'.freeze
7
+ end
@@ -0,0 +1,59 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'base64'
18
+ require 'builder'
19
+ require 'gyoku'
20
+ require_relative 'soap'
21
+ require_relative 'header'
22
+
23
+ module WinRM
24
+ module WSMV
25
+ # Base class for all WSMV message classes
26
+ class Base
27
+ include WinRM::WSMV::SOAP
28
+ include WinRM::WSMV::Header
29
+
30
+ # Builds the WSMV message XML payload
31
+ def build
32
+ builder = Builder::XmlMarkup.new
33
+ builder.instruct!(:xml, encoding: 'UTF-8')
34
+ builder.tag! :env, :Envelope, namespaces do |env|
35
+ env.tag!(:env, :Header) do |env_header|
36
+ create_header(env_header)
37
+ end
38
+ env.tag!(:env, :Body) do |env_body|
39
+ create_body(env_body)
40
+ end
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def create_header
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def create_body
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def encode_bytes(bytes)
55
+ Base64.strict_encode64(bytes.pack('C*'))
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,61 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'base'
18
+
19
+ module WinRM
20
+ module WSMV
21
+ # WSMV message to execute a command inside a remote shell
22
+ class CleanupCommand < Base
23
+ def initialize(session_opts, opts)
24
+ raise 'opts[:shell_id] is required' unless opts[:shell_id]
25
+ raise 'opts[:command_id] is required' unless opts[:command_id]
26
+ @session_opts = session_opts
27
+ @shell_id = opts[:shell_id]
28
+ @command_id = opts[:command_id]
29
+ @shell_uri = opts[:shell_uri] || RESOURCE_URI_CMD
30
+ end
31
+
32
+ protected
33
+
34
+ def create_header(header)
35
+ header << Gyoku.xml(cleanup_header)
36
+ end
37
+
38
+ def create_body(body)
39
+ body.tag!("#{NS_WIN_SHELL}:Signal", 'CommandId' => @command_id) do |cl|
40
+ cl << Gyoku.xml(cleanup_body)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def cleanup_header
47
+ merge_headers(shared_headers(@session_opts),
48
+ resource_uri_shell(@shell_uri),
49
+ action_signal,
50
+ selector_shell_id(@shell_id))
51
+ end
52
+
53
+ def cleanup_body
54
+ {
55
+ "#{NS_WIN_SHELL}:Code" =>
56
+ 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/signal/terminate'
57
+ }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'base'
18
+
19
+ module WinRM
20
+ module WSMV
21
+ # WSMV message to close a remote shell
22
+ class CloseShell < Base
23
+ def initialize(session_opts, shell_opts)
24
+ raise 'shell_opts[:shell_id] is required' unless shell_opts[:shell_id]
25
+ @session_opts = session_opts
26
+ @shell_id = shell_opts[:shell_id]
27
+ @shell_uri = shell_opts[:shell_uri] || RESOURCE_URI_CMD
28
+ end
29
+
30
+ protected
31
+
32
+ def create_header(header)
33
+ header << Gyoku.xml(close_header)
34
+ end
35
+
36
+ def create_body(_body)
37
+ # no body
38
+ end
39
+
40
+ private
41
+
42
+ def close_header
43
+ merge_headers(shared_headers(@session_opts),
44
+ resource_uri_shell(@shell_uri),
45
+ action_delete,
46
+ selector_shell_id(@shell_id))
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,101 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'base'
18
+
19
+ module WinRM
20
+ module WSMV
21
+ # WSMV message to execute a command inside a remote shell
22
+ class Command < Base
23
+ attr_reader :command_id
24
+
25
+ def initialize(session_opts, cmd_opts)
26
+ @command_id = SecureRandom.uuid.to_s.upcase
27
+ validate_opts(session_opts, cmd_opts)
28
+ init_ops(session_opts, cmd_opts)
29
+ end
30
+
31
+ def build
32
+ xml = super
33
+ issue69_unescape_single_quotes(xml)
34
+ end
35
+
36
+ protected
37
+
38
+ def create_header(header)
39
+ header << Gyoku.xml(command_headers)
40
+ end
41
+
42
+ def create_body(body)
43
+ body.tag!("#{NS_WIN_SHELL}:CommandLine", 'CommandId' => @command_id) do |cl|
44
+ cl << Gyoku.xml(command_body)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def init_ops(session_opts, cmd_opts)
51
+ @session_opts = session_opts
52
+ @shell_id = cmd_opts[:shell_id]
53
+ @command = cmd_opts[:command]
54
+ @arguments = cmd_opts[:arguments] || []
55
+ @shell_uri = cmd_opts[:shell_uri] || RESOURCE_URI_CMD
56
+ @consolemode = cmd_opts.key?(:console_mode_stdin) ? cmd_opts[:console_mode_stdin] : 'TRUE'
57
+ @skipcmd = cmd_opts.key?(:skip_cmd_shell) ? cmd_opts[:skip_cmd_shell] : 'FALSE'
58
+ end
59
+
60
+ def validate_opts(session_opts, cmd_opts)
61
+ raise 'session_opts is required' unless session_opts
62
+ raise 'cmd_opts[:shell_id] is required' unless cmd_opts[:shell_id]
63
+ raise 'cmd_opts[:command] is required' unless cmd_opts[:command]
64
+ end
65
+
66
+ def issue69_unescape_single_quotes(xml)
67
+ escaped_cmd = %r{<#{NS_WIN_SHELL}:Command>(.+)<\/#{NS_WIN_SHELL}:Command>}m.match(xml)[1]
68
+ xml[escaped_cmd] = escaped_cmd.gsub(/&#39;/, "'")
69
+ xml
70
+ end
71
+
72
+ def command_body
73
+ {
74
+ "#{NS_WIN_SHELL}:Command" => "\"#{@command}\"", "#{NS_WIN_SHELL}:Arguments" => @arguments
75
+ }
76
+ end
77
+
78
+ def command_headers
79
+ merge_headers(shared_headers(@session_opts),
80
+ resource_uri_shell(@shell_uri),
81
+ action_command,
82
+ command_header_opts,
83
+ selector_shell_id(@shell_id))
84
+ end
85
+
86
+ def command_header_opts
87
+ return {} if @shell_uri != RESOURCE_URI_CMD
88
+ # this is only needed for the regular Windows shell
89
+ {
90
+ "#{NS_WSMAN_DMTF}:OptionSet" => {
91
+ "#{NS_WSMAN_DMTF}:Option" => [@consolemode, @skipcmd], :attributes! => {
92
+ "#{NS_WSMAN_DMTF}:Option" => {
93
+ 'Name' => %w(WINRS_CONSOLEMODE_STDIN WINRS_SKIP_CMD_SHELL)
94
+ }
95
+ }
96
+ }
97
+ }
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,76 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'base'
18
+
19
+ module WinRM
20
+ module WSMV
21
+ # WSMV message to get output from a remote shell
22
+ class CommandOutput < Base
23
+ def initialize(session_opts, command_out_opts)
24
+ raise 'command_out_opts[:shell_id] is required' unless command_out_opts[:shell_id]
25
+ raise 'command_out_opts[:command_id] is required' unless command_out_opts[:command_id]
26
+ @session_opts = session_opts
27
+ @shell_id = command_out_opts[:shell_id]
28
+ @command_id = command_out_opts[:command_id]
29
+ @shell_uri = command_out_opts[:shell_uri] || RESOURCE_URI_CMD
30
+ @out_streams = command_out_opts[:out_streams] || %w(stdout stderr)
31
+ end
32
+
33
+ protected
34
+
35
+ def create_header(header)
36
+ header << Gyoku.xml(output_header)
37
+ end
38
+
39
+ def create_body(body)
40
+ body.tag!("#{NS_WIN_SHELL}:Receive") { |cl| cl << Gyoku.xml(output_body) }
41
+ end
42
+
43
+ private
44
+
45
+ def output_header
46
+ merge_headers(shared_headers(@session_opts),
47
+ resource_uri_shell(@shell_uri),
48
+ action_receive,
49
+ header_opts,
50
+ selector_shell_id(@shell_id))
51
+ end
52
+
53
+ def header_opts
54
+ {
55
+ "#{NS_WSMAN_DMTF}:OptionSet" => {
56
+ "#{NS_WSMAN_DMTF}:Option" => 'TRUE', :attributes! => {
57
+ "#{NS_WSMAN_DMTF}:Option" => {
58
+ 'Name' => 'WSMAN_CMDSHELL_OPTION_KEEPALIVE'
59
+ }
60
+ }
61
+ }
62
+ }
63
+ end
64
+
65
+ def output_body
66
+ {
67
+ "#{NS_WIN_SHELL}:DesiredStream" => @out_streams.join(' '), :attributes! => {
68
+ "#{NS_WIN_SHELL}:DesiredStream" => {
69
+ 'CommandId' => @command_id
70
+ }
71
+ }
72
+ }
73
+ end
74
+ end
75
+ end
76
+ end