train-winrm 0.1.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 12bed665790e51bd23cbe569c27f6a93c0300e8c
4
- data.tar.gz: 599a6d141eb447d549ca3b511c15929401dea19d
2
+ SHA256:
3
+ metadata.gz: 8bedb30ef9245e5953c85b86be962be97d177335bdc3ec5714f5eb4a3a83e407
4
+ data.tar.gz: 4a0beebeea34e8db4b989beac547d67d88cf57b915ae372d6ccf48689c1b74c3
5
5
  SHA512:
6
- metadata.gz: b12889e4dc8845c34c911e3856213eee6a8993d1d1e93488bd838a0ff0421722cba9256641b3c23bda1a7df9982e5c0ed3fdd805ee787f161edf57e34129f5a6
7
- data.tar.gz: 82873a1ed8096c63b6c56f8a8acf0981168429af31fcb63f421af272664d8822142f7fab0e7627d6aa413f1639201c84c8e91b076f1cd7cd551c88d0d38cef37
6
+ metadata.gz: 07d7e9550cf28e75d4f7c16fc266ccdb7a4a81d16438554fc6a6bb964dddd8a4cac4fea13efeb3551dfea2cab3bf148c86f20af982b7b5caa10ee59aabf382da
7
+ data.tar.gz: 79ef8219d7655d87cb58706c037dae54e6b67063d2b20b4bce459148c27a9f91d35beb8afb7185b91c4deb8020d492b4947cec302595703341b0ab39ee285352
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
5
  # This is a Gemfile, which is used by bundler
6
6
  # to ensure a coherent set of gems is installed.
@@ -12,12 +12,15 @@ gemspec
12
12
 
13
13
  # Remaining group is only used for development.
14
14
  group :development do
15
- gem 'bundler'
16
- gem 'byebug'
17
- gem 'm'
18
- gem 'minitest'
19
- gem 'mocha'
20
- gem 'pry'
21
- gem 'rake'
22
- gem 'rubocop', '= 0.49.1' # Need to keep in sync with main InSpec project, so config files will work
15
+ # Depend on this here, not in the gemspec - to avoid having to have
16
+ # client applications induce circular dependencies
17
+ gem "train-core", "~> 3.0"
18
+ gem "bundler"
19
+ gem "byebug"
20
+ gem "m"
21
+ gem "minitest"
22
+ gem "mocha"
23
+ gem "pry"
24
+ gem "rake"
25
+ gem "chefstyle"
23
26
  end
data/README.md CHANGED
@@ -1,8 +1,12 @@
1
1
  # train-winrm - Train Plugin for connecting to Windows via Remote Management
2
2
 
3
+ * **Project State: Active**
4
+ * **Issues Response SLA: 3 business days**
5
+ * **Pull Request Response SLA: 3 business days**
6
+
3
7
  This plugin allows applications that rely on Train to communicate with the WinRM API. For example, you could use this to audit Windows Server 2016 machines.
4
8
 
5
- TODO - details about underlying library
9
+ This plugin relies on the `winrm` and `winrm-fs` gems for implementation.
6
10
 
7
11
  Train itself has no CLI, nor a sophisticated test harness. Chef InSpec does have such facilities, so installing Train plugins will require a Chef InSpec installation. You do not need to use or understand Chef InSpec.
8
12
 
@@ -10,6 +14,12 @@ Train plugins may be developed without a Chef InSpec installation.
10
14
 
11
15
  ## To Install this as a User
12
16
 
17
+ ### ChefDK Installation
18
+
19
+ After August 2019, this plugin will be distributed with ChefDK; you do not need to install it separately.
20
+
21
+ ### Manual Installation using `inspec plugin install`
22
+
13
23
  Train plugins are distributed as gems. You may choose to manage the gem yourself, but if you are an Chef InSpec user, Chef InSpec can handle it for you.
14
24
 
15
25
  You will need Chef InSpec v2.3 or later.
@@ -20,15 +30,53 @@ Simply run:
20
30
  $ inspec plugin install train-winrm
21
31
  ```
22
32
 
23
- You can then run:
33
+ You can then run, using Chef InSpec as an example:
34
+
35
+ ```
36
+ you@home $ inspec some-profile winrm://someuser@somehost --password somepassword
37
+ ```
24
38
 
39
+ From Ruby code, you may use this plugin as follows:
25
40
  ```
