train 1.0.0 → 1.1.0

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
  SHA1:
3
- metadata.gz: '008089b91adad72506c6825bad3e8b4c6837af27'
4
- data.tar.gz: 7d584e084f13afe3ef7a915cbc7a19ee20597be3
3
+ metadata.gz: f52a89e11554a1520fed7d09db564885c954e88d
4
+ data.tar.gz: ca15551ae18c8a60cdf9c4f246170ddb5f04b123
5
5
  SHA512:
6
- metadata.gz: 67d87897890642480be62a48e8bc7571ebf0769f3561d85931bd524317c1503c0c4e4ff4e26b3a1d72e717a4f02c5f660956f741b0663046697d0549b3dd059d
7
- data.tar.gz: 8c6f4246840527633d22c5aee4947cc17349cf77a8a2f742db541d11f9a371aee4f41825428ee2e163f277aabaae62ce75a5cef8abc406220da0f6b9d01934bf
6
+ metadata.gz: c723c108b4a86e02d646f7389c2ea075a6c86d83aaaf87c845da1356b84eeeaf9b209f3cebbf959655e812db0dbbcb08929170f9539576cd1326fae7adc4751c
7
+ data.tar.gz: 8596b9929258af323373aae7a6d34bb1f341d3ab9aa28d92bd7739b62e325a56832833ea063f81619fb6a2d752ba4736c42741547b0f51bd8f49f4a53ce98bea
data/.rubocop.yml CHANGED
@@ -71,3 +71,5 @@ Style/IfUnlessModifier:
71
71
  Enabled: false
72
72
  Style/FrozenStringLiteralComment:
73
73
  Enabled: false
74
+ SignalException:
75
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,7 +1,20 @@
1
1
  # Change Log
2
2
 
