1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 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 111 112 113 114 115 116
|
# frozen_string_literal: true
require_relative '../../../puppet/file_serving/configuration'
require_relative '../../../puppet/util/watched_file'
class Puppet::FileServing::Configuration::Parser
Mount = Puppet::FileServing::Mount
MODULES = 'modules'
# Parse our configuration file.
def parse
raise(_("File server configuration %{config_file} does not exist") % { config_file: @file }) unless Puppet::FileSystem.exist?(@file)
raise(_("Cannot read file server configuration %{config_file}") % { config_file: @file }) unless FileTest.readable?(@file)
@mounts = {}
@count = 0
File.open(@file) do |f|
mount = nil
f.each_line do |line|
# Have the count increment at the top, in case we throw exceptions.
@count += 1
case line
when /^\s*#/; next # skip comments
when /^\s*$/; next # skip blank lines
when /\[([-\w]+)\]/
mount = newmount(::Regexp.last_match(1))
when /^\s*(\w+)\s+(.+?)(\s*#.*)?$/
var = ::Regexp.last_match(1)
value = ::Regexp.last_match(2)
value.strip!
raise(ArgumentError, _("Fileserver configuration file does not use '=' as a separator")) if value =~ /^=/
case var
when "path"
path(mount, value)
when "allow", "deny"
# ignore `allow *`, otherwise report error
if var != 'allow' || value != '*'
error_location_str = Puppet::Util::Errors.error_location(@file.filename, @count)
Puppet.err("Entry '#{line.chomp}' is unsupported and will be ignored at #{error_location_str}")
end
else
error_location_str = Puppet::Util::Errors.error_location(@file.filename, @count)
raise ArgumentError, _("Invalid argument '%{var}' at %{error_location}") %
{ var: var, error_location: error_location_str }
end
else
error_location_str = Puppet::Util::Errors.error_location(@file.filename, @count)
raise ArgumentError, _("Invalid entry at %{error_location}: '%{file_text}'") %
{ file_text: line.chomp, error_location: error_location_str }
end
end
end
validate
@mounts
end
def initialize(filename)
@file = Puppet::Util::WatchedFile.new(filename)
end
def changed?
@file.changed?
end
private
# Create a new mount.
def newmount(name)
if @mounts.include?(name)
error_location_str = Puppet::Util::Errors.error_location(@file, @count)
raise ArgumentError, _("%{mount} is already mounted at %{name} at %{error_location}") %
{ mount: @mounts[name], name: name, error_location: error_location_str }
end
case name
when "modules"
mount = Mount::Modules.new(name)
when "plugins"
mount = Mount::Plugins.new(name)
when "scripts"
mount = Mount::Scripts.new(name)
when "tasks"
mount = Mount::Tasks.new(name)
when "locales"
mount = Mount::Locales.new(name)
else
mount = Mount::File.new(name)
end
@mounts[name] = mount
mount
end
# Set the path for a mount.
def path(mount, value)
if mount.respond_to?(:path=)
begin
mount.path = value
rescue ArgumentError => detail
Puppet.log_exception(detail, _("Removing mount \"%{mount}\": %{detail}") % { mount: mount.name, detail: detail })
@mounts.delete(mount.name)
end
else
Puppet.warning _("The '%{mount}' module can not have a path. Ignoring attempt to set it") % { mount: mount.name }
end
end
# Make sure all of our mounts are valid. We have to do this after the fact
# because details are added over time as the file is parsed.
def validate
@mounts.each { |_name, mount| mount.validate }
end
end
|