Class: OctocatalogDiff::API::V1::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/octocatalog-diff/api/v1/config.rb

Overview

This class interacts with the configuration file typically named `.octocatalog-diff.cfg.rb`.

Constant Summary collapse

DEFAULT_PATHS =

Default directory paths: These are the documented default locations that will be checked for the configuration file.

[
  ENV['OCTOCATALOG_DIFF_CONFIG_FILE'],
  File.join(Dir.pwd, '.octocatalog-diff.cfg.rb'),
  File.join(ENV['HOME'], '.octocatalog-diff.cfg.rb'),
  '/opt/puppetlabs/octocatalog-diff/octocatalog-diff.cfg.rb',
  '/usr/local/etc/octocatalog-diff.cfg.rb',
  '/etc/octocatalog-diff.cfg.rb'
].compact.freeze

Class Method Summary collapse

Class Method Details

.config(options_in = {}) ⇒ Hash

Public: Find the configuration file in the specified path or one of the default paths as appropriate. Parses the configuration file and returns the hash object with its settings. Returns empty hash if the configuration file is not found anywhere.

Parameters:

  • :filename (String)

    Specified file name (default = search the default paths)

  • :logger (Logger)

    Logger object

  • :test (Boolean)

    Configuration file test mode (log some extra debugging, raises errors)

Returns:

  • (Hash)

    Parsed configuration file


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/octocatalog-diff/api/v1/config.rb', line 30

def self.config(options_in = {})
  # Initialize the logger - if not passed, set to a throwaway object.
  options, logger = OctocatalogDiff::API::V1::Common.logger_from_options(options_in)

  # Locate the configuration file
  paths = [options.fetch(:filename, DEFAULT_PATHS)].compact
  config_file = first_file(paths)

  # Can't find the configuration file?
  if config_file.nil?
    message = "Unable to find configuration file in #{paths.join(':')}"
    raise OctocatalogDiff::Errors::ConfigurationFileNotFoundError, message if options[:test]
    logger.debug message
    return {}
  end

  # Load/parse the configuration file - this returns a hash
  settings = load_config_file(config_file, logger)

  # Debug the configuration file if requested.
  debug_config_file(settings, logger) if options[:test]

  # Return the settings hash
  logger.debug "Loaded #{settings.keys.size} settings from #{config_file}"
  settings
end

.debug_config_file(settings, logger) ⇒ Object

Private: Print debugging details for the configuration file.

Parameters:

  • settings (Hash)

    Parsed settings from load_config_file

  • logger (Logger)

    Logger object


61
62
63
64
65
66
67
# File 'lib/octocatalog-diff/api/v1/config.rb', line 61

def self.debug_config_file(settings, logger)
  unless settings.is_a?(Hash)
    raise ArgumentError, "Settings must be hash not #{settings.class}"
  end

  settings.each { |key, val| logger.debug ":#{key} => (#{val.class}) #{val.inspect}" }
end

.first_file(search_paths) ⇒ Object

Private: Find the first element of the given array that is a file and return it. Return nil if none of the elements in the array are files.

Parameters:

  • search_paths (Array<String>)

    Paths to check


116
117
118
119
120
121
# File 'lib/octocatalog-diff/api/v1/config.rb', line 116

def self.first_file(search_paths)
  search_paths.flatten.compact.each do |path|
    return path if File.file?(path)
  end
  nil
end

.load_config_file(filename, logger) ⇒ Hash

Private: Load the configuration file from a given path. Returns the settings hash.

Parameters:

  • filename (String)

    File name to load

  • logger (Logger)

    Logger object

Returns:

  • (Hash)

    Settings


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/octocatalog-diff/api/v1/config.rb', line 74

def self.load_config_file(filename, logger)
  # This should never happen unless somebody calls this method directly outside of
  # the published `.config` method. Check for problems anyway.
  raise Errno::ENOENT, "File #{filename} doesn't exist" unless File.file?(filename)

  # Attempt to require in the file. Problems here will fall through to the rescued
  # exception below.
  logger.debug "Loading octocatalog-diff configuration from #{filename}"
  load filename

  # The required file should contain `OctocatalogDiff::Config` with `.config` method.
  # If this is undefined, raise an exception.
  begin
    loaded_class = Kernel.const_get(:OctocatalogDiff).const_get(:Config)
  rescue NameError
    message = 'Configuration must define OctocatalogDiff::Config!'
    raise OctocatalogDiff::Errors::ConfigurationFileContentError, message
  end

  unless loaded_class.respond_to?(:config)
    message = 'Configuration must define OctocatalogDiff::Config.config!'
    raise OctocatalogDiff::Errors::ConfigurationFileContentError, message
  end

  # The configuration file looks like it defines the correct method, so read it.
  # Make sure it's a hash.
  options = loaded_class.config
  unless options.is_a?(Hash)
    message = "Configuration must be Hash not #{options.class}!"
    raise OctocatalogDiff::Errors::ConfigurationFileContentError, message
  end

  options
rescue Exception => exc # rubocop:disable Lint/RescueException
  logger.fatal "#{exc.class} error with #{filename}: #{exc.message}\n#{exc.backtrace}"
  raise exc
end