train-core 2.1.19 → 3.0.1

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
2
  SHA256:
3
- metadata.gz: 49c2854136c56c84e5c6faf50ab984a40147044da89fcfa9d18c00c9dba45b37
4
- data.tar.gz: ecea91c8b628a255c768e99101998c2da73fbbb8bb423102e9ede66d41e504ec
3
+ metadata.gz: fc412482ed0f718b661526c4322fb9820f78a00cc6ae134016a26c2760678875
4
+ data.tar.gz: 15f5e5fb64c8a5ae82f00998c77c0e8022ee3c7f4e29224e15025638278e7e3f
5
5
  SHA512:
6
- metadata.gz: 0b02727f361fbfadb0c0f1a1557b962cffbc834eb2d4fa418910f26fb6f70ddd4ea737a07aaf4079c188030f99e2d28477e71a6e534c86b6687157de36032bea
7
- data.tar.gz: c936b2736c1c6de03b859e4be7dae31c40e33f3c136970676621374a10c86f5b982b6c05bd9fc3e4f6d7faf2bef19c47bc79ab86ef83d5152af11bbeb5812aa6
6
+ metadata.gz: 2d2095822f7c5fac05329fb14f39f16c0da669441990dffef2614fe6549d9b520adba18063538b40a5960a54dbc3fd711452ae9530d4387b5f40f366d93aaaf7
7
+ data.tar.gz: 8854eb8744b9046c8c166b9e6d162fa6deb2e311adf2db8f2670706f066907564f5b6ad9876fde9a9fd6eab94392bc3deb9bb8a321f005e2a808b7e635d7a1dc
@@ -12,7 +12,11 @@ module Train::Platforms::Detect::Helpers
12
12
  end
13
13
 
14
14
  def winrm?
15
- @backend.class.to_s == "Train::Transports::WinRM::Connection"
15
+ backend_name == "TrainPlugins::WinRM::Connection"
16
+ end
17
+
18
+ def backend_name
19
+ @backend.class.name
16
20
  end
17
21
 
18
22
  def unix_file_contents(path)
@@ -236,7 +236,10 @@ module Train::Platforms::Detect::Specifications
236
236
  # suse family
237
237
  plat.family("suse").in_family("linux")
238
238
  .detect do
239
- unless (suse = unix_file_contents("/etc/SuSE-release")).nil?
239
+ if linux_os_release && linux_os_release["ID_LIKE"] =~ /suse/i
240
+ @platform[:release] = linux_os_release["VERSION"]
241
+ true
242
+ elsif !(suse = unix_file_contents("/etc/SuSE-release")).nil?
240
243
  # https://rubular.com/r/UKaYWolCYFMfp1
241
244
  version = suse.scan(/VERSION = (\d+)\nPATCHLEVEL = (\d+)/).flatten.join(".")
242
245
  # https://rubular.com/r/b5PN3hZDxa5amV
@@ -247,11 +250,13 @@ module Train::Platforms::Detect::Specifications
247
250
  end
248
251
  plat.name("opensuse").title("OpenSUSE Linux").in_family("suse")
249
252
  .detect do
250
- true if unix_file_contents("/etc/SuSE-release") =~ /^opensuse/i
253
+ true if (linux_os_release && linux_os_release["NAME"] =~ /^opensuse/i) ||
254
+ unix_file_contents("/etc/SuSE-release") =~ /^opensuse/i
251
255
  end
252
256
  plat.name("suse").title("Suse Linux").in_family("suse")
253
257
  .detect do
254
- true if unix_file_contents("/etc/SuSE-release") =~ /suse/i
258
+ true if (linux_os_release && linux_os_release["NAME"] =~ /^sles/i) ||
259
+ unix_file_contents("/etc/SuSE-release") =~ /suse/i
255
260
  end
256
261
 
257
262
  # arch
data/lib/train/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
4
 
5
5
  module Train
6
- VERSION = "2.1.19".freeze
6
+ VERSION = "3.0.1".freeze
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.19
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-23 00:00:00.000000000 Z
11
+ date: 2019-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -90,34 +90,6 @@ dependencies:
90
90
  - - "<"
