diff options
Diffstat (limited to 'lib/chef/config_fetcher.rb')
-rw-r--r-- | lib/chef/config_fetcher.rb | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb new file mode 100644 index 0000000000..80a313590b --- /dev/null +++ b/lib/chef/config_fetcher.rb @@ -0,0 +1,79 @@ +require 'chef/application' +require 'chef/chef_fs/path_utils' +require 'chef/http/simple' +require 'chef/json_compat' + +class Chef + class ConfigFetcher + + attr_reader :config_location + attr_reader :config_file_jail + + def initialize(config_location, config_file_jail) + @config_location = config_location + @config_file_jail = config_file_jail + end + + def fetch_json + config_data = read_config + begin + Chef::JSONCompat.from_json(config_data) + rescue JSON::ParserError => error + Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2) + end + end + + def read_config + if remote_config? + fetch_remote_config + else + read_local_config + end + end + + def fetch_remote_config + http.get("") + rescue SocketError, SystemCallError, Net::HTTPServerException => error + Chef::Application.fatal!("Cannot fetch config '#{config_location}': '#{error.class}: #{error.message}", 2) + end + + def read_local_config + ::File.read(config_location) + rescue Errno::ENOENT => error + Chef::Application.fatal!("Cannot load configuration from #{config_location}", 2) + rescue Errno::EACCES => error + Chef::Application.fatal!("Permissions are incorrect on #{config_location}. Please chmod a+r #{config_location}", 2) + end + + def config_missing? + return false if remote_config? + + # Check if the config file exists, and check if it is underneath the config file jail + begin + real_config_file = Pathname.new(config_location).realpath.to_s + rescue Errno::ENOENT + return true + end + + # If realpath succeeded, the file exists + return false if !config_file_jail + + begin + real_jail = Pathname.new(config_file_jail).realpath.to_s + rescue Errno::ENOENT + Chef::Log.warn("Config file jail #{config_file_jail} does not exist: will not load any config file.") + return true + end + + !Chef::ChefFS::PathUtils.descendant_of?(real_config_file, real_jail) + end + + def http + Chef::HTTP::Simple.new(config_location) + end + + def remote_config? + !!(config_location =~ %r{^(http|https)://}) + end + end +end |