26
- TODO - example
41
+ require 'train'
42
+ transport = Train.create(
43
+ 'winrm',
44
+ host: '1.2.3.4',
45
+ user: 'Administrator',
46
+ password: '...',
47
+ ssl: true,
48
+ self_signed: true
49
+ )
50
+ conn = transport.connection
27
51
  ```
28
52
 
29
53
  ## Target Options for Train-WinRM
30
54
 
31
- TODO
55
+ ### host
56
+
57
+ Required `String`. The hostname or IP address used for connection.
58
+
59
+ #### port
60
+
61
+ Optional `Integer`, default 5985 (plain) or 5896 (SSL). The port number to which the connection should be made.
62
+
63
+ ### user
64
+
65
+ Optional `String`, username used for sign in. Default `Administrator`.
66
+
67
+ ### password
68
+
69
+ Optional `String`, password used for sign in. None sent if not provided.
70
+
71
+ ### ssl
72
+
73
+ Optional `Boolean`. Defaults to `false`. Determines whether to use SSL to encrypt communications.
74
+
75
+ Several other options exist. To see these options, run:
76
+
77
+ ```
78
+ puts Train.options('winrm')
79
+ ```
32
80
 
33
81
  ## Reporting Issues
34
82
 
@@ -46,6 +94,12 @@ If you wish to contribute to this plugin, please use the usual fork-branch-push-
46
94
 
47
95
  [Plugin Development](https://github.com/inspec/train/blob/master/docs/dev/plugins.md) is documented on the `train` project on GitHub.
48
96
 
97
+ ### Unit tests
98
+
99
+ Run `bundle exec rake test:unit` to run the unit tests.
100
+
49
101
  ### Testing changes against a Windows Machine
50
102
 
51
- TODO
103
+ Install Vagrant and VirtualBox. Check the Vagrantfile to verify that it references a Windows 2016 evaluation VagrantBox to which you have access.
104
+
105
+ Then, run `bundle exec rake test:integration`. There are sub-tasks you can use to run only the integration tests; to see a list of all tasks, run `rake -aT`.
data/lib/train-winrm.rb CHANGED
@@ -12,9 +12,9 @@ libdir = File.dirname(__FILE__)
12
12
  $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
13
13
 
14
14
  # It's traditonal to keep your gem version in a separate file, so CI can find it easier.
15
- require 'train-winrm/version'
15
+ require "train-winrm/version"
16
16
 
17
17
  # A train plugin has three components: Transport, Connection, and (optionally) Platform.
18
18
  # Transport acts as the glue.
19
- require 'train-winrm/transport'
20
- require 'train-winrm/connection'
19
+ require "train-winrm/transport"
20
+ require "train-winrm/connection"
@@ -33,8 +33,8 @@
33
33
  # * marshalling to / from JSON
34
34
  # You don't have to worry about most of this.
35
35
 
36
- require 'train'
37
- require 'train/plugins'
36
+ require "train"
37
+ require "train/plugins"
38
38
 
39
39
  module TrainPlugins
40
40
  module WinRM
@@ -54,6 +54,7 @@ module TrainPlugins
54
54
  # (see Base::Connection#close)
55
55
  def close
56
56
  return if @session.nil?
57
+
57
58
  session.close
58
59
  ensure
59
60
  @session = nil
@@ -61,7 +62,7 @@ module TrainPlugins
61
62
 
62
63
  # (see Base::Connection#login_command)
63
64
  def login_command
64
- case RbConfig::CONFIG['host_os']
65
+ case RbConfig::CONFIG["host_os"]
65
66
  when /darwin/
66
67
  login_command_for_mac
67
68
  when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
@@ -69,9 +70,9 @@ module TrainPlugins
69
70
  when /linux/
70
71
  login_command_for_linux
71
72
  else
72
- fail ActionFailed,
73
- "Remote login not supported in #{self.class} " \
74
- "from host OS '#{RbConfig::CONFIG['host_os']}'."
73
+ raise ActionFailed,
74
+ "Remote login not supported in #{self.class} " \
75
+ "from host OS '#{RbConfig::CONFIG["host_os"]}'."
75
76
  end
76
77
  end
77
78
 
@@ -91,7 +92,7 @@ module TrainPlugins
91
92
  delay = 3
92
93
  session(
93
94
  retry_limit: @max_wait_until_ready / delay,
94
- retry_delay: delay,
95
+ retry_delay: delay
95
96
  )
96
97
  run_command_via_connection(PING_COMMAND.dup)
97
98
  end
@@ -110,8 +111,9 @@ module TrainPlugins
110
111
 
111
112
  def run_command_via_connection(command, &data_handler)
112
113
  return if command.nil?
114
+
113
115
  logger.debug("[WinRM] #{self} (#{command})")
114
- out = ''
116
+ out = ""
115
117
 
116
118
  response = session.run(command) do |stdout, _|
117
119
  yield(stdout) if data_handler && stdout
@@ -131,7 +133,7 @@ module TrainPlugins
131
133
  host = URI.parse(options[:endpoint]).host
132
134
  content = [
133
135
  "full address:s:#{host}:#{@rdp_port}",
134
- 'prompt for credentials:i:1',
136
+ "prompt for credentials:i:1",
135
137
  "username:s:#{options[:user]}",
136
138
  ].join("\n")
137
139
 
@@ -157,10 +159,10 @@ module TrainPlugins
157
159
  # @return [LoginCommand] a login command
158
160
  # @api private
159
161
  def login_command_for_linux
160
- args = %W(-u #{options[:user]})
161
- args += %W(-p #{options[:pass]}) if options.key?(:pass)
162
- args += %W(#{URI.parse(options[:endpoint]).host}:#{@rdp_port})
163
- LoginCommand.new('rdesktop', args)
162
+ args = %W{-u #{options[:user]}}
163
+ args += %W{-p #{options[:pass]}} if options.key?(:pass)
164
+ args += %W{#{URI.parse(options[:endpoint]).host}:#{@rdp_port}}
165
+ LoginCommand.new("rdesktop", args)
164
166
  end
165
167
 
166
168
  # Builds a `LoginCommand` for use by Mac-based platforms.
@@ -168,7 +170,7 @@ module TrainPlugins
168
170
  # @return [LoginCommand] a login command
169
171
  # @api private
170
172
  def login_command_for_mac
171
- LoginCommand.new('open', rdp_doc(mac: true))
173
+ LoginCommand.new("open", rdp_doc(mac: true))
172
174
  end
173
175
 
174
176
  # Builds a `LoginCommand` for use by Windows-based platforms.
@@ -176,7 +178,7 @@ module TrainPlugins
176
178
  # @return [LoginCommand] a login command
177
179
  # @api private
178
180
  def login_command_for_windows
179
- LoginCommand.new('mstsc', rdp_doc)
181
+ LoginCommand.new("mstsc", rdp_doc)
180
182
  end
181
183
 
182
184
  # Establishes a remote shell session, or establishes one when invoked
@@ -205,7 +207,7 @@ module TrainPlugins
205
207
  # @api private
206
208
  def to_s
207
209
  options_to_print = @options.clone
208
- options_to_print[:password] = '<hidden>' if options_to_print.key?(:password)
210
+ options_to_print[:password] = "<hidden>" if options_to_print.key?(:password)
209
211
  "#{@username}@#{@hostname}<#{options_to_print.inspect}>"
210
212
  end
211
213
  end
@@ -21,11 +21,11 @@
21
21
  # See the License for the specific language governing permissions and
22
22
  # limitations under the License.
23
23
 
24
- require 'rbconfig'
25
- require 'uri'
26
- require 'train'
27
- require 'train/errors'
28
- require 'train/plugins'
24
+ require "rbconfig"
25
+ require "uri"
26
+ require "train"
27
+ require "train/errors"
28
+ require "train/plugins"
29
29
 
30
30
  # Train Plugins v1 are usually declared under the TrainPlugins namespace.
31
31
  # Each plugin has three components: Transport, Connection, and (optionally) Platform.
@@ -44,22 +44,22 @@ module TrainPlugins
44
44
  # @author Salim Afiune <salim@afiunemaya.com.mx>
45
45
  # @author Fletcher Nichol <fnichol@nichol.ca>
46
46
  class Transport < Train.plugin(1) # rubocop:disable Metrics/ClassLength
47
- name 'winrm'
47
+ name "winrm"
48
48
 
49
- require 'train-winrm/connection'
49
+ require "train-winrm/connection"
50
50
 
51
51
  # ref: https://github.com/winrb/winrm#transports
52
- SUPPORTED_WINRM_TRANSPORTS = %i(negotiate ssl plaintext kerberos).freeze
52
+ SUPPORTED_WINRM_TRANSPORTS = %i{negotiate ssl plaintext kerberos}.freeze
53
53
 
54
54
  # common target configuration
55
55
  option :host, required: true
56
56
  option :port
57
- option :user, default: 'administrator', required: true
57
+ option :user, default: "administrator", required: true
58
58
  option :password, nil
59
59
  option :winrm_transport, default: :negotiate
60
60
  option :winrm_disable_sspi, default: false
61
61
  option :winrm_basic_auth_only, default: false
62
- option :path, default: '/wsman'
62
+ option :path, default: "/wsman"
63
63
  option :ssl, default: false
64
64
  option :self_signed, default: false
65
65
 
@@ -101,21 +101,21 @@ module TrainPlugins
101
101
  super(opts)
102
102
 
103
103
  # set scheme and port based on ssl activation
104
- scheme = opts[:ssl] ? 'https' : 'http'
104
+ scheme = opts[:ssl] ? "https" : "http"
105
105
  port = opts[:port]
106
106
  port = (opts[:ssl] ? 5986 : 5985) if port.nil?
107
107
  winrm_transport = opts[:winrm_transport].to_sym
108
108
  unless SUPPORTED_WINRM_TRANSPORTS.include?(winrm_transport)
109
- fail Train::ClientError, "Unsupported transport type: #{winrm_transport.inspect}"
109
+ raise Train::ClientError, "Unsupported transport type: #{winrm_transport.inspect}"
110
110
  end
111
111
 
112
112
  # remove leading '/'
113
- path = (opts[:path] || '').sub(%r{^/+}, '')
113
+ path = (opts[:path] || "").sub(%r{^/+}, "")
114
114
 
115
115
  opts[:endpoint] = "#{scheme}://#{opts[:host]}:#{port}/#{path}"
116
116
  end
117
117
 
118
- WINRM_FS_SPEC_VERSION = '~> 1.0'.freeze
118
+ WINRM_FS_SPEC_VERSION = "~> 1.0".freeze
119
119
 
120
120
  # Builds the hash of options needed by the Connection object on
121
121
  # construction.
@@ -125,23 +125,23 @@ module TrainPlugins
125
125
  # @api private
126
126
  def connection_options(opts)
127
127
  {
128
- logger: logger,
129
- transport: opts[:winrm_transport].to_sym,
130
- disable_sspi: opts[:winrm_disable_sspi],
131
- basic_auth_only: opts[:winrm_basic_auth_only],
132
- hostname: opts[:host],
133
- endpoint: opts[:endpoint],
134
- user: opts[:user],
135
- password: opts[:password],
136
- rdp_port: opts[:rdp_port],
137
- connection_retries: opts[:connection_retries],
138
- connection_retry_sleep: opts[:connection_retry_sleep],
139
- max_wait_until_ready: opts[:max_wait_until_ready],
128
+ logger: logger,
129
+ transport: opts[:winrm_transport].to_sym,
130
+ disable_sspi: opts[:winrm_disable_sspi],
131
+ basic_auth_only: opts[:winrm_basic_auth_only],
132
+ hostname: opts[:host],
133
+ endpoint: opts[:endpoint],
134
+ user: opts[:user],
135
+ password: opts[:password],
136
+ rdp_port: opts[:rdp_port],
137
+ connection_retries: opts[:connection_retries],
138
+ connection_retry_sleep: opts[:connection_retry_sleep],
139
+ max_wait_until_ready: opts[:max_wait_until_ready],
140
140
  no_ssl_peer_verification: opts[:self_signed],
141
- realm: opts[:kerberos_realm],
142
- service: opts[:kerberos_service],
143
- ca_trust_file: opts[:ca_trust_file],
144
- ssl_peer_fingerprint: opts[:ssl_peer_fingerprint],
141
+ realm: opts[:kerberos_realm],
142
+ service: opts[:kerberos_service],
143
+ ca_trust_file: opts[:ca_trust_file],
144
+ ssl_peer_fingerprint: opts[:ssl_peer_fingerprint],
145
145
  }
146
146
  end
147
147
 
@@ -164,34 +164,34 @@ module TrainPlugins
164
164
  # (see Base#load_needed_dependencies!)
165
165
  def load_needed_dependencies!
166
166
  spec_version = WINRM_FS_SPEC_VERSION.dup
167
- logger.debug('winrm-fs requested,' \
167
+ logger.debug("winrm-fs requested," \
168
168
  " loading WinRM::FS gem (#{spec_version})")
169
- gem 'winrm-fs', spec_version
170
- first_load = require 'winrm-fs'
169
+ gem "winrm-fs", spec_version
170
+ first_load = require "winrm-fs"
171
171
  load_winrm_transport!
172
172
 
173
173
  if first_load
174
- logger.debug('WinRM::FS library loaded')
174
+ logger.debug("WinRM::FS library loaded")
175
175
  else
176
- logger.debug('WinRM::FS previously loaded')
176
+ logger.debug("WinRM::FS previously loaded")
177
177
  end
178
178
  rescue LoadError => e
179
179
  logger.fatal(
180
180
  "The `winrm-fs' gem is missing and must" \
181
- ' be installed or cannot be properly activated. Run' \
181
+ " be installed or cannot be properly activated. Run" \
182
182
  " `gem install winrm-fs --version '#{spec_version}'`" \
