winrm 1.3.0.dev.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/Gemfile +1 -0
- data/README.md +8 -27
- data/Rakefile +12 -10
- data/VERSION +1 -1
- data/Vagrantfile +3 -2
- data/bin/rwinrm +21 -15
- data/changelog.md +22 -1
- data/lib/winrm.rb +12 -9
- data/lib/winrm/exceptions/exceptions.rb +5 -10
- data/lib/winrm/helpers/iso8601_duration.rb +22 -15
- data/lib/winrm/helpers/powershell_script.rb +18 -3
- data/lib/winrm/http/response_handler.rb +32 -32
- data/lib/winrm/http/transport.rb +65 -37
- data/lib/winrm/output.rb +16 -0
- data/lib/winrm/soap_provider.rb +17 -14
- data/lib/winrm/winrm_service.rb +14 -6
- data/spec/auth_timeout_spec.rb +2 -1
- data/spec/cmd_spec.rb +12 -11
- data/spec/exception_spec.rb +6 -8
- data/spec/issue_59_spec.rb +15 -0
- data/spec/matchers.rb +5 -3
- data/spec/output_spec.rb +57 -53
- data/spec/powershell_spec.rb +16 -14
- data/spec/response_handler_spec.rb +12 -11
- data/spec/spec_helper.rb +10 -7
- data/spec/winrm_options_spec.rb +6 -5
- data/spec/winrm_primitives_spec.rb +9 -10
- data/spec/wql_spec.rb +2 -1
- data/winrm.gemspec +16 -15
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3608a4fcc34f3bcad9cee57c3fada4a67a4ccb0
|
4
|
+
data.tar.gz: 89f128800437d974194dedafb9ef3d56300c33e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b041e877f6b11c9b11acff78c714da8d2bb6e3cd80f87a8788deb62177edb8f2e1483e9f9aa7d36966fd8cccc2d57c0f69c601498f782b96535b397ec22486c3
|
7
|
+
data.tar.gz: e10dd4724ec11e483fa652ba49cf93a41f8999256ef3b5564235856b46b340dd120d7602b9da63901b356f986deecf6f54edbe0a81a8cd39ea2703b3abbcb661
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -72,28 +72,6 @@ iex $cmd
|
|
72
72
|
WinRM::WinRMWebService.new(endpoint, :kerberos, :realm => 'MYREALM.COM')
|
73
73
|
```
|
74
74
|
|
75
|
-
### Uploading files
|
76
|
-
Files may be copied from the local machine to the winrm endpoint. Individual
|
77
|
-
files or directories may be specified:
|
78
|
-
```ruby
|
79
|
-
service = WinRM::WinRMWebService.new(...
|
80
|
-
file_manager = WinRM::FileManager.new(service)
|
81
|
-
file_manager.upload('c:/dev/my_dir', '$env:AppData')
|
82
|
-
```
|
83
|
-
Or an array of several files and/or directories can be included:
|
84
|
-
```ruby
|
85
|
-
file_manager.upload(['c:/dev/file1.txt','c:/dev/dir1'], '$env:AppData')
|
86
|
-
```
|
87
|
-
|
88
|
-
#### Handling progress events
|
89
|
-
If you want to implemnt your own custom progress handling, you can pass a code
|
90
|
-
block and use the proggress data that `upload` yields to this block:
|
91
|
-
```ruby
|
92
|
-
file_manager.upload('c:/dev/my_dir', '$env:AppData') do |bytes_copied, total_bytes, local_path, remote_path|
|
93
|
-
puts "#{bytes_copied}bytes of #{total_bytes}bytes copied"
|
94
|
-
end
|
95
|
-
```
|
96
|
-
|
97
75
|
## Troubleshooting
|
98
76
|
You may have some errors like ```WinRM::WinRMAuthorizationError```.
|
99
77
|
You can run the following commands on the server to try to solve the problem:
|
@@ -118,11 +96,14 @@ You can read more about that on issue [#29](https://github.com/WinRb/WinRM/issue
|
|
118
96
|
'winrm quickconfig' on your server or enable WinRM via group policy and
|
119
97
|
everything should be working.
|
120
98
|
|
121
|
-
2. Multi-Instance support:
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
99
|
+
2. Multi-Instance support: Moving away from Handsoap allows multiple
|
100
|
+
instances to be created because the SOAP backend is no longer a Singleton
|
101
|
+
type class.
|
102
|
+
|
103
|
+
3. 100% Ruby: Nokogiri while faster can present additional frustration for
|
104
|
+
users above and beyond what is already required to get WinRM working.
|
105
|
+
The goal of this gem is make using WinRM easy. In V2 we plan on making
|
106
|
+
the parser swappable in case you really do need the performance.
|
126
107
|
|
127
108
|
## Contributing
|
128
109
|
|
data/Rakefile
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require 'rubygems'
|
2
3
|
require 'bundler/setup'
|
3
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
require 'bundler/gem_tasks'
|
4
7
|
|
5
8
|
# Change to the directory of this file.
|
6
|
-
Dir.chdir(File.expand_path(
|
7
|
-
|
8
|
-
# For gem creation and bundling
|
9
|
-
require "bundler/gem_tasks"
|
9
|
+
Dir.chdir(File.expand_path('../', __FILE__))
|
10
10
|
|
11
11
|
RSpec::Core::RakeTask.new(:spec) do |task|
|
12
|
-
task.pattern =
|
13
|
-
task.rspec_opts = [
|
12
|
+
task.pattern = 'test/spec/*_spec.rb'
|
13
|
+
task.rspec_opts = ['--color', '-f documentation']
|
14
14
|
task.rspec_opts << '-tunit'
|
15
15
|
end
|
16
16
|
|
17
17
|
# Run the integration test suite
|
18
18
|
RSpec::Core::RakeTask.new(:integration) do |task|
|
19
|
-
task.pattern =
|
20
|
-
task.rspec_opts = [
|
19
|
+
task.pattern = 'test/spec/*_spec.rb'
|
20
|
+
task.rspec_opts = ['--color', '-f documentation']
|
21
21
|
task.rspec_opts << '-tintegration'
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
RuboCop::RakeTask.new
|
25
|
+
|
26
|
+
task default: [:spec, :rubocop]
|
25
27
|
|
26
|
-
task :
|
28
|
+
task all: [:default, :integration]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.0
|
1
|
+
1.3.0
|
data/Vagrantfile
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# -*- mode: ruby -*-
|
2
3
|
# vi: set ft=ruby :
|
3
4
|
|
4
|
-
VAGRANTFILE_API_VERSION =
|
5
|
+
VAGRANTFILE_API_VERSION = '2'
|
5
6
|
|
6
7
|
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
7
|
-
config.vm.box =
|
8
|
+
config.vm.box = 'mwrock/Windows2012R2'
|
8
9
|
end
|
data/bin/rwinrm
CHANGED
@@ -1,41 +1,44 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
2
3
|
|
3
4
|
# Copyright 2014 Shawn Neal <sneal@sneal.net>
|
4
|
-
#
|
5
|
+
#
|
5
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
7
|
# you may not use this file except in compliance with the License.
|
7
8
|
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
+
#
|
9
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
+
#
|
11
12
|
# Unless required by applicable law or agreed to in writing, software
|
12
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
15
|
# See the License for the specific language governing permissions and
|
15
16
|
# limitations under the License.
|
16
17
|
|
17
|
-
|
18
|
+
# rubocop:disable all
|
19
|
+
|
20
|
+
$LOAD_PATH.push File.expand_path('../../lib', __FILE__)
|
18
21
|
|
19
22
|
require 'readline'
|
20
23
|
require 'io/console'
|
21
24
|
require 'winrm'
|
22
25
|
|
23
26
|
def help_msg
|
24
|
-
puts
|
25
|
-
puts
|
27
|
+
puts 'Usage: rwinrm user@host'
|
28
|
+
puts ''
|
26
29
|
end
|
27
30
|
|
28
31
|
def parse_options
|
29
32
|
options = {}
|
30
|
-
|
31
|
-
|
33
|
+
fail 'Missing required options' unless ARGV.length == 1
|
34
|
+
|
32
35
|
m = /^(?<user>\w+)@{1}(?<host>[a-zA-Z0-9\.]+)(?<port>:[0-9]+)?/.match(ARGV[0])
|
33
|
-
|
36
|
+
fail "#{ARGV[0]} is an invalid host" unless m
|
34
37
|
options[:user] = m[:user]
|
35
38
|
options[:endpoint] = "http://#{m[:host]}#{m[:port] || ':5985'}/wsman"
|
36
39
|
|
37
40
|
# Get the password
|
38
|
-
print
|
41
|
+
print 'Password: '
|
39
42
|
options[:pass] = STDIN.noecho(&:gets).chomp
|
40
43
|
puts
|
41
44
|
|
@@ -57,7 +60,7 @@ def repl(options)
|
|
57
60
|
options)
|
58
61
|
|
59
62
|
client.set_timeout(3600)
|
60
|
-
shell_id = client.open_shell
|
63
|
+
shell_id = client.open_shell
|
61
64
|
command_id = client.run_command(shell_id, 'cmd', "/K prompt [#{ARGV[0]}]$P$G")
|
62
65
|
|
63
66
|
read_thread = Thread.new do
|
@@ -68,9 +71,9 @@ def repl(options)
|
|
68
71
|
end
|
69
72
|
read_thread.abort_on_exception = true
|
70
73
|
|
71
|
-
while buf = Readline.readline('', true)
|
74
|
+
while (buf = Readline.readline('', true))
|
72
75
|
if buf =~ /^exit/
|
73
|
-
read_thread.exit
|
76
|
+
read_thread.exit
|
74
77
|
client.cleanup_command(shell_id, command_id)
|
75
78
|
client.close_shell(shell_id)
|
76
79
|
exit 0
|
@@ -79,13 +82,16 @@ def repl(options)
|
|
79
82
|
end
|
80
83
|
end
|
81
84
|
rescue Interrupt
|
85
|
+
puts 'exiting'
|
82
86
|
# ctrl-c
|
83
87
|
rescue WinRM::WinRMAuthorizationError
|
84
|
-
puts
|
88
|
+
puts 'Authentication failed, bad user name or password'
|
85
89
|
exit 1
|
86
90
|
rescue StandardError => e
|
87
91
|
puts e.message
|
88
92
|
exit 1
|
89
93
|
end
|
90
94
|
|
91
|
-
repl(parse_options
|
95
|
+
repl(parse_options)
|
96
|
+
|
97
|
+
# rubocop:enable all
|
data/changelog.md
CHANGED
@@ -1,4 +1,25 @@
|
|
1
|
-
|
1
|
+
# WinRM Gem Changelog
|
2
|
+
|
3
|
+
# 1.3.0
|
4
|
+
- Fixed multiple issues with WinRMHTTPTransportError incorrectly being raised
|
5
|
+
- Refactored and added more unit and integration tests
|
6
|
+
- Added ability to write to stdin
|
7
|
+
- Added rwinrm binary to launch remote shell
|
8
|
+
- Added WINRM_LOG env var to set log level
|
9
|
+
- Retry Kerberos auth once if 401 response is received
|
10
|
+
- Remove Savon dependency and use newer versions of underlying dependencies
|
11
|
+
- Remove Nokogiri dependency and replace with native Ruby XML
|
12
|
+
- Fixed issue 85, ensure WQL response is not nil
|
13
|
+
- All WinRM library errors inherit from base class WinRMError
|
14
|
+
- Integrations tests should now pass on Windows Server 2008+
|
15
|
+
- Bump Ruby NTLM gem version dependency
|
16
|
+
- HTTP client receive timeout is now configurable via set_timeout
|
17
|
+
- Added backwards compatible Output class to make it easier to collect output
|
18
|
+
- Bumped gssapi dependency from 1.0 to 1.2 and fixed issue 54
|
19
|
+
- Added Rubocop to build
|
20
|
+
- Fixed error when commands contain a newline character
|
21
|
+
|
22
|
+
# 1.2.0
|
2
23
|
- Allow user to disable SSL peer ceritifcate validation #44
|
3
24
|
- Allow commands with "'" chars on Ruby 2.x, fixes #69
|
4
25
|
- Fixed uninitialized constant Module::Kconv in Ruby 2.x, fixes #65
|
data/lib/winrm.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
1
3
|
# Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
|
2
|
-
#
|
4
|
+
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
6
|
# you may not use this file except in compliance with the License.
|
5
7
|
# You may obtain a copy of the License at
|
6
|
-
#
|
8
|
+
#
|
7
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
10
|
+
#
|
9
11
|
# Unless required by applicable law or agreed to in writing, software
|
10
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -13,22 +15,23 @@
|
|
13
15
|
# limitations under the License.
|
14
16
|
|
15
17
|
require 'date'
|
16
|
-
require 'kconv' # rubyntlm .0.1.1 doesn't require kconv, workaround for issue #65
|
17
18
|
require 'logging'
|
18
19
|
|
20
|
+
# Main WinRM module entry point
|
19
21
|
module WinRM
|
20
22
|
# Enable logging if it is requested. We do this before
|
21
23
|
# anything else so that we can setup the output before
|
22
24
|
# any logging occurs.
|
23
|
-
if ENV[
|
25
|
+
if ENV['WINRM_LOG'] && ENV['WINRM_LOG'] != ''
|
24
26
|
begin
|
25
|
-
Logging.logger.root.level = ENV[
|
27
|
+
Logging.logger.root.level = ENV['WINRM_LOG']
|
26
28
|
Logging.logger.root.appenders = Logging.appenders.stderr
|
27
29
|
rescue ArgumentError
|
28
30
|
# This means that the logging level wasn't valid
|
29
|
-
$stderr.puts "Invalid WINRM_LOG level is set: #{ENV[
|
30
|
-
$stderr.puts
|
31
|
-
$stderr.puts
|
31
|
+
$stderr.puts "Invalid WINRM_LOG level is set: #{ENV['WINRM_LOG']}"
|
32
|
+
$stderr.puts ''
|
33
|
+
$stderr.puts 'Please use one of the standard log levels: ' \
|
34
|
+
'debug, info, warn, or error'
|
32
35
|
end
|
33
36
|
end
|
34
37
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
1
3
|
# Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
|
2
|
-
#
|
4
|
+
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
6
|
# you may not use this file except in compliance with the License.
|
5
7
|
# You may obtain a copy of the License at
|
6
|
-
#
|
8
|
+
#
|
7
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
10
|
+
#
|
9
11
|
# Unless required by applicable law or agreed to in writing, software
|
10
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -13,19 +15,12 @@
|
|
13
15
|
# limitations under the License.
|
14
16
|
|
15
17
|
module WinRM
|
16
|
-
|
17
18
|
# WinRM base class for errors
|
18
19
|
class WinRMError < StandardError; end
|
19
20
|
|
20
21
|
# Authorization Error
|
21
22
|
class WinRMAuthorizationError < WinRMError; end
|
22
23
|
|
23
|
-
# Error that occurs when a file upload fails
|
24
|
-
class WinRMUploadError < WinRMError; end
|
25
|
-
|
26
|
-
# Error that occurs when a file download fails
|
27
|
-
class WinRMDownloadError < WinRMError; end
|
28
|
-
|
29
24
|
# A Fault returned in the SOAP response. The XML node is a WSManFault
|
30
25
|
class WinRMWSManFault < WinRMError
|
31
26
|
attr_reader :fault_code
|
@@ -1,44 +1,48 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
1
3
|
# Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
|
2
|
-
#
|
4
|
+
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
6
|
# you may not use this file except in compliance with the License.
|
5
7
|
# You may obtain a copy of the License at
|
6
|
-
#
|
8
|
+
#
|
7
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
10
|
+
#
|
9
11
|
# Unless required by applicable law or agreed to in writing, software
|
10
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
14
|
# See the License for the specific language governing permissions and
|
13
15
|
# limitations under the License.
|
14
16
|
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
18
|
+
# rubocop:disable Metrics/AbcSize
|
19
|
+
|
15
20
|
# Format an ISO8601 Duration
|
16
21
|
module Iso8601Duration
|
17
|
-
|
18
22
|
# Convert the number of seconds to an ISO8601 duration format
|
19
23
|
# @see http://tools.ietf.org/html/rfc2445#section-4.3.6
|
20
24
|
# @param [Fixnum] seconds The amount of seconds for this duration
|
21
25
|
def self.sec_to_dur(seconds)
|
22
26
|
seconds = seconds.to_i
|
23
|
-
iso_str =
|
24
|
-
if
|
25
|
-
weeks = seconds /
|
26
|
-
seconds -= (
|
27
|
+
iso_str = 'P'
|
28
|
+
if seconds > 604_800 # more than a week
|
29
|
+
weeks = seconds / 604_800
|
30
|
+
seconds -= (604_800 * weeks)
|
27
31
|
iso_str << "#{weeks}W"
|
28
32
|
end
|
29
|
-
if
|
30
|
-
days = seconds /
|
31
|
-
seconds -= (
|
33
|
+
if seconds > 86_400 # more than a day
|
34
|
+
days = seconds / 86_400
|
35
|
+
seconds -= (86_400 * days)
|
32
36
|
iso_str << "#{days}D"
|
33
37
|
end
|
34
|
-
if
|
35
|
-
iso_str <<
|
36
|
-
if
|
38
|
+
if seconds > 0
|
39
|
+
iso_str << 'T'
|
40
|
+
if seconds > 3600 # more than an hour
|
37
41
|
hours = seconds / 3600
|
38
42
|
seconds -= (3600 * hours)
|
39
43
|
iso_str << "#{hours}H"
|
40
44
|
end
|
41
|
-
if
|
45
|
+
if seconds > 60 # more than a minute
|
42
46
|
minutes = seconds / 60
|
43
47
|
seconds -= (60 * minutes)
|
44
48
|
iso_str << "#{minutes}M"
|
@@ -49,3 +53,6 @@ module Iso8601Duration
|
|
49
53
|
iso_str
|
50
54
|
end
|
51
55
|
end
|
56
|
+
|
57
|
+
# rubocop:enable Metrics/MethodLength
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
@@ -1,6 +1,22 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright 2014 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
|
+
|
1
17
|
module WinRM
|
18
|
+
# Wraps a PowerShell script to make it easy to Base64 encode for transport
|
2
19
|
class PowershellScript
|
3
|
-
|
4
20
|
attr_reader :text
|
5
21
|
|
6
22
|
# Creates a new PowershellScript object which can be used to encode
|
@@ -13,10 +29,9 @@ module WinRM
|
|
13
29
|
# Encodes the script so that it can be passed to the PowerShell
|
14
30
|
# --EncodedCommand argument.
|
15
31
|
# @return [String] The UTF-16LE base64 encoded script
|
16
|
-
def encoded
|
32
|
+
def encoded
|
17
33
|
encoded_script = text.encode('UTF-16LE', 'UTF-8')
|
18
34
|
Base64.strict_encode64(encoded_script)
|
19
35
|
end
|
20
|
-
|
21
36
|
end
|
22
37
|
end
|