Module: Train
- Defined in:
- lib/train/errors.rb,
lib/train.rb,
lib/train/file.rb,
lib/train/globals.rb,
lib/train/options.rb,
lib/train/plugins.rb,
lib/train/version.rb,
lib/train/audit_log.rb,
lib/train/file/local.rb,
lib/train/file/remote.rb,
lib/train/file/local/unix.rb,
lib/train/file/remote/aix.rb,
lib/train/file/remote/qnx.rb,
lib/train/file/remote/unix.rb,
lib/train/file/remote/linux.rb,
lib/train/file/local/windows.rb,
lib/train/file/remote/windows.rb
Overview
- Author
-
Dominik Richter (<[email protected]>)
Defined Under Namespace
Modules: Extras, Options, Platforms, Transports Classes: AuditLog, ClientError, CommandTimeoutReached, Error, File, PlatformDetectionFailed, PlatformUuidDetectionFailed, PluginLoadError, Plugins, TransportError, UnknownCacheType, UserError
Constant Summary collapse
- VERSION =
"3.12.7".freeze
Class Method Summary collapse
-
.create(name, *args) ⇒ Transport
Create a new transport instance, with the plugin indicated by the given name.
- .group_keys_and_keyfiles(conf) ⇒ Object
-
.load_transport(transport_name) ⇒ Train::Transport
Load the transport plugin indicated by name.
-
.options(name) ⇒ Hash
Retrieve the configuration options of a transport plugin.
-
.plugin(version = 1) ⇒ Transport
Create a new plugin by inheriting from the class returned by this method.
- .src_root ⇒ Object
-
.target_config(config = nil) ⇒ Object
Legacy code to unpack a series of items from an incoming Hash Inspec::Config.unpack_train_credentials now handles this in most cases that InSpec needs If you need to unpack a URI, use unpack_target_from_uri TODO: deprecate; can’t issue a warning because train doesn’t have a logger until the connection is setup (See base_connection.rb).
-
.unpack_target_from_uri(uri_string, opts = {}) ⇒ Object
Given a string that looks like a URI, unpack connection credentials.
-
.validate_backend(credentials, default_transport_name = "local") ⇒ Object
Examine the given credential information, and if all is well, return the transport name.
Class Method Details
.create(name, *args) ⇒ Transport
Create a new transport instance, with the plugin indicated by the given name.
18 19 20 21 |
# File 'lib/train.rb', line 18 def self.create(name, *args) cls = load_transport(name) cls.new(*args) unless cls.nil? end |
.group_keys_and_keyfiles(conf) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/train.rb', line 180 def self.group_keys_and_keyfiles(conf) # in case the user specified a key-file, register it that way # we will clear the list of keys and put keys and key_files separately keys_mixed = conf[:keys] return if keys_mixed.nil? conf[:key_files] = [] conf[:keys] = [] keys_mixed.each do |key| if !key.nil? && File.file?(key) conf[:key_files].push(key) else conf[:keys].push(key) end end end |
.load_transport(transport_name) ⇒ Train::Transport
Load the transport plugin indicated by name. If the plugin is not yet found in the plugin registry, it will be attempted to load from ‘train/transports/plugin_name`.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/train.rb', line 39 def self.load_transport(transport_name) transport_name = transport_name.to_s transport_class = Train::Plugins.registry[transport_name] return transport_class unless transport_class.nil? # Try to load the transport name from the core transports... require "train/transports/" + transport_name Train::Plugins.registry[transport_name] rescue LoadError => _ begin # If it's not in the core transports, try loading from a train plugin gem. gem_name = "train-" + transport_name require gem_name return Train::Plugins.registry[transport_name] # rubocop: disable Lint/HandleExceptions rescue LoadError => _ # rubocop: enable Lint/HandleExceptions # Intentionally empty rescue - we're handling it below anyway end ex = Train::PluginLoadError.new("Can't find train plugin #{transport_name}. Please install it first.") ex.transport_name = transport_name raise ex end |
.options(name) ⇒ Hash
Retrieve the configuration options of a transport plugin.
27 28 29 30 31 |
# File 'lib/train.rb', line 27 def self.(name) cls = load_transport(name) # Merging default_audit_log_options so that they will get listed in the options that are available. cls..merge(cls.) unless cls.nil? end |
.plugin(version = 1) ⇒ Transport
Create a new plugin by inheriting from the class returned by this method. Create a versioned plugin by providing the transport layer plugin version to this method. It will then select the correct class to inherit from.
The plugin version determines what methods will be available to your plugin.
30 31 32 33 34 35 36 37 38 |
# File 'lib/train/plugins.rb', line 30 def self.plugin(version = 1) if version != 1 raise ClientError, "Only understand train plugin version 1. You are trying to "\ "initialize a train plugin #{version}, which is not supported "\ "in the current release of train." end ::Train::Plugins::Transport end |
.src_root ⇒ Object
2 3 4 |
# File 'lib/train/globals.rb', line 2 def self.src_root File.(File.join(__FILE__, "..", "..", "..")) end |
.target_config(config = nil) ⇒ Object
Legacy code to unpack a series of items from an incoming Hash Inspec::Config.unpack_train_credentials now handles this in most cases that InSpec needs If you need to unpack a URI, use unpack_target_from_uri TODO: deprecate; can’t issue a warning because train doesn’t have a logger until the connection is setup (See base_connection.rb)
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/train.rb', line 68 def self.target_config(config = nil) conf = config.dup # Symbolize keys conf.keys.each do |key| unless key.is_a? Symbol conf[key.to_sym] = conf.delete(key) end end group_keys_and_keyfiles(conf) # TODO: move logic into SSH plugin return conf if conf[:target].to_s.empty? unpack_target_from_uri(conf[:target], conf).merge(conf) end |
.unpack_target_from_uri(uri_string, opts = {}) ⇒ Object
Given a string that looks like a URI, unpack connection credentials. The name of the desired transport is always taken from the ‘scheme’ slot of the URI; the remaining portion of the URI is parsed as if it were an HTTP URL, and then the URL components are stored in the credentials hash. It is up to the transport to interpret the fields in a sensible way for that transport. New transport authors are encouraged to use transport://credset format (see inspec/inspec/issues/3661) rather than inventing a new field mapping.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/train.rb', line 90 def self.unpack_target_from_uri(uri_string, opts = {}) # rubocop: disable Metrics/AbcSize creds = {} return creds if uri_string.empty? # split up the target's host/scheme configuration uri = parse_uri(uri_string) unless uri.host.nil? && uri.scheme.nil? creds[:backend] ||= uri.scheme creds[:host] ||= uri.hostname creds[:port] ||= uri.port creds[:user] ||= uri.user creds[:path] ||= uri.path creds[:password] ||= if opts[:www_form_encoded_password] && !uri.password.nil? Addressable::URI.unencode_component(uri.password) else uri.password end end # ensure path is nil, if its empty; e.g. required to reset defaults for winrm # TODO: move logic into winrm plugin creds[:path] = nil if !creds[:path].nil? && creds[:path].to_s.empty? # compact! is available in ruby 2.4+ # TODO: rewrite next line using compact! once we drop support for ruby 2.3 creds = creds.delete_if { |_, value| value.nil? } # merge train options in from the URI query string creds.merge!(uri.query_values.map { |k, v| [k.to_sym, v] }.to_h) unless uri.query_values.nil? # return the updated config creds end |
.validate_backend(credentials, default_transport_name = "local") ⇒ Object
Examine the given credential information, and if all is well, return the transport name. TODO: this actually does no validation of the credential options whatsoever
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/train.rb', line 151 def self.validate_backend(credentials, default_transport_name = "local") return default_transport_name if credentials.nil? transport_name = credentials[:backend] # TODO: Determine if it is ever possible (or supported) for transport_name to be 'localhost' # TODO: After inspec/inspec/pull/3750 is merged, should be able to remove nil from the list if credentials[:sudo] && [nil, "local", "localhost"].include?(transport_name) raise Train::UserError, "Sudo is only valid when running against a remote host. "\ "To run this locally with elevated privileges, run the command with `sudo ...`." end return transport_name unless transport_name.nil? unless credentials[:target].nil? # We should not get here, because if target_uri unpacking was successful, # it would have set credentials[:backend] raise Train::UserError, "Cannot determine backend from target "\ "configuration #{credentials[:target]}. Valid example: ssh://192.168.0.1" end unless credentials[:host].nil? raise Train::UserError, "Host configured, but no backend was provided. Please "\ "specify how you want to connect. Valid example: ssh://192.168.0.1" end credentials[:backend] = default_transport_name end |