train 1.4.15 → 1.4.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e221bdf06659f4754f5628e2c9ceb548472c0474eee1c8ef9016e33cf12a935
4
- data.tar.gz: 1f9306bec3656802db640c9249c4895fc3fb7bde05a503597a8f980f724341b0
3
+ metadata.gz: d49a72baf8b82a9e1a5ca0153de737c7c349ce49bc86237666c4671f3488b27c
4
+ data.tar.gz: 0bf8c7ef0b17cbb25660397875205653371b96480824e9632fd5e8b98c8c36de
5
5
  SHA512:
6
- metadata.gz: 33230dfafa35626de7dc94770e5000327134aad336f8dc99fa04381ecde4390a1b67eca92149882943c9fb2346a70efe9ce884d50322d08ed0b505aaf7b420b0
7
- data.tar.gz: 668dca30063621341c33202c39bbdeed1fe26aed5c9d9bd568a1e34f83d7a340b93332a4e6e9e766ea96a7264f2ff3c7997182d82eab4f4a3c5e23a8b93acc57
6
+ metadata.gz: 99531d210957232cec38e96deba36831731b37ba87165bb0aa362bdba5c15849483e9efe1b90ef9b8a1e50b54ea1cf47aad0be6bcfb2eaacda9fa69d963e640a
7
+ data.tar.gz: 5b4742273713e24028bccca8cef7adad3aa0d5e9e938cbaf46da708b7b6b39640c34687e43f4ce1db8fc11cc75565ab50d99fe2c32c2b4950bffc81ef13dcf1a
data/CHANGELOG.md CHANGED
@@ -1,26 +1,34 @@
1
- <!-- latest_release 1.4.15 -->
2
- ## [v1.4.15](https://github.com/inspec/train/tree/v1.4.15) (2018-06-14)
1
+ <!-- latest_release 1.4.19 -->
2
+ ## [v1.4.19](https://github.com/inspec/train/tree/v1.4.19) (2018-06-29)
3
3
 
4
4
  #### Merged Pull Requests