183
- ' or add the following to your Gemfile if you are using Bundler:' \
184
- " `gem 'winrm-fs', '#{spec_version}'`.",
183
+ " or add the following to your Gemfile if you are using Bundler:" \
184
+ " `gem 'winrm-fs', '#{spec_version}'`."
185
185
  )
186
186
  raise Train::UserError,
187
- "Could not load or activate WinRM::FS (#{e.message})"
187
+ "Could not load or activate WinRM::FS (#{e.message})"
188
188
  end
189
189
 
190
190
  # Load WinRM::Transport code.
191
191
  #
192
192
  # @api private
193
193
  def load_winrm_transport!
194
- silence_warnings { require 'winrm-fs' }
194
+ silence_warnings { require "winrm-fs" }
195
195
  end
196
196
 
197
197
  # Return the last saved WinRM connection instance.
@@ -5,6 +5,6 @@
5
5
 
6
6
  module TrainPlugins
7
7
  module WinRM
8
- VERSION = '0.1.0'.freeze
8
+ VERSION = "0.2.3".freeze
9
9
  end
10
10
  end
data/train-winrm.gemspec CHANGED
@@ -4,22 +4,22 @@
4
4
 
5
5
  # It is traditional in a gemspec to dynamically load the current version
6
6
  # from a file in the source tree. The next three lines make that happen.
