train 1.4.15 → 1.4.19

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: 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