summaryrefslogtreecommitdiff
path: root/lib/chef/train_transport.rb
diff options
context:
space:
mode:
authorDavin Taddeo <davin@chef.io>2020-09-30 13:11:08 -0400
committerDavin Taddeo <davin@chef.io>2020-09-30 13:11:08 -0400
commit3017f86f0363f6fb0b0d1dea32a4bb637055158a (patch)
treea88f98e919783e7736cab3cec5ceaa256a170143 /lib/chef/train_transport.rb
parent1f147b43fa93d716c52a6d4c7cca07e7beedd925 (diff)
parent050ebb9bae23ac288a74d52fd1e2e898d019c4ea (diff)
downloadchef-3017f86f0363f6fb0b0d1dea32a4bb637055158a.tar.gz
Merge branch 'master' of github.com:chef/chef into main
Signed-off-by: Davin Taddeo <davin@chef.io>
Diffstat (limited to 'lib/chef/train_transport.rb')
-rw-r--r--lib/chef/train_transport.rb109
1 files changed, 5 insertions, 104 deletions
diff --git a/lib/chef/train_transport.rb b/lib/chef/train_transport.rb
index a4f311fc51..4fe1fcadec 100644
--- a/lib/chef/train_transport.rb
+++ b/lib/chef/train_transport.rb
@@ -15,114 +15,15 @@
# limitations under the License.
#
-require "chef-config/mixin/credentials"
-autoload :Train, "train"
-require_relative "dist"
+require "chef-config/mixin/train_transport" unless defined?(ChefConfig::Mixin::TrainTransport)
class Chef
class TrainTransport
- extend ChefConfig::Mixin::Credentials
+ include ChefConfig::Mixin::TrainTransport
- #
- # Returns a RFC099 credentials profile as a hash
- #
- def self.load_credentials(profile)
- # Tomlrb.load_file returns a hash with keys as strings
- credentials = parse_credentials_file
- if contains_split_fqdn?(credentials, profile)
- Chef::Log.warn("Credentials file #{credentials_file_path} contains target '#{profile}' as a Hash, expected a string.")
- Chef::Log.warn("Hostnames must be surrounded by single quotes, e.g. ['host.example.org']")
- end
-
- # host names must be specified in credentials file as ['foo.example.org'] with quotes
- if !credentials.nil? && !credentials[profile].nil?
- credentials[profile].map { |k, v| [k.to_sym, v] }.to_h # return symbolized keys to match Train.options()
- else
- nil
- end
- end
-
- # Toml creates hashes when a key is separated by periods, e.g.
- # [host.example.org] => { host: { example: { org: {} } } }
- #
- # Returns true if the above example is true
- #
- # A hostname has to be specified as ['host.example.org']
- # This will be a common mistake so we should catch it
- #
- def self.contains_split_fqdn?(hash, fqdn)
- fqdn.split(".").reduce(hash) do |h, k|
- v = h[k]
- if Hash === v
- v
- else
- break false
- end
- end
- end
-
- # ChefConfig::Mixin::Credentials.credentials_file_path is designed around knife,
- # overriding it here.
- #
- # Credentials file preference:
- #
- # 1) target_mode.credentials_file
- # 2) /etc/chef/TARGET_MODE_HOST/credentials
- # 3) #credentials_file_path from parent ($HOME/.chef/credentials)
- #
- def self.credentials_file_path
- tm_config = Chef::Config.target_mode
- profile = tm_config.host
-
- credentials_file =
- if tm_config.credentials_file && File.exist?(tm_config.credentials_file)
- tm_config.credentials_file
- elsif File.exist?(Chef::Config.platform_specific_path("#{Chef::Dist::CONF_DIR}/#{profile}/credentials"))
- Chef::Config.platform_specific_path("#{Chef::Dist::CONF_DIR}/#{profile}/credentials")
- else
- super
- end
-
- raise ArgumentError, "No credentials file found for target '#{profile}'" unless credentials_file
- raise ArgumentError, "Credentials file specified for target mode does not exist: '#{credentials_file}'" unless File.exist?(credentials_file)
-
- Chef::Log.debug("Loading credentials file '#{credentials_file}' for target '#{profile}'")
-
- credentials_file
- end
-
- def self.build_transport(logger = Chef::Log.with_child(subsystem: "transport"))
- return nil unless Chef::Config.target_mode?
-
- # TODO: Consider supporting parsing the protocol from a URI passed to `--target`
- #
- train_config = {}
-
- # Load the target_mode config context from Chef::Config, and place any valid settings into the train configuration
- tm_config = Chef::Config.target_mode
- protocol = tm_config.protocol
- train_config = tm_config.to_hash.select { |k| Train.options(protocol).key?(k) }
- Chef::Log.trace("Using target mode options from #{Chef::Dist::PRODUCT} config file: #{train_config.keys.join(", ")}") if train_config
-
- # Load the credentials file, and place any valid settings into the train configuration
- credentials = load_credentials(tm_config.host)
- if credentials
- valid_settings = credentials.select { |k| Train.options(protocol).key?(k) }
- valid_settings[:enable_password] = credentials[:enable_password] if credentials.key?(:enable_password)
- train_config.merge!(valid_settings)
- Chef::Log.trace("Using target mode options from credentials file: #{valid_settings.keys.join(", ")}") if valid_settings
- end
-
- train_config[:logger] = logger
-
- # Train handles connection retries for us
- Train.create(protocol, train_config)
- rescue SocketError => e # likely a dns failure, not caught by train
- e.message.replace "Error connecting to #{train_config[:target]} - #{e.message}"
- raise e
- rescue Train::PluginLoadError
- logger.error("Invalid target mode protocol: #{protocol}")
- exit(false)
+ def config
+ require "chef/config" unless defined?(Chef::Config)
+ Chef::Config
end
end
end