7
- lib = File.expand_path('../lib', __FILE__)
7
+ lib = File.expand_path("../lib", __FILE__)
8
8
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
- require 'train-winrm/version'
9
+ require "train-winrm/version"
10
10
 
11
11
  Gem::Specification.new do |spec|
12
12
  # Importantly, all Train plugins must be prefixed with `train-`
13
- spec.name = 'train-winrm'
13
+ spec.name = "train-winrm"
14
14
 
15
15
  # It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
16
16
  spec.version = TrainPlugins::WinRM::VERSION
17
- spec.authors = ['Chef InSpec Team']
18
- spec.email = ['inspec@chef.io']
19
- spec.summary = 'Windows WinRM API Transport for Train'
20
- spec.description = 'Allows applictaions using Train to speak to Windows using Remote Management; handles authentication, cacheing, and SDK dependency management.'
21
- spec.homepage = 'https://github.com/inspec/train-winrm'
22
- spec.license = 'Apache-2.0'
17
+ spec.authors = ["Chef InSpec Team"]
18
+ spec.email = ["inspec@chef.io"]
19
+ spec.summary = "Windows WinRM API Transport for Train"
20
+ spec.description = "Allows applictaions using Train to speak to Windows using Remote Management; handles authentication, cacheing, and SDK dependency management."
21
+ spec.homepage = "https://github.com/inspec/train-winrm"
22
+ spec.license = "Apache-2.0"
23
23
 
