chef-winrm 2.3.10

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +202 -0
  3. data/README.md +277 -0
  4. data/bin/rwinrm +90 -0
  5. data/lib/winrm/connection.rb +84 -0
  6. data/lib/winrm/connection_opts.rb +92 -0
  7. data/lib/winrm/exceptions.rb +88 -0
  8. data/lib/winrm/http/response_handler.rb +127 -0
  9. data/lib/winrm/http/transport.rb +466 -0
  10. data/lib/winrm/http/transport_factory.rb +64 -0
  11. data/lib/winrm/output.rb +58 -0
  12. data/lib/winrm/psrp/create_pipeline.xml.erb +167 -0
  13. data/lib/winrm/psrp/fragment.rb +68 -0
  14. data/lib/winrm/psrp/init_runspace_pool.xml.erb +224 -0
  15. data/lib/winrm/psrp/message.rb +128 -0
  16. data/lib/winrm/psrp/message_data/base.rb +47 -0
  17. data/lib/winrm/psrp/message_data/error_record.rb +68 -0
  18. data/lib/winrm/psrp/message_data/pipeline_host_call.rb +30 -0
  19. data/lib/winrm/psrp/message_data/pipeline_output.rb +48 -0
  20. data/lib/winrm/psrp/message_data/pipeline_state.rb +38 -0
  21. data/lib/winrm/psrp/message_data/runspacepool_host_call.rb +30 -0
  22. data/lib/winrm/psrp/message_data/runspacepool_state.rb +37 -0
  23. data/lib/winrm/psrp/message_data/session_capability.rb +34 -0
  24. data/lib/winrm/psrp/message_data.rb +40 -0
  25. data/lib/winrm/psrp/message_defragmenter.rb +62 -0
  26. data/lib/winrm/psrp/message_factory.rb +86 -0
  27. data/lib/winrm/psrp/message_fragmenter.rb +58 -0
  28. data/lib/winrm/psrp/powershell_output_decoder.rb +142 -0
  29. data/lib/winrm/psrp/receive_response_reader.rb +95 -0
  30. data/lib/winrm/psrp/session_capability.xml.erb +7 -0
  31. data/lib/winrm/psrp/uuid.rb +39 -0
  32. data/lib/winrm/shells/base.rb +192 -0
  33. data/lib/winrm/shells/cmd.rb +59 -0
  34. data/lib/winrm/shells/power_shell.rb +202 -0
  35. data/lib/winrm/shells/retryable.rb +44 -0
  36. data/lib/winrm/shells/shell_factory.rb +56 -0
  37. data/lib/winrm/version.rb +5 -0
  38. data/lib/winrm/wsmv/base.rb +57 -0
  39. data/lib/winrm/wsmv/cleanup_command.rb +60 -0
  40. data/lib/winrm/wsmv/close_shell.rb +49 -0
  41. data/lib/winrm/wsmv/command.rb +100 -0
  42. data/lib/winrm/wsmv/command_output.rb +75 -0
  43. data/lib/winrm/wsmv/command_output_decoder.rb +54 -0
  44. data/lib/winrm/wsmv/configuration.rb +44 -0
  45. data/lib/winrm/wsmv/create_pipeline.rb +64 -0
  46. data/lib/winrm/wsmv/create_shell.rb +115 -0
  47. data/lib/winrm/wsmv/header.rb +213 -0
  48. data/lib/winrm/wsmv/init_runspace_pool.rb +96 -0
  49. data/lib/winrm/wsmv/iso8601_duration.rb +58 -0
  50. data/lib/winrm/wsmv/keep_alive.rb +66 -0
  51. data/lib/winrm/wsmv/receive_response_reader.rb +128 -0
  52. data/lib/winrm/wsmv/send_data.rb +66 -0
  53. data/lib/winrm/wsmv/soap.rb +49 -0
  54. data/lib/winrm/wsmv/wql_pull.rb +54 -0
  55. data/lib/winrm/wsmv/wql_query.rb +98 -0
  56. data/lib/winrm/wsmv/write_stdin.rb +86 -0
  57. data/lib/winrm.rb +37 -0
  58. metadata +333 -0