91
91
  - !ruby/object:Gem::Version
92
92
  version: '3.0'
93
- - !ruby/object:Gem::Dependency
94
- name: winrm
95
- requirement: !ruby/object:Gem::Requirement
96
- requirements:
97
- - - "~>"
98
- - !ruby/object:Gem::Version
99
- version: '2.0'
100
- type: :runtime
101
- prerelease: false
102
- version_requirements: !ruby/object:Gem::Requirement
103
- requirements:
104
- - - "~>"
105
- - !ruby/object:Gem::Version
106
- version: '2.0'
107
- - !ruby/object:Gem::Dependency
108
- name: winrm-fs
109
- requirement: !ruby/object:Gem::Requirement
110
- requirements:
111
- - - "~>"
112
- - !ruby/object:Gem::Version
113
- version: '1.0'
114
- type: :runtime
115
- prerelease: false
116
- version_requirements: !ruby/object:Gem::Requirement
117
- requirements:
118
- - - "~>"
119
- - !ruby/object:Gem::Version
120
- version: '1.0'
121
93
  description: A minimal Train with a backends for ssh and winrm.
122
94
  email:
123
95
  - drichter@chef.io
@@ -164,8 +136,6 @@ files:
164
136
  - lib/train/transports/mock.rb
165
137
  - lib/train/transports/ssh.rb
166
138
  - lib/train/transports/ssh_connection.rb
167
- - lib/train/transports/winrm.rb
168
- - lib/train/transports/winrm_connection.rb
169
139
  - lib/train/version.rb
170
140
  homepage: https://github.com/inspec/train/
171
141
  licenses:
@@ -1,207 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
4
- # Author:: Matt Wrock (<matt@mattwrock.com>)
5
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
6
- # Author:: Dominik Richter (<dominik.richter@gmail.com>)
7
- # Author:: Christoph Hartmann (<chris@lollyrock.com>)
8
- #
9
- # Copyright (C) 2014, Salim Afiune
10
- #
11
- # Licensed under the Apache License, Version 2.0 (the "License");
12
- # you may not use this file except in compliance with the License.
13
- # You may obtain a copy of the License at
14
- #
15
- # http://www.apache.org/licenses/LICENSE-2.0
16
- #
17
- # Unless required by applicable law or agreed to in writing, software
18
- # distributed under the License is distributed on an "AS IS" BASIS,
19
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
- # See the License for the specific language governing permissions and
21
- # limitations under the License.
22
-
23
- require "rbconfig"
24
- require "uri"
25
- require "train/errors"
26
-
27
- module Train::Transports
28
- # Wrapped exception for any internally raised WinRM-related errors.
29
- #
30
- # @author Fletcher Nichol <fnichol@nichol.ca>
31
- class WinRMFailed < Train::TransportError; end
32
-
33
- # A Transport which uses WinRM to execute commands and transfer files.
34
- #
35
- # @author Matt Wrock <matt@mattwrock.com>
36
- # @author Salim Afiune <salim@afiunemaya.com.mx>
37
- # @author Fletcher Nichol <fnichol@nichol.ca>
38
- class WinRM < Train.plugin(1) # rubocop:disable ClassLength
39
- name "winrm"
40
-
41
- require "train/transports/winrm_connection"
42
-
43
- # ref: https://github.com/winrb/winrm#transports
44
- SUPPORTED_WINRM_TRANSPORTS = %i{negotiate ssl plaintext kerberos}.freeze
45
-
46
- # common target configuration
47
- option :host, required: true
48
- option :port
49
- option :user, default: "administrator", required: true
50
- option :password, nil
51
- option :winrm_transport, default: :negotiate
52
- option :winrm_disable_sspi, default: false
53
- option :winrm_basic_auth_only, default: false
54
- option :path, default: "/wsman"
55
- option :ssl, default: false
56
- option :self_signed, default: false
57
-
58
- # additional winrm options
59
- option :rdp_port, default: 3389
60
- option :connection_retries, default: 5
61
- option :connection_retry_sleep, default: 1
62
- option :max_wait_until_ready, default: 600
63
- option :ssl_peer_fingerprint, default: nil
64
- option :kerberos_realm, default: nil
65
- option :kerberos_service, default: nil
66
- option :ca_trust_path, default: nil
67
- # The amount of time in SECONDS for which each operation must get an ack
68
- # from the winrm endpoint. Does not mean that the command has
69
- # completed in this time, only that the server has ack'd the request.
70
- option :operation_timeout, default: nil
71
-
72
- def initialize(opts)
73
- super(opts)
74
- load_needed_dependencies!
75
- end
76
-
77
- # (see Base#connection)
78
- def connection(state = nil, &block)
79
- opts = merge_options(options, state || {})
80
- validate_options(opts)
81
- conn_opts = connection_options(opts)
82
-
83
- if @connection && @connection_options == conn_opts
84
- reuse_connection(&block)
85
- else
86
- create_new_connection(conn_opts, &block)
87
- end
88
- end
89
-
90
- private
91
-
92
- def validate_options(opts)
93
- super(opts)
94
-
95
- # set scheme and port based on ssl activation
96
- scheme = opts[:ssl] ? "https" : "http"
97
- port = opts[:port]
98
- port = (opts[:ssl] ? 5986 : 5985) if port.nil?
99
- winrm_transport = opts[:winrm_transport].to_sym
100
- unless SUPPORTED_WINRM_TRANSPORTS.include?(winrm_transport)
101
- raise Train::ClientError, "Unsupported transport type: #{winrm_transport.inspect}"
102
- end
103
-
104
- # remove leading '/'
105
- path = (opts[:path] || "").sub(%r{^/+}, "")
106
-
107
- opts[:endpoint] = "#{scheme}://#{opts[:host]}:#{port}/#{path}"
108
- end
109
-
110
- WINRM_FS_SPEC_VERSION = "~> 1.0".freeze
111
-
112
- # Builds the hash of options needed by the Connection object on
113
- # construction.
114
- #
115
- # @param data [Hash] merged configuration and mutable state data
116
- # @return [Hash] hash of connection options
117
- # @api private
118
- def connection_options(opts)
119
- {
120
- logger: logger,
121
- transport: opts[:winrm_transport].to_sym,
122
- disable_sspi: opts[:winrm_disable_sspi],
123
- basic_auth_only: opts[:winrm_basic_auth_only],
124
- hostname: opts[:host],
125
- endpoint: opts[:endpoint],
126
- user: opts[:user],
127
- password: opts[:password],
128
- rdp_port: opts[:rdp_port],
129
- connection_retries: opts[:connection_retries],
130
- connection_retry_sleep: opts[:connection_retry_sleep],
131
- max_wait_until_ready: opts[:max_wait_until_ready],
132
- no_ssl_peer_verification: opts[:self_signed],
133
- realm: opts[:kerberos_realm],
134
- service: opts[:kerberos_service],
135
- ca_trust_path: opts[:ca_trust_path],
136
- ssl_peer_fingerprint: opts[:ssl_peer_fingerprint],
137
- }
138
- end
139
-
140
- # Creates a new WinRM Connection instance and save it for potential
141
- # future reuse.
142
- #
143
- # @param options [Hash] conneciton options
144
- # @return [WinRM::Connection] a WinRM Connection instance
145
- # @api private
146
- def create_new_connection(options, &block)
147
- if @connection
148
- logger.debug("[WinRM] shutting previous connection #{@connection}")
149
- @connection.close
150
- end
151
-
152
- @connection_options = options
153
- @connection = Connection.new(options, &block)
154
- end
155
-
156
- # (see Base#load_needed_dependencies!)
157
- def load_needed_dependencies!
158
- spec_version = WINRM_FS_SPEC_VERSION.dup
159
- logger.debug("winrm-fs requested," \
160
- " loading WinRM::FS gem (#{spec_version})")
161
- gem "winrm-fs", spec_version
162
- first_load = require "winrm-fs"
163
- load_winrm_transport!
164
-
165
- if first_load
166
- logger.debug("WinRM::FS library loaded")
167
- else
168
- logger.debug("WinRM::FS previously loaded")
169
- end
170
- rescue LoadError => e
171
- logger.fatal(
172
- "The `winrm-fs' gem is missing and must" \
173
- " be installed or cannot be properly activated. Run" \
174
- " `gem install winrm-fs --version '#{spec_version}'`" \
175
- " or add the following to your Gemfile if you are using Bundler:" \
176
- " `gem 'winrm-fs', '#{spec_version}'`."
177
- )
178
- raise Train::UserError,
179
- "Could not load or activate WinRM::FS (#{e.message})"
180
- end
181
-
182
- # Load WinRM::Transport code.
183
- #
184
- # @api private
185
- def load_winrm_transport!
186
- silence_warnings { require "winrm-fs" }
187
- end
188
-
189
- # Return the last saved WinRM connection instance.
190
- #
191
- # @return [Winrm::Connection] a WinRM Connection instance
192
- # @api private
193
- def reuse_connection
194
- logger.debug("[WinRM] reusing existing connection #{@connection}")
195
- yield @connection if block_given?
196
- @connection
197
- end
198
-
199
- def silence_warnings
200
- old_verbose = $VERBOSE
201
- $VERBOSE = nil
202
- yield
203
- ensure
204
- $VERBOSE = old_verbose
205
- end
206
- end
207
- end
@@ -1,202 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
4
- # Author:: Matt Wrock (<matt@mattwrock.com>)
5
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
6
- # Author:: Dominik Richter (<dominik.richter@gmail.com>)
7
- # Author:: Christoph Hartmann (<chris@lollyrock.com>)
8
- #
9
- # Copyright (C) 2014, Salim Afiune
10
- #
11
- # Licensed under the Apache License, Version 2.0 (the "License");
12
- # you may not use this file except in compliance with the License.
13
- # You may obtain a copy of the License at
14
- #
15
- # http://www.apache.org/licenses/LICENSE-2.0
16
- #
17
- # Unless required by applicable law or agreed to in writing, software
18
- # distributed under the License is distributed on an "AS IS" BASIS,
19
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
- # See the License for the specific language governing permissions and
21
- # limitations under the License.
22
-
23
- class Train::Transports::WinRM
24
- # A Connection instance can be generated and re-generated, given new
25
- # connection details such as connection port, hostname, credentials, etc.
26
- # This object is responsible for carrying out the actions on the remote
27
- # host such as executing commands, transferring files, etc.
28
- #
29
- # @author Fletcher Nichol <fnichol@nichol.ca>
30
- class Connection < BaseConnection # rubocop:disable Metrics/ClassLength
31
- attr_reader :hostname
32
- def initialize(options)
33
- super(options)
34
- @hostname = @options.delete(:hostname)
35
- @rdp_port = @options.delete(:rdp_port)
36
- @connection_retries = @options.delete(:connection_retries)
37
- @connection_retry_sleep = @options.delete(:connection_retry_sleep)
38
- @max_wait_until_ready = @options.delete(:max_wait_until_ready)
39
- @operation_timeout = @options.delete(:operation_timeout)
40
- end
41
-
42
- # (see Base::Connection#close)
43
- def close
44
- return if @session.nil?
45
-
46
- session.close
47
- ensure
48
- @session = nil
49
- end
50
-
51
- # (see Base::Connection#login_command)
52
- def login_command
53
- case RbConfig::CONFIG["host_os"]
54
- when /darwin/
55
- login_command_for_mac
56
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
57
- login_command_for_windows
58
- when /linux/
59
- login_command_for_linux
60
- else
61
- raise ActionFailed,
62
- "Remote login not supported in #{self.class} " \
63
- "from host OS '#{RbConfig::CONFIG["host_os"]}'."
64
- end
65
- end
66
-
67
- # (see Base::Connection#upload)
68
- def upload(locals, remote)
69
- file_manager.upload(locals, remote)
70
- end
71
-
72
- def download(remotes, local)
73
- Array(remotes).each do |remote|
74
- file_manager.download(remote, local)
75
- end
76
- end
77
-
78
- # (see Base::Connection#wait_until_ready)
79
- def wait_until_ready
80
- delay = 3
81
- session(
82
- retry_limit: @max_wait_until_ready / delay,
83
- retry_delay: delay
84
- )
85
- run_command_via_connection(PING_COMMAND.dup)
86
- end
87
-
88
- def uri
89
- "winrm://#{options[:user]}@#{options[:endpoint]}:#{@rdp_port}"
90
- end
91
-
92
- private
93
-
94
- PING_COMMAND = "Write-Host '[WinRM] Established\n'".freeze
95
-
96
- def file_via_connection(path)
97
- Train::File::Remote::Windows.new(self, path)
98
- end
99
-
100
- def run_command_via_connection(command, &data_handler)
101
- return if command.nil?
102
-
103
- logger.debug("[WinRM] #{self} (#{command})")
104
- out = ""
105
-
106
- response = session.run(command) do |stdout, _|
107
- yield(stdout) if data_handler && stdout
108
- out << stdout if stdout
109
- end
110
-
111
- CommandResult.new(out, response.stderr, response.exitcode)
112
- end
113
-
114
- # Create a local RDP document and return it
115
- #
116
- # @param opts [Hash] configuration options
117
- # @option opts [true,false] :mac whether or not the document is for a
118
- # Mac system
119
- # @api private
120
- def rdp_doc(opts = {})
121
- host = URI.parse(options[:endpoint]).host
122
- content = [
123
- "full address:s:#{host}:#{@rdp_port}",
124
- "prompt for credentials:i:1",
125
- "username:s:#{options[:user]}",
126
- ].join("\n")
127
-
128
- content.prepend("drivestoredirect:s:*\n") if opts[:mac]
129
-
130
- content
131
- end
132
-
133
- # @return [Winrm::FileManager] a file transporter
134
- # @api private
135
- def file_manager
136
- @file_manager ||= begin
137
- # Ensure @service is available:
138
- wait_until_ready
139
- WinRM::FS::FileManager.new(@service)
140
- end
141
- end
142
-
143
- # Builds a `LoginCommand` for use by Linux-based platforms.
144
- #
145
- # TODO: determine whether or not `desktop` exists
146
- #
147
- # @return [LoginCommand] a login command
148
- # @api private
149
- def login_command_for_linux
150
- args = %W{ -u #{options[:user]} }
151
- args += %W{ -p #{options[:pass]} } if options.key?(:pass)
152
- args += %W{ #{URI.parse(options[:endpoint]).host}:#{@rdp_port} }
153
- LoginCommand.new("rdesktop", args)
154
- end
155
-
156
- # Builds a `LoginCommand` for use by Mac-based platforms.
157
- #
158
- # @return [LoginCommand] a login command
159
- # @api private
160
- def login_command_for_mac
161
- LoginCommand.new("open", rdp_doc(mac: true))
162
- end
163
-
164
- # Builds a `LoginCommand` for use by Windows-based platforms.
165
- #
166
- # @return [LoginCommand] a login command
167
- # @api private
168
- def login_command_for_windows
169
- LoginCommand.new("mstsc", rdp_doc)
170
- end
171
-
172
- # Establishes a remote shell session, or establishes one when invoked
173
- # the first time.
174
- #
175
- # @param retry_options [Hash] retry options for the initial connection
176
- # @return [Winrm::CommandExecutor] the command executor session
177
- # @api private
178
- def session(retry_options = {})
179
- @session ||= begin
180
- opts = {
181
- retry_limit: @connection_retries.to_i,
182
- retry_delay: @connection_retry_sleep.to_i,
183
- }.merge(retry_options)
184
-
185
- opts[:operation_timeout] = @operation_timeout unless @operation_timeout.nil?
186
- @service = ::WinRM::Connection.new(options.merge(opts))
187
- @service.logger = logger
188
- @service.shell(:powershell)
189
- end
190
- end
191
-
192
- # String representation of object, reporting its connection details and
193
- # configuration.
194
- #
195
- # @api private
196
- def to_s
197
- options_to_print = @options.clone
198
- options_to_print[:password] = "<hidden>" if options_to_print.key?(:password)
199
- "#{@username}@#{@hostname}<#{options_to_print.inspect}>"
200
- end
201
- end
202
- end