train 3.2.14 → 3.2.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. metadata +29 -149
  3. data/LICENSE +0 -201
  4. data/lib/train.rb +0 -193
  5. data/lib/train/errors.rb +0 -44
  6. data/lib/train/extras.rb +0 -11
  7. data/lib/train/extras/command_wrapper.rb +0 -201
  8. data/lib/train/extras/stat.rb +0 -136
  9. data/lib/train/file.rb +0 -212
  10. data/lib/train/file/local.rb +0 -82
  11. data/lib/train/file/local/unix.rb +0 -96
  12. data/lib/train/file/local/windows.rb +0 -68
  13. data/lib/train/file/remote.rb +0 -40
  14. data/lib/train/file/remote/aix.rb +0 -29
  15. data/lib/train/file/remote/linux.rb +0 -21
  16. data/lib/train/file/remote/qnx.rb +0 -41
  17. data/lib/train/file/remote/unix.rb +0 -110
  18. data/lib/train/file/remote/windows.rb +0 -110
  19. data/lib/train/globals.rb +0 -5
  20. data/lib/train/options.rb +0 -81
  21. data/lib/train/platforms.rb +0 -102
  22. data/lib/train/platforms/common.rb +0 -34
  23. data/lib/train/platforms/detect.rb +0 -12
  24. data/lib/train/platforms/detect/helpers/os_common.rb +0 -160
  25. data/lib/train/platforms/detect/helpers/os_linux.rb +0 -80
  26. data/lib/train/platforms/detect/helpers/os_windows.rb +0 -142
  27. data/lib/train/platforms/detect/scanner.rb +0 -85
  28. data/lib/train/platforms/detect/specifications/api.rb +0 -20
  29. data/lib/train/platforms/detect/specifications/os.rb +0 -629
  30. data/lib/train/platforms/detect/uuid.rb +0 -32
  31. data/lib/train/platforms/family.rb +0 -31
  32. data/lib/train/platforms/platform.rb +0 -109
  33. data/lib/train/plugin_test_helper.rb +0 -51
  34. data/lib/train/plugins.rb +0 -40
  35. data/lib/train/plugins/base_connection.rb +0 -198
  36. data/lib/train/plugins/transport.rb +0 -49
  37. data/lib/train/transports/cisco_ios_connection.rb +0 -133
  38. data/lib/train/transports/local.rb +0 -240
  39. data/lib/train/transports/mock.rb +0 -183
  40. data/lib/train/transports/ssh.rb +0 -271
  41. data/lib/train/transports/ssh_connection.rb +0 -342
  42. data/lib/train/version.rb +0 -7
