train-winrm 0.2.6 → 0.2.13
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.
- checksums.yaml +4 -4
- data/lib/train-winrm/connection.rb +40 -7
- data/lib/train-winrm/transport.rb +36 -16
- data/lib/train-winrm/version.rb +1 -1
- data/lib/train-winrm.rb +1 -1
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f285f418da910b5aa18969c6eb97f9702024bbdbaca9ec085d293708af3172e5
|
4
|
+
data.tar.gz: 81e3e1f9f10a11d62b02911514acbb076d3bcc91424d11d6a39fed1db24afa6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4555a472e56ecf3f72f1f84e2002053d400305370daa41a3f39ce83d993c0859e6e0d089bcab236d173d2fe76bf4731feca62a8591bf63ac7784cf5ca1ccb061
|
7
|
+
data.tar.gz: ef30862cd5a211b093a44779069ff3b0273d50478fec2fe9eb276b630462254a990e8d119226f9f8f8f56bb41b992ae0e7f9374a5ff794a9eec596fadf0e886b
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
#
|
4
2
|
# Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
|
5
3
|
# Author:: Matt Wrock (<matt@mattwrock.com>)
|
@@ -35,6 +33,8 @@
|
|
35
33
|
|
36
34
|
require "train"
|
37
35
|
require "train/plugins"
|
36
|
+
# This module may need to directly require WinRM to reference its exception classes
|
37
|
+
require "winrm" unless defined?(WinRM)
|
38
38
|
|
39
39
|
module TrainPlugins
|
40
40
|
module WinRM
|
@@ -49,6 +49,7 @@ module TrainPlugins
|
|
49
49
|
@connection_retry_sleep = @options.delete(:connection_retry_sleep)
|
50
50
|
@max_wait_until_ready = @options.delete(:max_wait_until_ready)
|
51
51
|
@operation_timeout = @options.delete(:operation_timeout)
|
52
|
+
@shell_type = @options.delete(:winrm_shell_type)
|
52
53
|
end
|
53
54
|
|
54
55
|
# (see Base::Connection#close)
|
@@ -109,15 +110,47 @@ module TrainPlugins
|
|
109
110
|
Train::File::Remote::Windows.new(self, path)
|
110
111
|
end
|
111
112
|
|
112
|
-
def run_command_via_connection(command, &data_handler)
|
113
|
+
def run_command_via_connection(command, opts = {}, &data_handler)
|
113
114
|
return if command.nil?
|
114
115
|
|
115
116
|
logger.debug("[WinRM] #{self} (#{command})")
|
116
117
|
out = ""
|
118
|
+
response = nil
|
119
|
+
timeout = opts[:timeout]&.to_i
|
120
|
+
|
121
|
+
# Run the command in a thread, to support timing out the command
|
122
|
+
thr = Thread.new do
|
123
|
+
# Surface any exceptions in this thread back to this method
|
124
|
+
Thread.current.report_on_exception = false
|
125
|
+
Thread.current.abort_on_exception = true
|
126
|
+
begin
|
127
|
+
response = session.run(command) do |stdout, _|
|
128
|
+
yield(stdout) if data_handler && stdout
|
129
|
+
out << stdout if stdout
|
130
|
+
end
|
131
|
+
rescue ::WinRM::WinRMHTTPTransportError => e
|
132
|
+
# If this command hits timeout, there is also a potential race in the HTTP transport
|
133
|
+
# where decryption is attempted on an empty message.
|
134
|
+
raise e unless timeout && e.to_s == "Could not decrypt NTLM message. ()."
|
135
|
+
rescue RuntimeError => e
|
136
|
+
# Ref: https://github.com/WinRb/WinRM/issues/315
|
137
|
+
# If this command hits timeout, calling close with the command currently running causes
|
138
|
+
# a RuntimeError error in WinRM's cleanup code. This specific error can be ignored.
|
139
|
+
# The command will be terminated and further commands can be sent on the connection.
|
140
|
+
raise e unless timeout && e.to_s == "opts[:shell_id] is required"
|
141
|
+
end
|
142
|
+
end
|
117
143
|
|
118
|
-
|
119
|
-
|
120
|
-
|
144
|
+
if timeout
|
145
|
+
res = thr.join(timeout)
|
146
|
+
unless res
|
147
|
+
msg = "PowerShell command '(#{command})' reached timeout (#{timeout}s)"
|
148
|
+
logger.info("[WinRM] #{msg}")
|
149
|
+
close
|
150
|
+
raise Train::CommandTimeoutReached.new msg
|
151
|
+
end
|
152
|
+
else
|
153
|
+
thr.join
|
121
154
|
end
|
122
155
|
|
123
156
|
CommandResult.new(out, response.stderr, response.exitcode)
|
@@ -197,7 +230,7 @@ module TrainPlugins
|
|
197
230
|
opts[:operation_timeout] = @operation_timeout unless @operation_timeout.nil?
|
198
231
|
@service = ::WinRM::Connection.new(options.merge(opts))
|
199
232
|
@service.logger = logger
|
200
|
-
@service.shell(
|
233
|
+
@service.shell(@shell_type)
|
201
234
|
end
|
202
235
|
end
|
203
236
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
#
|
4
2
|
# Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
|
5
3
|
# Author:: Matt Wrock (<matt@mattwrock.com>)
|
@@ -21,8 +19,6 @@
|
|
21
19
|
# See the License for the specific language governing permissions and
|
22
20
|
# limitations under the License.
|
23
21
|
|
24
|
-
require "rbconfig"
|
25
|
-
require "uri"
|
26
22
|
require "train"
|
27
23
|
require "train/errors"
|
28
24
|
require "train/plugins"
|
@@ -50,6 +46,7 @@ module TrainPlugins
|
|
50
46
|
|
51
47
|
# ref: https://github.com/winrb/winrm#transports
|
52
48
|
SUPPORTED_WINRM_TRANSPORTS = %i{negotiate ssl plaintext kerberos}.freeze
|
49
|
+
SUPPORTED_WINRM_SHELL_TYPES = %i{powershell elevated cmd}.freeze
|
53
50
|
|
54
51
|
# common target configuration
|
55
52
|
option :host, required: true
|
@@ -76,6 +73,10 @@ module TrainPlugins
|
|
76
73
|
# from the winrm endpoint. Does not mean that the command has
|
77
74
|
# completed in this time, only that the server has ack'd the request.
|
78
75
|
option :operation_timeout, default: nil
|
76
|
+
option :winrm_shell_type , default: "powershell"
|
77
|
+
option :client_cert , default: nil
|
78
|
+
option :client_key , default: nil
|
79
|
+
option :client_key_pass , default: nil
|
79
80
|
|
80
81
|
def initialize(opts)
|
81
82
|
super(opts)
|
@@ -109,6 +110,11 @@ module TrainPlugins
|
|
109
110
|
raise Train::ClientError, "Unsupported transport type: #{winrm_transport.inspect}"
|
110
111
|
end
|
111
112
|
|
113
|
+
winrm_shell_type = opts[:winrm_shell_type].to_sym
|
114
|
+
unless SUPPORTED_WINRM_SHELL_TYPES.include?(winrm_shell_type)
|
115
|
+
raise Train::ClientError, "Unsupported winrm shell type: #{winrm_shell_type.inspect}"
|
116
|
+
end
|
117
|
+
|
112
118
|
# remove leading '/'
|
113
119
|
path = (opts[:path] || "").sub(%r{^/+}, "")
|
114
120
|
|
@@ -116,6 +122,7 @@ module TrainPlugins
|
|
116
122
|
end
|
117
123
|
|
118
124
|
WINRM_FS_SPEC_VERSION = "~> 1.0".freeze
|
125
|
+
WINRM_ELEVATED_SPEC_VERSION = "~> 1.2.2".freeze
|
119
126
|
|
120
127
|
# Builds the hash of options needed by the Connection object on
|
121
128
|
# construction.
|
@@ -142,13 +149,17 @@ module TrainPlugins
|
|
142
149
|
service: opts[:kerberos_service],
|
143
150
|
ca_trust_file: opts[:ca_trust_file],
|
144
151
|
ssl_peer_fingerprint: opts[:ssl_peer_fingerprint],
|
152
|
+
winrm_shell_type: opts[:winrm_shell_type],
|
153
|
+
client_cert: opts[:client_cert],
|
154
|
+
client_key: opts[:client_key],
|
155
|
+
key_pass: opts[:client_key_pass],
|
145
156
|
}
|
146
157
|
end
|
147
158
|
|
148
159
|
# Creates a new WinRM Connection instance and save it for potential
|
149
160
|
# future reuse.
|
150
161
|
#
|
151
|
-
# @param options [Hash]
|
162
|
+
# @param options [Hash] connection options
|
152
163
|
# @return [WinRM::Connection] a WinRM Connection instance
|
153
164
|
# @api private
|
154
165
|
def create_new_connection(options, &block)
|
@@ -166,32 +177,41 @@ module TrainPlugins
|
|
166
177
|
spec_version = WINRM_FS_SPEC_VERSION.dup
|
167
178
|
logger.debug("winrm-fs requested," \
|
168
179
|
" loading WinRM::FS gem (#{spec_version})")
|
169
|
-
|
170
|
-
|
171
|
-
|
180
|
+
load_dependency("winrm-fs", spec_version)
|
181
|
+
|
182
|
+
spec_version = WINRM_ELEVATED_SPEC_VERSION.dup
|
183
|
+
logger.debug("winrm-elevated requested," \
|
184
|
+
" loading WinRM-elevated gem (#{spec_version})")
|
185
|
+
load_dependency("winrm-elevated", spec_version)
|
186
|
+
end
|
187
|
+
|
188
|
+
def load_dependency(gem_name, spec_version)
|
189
|
+
gem gem_name, spec_version
|
190
|
+
first_load = require gem_name
|
191
|
+
load_winrm_transport!(gem_name)
|
172
192
|
|
173
193
|
if first_load
|
174
|
-
logger.debug("
|
194
|
+
logger.debug("#{gem_name} library loaded")
|
175
195
|
else
|
176
|
-
logger.debug("
|
196
|
+
logger.debug("#{gem_name} previously loaded")
|
177
197
|
end
|
178
198
|
rescue LoadError => e
|
179
199
|
logger.fatal(
|
180
|
-
"The
|
200
|
+
"The `#{gem_name}' gem is missing and must" \
|
181
201
|
" be installed or cannot be properly activated. Run" \
|
182
|
-
" `gem install
|
202
|
+
" `gem install #{gem_name} --version '#{spec_version}'`" \
|
183
203
|
" or add the following to your Gemfile if you are using Bundler:" \
|
184
|
-
" `gem '
|
204
|
+
" `gem '#{gem_name}', '#{spec_version}'`."
|
185
205
|
)
|
186
206
|
raise Train::UserError,
|
187
|
-
"Could not load or activate
|
207
|
+
"Could not load or activate #{gem_name} (#{e.message})"
|
188
208
|
end
|
189
209
|
|
190
210
|
# Load WinRM::Transport code.
|
191
211
|
#
|
192
212
|
# @api private
|
193
|
-
def load_winrm_transport!
|
194
|
-
silence_warnings { require
|
213
|
+
def load_winrm_transport!(gem_name)
|
214
|
+
silence_warnings { require gem_name }
|
195
215
|
end
|
196
216
|
|
197
217
|
# Return the last saved WinRM connection instance.
|
data/lib/train-winrm/version.rb
CHANGED
data/lib/train-winrm.rb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
libdir = File.dirname(__FILE__)
|
12
12
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
13
13
|
|
14
|
-
# It's
|
14
|
+
# It's traditional to keep your gem version in a separate file, so CI can find it easier.
|
15
15
|
require_relative "train-winrm/version"
|
16
16
|
|
17
17
|
# A train plugin has three components: Transport, Connection, and (optionally) Platform.
|
metadata
CHANGED
@@ -1,29 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: train-winrm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chef InSpec Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: winrm
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.3.6
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.3.6
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: winrm-elevated
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
16
36
|
requirements:
|
17
37
|
- - "~>"
|
18
38
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
39
|
+
version: 1.2.2
|
20
40
|
type: :runtime
|
21
41
|
prerelease: false
|
22
42
|
version_requirements: !ruby/object:Gem::Requirement
|
23
43
|
requirements:
|
24
44
|
- - "~>"
|
25
45
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
46
|
+
version: 1.2.2
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: winrm-fs
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
90
|
- !ruby/object:Gem::Version
|
71
91
|
version: '0'
|
72
92
|
requirements: []
|
73
|
-
rubygems_version: 3.
|
93
|
+
rubygems_version: 3.1.4
|
74
94
|
signing_key:
|
75
95
|
specification_version: 4
|
76
96
|
summary: Windows WinRM API Transport for Train
|