@@ -0,0 +1,92 @@
1
+ # Copyright 2016 Shawn Neal <sneal@sneal.net>
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'securerandom'
16
+
17
+ module WinRM
18
+ # WinRM connection options, provides defaults and validation.
19
+ class ConnectionOpts < Hash
20
+ DEFAULT_OPERATION_TIMEOUT = 60
21
+ DEFAULT_RECEIVE_TIMEOUT = DEFAULT_OPERATION_TIMEOUT + 10
22
+ DEFAULT_MAX_ENV_SIZE = 153600
23
+ DEFAULT_LOCALE = 'en-US'.freeze
24
+ DEFAULT_RETRY_DELAY = 10
25
+ DEFAULT_RETRY_LIMIT = 3
26
+ DEFAULT_USER_AGENT = 'Ruby WinRM Client'.freeze
27
+
28
+ class << self
29
+ def create_with_defaults(overrides)
30
+ config = default.merge(overrides)
31
+ config = ensure_receive_timeout_is_greater_than_operation_timeout(config)
32
+ config.validate
33
+ config
34
+ end
35
+
36
+ private
37
+
38
+ def ensure_receive_timeout_is_greater_than_operation_timeout(config)
39
+ if config[:receive_timeout] < config[:operation_timeout]
40
+ config[:receive_timeout] = config[:operation_timeout] + 10
41
+ end
42
+ config
43
+ end
44
+
45
+ def default
46
+ config = ConnectionOpts.new
47
+ config[:session_id] = SecureRandom.uuid.to_s.upcase
48
+ config[:transport] = :negotiate
49
+ config[:locale] = DEFAULT_LOCALE
50
+ config[:max_envelope_size] = DEFAULT_MAX_ENV_SIZE
51
+ config[:operation_timeout] = DEFAULT_OPERATION_TIMEOUT
52
+ config[:receive_timeout] = DEFAULT_RECEIVE_TIMEOUT
53
+ config[:retry_delay] = DEFAULT_RETRY_DELAY
54
+ config[:retry_limit] = DEFAULT_RETRY_LIMIT
55
+ config[:user_agent] = DEFAULT_USER_AGENT
56
+ config
57
+ end
58
+ end
59
+
60
+ def validate
61
+ validate_required_fields
62
+ validate_data_types
63
+ end
64
+
65
+ private
66
+
67
+ def validate_required_fields
68
+ raise 'endpoint is a required option' unless self[:endpoint]
69
+
70
+ if self[:client_cert]
71
+ raise 'path to client key is required' unless self[:client_key]
72
+ else
73
+ raise 'user is a required option' unless self[:user]
74
+ raise 'password is a required option' unless self[:password]
75
+ end
76
+ end
77
+
78
+ def validate_data_types
79
+ validate_integer(:retry_limit)
80
+ validate_integer(:retry_delay)
81
+ validate_integer(:max_envelope_size)
82
+ validate_integer(:operation_timeout)
83
+ validate_integer(:receive_timeout, self[:operation_timeout])
84
+ end
85
+
86
+ def validate_integer(key, min = 0)
87
+ value = self[key]
88
+ raise "#{key} must be a Integer" unless value && value.is_a?(Integer)
89
+ raise "#{key} must be greater than #{min}" unless value > min
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module WinRM
16
+ # WinRM base class for errors
17
+ class WinRMError < StandardError; end
18
+
19
+ # Authorization Error
20
+ class WinRMAuthorizationError < WinRMError; end
21
+
22
+ # Shell creation error
23
+ class InvalidShellError < WinRMError; end
24
+
25
+ # Exitcode error
26
+ class InvalidExitCode < WinRMError; end
27
+
28
+ # Shell creation error
29
+ class InvalidTransportError < WinRMError
30
+ attr_reader :invalid_transport
31
+
32
+ def initialize(invalid_transport, valid_transports)
33
+ @invalid_transport = invalid_transport
34
+ super(
35
+ "Invalid transport '#{invalid_transport}' specified" \
36
+ ", expected: #{valid_transports.join(', ')}."
37
+ )
38
+ end
39
+ end
40
+
41
+ # A Fault returned in the SOAP response. The XML node is a WSManFault
42
+ class WinRMWSManFault < WinRMError
43
+ attr_reader :fault_code
44
+ attr_reader :fault_description
45
+
46
+ def initialize(fault_description, fault_code)
47
+ @fault_description = fault_description
48
+ @fault_code = fault_code
49
+ super("[WSMAN ERROR CODE: #{fault_code}]: #{fault_description}")
50
+ end
51
+ end
52
+
53
+ # A Fault returned in the SOAP response. The XML node contains Code, SubCode and Reason
54
+ class WinRMSoapFault < WinRMError
55
+ attr_reader :code
56
+ attr_reader :subcode
57
+ attr_reader :reason
58
+
59
+ def initialize(code, subcode, reason)
60
+ @code = code
61
+ @subcode = subcode
62
+ @reason = reason
63
+ super("[SOAP ERROR CODE: #{code} (#{subcode})]: #{reason}")
64
+ end
65
+ end
66
+
67
+ # A Fault returned in the SOAP response. The XML node is a MSFT_WmiError
68
+ class WinRMWMIError < WinRMError
69
+ attr_reader :error_code
70
+ attr_reader :error
71
+
72
+ def initialize(error, error_code)
73
+ @error = error
74
+ @error_code = error_code
75
+ super("[WMI ERROR CODE: #{error_code}]: #{error}")
76
+ end
77
+ end
78
+
79
+ # non-200 response without a SOAP fault
80
+ class WinRMHTTPTransportError < WinRMError
81
+ attr_reader :status_code
82
+
83
+ def initialize(msg, status_code = nil)
84
+ @status_code = status_code
85
+ super(msg + " (#{status_code}).")
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,127 @@
1
+ # Copyright 2014 Shawn Neal <sneal@sneal.net>
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'rexml/document' unless defined?(REXML::Document)
16
+ require_relative '../wsmv/soap'
17
+
18
+ module WinRM
19
+ # Handles the raw WinRM HTTP response. Returns the body as an XML doc
20
+ # or raises the appropriate WinRM error if the response is an error.
21
+ class ResponseHandler
22
+ # @param [String] The raw unparsed response body, if any
23
+ # @param [Integer] The HTTP response status code
24
+ def initialize(response_body, status_code)
25
+ @response_body = response_body
26
+ @status_code = status_code
27
+ end
28
+
29
+ # Processes the response from the WinRM service and either returns an XML
30
+ # doc or raises an appropriate error.
31
+ #
32
+ # @returns [REXML::Document] The parsed response body
33
+ def parse_to_xml
34
+ raise_if_error
35
+ response_xml
36
+ end
37
+
38
+ private
39
+
40
+ def response_xml
41
+ @response_xml ||= REXML::Document.new(@response_body)
42
+ rescue REXML::ParseException => e
43
+ raise WinRMHTTPTransportError.new(
44
+ "Unable to parse WinRM response: #{e.message}", @status_code
45
+ )
46
+ end
47
+
48
+ def raise_if_error
49
+ return if @status_code == 200
50
+
51
+ raise_if_auth_error
52
+ raise_if_wsman_fault
53
+ raise_if_wmi_error
54
+ raise_if_soap_fault
55
+ raise_transport_error
56
+ end
57
+
58
+ def raise_if_auth_error
59
+ raise WinRMAuthorizationError if @status_code == 401
60
+ end
61
+
62
+ def raise_if_wsman_fault
63
+ soap_errors = REXML::XPath.match(
64
+ response_xml,
65
+ "//*[local-name() = 'Envelope']/*[local-name() = 'Body']/*[local-name() = 'Fault']/*"
66
+ )
67
+ return if soap_errors.empty?
68
+
69
+ fault = REXML::XPath.first(
70
+ soap_errors,
71
+ "//*[local-name() = 'WSManFault']"
72
+ )
73
+ raise WinRMWSManFault.new(fault.to_s, fault.attributes['Code']) unless fault.nil?
74
+ end
75
+
76
+ def raise_if_wmi_error
77
+ soap_errors = REXML::XPath.match(
78
+ response_xml,
79
+ "//*[local-name() = 'Envelope']/*[local-name() = 'Body']/*[local-name() = 'Fault']/*"
80
+ )
81
+ return if soap_errors.empty?
82
+
83
+ error = REXML::XPath.first(
84
+ soap_errors,
85
+ "//*[local-name() = 'MSFT_WmiError']"
86
+ )
87
+ return if error.nil?
88
+
89
+ error_code = REXML::XPath.first(
90
+ error,
91
+ "//*[local-name() = 'error_Code']"
92
+ ).text
93
+ raise WinRMWMIError.new(error.to_s, error_code)
94
+ end
95
+
96
+ def raise_if_soap_fault
97
+ soap_errors = REXML::XPath.match(
98
+ response_xml,
99
+ "//*[local-name() = 'Envelope']/*[local-name() = 'Body']/*[local-name() = 'Fault']/*"
100
+ )
101
+ return if soap_errors.empty?
102
+
103
+ code = REXML::XPath.first(
104
+ soap_errors,
105
+ "//*[local-name() = 'Code']/*[local-name() = 'Value']/text()"
106
+ )
107
+ subcode = REXML::XPath.first(
108
+ soap_errors,
109
+ "//*[local-name() = 'Subcode']/*[local-name() = 'Value']/text()"
110
+ )
111
+ reason = REXML::XPath.first(
112
+ soap_errors,
113
+ "//*[local-name() = 'Reason']/*[local-name() = 'Text']/text()"
114
+ )
115
+
116
+ raise WinRMSoapFault.new(code, subcode, reason) unless
117
+ code.nil? && subcode.nil? && reason.nil?
118
+ end
119
+
120
+ def raise_transport_error
121
+ raise WinRMHTTPTransportError.new(
122
+ "Bad HTTP response returned from server. Body(if present):#{@response_body}",
123
+ @status_code
124
+ )
125
+ end
126
+ end
127
+ end