class Inspec::Plugin::V2::ConfigFile
Represents the plugin config file on disk.
Attributes
path[R]
Public Class Methods
default_path()
click to toggle source
Returns the defaut path for a config file. This respects ENV.
# File lib/inspec/plugin/v2/config_file.rb, line 19 def self.default_path File.join(Inspec.config_dir, "plugins.json") end
new(path = nil)
click to toggle source
# File lib/inspec/plugin/v2/config_file.rb, line 10 def initialize(path = nil) @path = path || self.class.default_path @data = blank_structure read_and_validate_file if File.exist?(@path) end
Public Instance Methods
add_entry(proposed_entry)
click to toggle source
Add an entry with full validation.
# File lib/inspec/plugin/v2/config_file.rb, line 41 def add_entry(proposed_entry) unless proposed_entry.keys.all? { |field| field.is_a? Symbol } raise Inspec::Plugin::V2::ConfigError, "All keys to ConfigFile#add_entry must be symbols" end validate_entry(proposed_entry) if existing_entry?(proposed_entry[:name]) raise Inspec::Plugin::V2::ConfigError, "Duplicate plugin name in call to ConfigFile#add_entry: '#{proposed_entry[:name]}'" end @data[:plugins] << proposed_entry end
each(&block)
click to toggle source
Implement Enumerable. All Enumerable methds act on the plugins list, and yield Hashes that represent an entry.
# File lib/inspec/plugin/v2/config_file.rb, line 26 def each(&block) @data[:plugins].each(&block) end
existing_entry?(name)
click to toggle source
Check for a plugin
# File lib/inspec/plugin/v2/config_file.rb, line 36 def existing_entry?(name) !plugin_by_name(name).nil? end
plugin_by_name(name)
click to toggle source
Look for a plugin by name.
# File lib/inspec/plugin/v2/config_file.rb, line 31 def plugin_by_name(name) detect { |entry| entry[:name] == name.to_sym } end
remove_entry(name)
click to toggle source
Removes an entry specified by plugin name.
# File lib/inspec/plugin/v2/config_file.rb, line 56 def remove_entry(name) unless existing_entry?(name) raise Inspec::Plugin::V2::ConfigError, "No such entry with plugin name '#{name}'" end @data[:plugins].delete_if { |entry| entry[:name] == name.to_sym } end
save()
click to toggle source
Save the file to disk as a JSON structure at the path.
# File lib/inspec/plugin/v2/config_file.rb, line 65 def save dir = File.dirname(path) FileUtils.mkdir_p(dir) File.write(path, JSON.pretty_generate(@data)) end
Private Instance Methods
blank_structure()
click to toggle source
# File lib/inspec/plugin/v2/config_file.rb, line 73 def blank_structure { plugins_config_version: "1.0.0", plugins: [], } end
read_and_validate_file()
click to toggle source
# File lib/inspec/plugin/v2/config_file.rb, line 80 def read_and_validate_file @data = JSON.parse(File.read(path), symbolize_names: true) validate_file rescue JSON::ParserError => e raise Inspec::Plugin::V2::ConfigError, "Failed to load plugins JSON configuration from #{path}:\n#{e}" end
validate_entry(plugin_entry)
click to toggle source
# File lib/inspec/plugin/v2/config_file.rb, line 125 def validate_entry(plugin_entry) unless plugin_entry.is_a? Hash raise Inspec::Plugin::V2::ConfigError, "each 'plugins' entry should be a Hash / JSON object" end unless plugin_entry.key? :name raise Inspec::Plugin::V2::ConfigError, "'plugins' entry missing 'name' field" end # Symbolize the name. plugin_entry[:name] = plugin_entry[:name].to_sym if plugin_entry.key? :installation_type seen_type = plugin_entry[:installation_type] unless %i{gem path}.include? seen_type.to_sym raise Inspec::Plugin::V2::ConfigError, "'plugins' entry with unrecognized installation_type (must be one of 'gem' or 'path')" end plugin_entry[:installation_type] = seen_type.to_sym if plugin_entry[:installation_type] == :path && !plugin_entry.key?(:installation_path) raise Inspec::Plugin::V2::ConfigError, "'plugins' entry with a 'path' installation_type missing installation path" end end end
validate_file()
click to toggle source
# File lib/inspec/plugin/v2/config_file.rb, line 87 def validate_file # rubocop: disable Metrics/AbcSize unless @data[:plugins_config_version] raise Inspec::Plugin::V2::ConfigError, "Missing 'plugins_config_version' entry at #{path} - currently support versions: 1.0.0" end unless @data[:plugins_config_version] == "1.0.0" raise Inspec::Plugin::V2::ConfigError, "Unsupported plugins.json file version #{@data[:plugins_config_version]} at #{path} - currently support versions: 1.0.0" end plugin_entries = @data[:plugins] if plugin_entries.nil? raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file at #{path} - missing top-level key named 'plugins', whose value should be an array" end unless plugin_entries.is_a?(Array) raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file at #{path} - top-level key named 'plugins' should be an array" end plugin_entries.each_with_index do |plugin_entry, idx| begin validate_entry(plugin_entry) rescue Inspec::Plugin::V2::ConfigError => ex # append some context to the message raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - " + ex.message + " at index #{idx}" end # Check for duplicates plugin_entries.each_with_index do |other_entry, other_idx| next if idx == other_idx next unless other_entry.is_a? Hash # We'll catch that invalid entry later next if plugin_entry[:name] != other_entry[:name] indices = [idx, other_idx].sort raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - duplicate plugin entry '#{plugin_entry[:name]}' detected at index #{indices[0]} and #{indices[1]}" end end end