@@ -1,32 +0,0 @@
1
- require "digest/sha1"
2
- require "securerandom"
3
- require "json"
4
-
5
- module Train::Platforms::Detect
6
- class UUID
7
- include Train::Platforms::Detect::Helpers::OSCommon
8
-
9
- def initialize(platform)
10
- @platform = platform
11
- @backend = @platform.backend
12
- end
13
-
14
- def find_or_create_uuid
15
- # for api transports uuid is defined on the connection
16
- if defined?(@backend.unique_identifier)
17
- uuid_from_string(@backend.unique_identifier)
18
- elsif @platform.unix?
19
- unix_uuid
20
- elsif @platform.windows?
21
- windows_uuid
22
- else
23
- if @platform[:uuid_command]
24
- result = @backend.run_command(@platform[:uuid_command])
25
- return uuid_from_string(result.stdout.chomp) if result.exit_status == 0 && !result.stdout.empty?
26
- end
27
-
28
- raise "Could not find platform uuid! Please set a uuid_command for your platform."
29
- end
30
- end
31
- end
32
- end
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Train::Platforms
4
- class Family
5
- include Train::Platforms::Common
6
- attr_accessor :children, :condition, :families, :name
7
-
8
- def initialize(name, condition)
9
- @name = name
10
- @condition = condition
11
- @families = {}
12
- @children = {}
13
- @detect = nil
14
- @title = "#{name.to_s.capitalize} Family"
15
-
16
- # add itself to the families list
17
- Train::Platforms.families[@name.to_s] = self
18
- end
19
-
20
- def title(title = nil)
21
- return @title if title.nil?
22
-
23
- @title = title
24
- self
25
- end
26
-
27
- def inspect
28
- "%p[%s]" % [self.class, name]
29
- end
30
- end
31
- end
@@ -1,109 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Train::Platforms
4
- class Platform
5
- include Train::Platforms::Common
6
- attr_accessor :backend, :condition, :families, :family_hierarchy, :platform
7
-
8
- def initialize(name, condition = {})
9
- @name = name
10
- @condition = condition
11
- @families = {}
12
- @family_hierarchy = []
13
- @platform = {}
14
- @detect = nil
15
- @title = name.to_s.capitalize
16
-
17
- # add itself to the platform list
18
- Train::Platforms.list[name] = self
19
- end
20
-
21
- def direct_families
22
- @families.collect { |k, _v| k.name }
23
- end
24
-
25
- def find_family_hierarchy(platform = self)
26
- families = platform.families.map { |k, v| [k.name, find_family_hierarchy(k)] }
27
-
28
- @family_hierarchy = families.flatten
29
- end
30
-
31
- def family
32
- @platform[:family] || @family_hierarchy[0]
33
- end
34
-
35
- def name
36
- # Override here incase a updated name was set
37
- # during the detect logic
38
- clean_name
39
- end
40
-
41
- def clean_name(force: false)
42
- @cleaned_name = nil if force
43
- @cleaned_name ||= (@platform[:name] || @name).downcase.tr(" ", "_")
44
- end
45
-
46
- def uuid
47
- @uuid ||= Train::Platforms::Detect::UUID.new(self).find_or_create_uuid.downcase
48
- end
49
-
50
- # This is for backwords compatability with
51
- # the current inspec os resource.
52
- def[](name)
53
- if respond_to?(name)
54
- send(name)
55
- else
56
- "unknown"
57
- end
58
- end
59
-
60
- def title(title = nil)
61
- return @title if title.nil?
62
-
63
- @title = title
64
- self
65
- end
66
-
67
- def to_hash
68
- @platform
69
- end
70
-
71
- # Add generic family? and platform methods to an existing platform
72
- #
73
- # This is done later to add any custom
74
- # families/properties that were created
75
- def add_platform_methods
76
- # Redo clean name if there is a detect override
77
- clean_name(force: true) unless @platform[:name].nil?
78
-
79
- # Add in family methods
80
- family_list = Train::Platforms.families
81
- family_list.each_value do |k|
82
- name = "#{k.name}?"
83
-
84
- next if respond_to?(name)
85
-
86
- define_singleton_method(name) do
87
- family_hierarchy.include?(k.name)
88
- end
89
- end
90
-
91
- # Helper methods for direct platform info
92
- @platform.each_key do |m|
93
- next if respond_to?(m)
94
-
95
- define_singleton_method(m) do
96
- @platform[m]
97
- end
98
- end
99
-
100
- # Create method for name if its not already true
101
- m = name + "?"
102
- return if respond_to?(m)
103
-
104
- define_singleton_method(m) do
105
- true
106
- end
107
- end
108
- end
109
- end
@@ -1,51 +0,0 @@
1
- # This file is intended to be 'require'd by plugin authors who are developing a
2
- # plugin outside of the Train source tree.
3
-
4
- # Load Train. We certainly need the plugin system, and also several other parts
5
- # that are tightly coupled. Train itself is fairly light, and non-invasive.
6
- require_relative "../train"
7
-
8
- # You can select from a number of test harnesses. Since Train is closely related
9
- # to InSpec, and InSpec uses Spec-style controls in profile code, you will
10
- # probably want to use something like minitest/spec, which provides Spec-style
11
- # tests.
12
- require "minitest/spec"
13
- require "minitest/autorun"
14
-
15
- # Data formats commonly used in testing
16
- require "json"
17
- require "ostruct"
18
-
19
- # Utilities often needed
20
- require "fileutils"
21
- require "tmpdir"
22
- require "pathname"
23
-
24
- # You might want to put some debugging tools here. We run tests to find bugs,
25
- # after all.
26
- require "byebug"
27
-
28
- # Configure MiniTest to expose things like `let`
29
- class Module
30
- include Minitest::Spec::DSL
31
- end
32
-
33
- # Finally, let's make some modules that can help us out.
34
- module TrainPluginBaseHelper
35
- # Sneakily detect the location of the plugin
36
- # source code when they include this Module
37
- def self.included(base)
38
- plugin_test_helper_path = Pathname.new(caller_locations(4, 1).first.absolute_path)
39
- plugin_src_root = plugin_test_helper_path.parent.parent
40
- base.let(:plugin_src_path) { plugin_src_root }
41
- base.let(:plugin_fixtures_path) { File.join(plugin_src_root, "test", "fixtures") }
42
- end
43
-
44
- let(:train_src_path) { File.expand_path(File.join(__FILE__, "..", "..")) }
45
- let(:train_fixtures_path) { File.join(train_src_path, "test", "fixtures") }
46
- let(:registry) { Train::Plugins.registry }
47
- end
48
-
49
- module TrainPluginFunctionalHelper
50
- include TrainPluginBaseHelper
51
- end
data/lib/train/plugins.rb DELETED
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
- # Author:: Christoph Hartmann (<chris@lollyrock.com>)
5
-
6
- require_relative "errors"
7
-
8
- module Train
9
- class Plugins
10
- require_relative "plugins/transport"
11
-
12
- class << self
13
- # Retrieve the current plugin registry, containing all plugin names
14
- # and their transport handlers.
15
- #
16
- # @return [Hash] map with plugin names and plugins
17
- def registry
18
- @registry ||= {}
19
- end
20
- end
21
- end
22
-
23
- # Create a new plugin by inheriting from the class returned by this method.
24
- # Create a versioned plugin by providing the transport layer plugin version
25
- # to this method. It will then select the correct class to inherit from.
26
- #
27
- # The plugin version determins what methods will be available to your plugin.
28
- #
29
- # @param [Int] version = 1 the plugin version to use
30
- # @return [Transport] the versioned transport base class
31
- def self.plugin(version = 1)
32
- if version != 1
33
- raise ClientError,
34
- "Only understand train plugin version 1. You are trying to "\
35
- "initialize a train plugin #{version}, which is not supported "\
36
- "in the current release of train."
37
- end
38
- ::Train::Plugins::Transport
39
- end
40
- end
@@ -1,198 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require_relative "../errors"
4
- require_relative "../extras"
5
- require_relative "../file"
6
- require "logger"
7
-
8
- class Train::Plugins::Transport
9
- # A Connection instance can be generated and re-generated, given new
10
- # connection details such as connection port, hostname, credentials, etc.
11
- # This object is responsible for carrying out the actions on the remote
12
- # host such as executing commands, transferring files, etc.
13
- #
14
- # @author Fletcher Nichol <fnichol@nichol.ca>
15
- class BaseConnection
16
- include Train::Extras
17
-
18
- # Create a new Connection instance.
19
- #
20
- # @param options [Hash] connection options
21
- # @yield [self] yields itself for block-style invocation
22
- def initialize(options = nil)
23
- @options = options || {}
24
- @logger = @options.delete(:logger) || Logger.new($stdout, level: :fatal)
25
- Train::Platforms::Detect::Specifications::OS.load
26
- Train::Platforms::Detect::Specifications::Api.load
27
-
28
- # default caching options
29
- @cache_enabled = {
30
- file: true,
31
- command: false,
32
- api_call: false,
33
- }
34
-
35
- @cache = {}
36
- @cache_enabled.each_key do |type|
37
- clear_cache(type)
38
- end
39
- end
40
-
41
- def with_sudo_pty
42
- yield
43
- end
44
-
45
- # Returns cached client if caching enabled. Otherwise returns whatever is
46
- # given in the block.
47
- #
48
- # @example
49
- #
50
- # def demo_client
51
- # cached_client(:api_call, :demo_connection) do
52
- # DemoClient.new(args)
53
- # end
54
- # end
55
- #
56
- # @param [symbol] type one of [:api_call, :file, :command]
57
- # @param [symbol] key for your cached connection
58
- def cached_client(type, key)
59
- return yield unless cache_enabled?(type)
60
-
61
- @cache[type][key] ||= yield
62
- end
63
-
64
- def cache_enabled?(type)
65
- @cache_enabled[type.to_sym]
66
- end
67
-
68
- # Enable caching types for Train. Currently we support
69
- # :api_call, :file and :command types
70
- def enable_cache(type)
71
- raise Train::UnknownCacheType, "#{type} is not a valid cache type" unless @cache_enabled.keys.include?(type.to_sym)
72
-
73
- @cache_enabled[type.to_sym] = true
74
- end
75
-
76
- def disable_cache(type)
77
- raise Train::UnknownCacheType, "#{type} is not a valid cache type" unless @cache_enabled.keys.include?(type.to_sym)
78
-
79
- @cache_enabled[type.to_sym] = false
80
- clear_cache(type.to_sym)
81
- end
82
-
83
- # Closes the session connection, if it is still active.
84
- def close
85
- # this method may be left unimplemented if that is applicable
86
- end
87
-
88
- def to_json
89
- {
90
- "files" => Hash[@cache[:file].map { |x, y| [x, y.to_json] }],
91
- }
92
- end
93
-
94
- def load_json(j)
95
- require_relative "../transports/mock"
96
- j["files"].each do |path, jf|
97
- @cache[:file][path] = Train::Transports::Mock::Connection::File.from_json(jf)
98
- end
99
- end
100
-
101
- def force_platform!(name, platform_details = nil)
102
- plat = Train::Platforms.name(name)
103
- plat.backend = self
104
- plat.platform = platform_details unless platform_details.nil?
105
- plat.find_family_hierarchy
106
- plat.add_platform_methods
107
- plat
108
- end
109
-
110
- def inspect
111
- "%s[%s]" % [self.class, (@options[:backend] || "Unknown")]
112
- end
113
-
114
- alias direct_platform force_platform!
115
-
116
- # Get information on the operating system which this transport connects to.
117
- #
118
- # @return [Platform] system information
119
- def platform
120
- @platform ||= Train::Platforms::Detect.scan(self)
121
- end
122
- # we need to keep os as a method for backwards compatibility with inspec
123
- alias os platform
124
-
125
- # This is the main command call for all connections. This will call the private
126
- # run_command_via_connection on the connection with optional caching
127
- #
128
- # This command accepts an optional data handler block. When provided,
129
- # inbound data will be published vi `data_handler.call(data)`. This can allow
130
- # callers to receive and render updates from remote command execution.
131
- def run_command(cmd, &data_handler)
132
- return run_command_via_connection(cmd, &data_handler) unless cache_enabled?(:command)
133
-
134
- @cache[:command][cmd] ||= run_command_via_connection(cmd, &data_handler)
135
- end
136
-
137
- # This is the main file call for all connections. This will call the private
138
- # file_via_connection on the connection with optional caching
139
- def file(path, *args)
140
- return file_via_connection(path, *args) unless cache_enabled?(:file)
141
-
142
- @cache[:file][path] ||= file_via_connection(path, *args)
143
- end
144
-
145
- # Builds a LoginCommand which can be used to open an interactive
146
- # session on the remote host.
147
- #
148
- # @return [LoginCommand] array of command line tokens
149
- def login_command
150
- raise NotImplementedError, "#{self.class} does not implement #login_command()"
151
- end
152
-
153
- # Block and return only when the remote host is prepared and ready to
154
- # execute command and upload files. The semantics and details will
155
- # vary by implementation, but a round trip through the hosted
156
- # service is preferred to simply waiting on a socket to become
157
- # available.
158
- def wait_until_ready
159
- # this method may be left unimplemented if that is applicablelog
160
- end
161
-
162
- private
163
-
164
- # Execute a command using this connection.
165
- #
166
- # @param command [String] command string to execute
167
- # @param &data_handler(data) [Proc] proc that is called when data arrives from
168
- # the connection. This block is optional. Individual transports will need
169
- # to explicitly invoke the block in their implementation of run_command_via_connection;
170
- # if they do not, the block is ignored and will not be used to report data back to the caller.
171
- #
172
- # @return [CommandResult] contains the result of running the command
173
- def run_command_via_connection(_command, &_data_handler)
174
- raise NotImplementedError, "#{self.class} does not implement #run_command_via_connection()"
175
- end
176
-
177
- # Interact with files on the target. Read, write, and get metadata
178
- # from files via the transport.
179
- #
180
- # @param [String] path which is being inspected
181
- # @return [FileCommon] file object that allows for interaction
182
- def file_via_connection(_path, *_args)
183
- raise NotImplementedError, "#{self.class} does not implement #file_via_connection(...)"
184
- end
185
-
186
- def clear_cache(type)
187
- @cache[type.to_sym] = {}
188
- end
189
-
190
- # @return [Logger] logger for reporting information
191
- # @api private
192
- attr_reader :logger
193
-
194
- # @return [Hash] connection options
195
- # @api private
196
- attr_reader :options
197
- end
198
- end