24
24
  # Though complicated-looking, this is pretty standard for a gemspec.
25
25
  # It just filters what will actually be packaged in the gem (leaving
@@ -27,9 +27,9 @@ Gem::Specification.new do |spec|
27
27
  spec.files = %w{
28
28
  README.md train-winrm.gemspec Gemfile
29
29
  } + Dir.glob(
30
- 'lib/**/*', File::FNM_DOTMATCH
30
+ "lib/**/*", File::FNM_DOTMATCH
31
31
  ).reject { |f| File.directory?(f) }
32
- spec.require_paths = ['lib']
32
+ spec.require_paths = ["lib"]
33
33
 
34
34
  # If you rely on any other gems, list them here with any constraints.
35
35
  # This is how `inspec plugin install` is able to manage your dependencies.
@@ -38,8 +38,7 @@ Gem::Specification.new do |spec|
38
38
  # them in Gemfile, not here.
39
39
 
40
40
  # Do not list inspec as a dependency of a train plugin.
41
-
42
- spec.add_dependency 'train', '~> 2.0'
43
- spec.add_dependency 'winrm', '~> 2.0'
44
- spec.add_dependency 'winrm-fs', '~> 1.0'
41
+ # Do not list train or train-core as a dependency of a train plugin.
42
+ spec.add_dependency "winrm", "~> 2.0"
43
+ spec.add_dependency "winrm-fs", "~> 1.0"
45
44
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train-winrm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.3
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: 2019-05-09 00:00:00.000000000 Z
11
+ date: 2019-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: train
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: winrm
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -86,8 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
72
  - !ruby/object:Gem::Version
87
73
  version: '0'
88
74
  requirements: []
89
- rubyforge_project:
90
- rubygems_version: 2.6.14.3
75
+ rubygems_version: 3.0.3
91
76
  signing_key:
92
77
  specification_version: 4
93
78
  summary: Windows WinRM API Transport for Train