Introduces a new implicit 'modules' fileserver module, whose allow/deny can

be set from the fileserver.conf, but whose path is ignored and can
therefore not be used directly in puppet:// URL's.

When the fileserver looks for a file/directory, it first checks if the
first part of the URL references an existing module. If one is found, a new
temporary mount for that module is generated with the same permissions as
the 'modules' module. If no matching puppet module is found, the fileserver
behaves as it always has.


git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2278 980ebf18-57e1-0310-9a29-db15c13687c0
This commit is contained in:
lutter 2007-03-09 00:49:35 +00:00
Родитель ebcb6b6df7
Коммит 38975de420
3 изменённых файлов: 160 добавлений и 10 удалений

Просмотреть файл

@ -2,6 +2,7 @@
class Puppet::Module class Puppet::Module
TEMPLATES = "templates" TEMPLATES = "templates"
FILES = "files"
# Return an array of paths by splitting the +modulepath+ config # Return an array of paths by splitting the +modulepath+ config
# parameter. Only consider paths that are absolute and existing # parameter. Only consider paths that are absolute and existing
@ -68,5 +69,9 @@ class Puppet::Module
return File::join(path, TEMPLATES, strip(file)) return File::join(path, TEMPLATES, strip(file))
end end
def files
return File::join(path, FILES)
end
private :initialize private :initialize
end end

Просмотреть файл

@ -11,6 +11,9 @@ class Puppet::Network::Handler
CHECKPARAMS = [:mode, :type, :owner, :group, :checksum] CHECKPARAMS = [:mode, :type, :owner, :group, :checksum]
# Special filserver module for puppet's module system
MODULES = "modules"
@interface = XMLRPC::Service::Interface.new("fileserver") { |iface| @interface = XMLRPC::Service::Interface.new("fileserver") { |iface|
iface.add_method("string describe(string, string)") iface.add_method("string describe(string, string)")
iface.add_method("string list(string, string, boolean, array)") iface.add_method("string list(string, string, boolean, array)")
@ -263,12 +266,16 @@ class Puppet::Network::Handler
value = $2 value = $2
case var case var
when "path": when "path":
begin if mount.name == MODULES
mount.path = value Puppet.warning "The '#{MODULES}' module can not have a path. Ignoring attempt to set it"
rescue FileServerError => detail else
Puppet.err "Removing mount %s: %s" % begin
[mount.name, detail] mount.path = value
newmounts.delete(mount.name) rescue FileServerError => detail
Puppet.err "Removing mount %s: %s" %
[mount.name, detail]
newmounts.delete(mount.name)
end
end end
when "allow": when "allow":
value.split(/\s*,\s*/).each { |val| value.split(/\s*,\s*/).each { |val|
@ -312,6 +319,12 @@ class Puppet::Network::Handler
# Puppet.err "FileServer error: %s" % detail # Puppet.err "FileServer error: %s" % detail
end end
unless newmounts[MODULES]
mount = Mount.new(MODULES)
mount.allow("*")
newmounts[MODULES] = mount
end
# Verify each of the mounts are valid. # Verify each of the mounts are valid.
# We let the check raise an error, so that it can raise an error # We let the check raise an error, so that it can raise an error
# pointing to the specific problem. # pointing to the specific problem.
@ -375,8 +388,13 @@ class Puppet::Network::Handler
tmp = $1 tmp = $1
path = dir.sub(%r{/#{tmp}/?}, '') path = dir.sub(%r{/#{tmp}/?}, '')
unless mount = @mounts[tmp] mod = Puppet::Module::find(tmp)
raise FileServerError, "Fileserver module '%s' not mounted" % tmp if mod
mount = @mounts[MODULES].copy(mod, mod.files)
else
unless mount = @mounts[tmp]
raise FileServerError, "Fileserver module '%s' not mounted" % tmp
end
end end
else else
raise FileServerError, "Fileserver error: Invalid path '%s'" % dir raise FileServerError, "Fileserver error: Invalid path '%s'" % dir
@ -579,9 +597,20 @@ class Puppet::Network::Handler
# Verify our configuration is valid. This should really check to # Verify our configuration is valid. This should really check to
# make sure at least someone will be allowed, but, eh. # make sure at least someone will be allowed, but, eh.
def valid? def valid?
return false unless @path if name == MODULES
return @path.nil?
else
return ! @path.nil?
end
end
return true # Return a new mount with the same properties as +self+, except
# with a different name and path.
def copy(name, path)
result = self.clone
result.path = path
result.instance_variable_set(:@name, name)
return result
end end
end end
end end

Просмотреть файл

@ -1018,6 +1018,122 @@ allow *
File.unlink(file) File.unlink(file)
end end
end end
# Test the default modules fileserving
def test_modules_default
moddir = tempfile
Dir.mkdir(moddir)
mounts = {}
Puppet[:modulepath] = moddir
mods = %w{green red}.collect do |name|
path = File::join(moddir, name, Puppet::Module::FILES)
FileUtils::mkdir_p(path)
if name == "green"
file = File::join(path, "test.txt")
File::open(file, "w") { |f| f.print name }
end
Puppet::Module::find(name)
end
conffile = tempfile
@@tmpfiles << conffile
File.open(conffile, "w") { |f| f.puts "# a test config file" }
# create a server with the file
server = nil
assert_nothing_raised {
server = Puppet::Network::Handler::FileServer.new(
:Local => false ,
:Config => conffile
)
}
mods.each do |mod|
mount = "/#{mod.name}/"
list = nil
assert_nothing_raised {
list = server.list(mount, :ignore, true, false)
}
list = list.split("\n")
if mod.name == "green"
assert_equal(2, list.size)
assert_equal("/\tdirectory", list[0])
assert_equal("/test.txt\tfile", list[1])
else
assert_equal(1, list.size)
assert_equal("/\tdirectory", list[0])
end
assert_nothing_raised("Host 'allow' denied #{mount}") {
server.list(mount, :ignore, true, false,
'allow.example.com', "192.168.0.1")
}
end
end
# Test that configuring deny/allow for modules works
def test_modules_config
moddir = tempfile
Dir.mkdir(moddir)
mounts = {}
Puppet[:modulepath] = moddir
path = File::join(moddir, "amod", Puppet::Module::FILES)
file = File::join(path, "test.txt")
FileUtils::mkdir_p(path)
File::open(file, "w") { |f| f.print "Howdy" }
mod = Puppet::Module::find("amod")
conffile = tempfile
@@tmpfiles << conffile
File.open(conffile, "w") { |f|
f.print "# a test config file
[modules]
path #{basedir}/thing
allow 192.168.0.*
"
}
# create a server with the file
server = nil
assert_nothing_raised {
server = Puppet::Network::Handler::FileServer.new(
:Local => false,
:Config => conffile
)
}
list = nil
mount = "/#{mod.name}/"
assert_nothing_raised {
list = server.list(mount, :ignore, true, false)
}
assert_nothing_raised {
list.split("\n").each { |line|
file, type = line.split("\t")
server.describe(mount + file)
}
}
assert_describe(mount, file, server)
# now let's check that things are being correctly forbidden
assert_raise(Puppet::AuthorizationError,
"Host 'deny' allowed #{mount}") {
server.list(mount, :ignore, true, false,
'deny.example.com', "192.168.1.1")
}
assert_nothing_raised("Host 'allow' denied #{mount}") {
server.list(mount, :ignore, true, false,
'allow.example.com', "192.168.0.1")
}
end
end end
# $Id$ # $Id$