5
- - Don&#39;t double-escape paths [#306](https://github.com/inspec/train/pull/306) ([voroniys](https://github.com/voroniys))
5
+ - Remove the deploy config from Travis [#315](https://github.com/inspec/train/pull/315) ([tas50](https://github.com/tas50))
6
6
  <!-- latest_release -->
7
7
 
8
- <!-- release_rollup since=1.4.11 -->
9
- ### Changes since 1.4.11 release
8
+ <!-- release_rollup since=1.4.15 -->
9
+ ### Changes since 1.4.15 release
10
10
 
11
11
  #### Merged Pull Requests
12
- - Don&#39;t double-escape paths [#306](https://github.com/inspec/train/pull/306) ([voroniys](https://github.com/voroniys)) <!-- 1.4.15 -->
13
- - Add the mock transport to train-core [#308](https://github.com/inspec/train/pull/308) ([jquick](https://github.com/jquick)) <!-- 1.4.14 -->
14
- - Adding Oneview to platform detection. [#307](https://github.com/inspec/train/pull/307) ([skpaterson](https://github.com/skpaterson)) <!-- 1.4.13 -->
15
- - Allow TrainError to provide a supplement reason [#303](https://github.com/chef/train/pull/303) ([marcparadise](https://github.com/marcparadise)) <!-- 1.4.12 -->
12
+ - Remove the deploy config from Travis [#315](https://github.com/inspec/train/pull/315) ([tas50](https://github.com/tas50)) <!-- 1.4.19 -->
13
+ - Remove github_changelog_generator [#313](https://github.com/inspec/train/pull/313) ([tas50](https://github.com/tas50)) <!-- 1.4.18 -->
14
+ - Adding proper bastion support [#310](https://github.com/inspec/train/pull/310) ([frezbo](https://github.com/frezbo)) <!-- 1.4.17 -->
15
+ - Fix detection of amazon linux 2 [#312](https://github.com/inspec/train/pull/312) ([artem-sidorenko](https://github.com/artem-sidorenko)) <!-- 1.4.16 -->
16
16
  <!-- release_rollup -->
17
17
 
18
18
  <!-- latest_stable_release -->
19
+ ## [v1.4.15](https://github.com/inspec/train/tree/v1.4.15) (2018-06-14)
20
+
21
+ #### Merged Pull Requests
22
+ - Allow TrainError to provide a supplement reason [#303](https://github.com/chef/train/pull/303) ([marcparadise](https://github.com/marcparadise))
23
+ - Adding Oneview to platform detection. [#307](https://github.com/inspec/train/pull/307) ([skpaterson](https://github.com/skpaterson))
24
+ - Add the mock transport to train-core [#308](https://github.com/inspec/train/pull/308) ([jquick](https://github.com/jquick))
25
+ - Don&#39;t double-escape paths [#306](https://github.com/inspec/train/pull/306) ([voroniys](https://github.com/voroniys))
26
+ <!-- latest_stable_release -->
27
+
19
28
  ## [v1.4.11](https://github.com/chef/train/tree/v1.4.11) (2018-05-17)
20
29
 
21
30
  #### Merged Pull Requests
22
31
  - Add required env for azure shell msi headers [#302](https://github.com/chef/train/pull/302) ([jquick](https://github.com/jquick))
23
- <!-- latest_stable_release -->
24
32
 
25
33
  ## [v1.4.10](https://github.com/chef/train/tree/v1.4.10) (2018-05-17)
26
34
 
data/Gemfile CHANGED
@@ -10,7 +10,6 @@ end
10
10
 
11
11
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
12
12
  gem 'json', '< 2.0'
13
- gem 'rack', '< 2.0'
14
13
  end
15
14
 
16
15
  group :test do
@@ -32,5 +31,4 @@ group :tools do
32
31
  gem 'pry', '~> 0.10'
33
32
  gem 'rb-readline'
34
33
  gem 'license_finder'
35
- gem 'github_changelog_generator', '~> 1'
36
34
  end
@@ -10,7 +10,9 @@ module Train::Platforms::Detect::Helpers
10
10
  case conf
11
11
  when /rawhide/i
12
12
  /((\d+) \(Rawhide\))/i.match(conf)[1].downcase
13
- when /derived from .*linux/i
13
+ when /Amazon Linux AMI/i
14
+ /release ([\d\.]+)/.match(conf)[1]
15
+ when /derived from .*linux|amazon/i
14
16
  /Linux ((\d+|\.)+)/i.match(conf)[1]
15
17
  else
16
18
  /release ([\d\.]+)/.match(conf)[1]
@@ -58,6 +58,10 @@ module Train::Transports
58
58
  option :max_wait_until_ready, default: 600
59
59
  option :compression, default: false
60
60
  option :pty, default: false
61
+ option :proxy_command, default: nil
62
+ option :bastion_host, default: nil
63
+ option :bastion_user, default: 'root'
64
+ option :bastion_port, default: 22
61
65
 
62
66
  option :compression_level do |opts|
63
67
  # on nil or false: set compression level to 0
@@ -109,6 +113,10 @@ module Train::Transports
109
113
  logger.warn('[SSH] PTY requested: stderr will be merged into stdout')
110
114
  end
111
115
 
116
+ if [options[:proxy_command], options[:bastion_host]].all? { |type| !type.nil? }
117
+ fail Train::ClientError, 'Only one of proxy_command or bastion_host needs to be specified'
118
+ end
119
+
112
120
  super
113
121
  self
114
122
  end
@@ -151,6 +159,9 @@ module Train::Transports
151
159
  password: opts[:password],
152
160
  forward_agent: opts[:forward_agent],
153
161
  proxy_command: opts[:proxy_command],
162
+ bastion_host: opts[:bastion_host],
163
+ bastion_user: opts[:bastion_user],
164
+ bastion_port: opts[:bastion_port],
154
165
  transport_options: opts,
155
166
  }
156
167
 
@@ -43,6 +43,10 @@ class Train::Transports::SSH
43
43
  @session = nil
44
44
  @transport_options = @options.delete(:transport_options)
45
45
  @cmd_wrapper = nil
46
+ @proxy_command = @options.delete(:proxy_command)
47
+ @bastion_host = @options.delete(:bastion_host)
48
+ @bastion_user = @options.delete(:bastion_user)
49
+ @bastion_port = @options.delete(:bastion_port)
46
50
  @cmd_wrapper = CommandWrapper.load(self, @transport_options)
47
51
  end
48
52
 
@@ -55,8 +59,7 @@ class Train::Transports::SSH
55
59
  @session = nil
56
60
  end
57
61
 
58
- # (see Base::Connection#login_command)
59
- def login_command
62
+ def ssh_opts
60
63
  level = logger.debug? ? 'VERBOSE' : 'ERROR'
61
64
  fwd_agent = options[:forward_agent] ? 'yes' : 'no'
62
65
 
@@ -65,13 +68,32 @@ class Train::Transports::SSH
65
68
  args += %w{ -o IdentitiesOnly=yes } if options[:keys]
66
69
  args += %W( -o LogLevel=#{level} )
67
70
  args += %W( -o ForwardAgent=#{fwd_agent} ) if options.key?(:forward_agent)
68
- args += %W( -o ProxyCommand='#{options[:proxy_command]}' ) unless options[:proxy_command].nil?
69
71
  Array(options[:keys]).each do |ssh_key|
70
72
  args += %W( -i #{ssh_key} )
71
73
  end
74
+ args
75
+ end
76
+
77
+ def check_proxy
78
+ [@proxy_command, @bastion_host].any? { |type| !type.nil? }
79
+ end
80
+
81
+ def generate_proxy_command
82
+ return @proxy_command unless @proxy_command.nil?
83
+ args = %w{ ssh }
84
+ args += ssh_opts
85
+ args += %W( #{@bastion_user}@#{@bastion_host} )
86
+ args += %W( -p #{@bastion_port} )
87
+ args += %w{ -W %h:%p }
88
+ args.join(' ')
89
+ end
90
+
91
+ # (see Base::Connection#login_command)
92
+ def login_command
93
+ args = ssh_opts
94
+ args += %W( -o ProxyCommand='#{generate_proxy_command}' ) if check_proxy
72
95
  args += %W( -p #{@port} )
73
96
  args += %W( #{@username}@#{@hostname} )
74
-
75
97
  LoginCommand.new('ssh', args)
76
98
  end
77
99
 
@@ -145,10 +167,9 @@ class Train::Transports::SSH
145
167
  # @api private
146
168
  def establish_connection(opts)
147
169
  logger.debug("[SSH] opening connection to #{self}")
148
- if @options[:proxy_command]
170
+ if check_proxy
149
171
  require 'net/ssh/proxy/command'
150
- @options[:proxy] = Net::SSH::Proxy::Command.new(@options[:proxy_command])
151
- @options.delete(:proxy_command)
172
+ @options[:proxy] = Net::SSH::Proxy::Command.new(generate_proxy_command)
152
173
  end
153
174
  Net::SSH.start(@hostname, @username, @options.clone.delete_if { |_key, value| value.nil? })
154
175
  rescue *RESCUE_EXCEPTIONS_ON_ESTABLISH => e
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 = '1.4.15'.freeze
6
+ VERSION = '1.4.19'.freeze
7
7
  end
@@ -96,8 +96,8 @@ describe 'ssh transport' do
96
96
  "-o", "IdentitiesOnly=yes",
97
97
  "-o", "LogLevel=VERBOSE",
98
98
  "-o", "ForwardAgent=no",
99
- "-o", "ProxyCommand='ssh root@127.0.0.1 -W %h:%p'",
100
99
  "-i", conf[:key_files],
100
+ "-o", "ProxyCommand='ssh root@127.0.0.1 -W %h:%p'",
101
101
  "-p", "22",
102
102
  "root@#{conf[:host]}",
103
103
  ])
@@ -175,3 +175,144 @@ describe 'ssh transport' do
175
175
  end
176
176
  end
177
177
  end
178
+
179
+ describe 'ssh transport with bastion' do
180
+ let(:cls) do
181
+ plat = Train::Platforms.name('mock').in_family('linux')
182
+ plat.add_platform_methods
183
+ Train::Platforms::Detect.stubs(:scan).returns(plat)
184
+ Train::Transports::SSH
185
+ end
186
+
187
+ let(:conf) {{
188
+ host: rand.to_s,
189
+ password: rand.to_s,
190
+ key_files: rand.to_s,
191
+ bastion_host: 'bastion_dummy',
192
+ }}
193
+ let(:cls_agent) { cls.new({ host: rand.to_s }) }
194
+
195
+ describe 'bastion' do
196
+ describe 'default options' do
197
+ let(:ssh) { cls.new({ bastion_host: 'bastion_dummy' }) }
198
+
199
+ it 'configures the host' do
200
+ ssh.options[:bastion_host].must_equal 'bastion_dummy'
201
+ end
202
+
203
+ it 'has default port' do
204
+ ssh.options[:bastion_port].must_equal 22
205
+ end
206
+
207
+ it 'has default user' do
208
+ ssh.options[:bastion_user].must_equal 'root'
209
+ end
210
+ end
211
+
212
+ describe 'opening a connection' do
213
+ let(:ssh) { cls.new(conf) }
214
+ let(:connection) { ssh.connection }
215
+
216
+ it 'provides a run_command_via_connection method' do
217
+ methods = connection.class.private_instance_methods(false)
218
+ methods.include?(:run_command_via_connection).must_equal true
219
+ end
220
+
221
+ it 'provides a file_via_connection method' do
222
+ methods = connection.class.private_instance_methods(false)
223
+ methods.include?(:file_via_connection).must_equal true
224
+ end
225
+
226
+ it 'gets the connection' do
227
+ connection.must_be_kind_of Train::Transports::SSH::Connection
228
+ end
229
+
230
+ it 'provides a uri' do
231
+ connection.uri.must_equal "ssh://root@#{conf[:host]}:22"
232
+ end
233
+
234
+ it 'must respond to wait_until_ready' do
235
+ connection.must_respond_to :wait_until_ready
236
+ end
237
+
238
+ it 'can be closed' do
239
+ connection.close.must_be_nil
240
+ end
241
+
242
+ it 'has a login command == ssh' do
243
+ connection.login_command.command.must_equal 'ssh'
244
+ end
245
+
246
+ it 'has login command arguments' do
247
+ connection.login_command.arguments.must_equal([
248
+ "-o", "UserKnownHostsFile=/dev/null",
249
+ "-o", "StrictHostKeyChecking=no",
250
+ "-o", "IdentitiesOnly=yes",
251
+ "-o", "LogLevel=VERBOSE",
252
+ "-o", "ForwardAgent=no",
253
+ "-i", conf[:key_files],
254
+ "-o", "ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -o LogLevel=VERBOSE -o ForwardAgent=no -i #{conf[:key_files]} root@bastion_dummy -p 22 -W %h:%p'",
255
+ "-p", "22",
256
+ "root@#{conf[:host]}",
257
+ ])
258
+ end
259
+
260
+ it 'sets the right auth_methods when password is specified' do
261
+ conf[:key_files] = nil
262
+ cls.new(conf).connection.method(:options).call[:auth_methods].must_equal ["none", "password", "keyboard-interactive"]
263
+ end
264
+
265
+ it 'sets the right auth_methods when keys are specified' do
266
+ conf[:password] = nil
267
+ cls.new(conf).connection.method(:options).call[:auth_methods].must_equal ["none", "publickey"]
268
+ end
269
+
270
+ it 'sets the right auth_methods for agent auth' do
271
+ cls_agent.stubs(:ssh_known_identities).returns({:some => 'rsa_key'})
272
+ cls_agent.connection.method(:options).call[:auth_methods].must_equal ['none', 'publickey']
273
+ end
274
+
275
+ it 'works with ssh agent auth' do
276
+ cls_agent.stubs(:ssh_known_identities).returns({:some => 'rsa_key'})
277
+ cls_agent.connection
278
+ end
279
+
280
+ it 'sets up a proxy when ssh proxy command is specified' do
281
+ mock = MiniTest::Mock.new
282
+ mock.expect(:call, true) do |hostname, username, options|
283
+ options[:proxy].kind_of?(Net::SSH::Proxy::Command) &&
284
+ "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -o LogLevel=VERBOSE -o ForwardAgent=no -i #{conf[:key_files]} root@bastion_dummy -p 22 -W %h:%p" == options[:proxy].command_line_template
285
+ end
286
+ connection.stubs(:run_command)
287
+ Net::SSH.stub(:start, mock) do
288
+ connection.wait_until_ready
289
+ end
290
+ mock.verify
291
+ end
292
+ end
293
+ end
294
+ end
295
+
296
+ describe 'ssh transport with bastion and proxy' do
297
+ let(:cls) do
298
+ plat = Train::Platforms.name('mock').in_family('linux')
299
+ plat.add_platform_methods
300
+ Train::Platforms::Detect.stubs(:scan).returns(plat)
301
+ Train::Transports::SSH
302
+ end
303
+
304
+ let(:conf) {{
305
+ host: rand.to_s,
306
+ password: rand.to_s,
307
+ key_files: rand.to_s,
308
+ bastion_host: 'bastion_dummy',
309
+ proxy_command: 'dummy'
310
+ }}
311
+ let(:cls_agent) { cls.new({ host: rand.to_s }) }
312
+
313
+ describe 'bastion and proxy' do
314
+ it 'will throw an exception when both proxy_command and bastion_host is specified' do
315
+ proc { cls.new(conf).connection }.must_raise Train::ClientError
316
+ end
317
+ end
318
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.15
4
+ version: 1.4.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-14 00:00:00.000000000 Z
11
+ date: 2018-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json