summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlutter <lutter@980ebf18-57e1-0310-9a29-db15c13687c0>2007-03-09 00:49:35 +0000
committerlutter <lutter@980ebf18-57e1-0310-9a29-db15c13687c0>2007-03-09 00:49:35 +0000
commit38975de420bfd2f1350e7e55a996db40bc05d0b8 (patch)
tree3b063f4dd72af8ba4e3221c01b0f94542e313f90
parentebcb6b6df7af42632a6c1beaa1b60171ff32b61e (diff)
downloadpuppet-38975de420bfd2f1350e7e55a996db40bc05d0b8.tar.gz
puppet-38975de420bfd2f1350e7e55a996db40bc05d0b8.tar.xz
puppet-38975de420bfd2f1350e7e55a996db40bc05d0b8.zip
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
-rw-r--r--lib/puppet/modules.rb5
-rwxr-xr-xlib/puppet/network/handler/fileserver.rb49
-rwxr-xr-xtest/network/handler/fileserver.rb116
3 files changed, 160 insertions, 10 deletions
diff --git a/lib/puppet/modules.rb b/lib/puppet/modules.rb
index 2d48a6a4e..3d071b05a 100644
--- a/lib/puppet/modules.rb
+++ b/lib/puppet/modules.rb
@@ -2,6 +2,7 @@
class Puppet::Module
TEMPLATES = "templates"
+ FILES = "files"
# Return an array of paths by splitting the +modulepath+ config
# parameter. Only consider paths that are absolute and existing
@@ -68,5 +69,9 @@ class Puppet::Module
return File::join(path, TEMPLATES, strip(file))
end
+ def files
+ return File::join(path, FILES)
+ end
+
private :initialize
end
diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb
index 6def09837..1dd6ad793 100755
--- a/lib/puppet/network/handler/fileserver.rb
+++ b/lib/puppet/network/handler/fileserver.rb
@@ -11,6 +11,9 @@ class Puppet::Network::Handler
CHECKPARAMS = [:mode, :type, :owner, :group, :checksum]
+ # Special filserver module for puppet's module system
+ MODULES = "modules"
+
@interface = XMLRPC::Service::Interface.new("fileserver") { |iface|
iface.add_method("string describe(string, string)")
iface.add_method("string list(string, string, boolean, array)")
@@ -263,12 +266,16 @@ class Puppet::Network::Handler
value = $2
case var
when "path":
- begin
- mount.path = value
- rescue FileServerError => detail
- Puppet.err "Removing mount %s: %s" %
- [mount.name, detail]
- newmounts.delete(mount.name)
+ if mount.name == MODULES
+ Puppet.warning "The '#{MODULES}' module can not have a path. Ignoring attempt to set it"
+ else
+ begin
+ mount.path = value
+ rescue FileServerError => detail
+ Puppet.err "Removing mount %s: %s" %
+ [mount.name, detail]
+ newmounts.delete(mount.name)
+ end
end
when "allow":
value.split(/\s*,\s*/).each { |val|
@@ -312,6 +319,12 @@ class Puppet::Network::Handler
# Puppet.err "FileServer error: %s" % detail
end
+ unless newmounts[MODULES]
+ mount = Mount.new(MODULES)
+ mount.allow("*")
+ newmounts[MODULES] = mount
+ end
+
# Verify each of the mounts are valid.
# We let the check raise an error, so that it can raise an error
# pointing to the specific problem.
@@ -375,8 +388,13 @@ class Puppet::Network::Handler
tmp = $1
path = dir.sub(%r{/#{tmp}/?}, '')
- unless mount = @mounts[tmp]
- raise FileServerError, "Fileserver module '%s' not mounted" % tmp
+ mod = Puppet::Module::find(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
else
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
# make sure at least someone will be allowed, but, eh.
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
diff --git a/test/network/handler/fileserver.rb b/test/network/handler/fileserver.rb
index 8ac2762c6..c4db60f71 100755
--- a/test/network/handler/fileserver.rb
+++ b/test/network/handler/fileserver.rb
@@ -1018,6 +1018,122 @@ allow *
File.unlink(file)
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
# $Id$