3
- ## [1.0.0](https://github.com/chef/train/tree/1.0.0) (2018-02-01)
4
- [Full Changelog](https://github.com/chef/train/compare/v0.32.0...1.0.0)
3
+ ## [1.1.0](https://github.com/chef/train/tree/1.1.0) (2018-02-08)
4
+ [Full Changelog](https://github.com/chef/train/compare/v1.0.0...1.1.0)
5
+
6
+ **Closed issues:**
7
+
8
+ - Add azure:// target [\#233](https://github.com/chef/train/issues/233)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - Add qnx platform support [\#253](https://github.com/chef/train/pull/253) ([jquick](https://github.com/jquick))
13
+ - Add azure transport [\#250](https://github.com/chef/train/pull/250) ([jquick](https://github.com/jquick))
14
+ - Fix AIX and QNX file support [\#249](https://github.com/chef/train/pull/249) ([adamleff](https://github.com/adamleff))
15
+
16
+ ## [v1.0.0](https://github.com/chef/train/tree/v1.0.0) (2018-02-01)
17
+ [Full Changelog](https://github.com/chef/train/compare/v0.32.0...v1.0.0)
5
18
 
6
19
  **Closed issues:**
7
20
 
@@ -9,6 +22,7 @@
9
22
 
10
23
  **Merged pull requests:**
11
24
 
25
+ - Update version to 1.0.0 [\#248](https://github.com/chef/train/pull/248) ([jquick](https://github.com/jquick))
12
26
  - cisco nexus + ios12 [\#247](https://github.com/chef/train/pull/247) ([arlimus](https://github.com/arlimus))
13
27
  - Add a CONTRIBUTING.md to Train [\#245](https://github.com/chef/train/pull/245) ([miah](https://github.com/miah))
14
28
  - catch detect failing to parse json [\#243](https://github.com/chef/train/pull/243) ([arlimus](https://github.com/arlimus))
data/Gemfile CHANGED
@@ -19,7 +19,7 @@ group :test do
19
19
  gem 'rake', '~> 10'
20
20
  gem 'rubocop', '~> 0.36.0'
21
21
  gem 'simplecov', '~> 0.10'
22
- gem 'concurrent-ruby', '~> 0.9'
22
+ gem 'concurrent-ruby', '~> 1.0'
23
23
  end
24
24
 
25
25
  group :integration do
data/README.md CHANGED
@@ -21,6 +21,7 @@ Train supports:
21
21
  * Docker
22
22
  * Mock (for testing and debugging)
23
23
  * AWS as an API
24
+ * Azure as an API
24
25
 
25
26
  # Examples
26
27
 
data/lib/train/file.rb CHANGED
@@ -4,13 +4,7 @@
4
4
  # author: Dominik Richter
5
5
 
6
6
  require 'train/file/local'
7
- require 'train/file/local/unix'
8
- require 'train/file/local/windows'
9
7
  require 'train/file/remote'
10
- require 'train/file/remote/unix'
11
- require 'train/file/remote/linux'
12
- require 'train/file/remote/windows'
13
- require 'train/file/remote/qnx'
14
8
  require 'digest/sha2'
15
9
  require 'digest/md5'
16
10
  require 'train/extras/stat'
@@ -68,3 +68,8 @@ module Train
68
68
  end
69
69
  end
70
70
  end
71
+
72
+ # subclass requires are loaded after Train::File::Local is defined
73
+ # to avoid superclass mismatch errors
74
+ require 'train/file/local/unix'
75
+ require 'train/file/local/windows'
@@ -26,3 +26,11 @@ module Train
26
26
  end
27
27
  end
28
28
  end
29
+
30
+ # subclass requires are loaded after Train::File::Remote is defined
31
+ # to avoid superclass mismatch errors
32
+ require 'train/file/remote/aix'
33
+ require 'train/file/remote/linux'
34
+ require 'train/file/remote/qnx'
35
+ require 'train/file/remote/unix'
36
+ require 'train/file/remote/windows'
@@ -8,7 +8,7 @@ require 'train/file/remote/unix'
8
8
  module Train
9
9
  class File
10
10
  class Remote
11
- class Aix < Train::File::Remote::Unix
11
+ class Qnx < Train::File::Remote::Unix
12
12
  def content
13
13
  cat = 'cat'
14
14
  cat = '/proc/boot/cat' if @backend.os[:release].to_i >= 7
@@ -32,7 +32,7 @@ module Train
32
32
  mode owner group uid gid mtime size selinux_label link_path mounted stat
33
33
  }.each do |field|
34
34
  define_method field.to_sym do
35
- fail NotImplementedError, "QNX does not implement the #{m}() method yet."
35
+ fail NotImplementedError, "QNX does not implement the #{field}() method yet."
36
36
  end
37
37
  end
38
38
  end
@@ -6,8 +6,10 @@ module Train::Platforms::Detect::Specifications
6
6
  plat = Train::Platforms
7
7
 
8
8
  plat.family('api')
9
+
9
10
  plat.family('cloud').in_family('api')
10
11
  plat.name('aws').in_family('cloud')
12
+ plat.name('azure').in_family('cloud')
11
13
  end
12
14
  end
13
15
  end
@@ -453,6 +453,19 @@ module Train::Platforms::Detect::Specifications
453
453
  true
454
454
  }
455
455
 
456
+ # qnx
457
+ plat.family('qnx').in_family('unix')
458
+ .detect {
459
+ true if unix_uname_s =~ /qnx/i
460
+ }
461
+ plat.name('qnx').title('QNX').in_family('qnx')
462
+ .detect {
463
+ @platform[:name] = unix_uname_s.lines[0].chomp.downcase
464
+ @platform[:release] = unix_uname_r.lines[0].chomp
465
+ @platform[:arch] = unix_uname_m
466
+ true
467
+ }
468
+
456
469
  # bsd family
457
470
  plat.family('bsd').in_family('unix')
458
471
  .detect {
@@ -0,0 +1,153 @@
1
+ # encoding: utf-8
2
+
3
+ require 'train/plugins'
4
+ require 'ms_rest_azure'
5
+ require 'azure_mgmt_resources'
6
+ require 'inifile'
7
+
8
+ module Train::Transports
9
+ class Azure < Train.plugin(1)
10
+ name 'azure'
11
+ option :tenant_id, default: ENV['AZURE_TENANT_ID']
12
+ option :client_id, default: ENV['AZURE_CLIENT_ID']
13
+ option :client_secret, default: ENV['AZURE_CLIENT_SECRET']
14
+ option :subscription_id, default: ENV['AZURE_SUBSCRIPTION_ID']
15
+
16
+ # This can provide the client id and secret
17
+ option :credentials_file, default: ENV['AZURE_CRED_FILE']
18
+
19
+ def connection(_ = nil)
20
+ @connection ||= Connection.new(@options)
21
+ end
22
+
23
+ class Connection < BaseConnection
24
+ def initialize(options)
25
+ @apis = {}
26
+
27
+ # Override for any cli options
28
+ # azure://subscription_id
29
+ options[:subscription_id] = options[:host] || options[:subscription_id]
30
+ super(options)
31
+
32
+ @cache_enabled[:api_call] = true
33
+ @cache[:api_call] = {}
34
+
35
+ if @options[:client_secret].nil? && @options[:client_id].nil?
36
+ parse_credentials_file
37
+ end
38
+ connect
39
+ end
40
+
41
+ def platform
42
+ direct_platform('azure')
43
+ end
44
+
45
+ def azure_client(klass = ::Azure::Resources::Profiles::Latest::Mgmt::Client)
46
+ return klass.new(@credentials) unless cache_enabled?(:api_call)
47
+
48
+ @cache[:api_call][klass.to_s.to_sym] ||= klass.new(@credentials)
49
+ end
50
+
51
+ def connect
52
+ provider = ::MsRestAzure::ApplicationTokenProvider.new(
53
+ @options[:tenant_id],
54
+ @options[:client_id],
55
+ @options[:client_secret],
56
+ )
57
+
58
+ @credentials = {
59
+ credentials: ::MsRest::TokenCredentials.new(provider),
60
+ subscription_id: @options[:subscription_id],
61
+ tenant_id: @options[:tenant_id],
62
+ client_id: @options[:client_id],
63
+ client_secret: @options[:client_secret],
64
+ }
65
+ end
66
+
67
+ def uri
68
+ "azure://#{@options[:subscription_id]}"
69
+ end
70
+
71
+ # Returns the api version for the specified resource type
72
+ #
73
+ # If an api version has been specified in the options then the apis version table is updated
74
+ # with that value and it is returned
75
+ #
76
+ # However if it is not specified, or multiple types are being interrogated then this method
77
+ # will interrogate Azure for each of the types versions and pick the latest one. This is added
78
+ # to the apis table so that it can be retrieved quickly again of another one of those resources
79
+ # is encountered again in the resource collection.
80
+ #
81
+ # @param string resource_type The resource type for which the API is required
82
+ # @param hash options Options have that have been passed to the resource during the test.
83
+ # @option opts [String] :group_name Resource group name
84
+ # @option opts [String] :type Azure resource type
85
+ # @option opts [String] :name Name of specific resource to look for
86
+ # @option opts [String] :apiversion If looking for a specific item or type specify the api version to use
87
+ #
88
+ # @return string API Version of the specified resource type
89
+ def get_api_version(resource_type, options)
90
+ # if an api version has been set in the options, add to the apis hashtable with
91
+ # the resource type
92
+ if options[:apiversion]
93
+ @apis[resource_type] = options[:apiversion]
94
+ else
95
+ # only attempt to get the api version from Azure if the resource type
96
+ # is not present in the apis hashtable
97
+ unless @apis.key?(resource_type)
98
+
99
+ # determine the namespace for the resource type
100
+ namespace, type = resource_type.split(%r{/})
101
+
102
+ client = azure_client(::Azure::Resources::Profiles::Latest::Mgmt::Client)
103
+ provider = client.providers.get(namespace)
104
+
105
+ # get the latest API version for the type
106
+ # assuming that this is the first one in the list
107
+ api_versions = (provider.resource_types.find { |v| v.resource_type == type }).api_versions
108
+ @apis[resource_type] = api_versions[0]
109
+ end
110
+ end
111
+
112
+ # return the api version for the type
113
+ @apis[resource_type]
114
+ end
115
+
116
+ private
117
+
118
+ def parse_credentials_file # rubocop:disable Metrics/AbcSize
119
+ # If an AZURE_CRED_FILE environment variable has been specified set the
120
+ # the credentials file to that, otherwise set the one in home
121
+ azure_creds_file = @options[:credentials_file]
122
+ azure_creds_file = File.join(Dir.home, '.azure', 'credentials') if azure_creds_file.nil?
123
+ return unless File.readable?(azure_creds_file)
124
+
125
+ credentials = IniFile.load(File.expand_path(azure_creds_file))
126
+ if @options[:subscription_id]
127
+ id = @options[:subscription_id]
128
+ elsif !ENV['AZURE_SUBSCRIPTION_NUMBER'].nil?
129
+ subscription_number = ENV['AZURE_SUBSCRIPTION_NUMBER'].to_i
130
+
131
+ # Check that the specified index is not greater than the number of subscriptions
132
+ if subscription_number > credentials.sections.length
133
+ raise format(
134
+ 'Your credentials file only contains %s subscriptions. You specified number %s.',
135
+ @credentials.sections.length,
136
+ subscription_number,
137
+ )
138
+ end
139
+ id = credentials.sections[subscription_number - 1]
140
+ else
141
+ raise 'Multiple credentials detected, please set the AZURE_SUBSCRIPTION_ID environment variable.' if credentials.sections.count > 1
142
+ id = credentials.sections[0]
143
+ end
144
+
145
+ raise "No credentials found for subscription number #{id}" if credentials.sections.empty? || credentials[id].empty?
146
+ @options[:subscription_id] = id
147
+ @options[:tenant_id] = credentials[id]['tenant_id']
148
+ @options[:client_id] = credentials[id]['client_id']
149
+ @options[:client_secret] = credentials[id]['client_secret']
150
+ end
151
+ end
152
+ end
153
+ end
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.0.0'.freeze
6
+ VERSION = '1.1.0'.freeze
7
7
  end
@@ -0,0 +1,26 @@
1
+ require 'helper'
2
+ require 'train/transports/local'
3
+ require 'train/file/remote/aix'
4
+ require 'train/transports/mock'
5
+
6
+ describe Train::File::Remote::Aix do
7
+ let(:cls) { Train::File::Remote::Aix }
8
+ let(:backend) {
9
+ backend = Train::Transports::Mock.new.connection
10
+ backend.mock_os({ name: 'aix', family: 'unix' })
11
+ backend
12
+ }
13
+
14
+ it 'returns a nil link_path if the object is not a symlink' do
15
+ file = cls.new(backend, 'path')
16
+ file.stubs(:symlink?).returns(false)
17
+ file.link_path.must_be_nil
18
+ end
19
+
20
+ it 'returns a correct link_path' do
21
+ file = cls.new(backend, 'path')
22
+ file.stubs(:symlink?).returns(true)
23
+ backend.mock_command("perl -e 'print readlink shift' path", 'our_link_path')
24
+ file.link_path.must_equal 'our_link_path'
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+ require 'train/transports/local'
3
+ require 'train/file/remote/qnx'
4
+ require 'train/transports/mock'
5
+
6
+ describe Train::File::Remote::Qnx do
7
+ let(:cls) { Train::File::Remote::Qnx }
8
+ let(:backend) {
9
+ backend = Train::Transports::Mock.new.connection
10
+ backend.mock_os({ name: 'qnx', family: 'unix' })
11
+ backend
12
+ }
13
+
14
+ it 'returns file contents when the file exists' do
15
+ out = rand.to_s
16
+ backend.mock_command('cat path', out)
17
+ file = cls.new(backend, 'path')
18
+ file.stubs(:exist?).returns(true)
19
+ file.content.must_equal out
20
+ end
21
+
22
+ it 'returns nil contents when the file does not exist' do
23
+ file = cls.new(backend, 'path')
24
+ file.stubs(:exist?).returns(false)
25
+ file.content.must_be_nil
26
+ end
27
+
28
+ it 'returns a file type' do
29
+ backend.mock_command('file path', 'blah directory blah')
30
+ cls.new(backend, 'path').type.must_equal :directory
31
+ end
32
+
33
+ it 'returns a directory type' do
34
+ backend.mock_command('file path', 'blah regular file blah')
35
+ cls.new(backend, 'path').type.must_equal :file
36
+ end
37
+
38
+ it 'raises exception for unimplemented methods' do
39
+ file = cls.new(backend, 'path')
40
+ %w{mode owner group uid gid mtime size selinux_label link_path mounted stat}.each do |m|
41
+ proc { file.send(m) }.must_raise NotImplementedError
42
+ end
43
+ end
44
+ end
@@ -183,6 +183,16 @@ describe 'os_detect' do
183
183
  end
184
184
  end
185
185
 
186
+ describe 'qnx' do
187
+ it 'sets the correct info for qnx platform' do
188
+ platform = scan_with_files('qnx', {})
189
+
190
+ platform[:name].must_equal('qnx')
191
+ platform[:family].must_equal('qnx')
192
+ platform[:release].must_equal('test-release')
193
+ end
194
+ end
195
+
186
196
  describe 'cisco' do
187
197
  it 'recognizes Cisco IOS12' do
188
198
  mock = Train::Transports::Mock::Connection.new
@@ -0,0 +1,148 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ describe 'azure transport' do
6
+ def transport(options = nil)
7
+ ENV['AZURE_TENANT_ID'] = 'test_tenant_id'
8
+ ENV['AZURE_CLIENT_ID'] = 'test_client_id'
9
+ ENV['AZURE_CLIENT_SECRET'] = 'test_client_secret'
10
+ ENV['AZURE_SUBSCRIPTION_ID'] = 'test_subscription_id'
11
+
12
+ # need to require this at here as it captures the envs on load
13
+ require 'train/transports/azure'
14
+ Train::Transports::Azure.new(options)
15
+ end
16
+ let(:connection) { transport.connection }
17
+ let(:options) { connection.instance_variable_get(:@options) }
18
+ let(:cache) { connection.instance_variable_get(:@cache) }
19
+ let(:credentials) { connection.instance_variable_get(:@credentials) }
20
+
21
+ describe 'options' do
22
+ it 'defaults to env options' do
23
+ options[:tenant_id].must_equal 'test_tenant_id'
24
+ options[:client_id].must_equal 'test_client_id'
25
+ options[:client_secret].must_equal 'test_client_secret'
26
+ options[:subscription_id].must_equal 'test_subscription_id'
27
+ end
28
+
29
+ it 'allows for options override' do
30
+ transport = transport(subscription_id: '102', client_id: '717')
31
+ options = transport.connection.instance_variable_get(:@options)
32
+ options[:tenant_id].must_equal 'test_tenant_id'
33
+ options[:client_id].must_equal '717'
34
+ options[:client_secret].must_equal 'test_client_secret'
35
+ options[:subscription_id].must_equal '102'
36
+ end
37
+
38
+ it 'allows uri parse override' do
39
+ transport = transport(host: '999')
40
+ options = transport.connection.instance_variable_get(:@options)
41
+ options[:tenant_id].must_equal 'test_tenant_id'
42
+ options[:subscription_id].must_equal '999'
43
+ end
44
+ end
45
+
46
+ describe 'platform' do
47
+ it 'returns platform' do
48
+ plat = connection.platform
49
+ plat.name.must_equal 'azure'
50
+ plat.family_hierarchy.must_equal ['cloud', 'api']
51
+ end
52
+ end
53
+
54
+ describe 'azure_client' do
55
+ class AzureResource
56
+ attr_reader :hash
57
+ def initialize(hash)
58
+ @hash = hash
59
+ end
60
+ end
61
+
62
+ it 'can use azure_client with caching' do
63
+ connection.instance_variable_set(:@credentials, {})
64
+ client = connection.azure_client(AzureResource)
65
+ client.is_a?(AzureResource).must_equal true
66
+ cache[:api_call].count.must_equal 1
67
+ end
68
+
69
+ it 'can use azure_client without caching' do
70
+ connection.instance_variable_set(:@credentials, {})
71
+ connection.disable_cache(:api_call)
72
+ client = connection.azure_client(AzureResource)
73
+ client.is_a?(AzureResource).must_equal true
74
+ cache[:api_call].count.must_equal 0
75
+ end
76
+
77
+ it 'can use azure_client default client' do
78
+ client = connection.azure_client
79
+ client.class.must_equal Azure::Resources::Profiles::Latest::Mgmt::Client
80
+ end
81
+ end
82
+
83
+ describe 'connect' do
84
+ it 'validate credentials' do
85
+ connection.connect
86
+ credentials[:credentials].class.must_equal MsRest::TokenCredentials
87
+ credentials[:tenant_id].must_equal 'test_tenant_id'
88
+ credentials[:client_id].must_equal 'test_client_id'
89
+ credentials[:client_secret].must_equal 'test_client_secret'
90
+ credentials[:subscription_id].must_equal 'test_subscription_id'
91
+ end
92
+ end
93
+
94
+ describe 'parse_credentials_file' do
95
+ let(:cred_file) do
96
+ require 'tempfile'
97
+ file = Tempfile.new('cred_file')
98
+ info = <<-INFO
99
+ [my_subscription_id]
100
+ client_id = "my_client_id"
101
+ client_secret = "my_client_secret"
102
+ tenant_id = "my_tenant_id"
103
+
104
+ [my_subscription_id2]
105
+ client_id = "my_client_id2"
106
+ client_secret = "my_client_secret2"
107
+ tenant_id = "my_tenant_id2"
108
+ INFO
109
+ file.write(info)
110
+ file.close
111
+ file
112
+ end
113
+
114
+ it 'validate credentials from file' do
115
+ options[:credentials_file] = cred_file.path
116
+ options[:subscription_id] = 'my_subscription_id'
117
+ connection.send(:parse_credentials_file)
118
+
119
+ options[:tenant_id].must_equal 'my_tenant_id'
120
+ options[:client_id].must_equal 'my_client_id'
121
+ options[:client_secret].must_equal 'my_client_secret'
122
+ options[:subscription_id].must_equal 'my_subscription_id'
123
+ end
124
+
125
+ it 'validate credentials from file subscription override' do
126
+ options[:credentials_file] = cred_file.path
127
+ options[:subscription_id] = 'my_subscription_id2'
128
+ connection.send(:parse_credentials_file)
129
+
130
+ options[:tenant_id].must_equal 'my_tenant_id2'
131
+ options[:client_id].must_equal 'my_client_id2'
132
+ options[:client_secret].must_equal 'my_client_secret2'
133
+ options[:subscription_id].must_equal 'my_subscription_id2'
134
+ end
135
+
136
+ it 'validate credentials from file subscription index' do
137
+ options[:credentials_file] = cred_file.path
138
+ options[:subscription_id] = nil
139
+ ENV['AZURE_SUBSCRIPTION_NUMBER'] = '2'
140
+ connection.send(:parse_credentials_file)
141
+
142
+ options[:tenant_id].must_equal 'my_tenant_id2'
143
+ options[:client_id].must_equal 'my_client_id2'
144
+ options[:client_secret].must_equal 'my_client_secret2'
145
+ options[:subscription_id].must_equal 'my_subscription_id2'
146
+ end
147
+ end
148
+ end
data/train.gemspec CHANGED
@@ -34,6 +34,8 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency 'winrm-fs', '~> 1.0'
35
35
  spec.add_dependency 'docker-api', '~> 1.26'
36
36
  spec.add_dependency 'aws-sdk', '~> 2'
37
+ spec.add_dependency 'azure_mgmt_resources', '~> 0.15'
38
+ spec.add_dependency 'inifile'
37
39
 
38
40
  spec.add_development_dependency 'mocha', '~> 1.1'
39
41
  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.0.0
4
+ version: 1.1.0
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-02-01 00:00:00.000000000 Z
11
+ date: 2018-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -134,6 +134,34 @@ dependencies:
134
134
  - - "~>"
135
135
  - !ruby/object:Gem::Version
136
136
  version: '2'
137
+ - !ruby/object:Gem::Dependency
138
+ name: azure_mgmt_resources
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '0.15'
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '0.15'
151
+ - !ruby/object:Gem::Dependency
152
+ name: inifile
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ type: :runtime
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
137
165
  - !ruby/object:Gem::Dependency
138
166
  name: mocha
139
167
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +220,7 @@ files:
192
220
  - lib/train/plugins/base_connection.rb
193
221
  - lib/train/plugins/transport.rb
194
222
  - lib/train/transports/aws.rb
223
+ - lib/train/transports/azure.rb
195
224
  - lib/train/transports/docker.rb
196
225
  - lib/train/transports/local.rb
197
226
  - lib/train/transports/mock.rb
@@ -236,7 +265,9 @@ files:
236
265
  - test/unit/file/local/unix_test.rb
237
266
  - test/unit/file/local/windows_test.rb
238
267
  - test/unit/file/local_test.rb
268
+ - test/unit/file/remote/aix_test.rb
239
269
  - test/unit/file/remote/linux_test.rb
270
+ - test/unit/file/remote/qnx_test.rb
240
271
  - test/unit/file/remote/unix_test.rb
241
272
  - test/unit/file/remote_test.rb
242
273
  - test/unit/file_test.rb
@@ -254,6 +285,7 @@ files:
254
285
  - test/unit/plugins_test.rb
255
286
  - test/unit/train_test.rb
256
287
  - test/unit/transports/aws_test.rb
288
+ - test/unit/transports/azure_test.rb
257
289
  - test/unit/transports/local_test.rb
258
290
  - test/unit/transports/mock_test.rb
259
291
  - test/unit/transports/ssh_test.rb
@@ -322,7 +354,9 @@ test_files:
322
354
  - test/unit/file/local/unix_test.rb
323
355
  - test/unit/file/local/windows_test.rb
324
356
  - test/unit/file/local_test.rb
357
+ - test/unit/file/remote/aix_test.rb
325
358
  - test/unit/file/remote/linux_test.rb
359
+ - test/unit/file/remote/qnx_test.rb
326
360
  - test/unit/file/remote/unix_test.rb
327
361
  - test/unit/file/remote_test.rb
328
362
  - test/unit/file_test.rb
@@ -340,6 +374,7 @@ test_files:
340
374
  - test/unit/plugins_test.rb
341
375
  - test/unit/train_test.rb
342
376
  - test/unit/transports/aws_test.rb
377
+ - test/unit/transports/azure_test.rb
343
378
  - test/unit/transports/local_test.rb
344
379
  - test/unit/transports/mock_test.rb
345
380
  - test/unit/transports/ssh_test.rb