Merging the webserver_portability branch from version 2182 to version 2258.

git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2259 980ebf18-57e1-0310-9a29-db15c13687c0
This commit is contained in:
luke 2007-03-06 19:03:05 +00:00
Родитель 68233706a9
Коммит 46d344b9da
113 изменённых файлов: 2736 добавлений и 1807 удалений

1
bin/pi
Просмотреть файл

@ -12,7 +12,6 @@
# present the various pieces of info to user
require 'puppet'
require 'puppet/type'
require 'optparse'
class Formatter

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

@ -60,7 +60,7 @@
# Licensed under the GNU Public License
require 'puppet'
require 'puppet/network/server'
require 'puppet/network/handler'
require 'puppet/network/client'
require 'getoptlong'
@ -179,8 +179,8 @@ if loadclasses
end
begin
server = Puppet::Network::Server::Master.new(master)
client = Puppet::Network::Client::MasterClient.new(
server = Puppet::Network::Handler.master.new(master)
client = Puppet::Network::Client.master.new(
:Master => server,
:Cache => false
)

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

@ -155,7 +155,6 @@ trap(:INT) do
end
require 'puppet'
require 'puppet/network/server'
require 'puppet/network/client'
require 'getoptlong'
@ -300,13 +299,9 @@ if options[:centrallogs]
Puppet::Util::Log.newdestination(logdest)
end
if options[:onetime]
Puppet[:setpidfile] = false
end
# We need tomake the client either way, we just don't start it
# if --no-client is set.
client = Puppet::Network::Client::MasterClient.new(args)
client = Puppet::Network::Client.master.new(args)
if options[:enable]
client.enable
elsif options[:disable]
@ -325,13 +320,13 @@ if options[:daemonize]
client.daemonize
end
unless client.readcert
unless client.cert
# If we don't already have the certificate, then create a client to
# request one.
caclient = Puppet::Network::Client::CA.new(args)
# request one. Use the special ca stuff, don't use the normal server and port.
caclient = Puppet::Network::Client.ca.new()
if options[:waitforcert] > 0
begin
while ! caclient.requestcert do
while ! caclient.request_cert do
Puppet.notice "Did not receive certificate"
sleep options[:waitforcert]
end
@ -340,7 +335,7 @@ unless client.readcert
exit(23)
end
else
unless caclient.requestcert
unless caclient.request_cert
Puppet.notice "No certificates; exiting"
exit(1)
end
@ -387,8 +382,10 @@ if Puppet[:listen] and ! options[:onetime]
args[:Handlers] = handlers
args[:Port] = Puppet[:puppetport]
require 'puppet/network/server/webrick'
begin
server = Puppet::Network::Server.new(args)
server = Puppet::Network::Server::WEBrick.new(args)
rescue => detail
$stderr.puts detail
puts detail.backtrace
@ -400,9 +397,6 @@ elsif options[:onetime]
Puppet.notice "Ignoring --listen on onetime run"
end
# now set up the network client with the certs, now that we have them
client.setcerts
if options[:client]
objects << client
end
@ -424,10 +418,10 @@ if options[:onetime]
begin
client.run
rescue => detail
Puppet.err detail.to_s
if Puppet[:debug]
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err detail.to_s
end
exit(0)
else
@ -445,5 +439,4 @@ else
Puppet.start
end
# $Id$

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

@ -3,12 +3,12 @@
#
# = Synopsis
#
# The central puppet server. Can also function as a certificate authority.
# The central puppet server. Functions as a certificate authority by default.
#
# = Usage
#
# puppetmasterd [-D|--daemonize] [-d|--debug] [-h|--help]
# [-l|--logdest <file>|console|syslog] [--noca] [--nobucket] [--nonodes]
# [-l|--logdest <file>|console|syslog] [--nobucket] [--nonodes]
# [-v|--verbose] [-V|--version]
#
# = Description
@ -45,10 +45,6 @@
# nobucket::
# Do not function as a file bucket.
#
# noca::
# Do not function as a certificate authority. This is deprecated. Use '--no-ca'
# now.
#
# nonodes::
# Do not use individual node designations; each node will receive the result
# of evaluating the entire configuration.
@ -83,7 +79,7 @@ end
require 'getoptlong'
require 'puppet'
require 'puppet/network/server'
require 'puppet/sslcertificates'
options = [
[ "--daemonize", "-D", GetoptLong::NO_ARGUMENT ],
@ -97,7 +93,6 @@ options = [
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
[ "--version", "-V", GetoptLong::NO_ARGUMENT ]
]
#Puppet::Util::Log.newdestination(:syslog)
# Add all of the config parameters as valid options.
Puppet.config.addargs(options)
@ -109,7 +104,6 @@ ca = {}
report = {}
fs = {}
bucket = {}
args = {}
options = {
:havereport => true,
@ -136,9 +130,6 @@ begin
end
when "--noreports"
options[:havereport] = false
when "--noca"
Puppet[:ca] = false
Puppet.warning "--noca is deprecated. Please use --no-ca."
when "--nomaster"
options[:havemaster] = false
when "--nobucket"
@ -230,7 +221,7 @@ end
if Puppet[:parseonly]
begin
Puppet::Network::Server::Master.new(master)
Puppet::Network::Handler.master.new(master)
rescue => detail
if Puppet[:trace]
puts detail.backtrace
@ -252,12 +243,21 @@ if fs.include?(:Config)
handlers[:FileServer] = fs
end
args[:Handlers] = handlers
begin
# use the default, um, everything
#server = Puppet::Network::Server.new(:CA => ca)
server = Puppet::Network::Server.new(args)
case Puppet[:servertype]
when "webrick"
# use the default, um, everything
require 'puppet/network/server/webrick'
server = Puppet::Network::Server::WEBrick.new(:Handlers => handlers)
when "mongrel":
require 'puppet/network/server/mongrel'
handler = Puppet::Network::Server::MongrelHandler.new(handlers)
server = Mongrel::HttpServer.new("0.0.0.0", Puppet[:masterport])
server.register("/", handler)
else
Puppet.err "Invalid server type %s" % Puppet[:servertype]
exit(45)
end
rescue => detail
if Puppet[:trace]
puts detail.backtrace
@ -278,7 +278,10 @@ if Process.uid == 0
end
end
Puppet.newservice(server)
# Mongrel doesn't shut down like webrick; we really need to write plugins for it.
if Puppet[:servertype] == "webrick"
Puppet.newservice(server)
end
Puppet.settraps
if options[:daemonize]
@ -286,6 +289,11 @@ if options[:daemonize]
end
Puppet.notice "Starting Puppet server version %s" % [Puppet.version]
Puppet.start
case Puppet[:servertype]
when "webrick"
Puppet.start
when "mongrel":
server.run.join
end
# $Id$

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

@ -137,7 +137,6 @@ rescue LoadError
$stderr.puts "Failed to load ruby LDAP library. LDAP functionality will not be available"
end
require 'puppet'
require 'puppet/network/server'
require 'puppet/network/client'
require 'getoptlong'

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

@ -47,8 +47,8 @@
# Licensed under the GNU Public License
require 'puppet'
require 'puppet/server'
require 'puppet/client'
require 'puppet/network/handler'
require 'puppet/network/client'
require 'getoptlong'
options = [
@ -93,16 +93,16 @@ begin
when "--use-nodes"
master[:UseNodes] = true
when "--verbose"
Puppet::Log.level = :info
Puppet::Log.newdestination(:console)
Puppet::Util::Log.level = :info
Puppet::Util::Log.newdestination(:console)
verbose = true
when "--debug"
Puppet::Log.level = :debug
Puppet::Log.newdestination(:console)
Puppet::Util::Log.level = :debug
Puppet::Util::Log.newdestination(:console)
debug = true
when "--logdest"
begin
Puppet::Log.newdestination arg
Puppet::Util::Log.newdestination arg
setdest=true
rescue => detail
$stderr.puts detail.to_s
@ -147,7 +147,7 @@ unless ARGV.length > 0
end
unless setdest
Puppet::Log.newdestination(:syslog)
Puppet::Util::Log.newdestination(:syslog)
end
master[:Manifest] = ARGV.shift
@ -169,14 +169,14 @@ end
master[:Classes] = classes
begin
server = Puppet::Server::Master.new(master)
server = Puppet::Network::Handler.master.new(master)
rescue => detail
$stderr.puts detail
exit(1)
end
begin
client = Puppet::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => server,
:Cache => false
)

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

@ -35,15 +35,7 @@ module Puppet
# lazy.
attr_accessor :args
attr_reader :features
end
def Puppet.execname
unless defined? @name
@name = $0.gsub(/.+#{File::SEPARATOR}/,'').sub(/\.rb$/, '')
end
return @name
attr_writer :name
end
# the hash that determines how our system behaves
@ -78,9 +70,6 @@ module Puppet
@@config.setdefaults(section, hash)
end
# Load all of the configuration parameters.
require 'puppet/configuration'
# configuration parameter access and stuff
def self.[](param)
case param
@ -116,6 +105,9 @@ module Puppet
@@config
end
# Load all of the configuration parameters.
require 'puppet/configuration'
def self.genconfig
if Puppet[:configprint] != ""
val = Puppet[:configprint]
@ -268,6 +260,7 @@ module Puppet
# Stop our services
defined? @services and @services.each do |svc|
next unless svc.respond_to?(:shutdown)
begin
timeout(20) do
svc.shutdown
@ -389,9 +382,9 @@ module Puppet
end
end
require 'puppet/network/server'
require 'puppet/type'
require 'puppet/util/storage'
require 'puppet/parser/interpreter'
if Puppet[:storeconfigs]
require 'puppet/rails'
end

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

@ -4,7 +4,8 @@ module Puppet
# use basedirs that are in the user's home directory.
conf = nil
var = nil
if self.name != "puppetmasterd" and Puppet::Util::SUIDManager.uid != 0
name = $0.gsub(/.+#{File::SEPARATOR}/,'').sub(/\.rb$/, '')
if name != "puppetmasterd" and Puppet::Util::SUIDManager.uid != 0
conf = File.expand_path("~/.puppet")
var = File.expand_path("~/.puppet/var")
else
@ -15,10 +16,12 @@ module Puppet
self.setdefaults(:puppet,
:confdir => [conf, "The main Puppet configuration directory."],
:vardir => [var, "Where Puppet stores dynamic and growing data."]
:vardir => [var, "Where Puppet stores dynamic and growing data."],
:name => [name, "The name of the service, if we are running as one. The
default is essentially $0 without the path or '.rb'."]
)
if self.name == "puppetmasterd"
if name == "puppetmasterd"
logopts = {:default => "$vardir/log",
:mode => 0750,
:owner => "$user",
@ -114,7 +117,14 @@ module Puppet
# Define the config default.
self.setdefaults(self.name,
:config => ["$confdir/#{self.name}.conf",
"The configuration file for #{self.name}."]
"The configuration file for #{self.name}."],
:pidfile => ["", "The pid file"],
:bindaddress => ["", "The address to bind to. Mongrel servers
default to 127.0.0.1 and WEBrick defaults to 0.0.0.0."],
:servertype => ["webrick", "The type of server to use. Currently supported
options are webrick and mongrel. If you use mongrel, you will need
a proxy in front of the process or processes, since Mongrel cannot
speak SSL."]
)
self.setdefaults("puppetmasterd",
@ -145,7 +155,15 @@ module Puppet
for determining which 'node' statement applies to the client.
Possible values are 'cert' (use the subject's CN in the client's
certificate) and 'facter' (use the hostname that the client
reported in its facts)"]
reported in its facts)"],
:bucketdir => {
:default => "$vardir/bucket",
:mode => 0750,
:owner => "$user",
:group => "$group",
:desc => "Where FileBucket files are stored."
},
:ca => [true, "Wether the master should function as a certificate authority."]
)
self.setdefaults("puppetd",
@ -179,7 +197,121 @@ module Puppet
:puppetport => [8139, "Which port puppetd listens on."],
:noop => [false, "Whether puppetd should be run in noop mode."],
:runinterval => [1800, # 30 minutes
"How often puppetd applies the client configuration; in seconds"]
"How often puppetd applies the client configuration; in seconds"],
:listen => [false, "Whether puppetd should listen for
connections. If this is true, then by default only the
``runner`` server is started, which allows remote authorized
and authenticated nodes to connect and trigger ``puppetd``
runs."],
:ca_server => ["$server", "The server to use for certificate
authority requests. It's a separate server because it cannot
and does not need to horizontally scale."],
:ca_port => ["$master_port", "The port to use for the certificate authority."]
)
self.setdefaults("filebucket",
:clientbucketdir => {
:default => "$vardir/clientbucket",
:mode => 0750,
:desc => "Where FileBucket files are stored locally."
}
)
self.setdefaults("fileserver",
:fileserverconfig => ["$confdir/fileserver.conf",
"Where the fileserver configuration is stored."]
)
self.setdefaults(:reporting,
:reports => ["store",
"The list of reports to generate. All reports are looked for
in puppet/reports/<name>.rb, and multiple report names should be
comma-separated (whitespace is okay)."
],
:reportdir => {:default => "$vardir/reports",
:mode => 0750,
:owner => "$user",
:group => "$group",
:desc => "The directory in which to store reports
received from the client. Each client gets a separate
subdirectory."}
)
self.setdefaults("puppetd",
:puppetdlockfile => [ "$statedir/puppetdlock",
"A lock file to temporarily stop puppetd from doing anything."],
:usecacheonfailure => [true,
"Whether to use the cached configuration when the remote
configuration will not compile. This option is useful for testing
new configurations, where you want to fix the broken configuration
rather than reverting to a known-good one."
],
:ignorecache => [false,
"Ignore cache and always recompile the configuration. This is
useful for testing new configurations, where the local cache may in
fact be stale even if the timestamps are up to date - if the facts
change or if the server changes."
],
:downcasefacts => [false,
"Whether facts should be made all lowercase when sent to the server."]
)
self.setdefaults(:puppetd,
:configtimeout => [120,
"How long the client should wait for the configuration to be retrieved
before considering it a failure. This can help reduce flapping if too
many clients contact the server at one time."
],
:reportserver => ["$server",
"The server to which to send transaction reports."
],
:report => [false,
"Whether to send reports after every transaction."
]
)
# Plugin information.
self.setdefaults("puppet",
:pluginpath => ["$vardir/plugins",
"Where Puppet should look for plugins. Multiple directories should
be colon-separated, like normal PATH variables."],
:plugindest => ["$vardir/plugins",
"Where Puppet should store plugins that it pulls down from the central
server."],
:pluginsource => ["puppet://$server/plugins",
"From where to retrieve plugins. The standard Puppet ``file`` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:pluginsync => [false,
"Whether plugins should be synced with the central server."],
:pluginsignore => [".svn CVS",
"What files to ignore when pulling down plugins."]
)
# Central fact information.
self.setdefaults("puppet",
:factpath => ["$vardir/facts",
"Where Puppet should look for facts. Multiple directories should
be colon-separated, like normal PATH variables."],
:factdest => ["$vardir/facts",
"Where Puppet should store facts that it pulls down from the central
server."],
:factsource => ["puppet://$server/facts",
"From where to retrieve facts. The standard Puppet ``file`` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:factsync => [false,
"Whether facts should be synced with the central server."],
:factsignore => [".svn CVS",
"What files to ignore when pulling down facts."]
)
self.setdefaults(:reporting,
:tagmap => ["$confdir/tagmail.conf",
"The mapping between reporting tags and email addresses."],
:sendmail => [%x{which sendmail 2>/dev/null}.chomp,
"Where to find the sendmail binary with which to send email."],
:reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."),
"The 'from' email address for the reports."],
:smtpserver => ["none",
"The server through which to send email reports."]
)
end

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

@ -1,284 +1,83 @@
# helper functions for daemons
require 'puppet'
require 'puppet/util/pidlock'
module Puppet
# A module that handles operations common to all daemons. This is included
# into the Server and Client base classes.
module Daemon
include Puppet::Util
# A module that handles operations common to all daemons. This is included
# into the Server and Client base classes.
module Puppet::Daemon
include Puppet::Util
Puppet.config.setdefaults(:puppet, :setpidfile => [true,
"Whether to store a PID file for the daemon."])
def daemonname
#$0.sub(/.+#{File::SEPARATOR}/,'')
Puppet.execname
def daemonname
Puppet[:name]
end
# Put the daemon into the background.
def daemonize
if pid = fork()
Process.detach(pid)
exit(0)
end
setpidfile()
# The path to the pid file for this server
def pidfile
# Get rid of console logging
Puppet::Util::Log.close(:console)
Process.setsid
Dir.chdir("/")
begin
$stdin.reopen "/dev/null"
$stdout.reopen "/dev/null", "a"
$stderr.reopen $stdout
Puppet::Util::Log.reopen
rescue => detail
File.open("/tmp/daemonout", "w") { |f|
f.puts "Could not start %s: %s" % [Puppet[:name], detail]
}
Puppet.err "Could not start %s: %s" % [Puppet[:name], detail]
exit(12)
end
end
# The path to the pid file for this server
def pidfile
if Puppet[:pidfile] != ""
Puppet[:pidfile]
else
File.join(Puppet[:rundir], daemonname() + ".pid")
end
end
# Put the daemon into the background.
def daemonize
if pid = fork()
Process.detach(pid)
exit(0)
end
# Get rid of console logging
Puppet::Util::Log.close(:console)
Process.setsid
Dir.chdir("/")
begin
$stdin.reopen "/dev/null"
$stdout.reopen "/dev/null", "a"
$stderr.reopen $stdout
Puppet::Util::Log.reopen
rescue => detail
File.open("/tmp/daemonout", "w") { |f|
f.puts "Could not start %s: %s" % [Puppet.execname, detail]
}
Puppet.err "Could not start %s: %s" % [Puppet.execname, detail]
exit(12)
# Remove the pid file
def rmpidfile
threadlock(:pidfile) do
locker = Puppet::Util::Pidlock.new(pidfile)
if locker.locked?
locker.unlock or Puppet.err "Could not remove PID file %s" % [pidfile]
end
end
end
def fqdn
unless defined? @fqdn and @fqdn
hostname = Facter.value("hostname")
domain = Facter.value("domain")
if !domain || domain.empty? then
@fqdn = hostname
else
@fqdn = [hostname, domain].join(".")
end
end
return @fqdn
end
def httplog
args = []
# yuck; separate http logs
file = nil
Puppet.config.use(:puppet, :certificates, Puppet.execname)
if Puppet.execname == "puppetmasterd"
file = Puppet[:masterhttplog]
else
file = Puppet[:httplog]
end
#
# unless FileTest.exists?(File.dirname(file))
# Puppet.recmkdir(File.dirname(file))
# end
args << file
if Puppet[:debug]
args << WEBrick::Log::DEBUG
end
log = WEBrick::Log.new(*args)
return log
end
# Read in an existing certificate.
def readcert
return unless @secureinit
Puppet.config.use(:puppet, :certificates)
# verify we've got all of the certs set up and such
if defined? @cert and defined? @key and @cert and @key
return true
end
unless defined? @fqdn
self.fqdn
end
# we are not going to encrypt our key, but we need at a minimum
# a keyfile and a certfile
#@certfile = File.join(Puppet[:certdir], [@fqdn, "pem"].join("."))
#@cacertfile = File.join(Puppet[:certdir], ["ca", "pem"].join("."))
#@keyfile = File.join(Puppet[:privatekeydir], [@fqdn, "pem"].join("."))
#@publickeyfile = File.join(Puppet[:publickeydir], [@fqdn, "pem"].join("."))
@certfile = Puppet[:hostcert]
@cacertfile = Puppet[:localcacert]
@keyfile = Puppet[:hostprivkey]
@publickeyfile = Puppet[:hostpubkey]
if File.exists?(@keyfile)
# load the key
@key = OpenSSL::PKey::RSA.new(File.read(@keyfile))
else
return false
end
if File.exists?(@certfile)
if File.exists?(@cacertfile)
@cacert = OpenSSL::X509::Certificate.new(File.read(@cacertfile))
else
raise Puppet::Error, "Found cert file with no ca cert file"
end
@cert = OpenSSL::X509::Certificate.new(File.read(@certfile))
else
return false
end
return true
end
# Request a certificate from the remote system. This does all of the work
# of creating the cert request, contacting the remote system, and
# storing the cert locally.
def requestcert
unless @secureinit
raise Puppet::DevError,
"Tried to request cert without initialized security"
end
retrieved = false
Puppet.config.use(:puppet, :certificates)
# create the directories involved
# FIXME it's a stupid hack that i have to do this
# [Puppet[:certdir], Puppet[:privatekeydir], Puppet[:csrdir],
# Puppet[:publickeydir]].each { |dir|
# unless FileTest.exists?(dir)
# Puppet.recmkdir(dir, 0770)
# end
# }
if self.readcert
Puppet.info "Certificate already exists; not requesting"
return true
end
unless defined? @key and @key
# create a new one and store it
Puppet.info "Creating a new SSL key at %s" % @keyfile
@key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
Puppet.config.write(:hostprivkey) do |f| f.print @key.to_pem end
Puppet.config.write(:hostpubkey) do |f|
f.print @key.public_key.to_pem
end
#File.open(@keyfile, "w", 0660) { |f| f.print @key.to_pem }
#File.open(@publickeyfile, "w", 0660) { |f|
# f.print @key.public_key.to_pem
#}
end
unless defined? @driver
Puppet.err "Cannot request a certificate without a defined target"
return false
end
unless defined? @csr
Puppet.info "Creating a new certificate request for %s" % @fqdn
name = OpenSSL::X509::Name.new([["CN", @fqdn]])
@csr = OpenSSL::X509::Request.new
@csr.version = 0
@csr.subject = name
@csr.public_key = @key.public_key
@csr.sign(@key, OpenSSL::Digest::MD5.new)
end
Puppet.info "Requesting certificate"
# We can only request a client with a CA client, so we need
# to create one if we don't already have one (or if we're not a CA
# server).
caclient = nil
if @driver.is_a? Puppet::Network::Client::CA or @driver.is_a? Puppet::Network::Server::CA
caclient = @driver
else
# Create a CA client with which to request the cert.
if @driver.local?
raise Puppet::DevError,
"Incorrect setup for a local CA request"
end
caclient = Puppet::Network::Client::CA.new(
:Port => @driver.puppet_port,
:Server => @driver.puppet_server
)
end
begin
cert, cacert = caclient.getcert(@csr.to_pem)
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
raise Puppet::Error.new("Certificate retrieval failed: %s" %
detail)
end
if cert.nil? or cert == ""
return nil
end
Puppet.config.write(:hostcert) do |f| f.print cert end
Puppet.config.write(:localcacert) do |f| f.print cacert end
#File.open(@certfile, "w", 0644) { |f| f.print cert }
#File.open(@cacertfile, "w", 0644) { |f| f.print cacert }
begin
@cert = OpenSSL::X509::Certificate.new(cert)
@cacert = OpenSSL::X509::Certificate.new(cacert)
retrieved = true
rescue => detail
raise Puppet::Error.new(
"Invalid certificate: %s" % detail
)
end
unless @cert.check_private_key(@key)
raise Puppet::DevError, "Received invalid certificate"
end
return retrieved
end
# Remove the pid file
def rmpidfile
threadlock(:pidfile) do
locker = Puppet::Util::Pidlock.new(pidfile)
if locker.locked?
locker.unlock or Puppet.err "Could not remove PID file %s" % [pidfile]
end
# Create the pid file.
def setpidfile
threadlock(:pidfile) do
unless Puppet::Util::Pidlock.new(pidfile).lock
Puppet.err("Could not create PID file: %s" % [pidfile])
exit(74)
end
end
end
# Create the pid file.
def setpidfile
return unless Puppet[:setpidfile]
threadlock(:pidfile) do
unless Puppet::Util::Pidlock.new(pidfile).lock
Puppet.err("Could not create PID file: %s" % [pidfile])
exit(74)
end
end
# Shut down our server
def shutdown
# Remove our pid file
rmpidfile()
# And close all logs except the console.
Puppet::Util::Log.destinations.reject { |d| d == :console }.each do |dest|
Puppet::Util::Log.close(dest)
end
# Shut down our server
def shutdown
# Remove our pid file
rmpidfile()
# And close all logs except the console.
Puppet::Util::Log.destinations.reject { |d| d == :console }.each do |dest|
Puppet::Util::Log.close(dest)
end
super
end
def start
setpidfile()
super
end
super
end
end

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

@ -68,7 +68,7 @@ module Puppet
def apply
bucket = export()
objects = bucket.to_type
master = Puppet::Network::Client::MasterClient.new :Master => "whatever"
master = Puppet::Network::Client.master.new :Master => "whatever"
master.objects = objects
master.apply

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

@ -12,6 +12,13 @@ module Puppet
]
)
def self.main
unless defined? @main
@main = self.new()
end
@main
end
# Just proxy the setting methods to our rights stuff
[:allow, :deny].each do |method|
define_method(method) do |*args|
@ -19,24 +26,19 @@ module Puppet
end
end
# Here we add a little bit of semantics. They can set auth on a whole namespace
# or on just a single method in the namespace.
def allowed?(name, host, ip)
namespace, method = name.to_s.split(".")
unless namespace and method
raise ArgumentError, "Invalid method name %s" % name
end
name = name.intern if name.is_a? String
namespace = namespace.intern
method = method.intern
# Here we add a little bit of semantics. They can set auth on a whole
# namespace or on just a single method in the namespace.
def allowed?(request)
name = request.call.intern
namespace = request.handler.intern
method = request.method.intern
read()
if @rights.include?(name)
return @rights[name].allowed?(host, ip)
return @rights[name].allowed?(request.name, request.ip)
elsif @rights.include?(namespace)
return @rights[namespace].allowed?(host, ip)
return @rights[namespace].allowed?(request.name, request.ip)
else
return false
end

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

@ -0,0 +1,84 @@
require 'puppet/network/client_request'
require 'puppet/network/authconfig'
module Puppet::Network
# Most of our subclassing is just so that we can get
# access to information from the request object, like
# the client name and IP address.
class InvalidClientRequest < Puppet::Error; end
module Authorization
# Create our config object if necessary. This works even if
# there's no configuration file.
def authconfig
unless defined? @authconfig
@authconfig = Puppet::Network::AuthConfig.main()
end
@authconfig
end
# Verify that our client has access. We allow untrusted access to
# puppetca methods but no others.
def authorized?(request)
msg = "%s client %s access to %s" %
[request.authenticated? ? "authenticated" : "unauthenticated",
request, request.call]
if request.authenticated?
if authconfig.exists?
if authconfig.allowed?(request)
Puppet.debug "Allowing " + msg
return true
else
Puppet.notice "Denying " + msg
return false
end
else
# This is a hack way of seeing if we're a config master.
if Puppet[:name] == "puppetmasterd"
Puppet.debug "Allowing " + msg
return true
else
Puppet.notice "Denying " + msg
return false
end
end
else
if request.handler == "puppetca"
Puppet.notice "Allowing " + msg
else
Puppet.notice "Denying " + msg
return false
end
end
end
# Is this functionality available?
def available?(request)
if handler_loaded?(request.handler)
return true
else
Puppet.warning "Client %s requested unavailable functionality %s" %
[request, request.handler]
return false
end
end
# Make sure that this method is available and authorized.
def verify(request)
unless available?(request)
raise InvalidClientRequest.new(
"Functionality %s not available" % request.handler
)
end
unless authorized?(request)
raise InvalidClientRequest.new(
"Host %s not authorized to call %s" %
[request, request.call]
)
end
end
end
end
# $Id$

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

@ -1,60 +1,73 @@
# the available clients
require 'puppet'
require 'puppet/network/networkclient'
require 'puppet/daemon'
require 'puppet/network/xmlrpc/client'
require 'puppet/util/subclass_loader'
require 'puppet/util/methodhelper'
require 'puppet/sslcertificates/support'
# FIXME this still isn't a good design, because none of the handlers overlap
# so i could just as easily include them all in the main module
# but at least it's better organized for now
require 'net/http'
# Some versions of ruby don't have this method defined, which basically causes
# us to never use ssl. Yay.
class Net::HTTP
def use_ssl?
if defined? @use_ssl
@use_ssl
else
false
end
end
end
# The base class for all of the clients. Many clients just directly
# call methods, but some of them need to do some extra work or
# provide a different interface.
class Puppet::Network::Client
Client = self
include Puppet::Daemon
include Puppet::Util
extend Puppet::Util::SubclassLoader
include Puppet::Util::MethodHelper
# This handles reading in the key and such-like.
include Puppet::SSLCertificates::Support
# FIXME The cert stuff should only come up with networking, so it
# should be in the network client, not the normal client. But if i do
# that, it's hard to tell whether the certs have been initialized.
include Puppet::Daemon
attr_reader :secureinit
attr_accessor :schedule, :lastrun, :local, :stopping
class << self
attr_reader :drivername, :handler
attr_accessor :netclient
# Set up subclass loading
handle_subclasses :client, "puppet/network/client"
# Determine what clients look for when being passed an object for local
# client/server stuff. E.g., you could call Client::CA.new(:CA => ca).
def self.drivername
unless defined? @drivername
@drivername = self.name
end
@drivername
end
def initcerts
unless self.readcert
#if self.is_a? Puppet::Network::Client::CA
unless self.requestcert
return nil
end
#else
# return nil
#end
#unless self.requestcert
#end
# Figure out the handler for our client.
def self.handler
unless defined? @handler
@handler = Puppet::Network::Handler.handler(self.name)
end
# unless we have a driver, we're a local client and we can't add
# certs anyway, so it doesn't matter
unless @driver
return true
end
self.setcerts
@handler
end
# The class that handles xmlrpc interaction for us.
def self.xmlrpc_client
unless defined? @xmlrpc_client
@xmlrpc_client = Puppet::Network::XMLRPCClient.handler_class(self.handler)
end
@xmlrpc_client
end
# Create our client.
def initialize(hash)
# to whom do we connect?
@server = nil
@nil = nil
@secureinit = hash[:NoSecureInit] || true
if hash.include?(:FQDN)
@fqdn = hash[:FQDN]
else
self.fqdn
end
if hash.include?(:Cache)
@cache = hash[:Cache]
@ -64,37 +77,24 @@ class Puppet::Network::Client
driverparam = self.class.drivername
if hash.include?(:Server)
if $noclientnetworking
raise NetworkClientError.new("Networking not available: %s" %
$nonetworking)
end
args = {:Server => hash[:Server]}
args[:Port] = hash[:Port] || Puppet[:masterport]
if self.readcert
args[:Certificate] = @cert
args[:Key] = @key
args[:CAFile] = @cacertfile
@driver = self.class.xmlrpc_client.new(args)
if self.read_cert
@driver.cert_setup(self)
end
netclient = nil
unless netclient = self.class.netclient
unless handler = self.class.handler
raise Puppet::DevError,
"Class %s has no handler defined" % self.class
end
namespace = self.class.handler.interface.prefix
netclient = Puppet::Network::NetworkClient.netclient(namespace)
self.class.netclient = netclient
end
@driver = netclient.new(args)
@local = false
elsif hash.include?(driverparam)
@driver = hash[driverparam]
if @driver == true
@driver = self.class.handler.new
end
@local = true
else
raise ClientError, "%s must be passed a Server or %s" %
raise Puppet::Network::ClientError, "%s must be passed a Server or %s" %
[self.class, driverparam]
end
end
@ -138,12 +138,6 @@ class Puppet::Network::Client
end
end
def setcerts
@driver.cert = @cert
@driver.key = @key
@driver.ca_file = @cacertfile
end
def shutdown
if self.stopping
Puppet.notice "Already in shutdown"
@ -159,7 +153,6 @@ class Puppet::Network::Client
# Start listening for events. We're pretty much just listening for
# timer events here.
def start
setpidfile()
# Create our timer. Puppet will handle observing it and such.
timer = Puppet.newtimer(
:interval => Puppet[:runinterval],
@ -176,15 +169,6 @@ class Puppet::Network::Client
end
require 'puppet/network/client/proxy'
require 'puppet/network/client/ca'
require 'puppet/network/client/dipper'
require 'puppet/network/client/file'
require 'puppet/network/client/log'
require 'puppet/network/client/master'
require 'puppet/network/client/runner'
require 'puppet/network/client/status'
require 'puppet/network/client/reporter'
require 'puppet/network/client/resource'
end
# $Id$

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

@ -1,22 +1,55 @@
require 'puppet/network/client/proxy'
require 'puppet/network/client'
class Puppet::Network::Client::CA < Puppet::Network::Client::ProxyClient
@drivername = :CA
# Request a certificate from the remote system.
class Puppet::Network::Client::CA < Puppet::Network::Client
class InvalidCertificate < Puppet::Error; end
# set up the appropriate interface methods
@handler = Puppet::Network::Server::CA
self.mkmethods
def initialize(options = {})
options = symbolize_options(options)
unless options.include?(:Server) or options.include?(:CA)
options[:Server] = Puppet[:ca_server]
options[:Port] = Puppet[:ca_port]
end
super(options)
end
def initialize(hash = {})
if hash.include?(:CA)
if hash[:CA].is_a? Hash
hash[:CA] = Puppet::Network::Server::CA.new(hash[:CA])
else
hash[:CA] = Puppet::Network::Server::CA.new()
end
# This client is really only able to request certificates for the
# current host. It uses the Puppet.config settings to figure everything out.
def request_cert
Puppet.config.use(:puppet, :certificates)
if cert = read_cert
return cert
end
super(hash)
begin
cert, cacert = @driver.getcert(csr.to_pem)
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
raise Puppet::Error.new("Certificate retrieval failed: %s" % detail)
end
if cert.nil? or cert == ""
return nil
end
Puppet.config.write(:hostcert) do |f| f.print cert end
Puppet.config.write(:localcacert) do |f| f.print cacert end
begin
@cert = OpenSSL::X509::Certificate.new(cert)
@cacert = OpenSSL::X509::Certificate.new(cacert)
rescue => detail
raise InvalidCertificate.new(
"Invalid certificate: %s" % detail
)
end
unless @cert.check_private_key(key)
raise InvalidCertificate, "Certificate does not match private key"
end
return @cert
end
end

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

@ -1,17 +1,14 @@
# The client class for filebuckets.
class Puppet::Network::Client::Dipper < Puppet::Network::Client
@handler = Puppet::Network::Handler.handler(:filebucket)
@drivername = :Bucket
@handler = Puppet::Network::Server::FileBucket
attr_accessor :name
# Create our bucket client
def initialize(hash = {})
if hash.include?(:Path)
bucket = Puppet::Network::Server::FileBucket.new(
:Path => hash[:Path]
)
bucket = self.class.handler.new(:Path => hash[:Path])
hash.delete(:Path)
hash[:Bucket] = bucket
end
@ -24,7 +21,7 @@ class Puppet::Network::Client::Dipper < Puppet::Network::Client
unless FileTest.exists?(file)
raise(BucketError, "File %s does not exist" % file)
end
contents = File.read(file)
contents = ::File.read(file)
unless local?
contents = Base64.encode64(contents)
end
@ -35,7 +32,7 @@ class Puppet::Network::Client::Dipper < Puppet::Network::Client
def restore(file,sum)
restore = true
if FileTest.exists?(file)
cursum = Digest::MD5.hexdigest(File.read(file))
cursum = Digest::MD5.hexdigest(::File.read(file))
# if the checksum has changed...
# this might be extra effort
@ -53,14 +50,14 @@ class Puppet::Network::Client::Dipper < Puppet::Network::Client
newsum = Digest::MD5.hexdigest(newcontents)
changed = nil
unless FileTest.writable?(file)
changed = File.stat(file).mode
File.chmod(changed | 0200, file)
changed = ::File.stat(file).mode
::File.chmod(changed | 0200, file)
end
File.open(file,File::WRONLY|File::TRUNC) { |of|
::File.open(file,::File::WRONLY|::File::TRUNC) { |of|
of.print(newcontents)
}
if changed
File.chmod(changed, file)
::File.chmod(changed, file)
end
else
Puppet.err "Could not find file with checksum %s" % sum

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

@ -1,20 +1,7 @@
class Puppet::Network::Client::FileClient < Puppet::Network::Client::ProxyClient
class Puppet::Network::Client::File < Puppet::Network::Client::ProxyClient
@handler = Puppet::Network::Handler.handler(:fileserver)
@drivername = :FileServer
# set up the appropriate interface methods
@handler = Puppet::Network::Server::FileServer
self.mkmethods
def initialize(hash = {})
if hash.include?(:FileServer)
unless hash[:FileServer].is_a?(Puppet::Network::Server::FileServer)
raise Puppet::DevError, "Must pass an actual FS object"
end
end
super(hash)
end
end
# $Id$

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

@ -1,17 +0,0 @@
class Puppet::Network::Client::LogClient < Puppet::Network::Client::ProxyClient
@drivername = :Logger
# set up the appropriate interface methods
@handler = Puppet::Network::Server::Logger
self.mkmethods
def initialize(hash = {})
if hash.include?(:Logger)
hash[:Logger] = Puppet::Network::Server::Logger.new()
end
super(hash)
end
end
# $Id$

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

@ -0,0 +1,6 @@
class Puppet::Network::Client::Logger < Puppet::Network::Client::ProxyClient
@handler = Puppet::Network::Handler.handler(:logger)
self.mkmethods
end
# $Id$

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

@ -2,84 +2,11 @@
require 'sync'
require 'timeout'
class Puppet::Network::Client::MasterClient < Puppet::Network::Client
class Puppet::Network::Client::Master < Puppet::Network::Client
unless defined? @@sync
@@sync = Sync.new
end
@handler = Puppet::Network::Server::Master
Puppet.setdefaults("puppetd",
:puppetdlockfile => [ "$statedir/puppetdlock",
"A lock file to temporarily stop puppetd from doing anything."],
:usecacheonfailure => [true,
"Whether to use the cached configuration when the remote
configuration will not compile. This option is useful for testing
new configurations, where you want to fix the broken configuration
rather than reverting to a known-good one."
],
:ignorecache => [false,
"Ignore cache and always recompile the configuration. This is
useful for testing new configurations, where the local cache may in
fact be stale even if the timestamps are up to date - if the facts
change or if the server changes."
],
:downcasefacts => [false,
"Whether facts should be made all lowercase when sent to the server."]
)
Puppet.setdefaults(:puppetd,
:configtimeout => [30,
"How long the client should wait for the configuration to be retrieved
before considering it a failure. This can help reduce flapping if too
many clients contact the server at one time."
],
:reportserver => ["$server",
"The server to which to send transaction reports."
],
:report => [false,
"Whether to send reports after every transaction."
]
)
# Plugin information.
Puppet.setdefaults("puppet",
:pluginpath => ["$vardir/plugins",
"Where Puppet should look for plugins. Multiple directories should
be colon-separated, like normal PATH variables."],
:plugindest => ["$vardir/plugins",
"Where Puppet should store plugins that it pulls down from the central
server."],
:pluginsource => ["puppet://$server/plugins",
"From where to retrieve plugins. The standard Puppet ``file`` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:pluginsync => [false,
"Whether plugins should be synced with the central server."],
:pluginsignore => [".svn CVS",
"What files to ignore when pulling down plugins."]
)
# Central fact information.
Puppet.setdefaults("puppet",
:factpath => ["$vardir/facts",
"Where Puppet should look for facts. Multiple directories should
be colon-separated, like normal PATH variables."],
:factdest => ["$vardir/facts",
"Where Puppet should store facts that it pulls down from the central
server."],
:factsource => ["puppet://$server/facts",
"From where to retrieve facts. The standard Puppet ``file`` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:factsync => [false,
"Whether facts should be synced with the central server."],
:factsignore => [".svn CVS",
"What files to ignore when pulling down facts."]
)
@drivername = :Master
attr_accessor :objects
attr_reader :compile_time
@ -160,11 +87,11 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
# Cache the config
def cache(text)
Puppet.info "Caching configuration at %s" % self.cachefile
confdir = File.dirname(Puppet[:localconfig])
File.open(self.cachefile + ".tmp", "w", 0660) { |f|
confdir = ::File.dirname(Puppet[:localconfig])
::File.open(self.cachefile + ".tmp", "w", 0660) { |f|
f.print text
}
File.rename(self.cachefile + ".tmp", self.cachefile)
::File.rename(self.cachefile + ".tmp", self.cachefile)
end
def cachefile
@ -191,7 +118,7 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
end
Puppet.err "Corrupt state file %s: %s" % [Puppet[:statefile], detail]
begin
File.unlink(Puppet[:statefile])
::File.unlink(Puppet[:statefile])
retry
rescue => detail
raise Puppet::Error.new("Cannot remove %s: %s" %
@ -336,7 +263,7 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
# Retrieve the cached config
def retrievecache
if FileTest.exists?(self.cachefile)
return File.read(self.cachefile)
return ::File.read(self.cachefile)
else
return ""
end
@ -395,7 +322,7 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
return
end
begin
File.open(Puppet[:classfile], "w") { |f|
::File.open(Puppet[:classfile], "w") { |f|
f.puts ary.join("\n")
}
rescue => detail
@ -467,7 +394,7 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
download(:dest => Puppet[:factdest], :source => Puppet[:factsource],
:ignore => Puppet[:factsignore], :name => "fact") do |object|
next unless path.include?(File.dirname(object[:path]))
next unless path.include?(::File.dirname(object[:path]))
files << object[:path]
@ -495,11 +422,11 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
download(:dest => Puppet[:plugindest], :source => Puppet[:pluginsource],
:ignore => Puppet[:pluginsignore], :name => "plugin") do |object|
next unless path.include?(File.dirname(object[:path]))
next unless path.include?(::File.dirname(object[:path]))
begin
Puppet.info "Reloading plugin %s" %
File.basename(File.basename(object[:path])).sub(".rb",'')
::File.basename(::File.basename(object[:path])).sub(".rb",'')
load object[:path]
rescue => detail
Puppet.warning "Could not reload plugin %s: %s" %
@ -512,9 +439,9 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
return unless FileTest.directory?(dir)
Dir.entries(dir).find_all { |e| e =~ /\.rb$/ }.each do |file|
fqfile = File.join(dir, file)
fqfile = ::File.join(dir, file)
begin
Puppet.info "Loading #{type} %s" % File.basename(file.sub(".rb",''))
Puppet.info "Loading #{type} %s" % ::File.basename(file.sub(".rb",''))
Timeout::timeout(self.timeout) do
load fqfile
end
@ -560,7 +487,7 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
def reportclient
unless defined? @reportclient
@reportclient = Puppet::Network::Client::Reporter.new(
@reportclient = Puppet::Network::Client.report.new(
:Server => Puppet[:reportserver]
)
end
@ -572,7 +499,8 @@ class Puppet::Network::Client::MasterClient < Puppet::Network::Client
private
# Actually retrieve the configuration, either from the server or from a local master.
# Actually retrieve the configuration, either from the server or from a
# local master.
def get_actual_config(facts)
if @local
return get_local_config(facts)

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

@ -3,7 +3,7 @@
# and that's about it
class Puppet::Network::Client::ProxyClient < Puppet::Network::Client
def self.mkmethods
interface = @handler.interface
interface = self.handler.interface
namespace = interface.prefix

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

@ -1,12 +1,9 @@
class Puppet::Network::Client::Reporter < Puppet::Network::Client
@drivername = :Report
# set up the appropriate interface methods
@handler = Puppet::Network::Server::Report
class Puppet::Network::Client::Report < Puppet::Network::Client
@handler = Puppet::Network::Handler.handler(:report)
def initialize(hash = {})
if hash.include?(:Report)
hash[:Report] = Puppet::Network::Server::Report.new()
hash[:Report] = self.class.handler.new
end
super(hash)

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

@ -1,10 +1,7 @@
# The client for interacting with remote Puppet agents to query and modify
# remote system state.
class Puppet::Network::Client::Resource < Puppet::Network::Client
@drivername = :ResourceServer
@handler = Puppet::Network::Server::Resource
def apply(bucket)
case bucket
when Puppet::TransObject
tmp = Puppet::TransBucket.new
@ -41,16 +38,6 @@ class Puppet::Network::Client::Resource < Puppet::Network::Client
return object
end
def initialize(hash = {})
if hash.include?(:ResourceServer)
unless hash[:ResourceServer].is_a?(Puppet::Network::Server::Resource)
raise Puppet::DevError, "Must pass an actual PElement server object"
end
end
super(hash)
end
def list(type, ignore = false, base = false)
bucket = @driver.list(type, ignore, base, "yaml")

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

@ -1,13 +1,9 @@
class Puppet::Network::Client::Runner < Puppet::Network::Client::ProxyClient
@drivername = :Runner
# set up the appropriate interface methods
@handler = Puppet::Network::Server::Runner
self.mkmethods
def initialize(hash = {})
if hash.include?(:Runner)
hash[:Runner] = Puppet::Network::Server::Runner.new()
hash[:Runner] = self.class.handler.new()
end
super(hash)

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

@ -1,6 +1,4 @@
class Puppet::Network::Client::StatusClient < Puppet::Network::Client::ProxyClient
# set up the appropriate interface methods
@handler = Puppet::Network::Server::ServerStatus
class Puppet::Network::Client::Status < Puppet::Network::Client::ProxyClient
self.mkmethods
end

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

@ -0,0 +1,32 @@
module Puppet::Network # :nodoc:
# A struct-like class for passing around a client request. It's mostly
# just used for validation and authorization.
class ClientRequest
attr_accessor :name, :ip, :authenticated, :handler, :method
def authenticated?
self.authenticated
end
# A common way of talking about the full call. Individual servers
# are responsible for setting the values correctly, but this common
# format makes it possible to check rights.
def call
unless handler and method
raise ArgumentError, "Request is not set up; cannot build call"
end
[handler, method].join(".")
end
def initialize(name, ip, authenticated)
@name, @ip, @authenticated = name, ip, authenticated
end
def to_s
"%s(%s)" % [self.name, self.ip]
end
end
end
# $Id$

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

@ -0,0 +1,33 @@
require 'puppet/util/subclass_loader'
module Puppet::Network
# The base class for the different handlers. The handlers are each responsible
# for separate xmlrpc namespaces.
class Handler
# This is so that the handlers can subclass just 'Handler', rather
# then having to specify the full class path.
Handler = self
attr_accessor :server
extend Puppet::Util::SubclassLoader
extend Puppet::Util
handle_subclasses :handler, "puppet/network/handler"
# Return the xmlrpc interface.
def self.interface
if defined? @interface
return @interface
else
raise Puppet::DevError, "Handler %s has no defined interface" %
self
end
end
# Create an empty init method with the same signature.
def initialize(hash = {})
end
end
end
# $Id$

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

@ -6,7 +6,7 @@ require 'xmlrpc/server'
# Much of this was taken from QuickCert:
# http://segment7.net/projects/ruby/QuickCert/
class Puppet::Network::Server
class Puppet::Network::Handler
class CA < Handler
attr_reader :ca

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

@ -9,26 +9,9 @@ require 'facter'
require 'digest/md5'
require 'puppet/external/base64'
class Puppet::Network::Server
class Puppet::Network::Handler
class BucketError < RuntimeError; end
class FileBucket < Handler
Puppet.config.setdefaults("puppetmasterd",
:bucketdir => {
:default => "$vardir/bucket",
:mode => 0750,
:owner => "$user",
:group => "$group",
:desc => "Where FileBucket files are stored."
}
)
Puppet.config.setdefaults("filebucket",
:clientbucketdir => {
:default => "$vardir/clientbucket",
:mode => 0750,
:desc => "Where FileBucket files are stored locally."
}
)
@interface = XMLRPC::Service::Interface.new("puppetbucket") { |iface|
iface.add_method("string addfile(string, string)")
iface.add_method("string getfile(string)")
@ -38,7 +21,7 @@ class Puppet::Network::Server
attr_reader :name, :path
# this doesn't work for relative paths
def FileBucket.paths(base,md5)
def self.paths(base,md5)
return [
File.join(base, md5),
File.join(base, md5, "contents"),

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

@ -1,17 +1,14 @@
require 'puppet'
require 'puppet/network/authstore'
require 'webrick/httpstatus'
require 'cgi'
require 'delegate'
class Puppet::Network::Server
class Puppet::Network::Handler
class FileServerError < Puppet::Error; end
class FileServer < Handler
attr_accessor :local
Puppet.setdefaults("fileserver",
:fileserverconfig => ["$confdir/fileserver.conf",
"Where the fileserver configuration is stored."])
CHECKPARAMS = [:mode, :type, :owner, :group, :checksum]
@interface = XMLRPC::Service::Interface.new("fileserver") { |iface|
@ -20,13 +17,17 @@ class Puppet::Network::Server
iface.add_method("string retrieve(string, string)")
}
def self.params
CHECKPARAMS.dup
end
# Describe a given file. This returns all of the manageable aspects
# of that file.
def describe(url, links = :ignore, client = nil, clientip = nil)
links = links.intern if links.is_a? String
if links == :manage
raise Puppet::Network::Server::FileServerError, "Cannot currently copy links"
raise Puppet::Network::Handler::FileServerError, "Cannot currently copy links"
end
mount, path = convert(url, client, clientip)

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

@ -1,6 +1,6 @@
require 'yaml'
class Puppet::Network::Server
class Puppet::Network::Handler
class LoggerError < RuntimeError; end
# Receive logs from remote hosts.

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

@ -5,7 +5,7 @@ require 'puppet/sslcertificates'
require 'xmlrpc/server'
require 'yaml'
class Puppet::Network::Server
class Puppet::Network::Handler
class MasterError < Puppet::Error; end
class Master < Handler
include Puppet::Util
@ -24,7 +24,7 @@ class Puppet::Network::Server
facts["serverversion"] = Puppet.version.to_s
# And then add the server name and IP
{"servername" => "fqdn",
{"servername" => "hostname",
"serverip" => "ipaddress"
}.each do |var, fact|
if obj = Facter[fact]
@ -55,6 +55,8 @@ class Puppet::Network::Server
# Tell a client whether there's a fresh config for it
def freshness(client = nil, clientip = nil)
if Puppet.features.rails? and Puppet[:storeconfigs]
Puppet::Rails.connect
host = Puppet::Rails::Host.find_or_create_by_name(client)
host.last_freshcheck = Time.now
if clientip and (! host.ip or host.ip == "")

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

@ -1,9 +1,7 @@
# A simple server for triggering a new run on a Puppet client.
class Puppet::Network::Server
class Puppet::Network::Handler
class Report < Handler
class << self
include Puppet::Util::ClassGen
end
extend Puppet::Util::ClassGen
module ReportBase
include Puppet::Util::Docs
@ -22,21 +20,6 @@ class Puppet::Network::Server
iface.add_method("string report(array)")
}
Puppet.setdefaults(:reporting,
:reports => ["store",
"The list of reports to generate. All reports are looked for
in puppet/reports/<name>.rb, and multiple report names should be
comma-separated (whitespace is okay)."
],
:reportdir => {:default => "$vardir/reports",
:mode => 0750,
:owner => "$user",
:group => "$group",
:desc => "The directory in which to store reports
received from the client. Each client gets a separate
subdirectory."}
)
@reports = {}
@reportloader = Puppet::Util::Autoload.new(self, "puppet/reports")
@ -78,6 +61,7 @@ class Puppet::Network::Server
@reports[symbolize(name)]
end
# Collect the docs for all of our reports.
def self.reportdocs
docs = ""
@ -92,6 +76,7 @@ class Puppet::Network::Server
docs
end
# List each of the reports.
def self.reports
@reportloader.loadall
@reports.keys
@ -110,16 +95,15 @@ class Puppet::Network::Server
report = CGI.unescape(report)
end
Puppet.info "Processing reports %s for %s" % [reports().join(", "), client]
begin
process(report)
rescue => detail
Puppet.err "Could not process report %s: %s" % [$1, detail]
Puppet.err "Could not process report for %s: %s" % [client, detail]
if Puppet[:trace]
puts detail.backtrace
end
end
update_timestamp(client)
end
private
@ -141,8 +125,6 @@ class Puppet::Network::Server
reports().each do |name|
if mod = self.class.report(name)
Puppet.info "Processing report %s for %s" % [name, client]
# We have to use a dup because we're including a module in the
# report.
newrep = report.dup
@ -170,17 +152,6 @@ class Puppet::Network::Server
def reports
Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
end
def update_timestamp(client)
return unless Puppet[:storeconfigs]
if host = Puppet::Rails::Host.find_by_name(client)
host.last_report = Time.now
host.save
else
Puppet.warning "Could not find Rails host for %s" % client
end
end
end
end

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

@ -1,8 +1,8 @@
require 'puppet'
require 'puppet/network/server'
require 'puppet/network/handler'
# Serve Puppet elements. Useful for querying, copying, and, um, other stuff.
class Puppet::Network::Server
class Puppet::Network::Handler
class Resource < Handler
attr_accessor :local
@ -31,7 +31,7 @@ class Puppet::Network::Server
# Create a client, but specify the remote machine as the server
# because the class requires it, even though it's unused
client = Puppet::Network::Client::MasterClient.new(:Server => client||"localhost")
client = Puppet::Network::Client.client(:Master).new(:Server => client||"localhost")
# Set the objects
client.objects = component

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

@ -1,4 +1,4 @@
class Puppet::Network::Server
class Puppet::Network::Handler
class MissingMasterError < RuntimeError; end # Cannot find the master client
# A simple server for triggering a new run on a Puppet client.
class Runner < Handler
@ -10,7 +10,7 @@ class Puppet::Network::Server
# tags and whether to ignore schedules
def run(tags = nil, ignoreschedules = false, fg = true, client = nil, clientip = nil)
# We need to retrieve the client
master = Puppet::Network::Client::MasterClient.instance
master = Puppet::Network::Client.client(:Master).instance
unless master
raise MissingMasterError, "Could not find the master client"

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

@ -0,0 +1,13 @@
class Puppet::Network::Handler
class Status < Handler
@interface = XMLRPC::Service::Interface.new("status") { |iface|
iface.add_method("int status()")
}
def status(client = nil, clientip = nil)
return 1
end
end
end
# $Id$

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

@ -1,167 +0,0 @@
require 'puppet/sslcertificates'
require 'openssl'
require 'puppet/daemon'
require 'puppet/network/server'
require 'puppet/external/base64'
require 'webrick'
require 'cgi'
require 'xmlrpc/client'
require 'xmlrpc/server'
require 'yaml'
module Puppet
module Network
class ClientError < Puppet::Error; end
class NetworkClientError < Puppet::Error; end
class NetworkClient < XMLRPC::Client
attr_accessor :puppet_server, :puppet_port
@clients = {}
class << self
include Puppet::Util
include Puppet::Util::ClassGen
end
# Create a netclient for each handler
def self.mkclients
# add the methods associated with each namespace
Puppet::Network::Server::Handler.each { |handler|
interface = handler.interface
namespace = interface.prefix
# Create a subclass for every client type. This is
# so that all of the methods are on their own class,
# so that they namespaces can define the same methods if
# they want.
constant = handler.to_s.sub(/^.+::/, '')
name = namespace.downcase
newclient = genclass(name, :hash => @clients,
:constant => constant)
interface.methods.each { |ary|
method = ary[0]
if public_method_defined?(method)
raise Puppet::DevError, "Method %s is already defined" %
method
end
newclient.send(:define_method,method) { |*args|
Puppet.debug "Calling %s.%s" % [namespace, method]
#Puppet.info "peer cert is %s" % @http.peer_cert
#Puppet.info "cert is %s" % @http.cert
begin
call("%s.%s" % [namespace, method.to_s],*args)
rescue OpenSSL::SSL::SSLError => detail
raise NetworkClientError,
"Certificates were not trusted: %s" % detail
rescue XMLRPC::FaultException => detail
#Puppet.err "Could not call %s.%s: %s" %
# [namespace, method, detail.faultString]
#raise NetworkClientError,
# "XMLRPC Error: %s" % detail.faultString
raise NetworkClientError, detail.faultString
rescue Errno::ECONNREFUSED => detail
msg = "Could not connect to %s on port %s" %
[@host, @port]
raise NetworkClientError, msg
rescue SocketError => detail
error = NetworkClientError.new(
"Could not find server %s" % @puppetserver
)
error.set_backtrace detail.backtrace
raise error
rescue => detail
Puppet.err "Could not call %s.%s: %s" %
[namespace, method, detail.inspect]
error = NetworkClientError.new(detail.to_s)
error.set_backtrace detail.backtrace
raise error
end
}
}
}
end
def self.netclient(namespace)
if @clients.empty?
self.mkclients()
end
namespace = symbolize(namespace)
@clients[namespace]
end
def ca_file=(cafile)
@http.ca_file = cafile
store = OpenSSL::X509::Store.new
store.add_file(cafile)
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
@http.cert_store = store
end
def cert=(cert)
#Puppet.debug "Adding certificate"
@http.cert = cert
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
end
def key=(key)
@http.key = key
end
def initialize(hash)
hash[:Path] ||= "/RPC2"
hash[:Server] ||= "localhost"
hash[:Port] ||= Puppet[:masterport]
@puppet_server = hash[:Server]
@puppet_port = hash[:Port]
@puppetserver = hash[:Server]
super(
hash[:Server],
hash[:Path],
hash[:Port],
nil, # proxy_host
nil, # proxy_port
nil, # user
nil, # password
true, # use_ssl
120 # a two minute timeout, instead of 30 seconds
)
if hash[:Certificate]
self.cert = hash[:Certificate]
else
unless defined? $nocertwarned
Puppet.err "No certificate; running with reduced functionality."
$nocertwarned = true
end
end
if hash[:Key]
self.key = hash[:Key]
end
if hash[:CAFile]
self.ca_file = hash[:CAFile]
end
# from here, i need to add the key, cert, and ca cert
# and reorgize how i start the client
end
def local
false
end
def local?
false
end
end
end
end
# $Id$

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

@ -1,208 +1,5 @@
# the server
#
# allow things to connect to us and communicate, and stuff
require 'puppet'
require 'puppet/daemon'
require 'webrick'
require 'webrick/https'
require 'cgi'
require 'xmlrpc/server'
require 'xmlrpc/client'
module Puppet
class ServerError < RuntimeError; end
module Network
class Server < WEBrick::HTTPServer
include Puppet::Daemon
Puppet.config.setdefaults(:puppetd,
:listen => [false, "Whether puppetd should listen for
connections. If this is true, then by default only the
``runner`` server is started, which allows remote authorized
and authenticated nodes to connect and trigger ``puppetd``
runs."]
)
# Create our config object if necessary. This works even if
# there's no configuration file.
def authconfig
unless defined? @authconfig
@authconfig = Puppet::Network::AuthConfig.new()
end
@authconfig
end
# Read the CA cert and CRL and populate an OpenSSL::X509::Store
# with them, with flags appropriate for checking client
# certificates for revocation
def x509store
if Puppet[:cacrl] == 'none'
# No CRL, no store needed
return nil
end
unless File.exist?(Puppet[:cacrl])
raise Puppet::Error, "Could not find CRL"
end
crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
store = OpenSSL::X509::Store.new
store.purpose = OpenSSL::X509::PURPOSE_ANY
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
store.add_file(@cacertfile)
store.add_crl(crl)
return store
end
def initialize(hash = {})
Puppet.info "Starting server for Puppet version %s" % Puppet.version
daemonize = nil
if hash.include?(:Daemonize)
daemonize = hash[:Daemonize]
end
# FIXME we should have some kind of access control here, using
# :RequestHandler
hash[:Port] ||= Puppet[:masterport]
hash[:Logger] ||= self.httplog
hash[:AccessLog] ||= [
[ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
[ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
]
if hash.include?(:Handlers)
unless hash[:Handlers].is_a?(Hash)
raise ServerError, "Handlers must have arguments"
end
@handlers = hash[:Handlers].collect { |handler, args|
hclass = nil
unless hclass = Handler.handler(handler)
raise ServerError, "Invalid handler %s" % handler
end
hclass.new(args)
}
else
raise ServerError, "A server must have handlers"
end
# okay, i need to retrieve my cert and set it up, somehow
# the default case will be that i'm also the ca
if ca = @handlers.find { |handler| handler.is_a?(Puppet::Network::Server::CA) }
@driver = ca
@secureinit = true
self.fqdn
else
if hash.include?(:NoSecureInit)
@secureinit = false
else
@secureinit = true
end
end
unless self.readcert
unless self.requestcert
raise Puppet::Error, "Cannot start without certificates"
end
end
hash[:SSLCertificateStore] = x509store
hash[:SSLCertificate] = @cert
hash[:SSLPrivateKey] = @key
hash[:SSLStartImmediately] = true
hash[:SSLEnable] = true
hash[:SSLCACertificateFile] = @cacertfile
hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
hash[:SSLCertName] = nil
super(hash)
Puppet.info "Listening on port %s" % hash[:Port]
# this creates a new servlet for every connection,
# but all servlets have the same list of handlers
# thus, the servlets can have their own state -- passing
# around the requests and such -- but the handlers
# have a global state
# mount has to be called after the server is initialized
self.mount("/RPC2", Puppet::Network::Server::Servlet, @handlers)
end
# the base class for the different handlers
class Handler
attr_accessor :server
class << self
include Puppet::Util
end
@subclasses = []
def self.each
@subclasses.each { |c| yield c }
end
def self.handler(name)
name = name.to_s.downcase
@subclasses.find { |h|
h.name.to_s.downcase == name
}
end
def self.inherited(sub)
@subclasses << sub
end
def self.interface
if defined? @interface
return @interface
else
raise Puppet::DevError, "Handler %s has no defined interface" %
self
end
end
def self.name
unless defined? @name
@name = self.to_s.sub(/.+::/, '').intern
end
return @name
end
def initialize(hash = {})
end
end
class ServerStatus < Handler
@interface = XMLRPC::Service::Interface.new("status") { |iface|
iface.add_method("int status()")
}
@name = :Status
def status(status = nil, client = nil, clientip = nil)
return 1
end
end
end
end
# Just a stub, so we can correctly scope other classes.
module Puppet::Network::Server # :nodoc:
end
require 'puppet/network/authstore'
require 'puppet/network/authconfig'
require 'puppet/network/rights'
require 'puppet/network/server/servlet'
require 'puppet/network/server/master'
require 'puppet/network/server/ca'
require 'puppet/network/server/fileserver'
require 'puppet/network/server/filebucket'
require 'puppet/network/server/resource'
require 'puppet/network/server/runner'
require 'puppet/network/server/logger'
require 'puppet/network/server/report'
require 'puppet/network/client'
# $Id$

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

@ -0,0 +1,138 @@
#!/usr/bin/env ruby
# File: 06-11-14-mongrel_xmlrpc.rb
# Author: Manuel Holtgrewe <purestorm at ggnore.net>
#
# Copyright (c) 2006 Manuel Holtgrewe, 2007 Luke Kanies
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This file is based heavily on a file retrieved from
# http://ttt.ggnore.net/2006/11/15/xmlrpc-with-mongrel-and-ruby-off-rails/
require 'rubygems'
require 'mongrel'
require 'xmlrpc/server'
require 'puppet/network/server'
require 'puppet/network/xmlrpc/server'
require 'puppet/network/client_request'
require 'resolv'
# This handler can be hooked into Mongrel to accept HTTP requests. After
# checking whether the request itself is sane, the handler forwards it
# to an internal instance of XMLRPC::BasicServer to process it.
#
# You can access the server by calling the Handler's "xmlrpc_server"
# attribute accessor method and add XMLRPC handlers there. For example:
#
# <pre>
# handler = XmlRpcHandler.new
# handler.xmlrpc_server.add_handler("my.add") { |a, b| a.to_i + b.to_i }
# </pre>
class Puppet::Network::Server
class MongrelHandler < Mongrel::HttpHandler
attr_reader :xmlrpc_server
def initialize(handlers)
# Create a new instance of BasicServer. We are supposed to subclass it
# but that does not make sense since we would not introduce any new
# behaviour and we have to subclass Mongrel::HttpHandler so our handler
# works for Mongrel.
@xmlrpc_server = Puppet::Network::XMLRPCServer.new
handlers.each do |name, args|
unless handler = Puppet::Network::Handler.handler(name)
raise ArgumentError, "Invalid handler %s" % name
end
@xmlrpc_server.add_handler(handler.interface, handler.new(args))
end
end
# This method produces the same results as XMLRPC::CGIServer.serve
# from Ruby's stdlib XMLRPC implementation.
def process(request, response)
# Make sure this has been a POST as required for XMLRPC.
request_method = request.params[Mongrel::Const::REQUEST_METHOD] || Mongrel::Const::GET
if request_method != "POST" then
response.start(405) { |head, out| out.write("Method Not Allowed") }
return
end
# Make sure the user has sent text/xml data.
request_mime = request.params["CONTENT_TYPE"] || "text/plain"
if parse_content_type(request_mime).first != "text/xml" then
response.start(400) { |head, out| out.write("Bad Request") }
return
end
# Make sure there is data in the body at all.
length = request.params[Mongrel::Const::CONTENT_LENGTH].to_i
if length <= 0 then
response.start(411) { |head, out| out.write("Length Required") }
return
end
# Check the body to be valid.
if request.body.nil? or request.body.size != length then
response.start(400) { |head, out| out.write("Bad Request") }
return
end
info = client_info(request)
# All checks above passed through
response.start(200) do |head, out|
head["Content-Type"] = "text/xml; charset=utf-8"
begin
out.write(@xmlrpc_server.process(request.body, info))
rescue => detail
puts detail.backtrace
raise
end
end
end
private
def client_info(request)
params = request.params
ip = params["REMOTE_ADDR"]
if dn = params["HTTP_X_CLIENT_DN"]
client = dn.sub("/CN=", '')
valid = true
else
client = Resolv.getname(ip)
valid = false
end
info = Puppet::Network::ClientRequest.new(client, ip, valid)
return info
end
# Taken from XMLRPC::ParseContentType
def parse_content_type(str)
a, *b = str.split(";")
return a.strip, *b
end
end
end
# $Id$

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

@ -1,277 +0,0 @@
require 'xmlrpc/server'
class Puppet::Network::Server
class ServletError < RuntimeError; end
class Servlet < XMLRPC::WEBrickServlet
ERR_UNAUTHORIZED = 30
attr_accessor :request
# this is just a duplicate of the normal method; it's here for
# debugging when i need it
def self.get_instance(server, *options)
self.new(server, *options)
end
# This is a hackish way to avoid an auth message every time we have a
# normal operation
def self.log(msg)
unless defined? @logs
@logs = {}
end
if @logs.include?(msg)
@logs[msg] += 1
else
Puppet.info msg
@logs[msg] = 1
end
end
def add_handler(interface, handler)
@loadedhandlers << interface.prefix
super
end
# Verify that our client has access. We allow untrusted access to
# puppetca methods but no others.
def authorize(request, method)
namespace = method.sub(/\..+/, '')
client = request.peeraddr[2]
if defined? @client and @client
client = @client
end
ip = request.peeraddr[3]
if request.client_cert
if @puppetserver.authconfig.exists?
allowed = @puppetserver.authconfig.allowed?(method, client, ip)
if allowed
Puppet.debug "Allowing %s(%s) trusted access to %s" %
[client, ip, method]
return true
else
Puppet.debug "Denying %s(%s) trusted access to %s" %
[client, ip, method]
return false
end
else
# This is pretty hackish, but...
# This means we can't actually test this method at this point.
# The next release of Puppet will almost definitely require
# this file to exist or will default to denying all access.
if Puppet.execname == "puppetmasterd" or defined? Test::Unit::TestCase
Puppet.debug "Allowing %s(%s) trusted access to %s" %
[client, ip, method]
return true
else
Puppet.debug "Denying %s(%s) trusted access to %s on %s" %
[client, ip, method, Puppet.execname]
return false
end
end
else
if method =~ /^puppetca\./
Puppet.notice "Allowing %s(%s) untrusted access to CA methods" %
[client, ip]
else
Puppet.err "Unauthenticated client %s(%s) cannot call %s" %
[client, ip, method]
return false
end
end
end
def available?(method)
namespace = method.sub(/\..+/, '')
client = request.peeraddr[2]
ip = request.peeraddr[3]
if @loadedhandlers.include?(namespace)
return true
else
Puppet.warning "Client %s(%s) requested unavailable functionality %s" %
[client, ip, namespace]
return false
end
end
def initialize(server, handlers)
@puppetserver = server
@notified = {}
# the servlet base class does not consume any arguments
# and its BasicServer base class only accepts a 'class_delim'
# option which won't change in Puppet at all
# thus, we don't need to pass any args to our base class,
# and we can consume them all ourselves
super()
@loadedhandlers = []
handlers.each { |handler|
#Puppet.debug "adding handler for %s" % handler.class
self.add_handler(handler.class.interface, handler)
}
# Initialize these to nil, but they will get set to values
# by the 'service' method. These have to instance variables
# because I don't have a clear line from the service method to
# the service hook.
@request = nil
@client = nil
@clientip = nil
self.set_service_hook { |obj, *args|
if @client and @clientip
args.push(@client, @clientip)
end
begin
obj.call(*args)
rescue XMLRPC::FaultException
raise
rescue Puppet::AuthorizationError => detail
#Puppet.warning obj.inspect
#Puppet.warning args.inspect
Puppet.err "Permission denied: %s" % detail.to_s
raise XMLRPC::FaultException.new(
1, detail.to_s
)
rescue Puppet::Error => detail
#Puppet.warning obj.inspect
#Puppet.warning args.inspect
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err detail.to_s
error = XMLRPC::FaultException.new(
1, detail.to_s
)
error.set_backtrace detail.backtrace
raise error
rescue => detail
#Puppet.warning obj.inspect
#Puppet.warning args.inspect
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err "Could not call: %s" % detail.to_s
error = XMLRPC::FaultException.new(1, detail.to_s)
error.set_backtrace detail.backtrace
raise error
end
}
end
# Handle the actual request. This does some basic collection of
# data, and then just calls the parent method.
def service(request, response)
@request = request
# The only way that @client can be nil is if the request is local.
if peer = request.peeraddr
@client = peer[2]
@clientip = peer[3]
else
raise XMLRPC::FaultException.new(
ERR_UNCAUGHT_EXCEPTION,
"Could not retrieve client information"
)
end
# If they have a certificate (which will almost always be true)
# then we get the hostname from the cert, instead of via IP
# info
if cert = request.client_cert
nameary = cert.subject.to_a.find { |ary|
ary[0] == "CN"
}
if nameary.nil?
Puppet.warning "Could not retrieve server name from cert"
else
unless @client == nameary[1]
Puppet.debug "Overriding %s with cert name %s" %
[@client, nameary[1]]
@client = nameary[1]
end
end
end
begin
super
rescue => detail
Puppet.err "Could not service request: %s: %s" %
[detail.class, detail]
end
@client = nil
@clientip = nil
@request = nil
end
private
# this is pretty much just a copy of the original method but with more
# feedback
# here's where we have our authorization hooks
def dispatch(methodname, *args)
if defined? @request and @request
unless self.available?(methodname)
raise XMLRPC::FaultException.new(
ERR_UNAUTHORIZED,
"Functionality %s not available" %
methodname.sub(/\..+/, '')
)
end
unless self.authorize(@request, methodname)
raise XMLRPC::FaultException.new(
ERR_UNAUTHORIZED,
"Host %s not authorized to call %s" %
[@request.host, methodname]
)
end
else
raise Puppet::DevError, "Did not get request in dispatch"
end
#Puppet.warning "dispatch on %s called with %s" %
# [methodname, args.inspect]
for name, obj in @handler
if obj.kind_of? Proc
unless methodname == name
#Puppet.debug "obj is proc but %s != %s" %
# [methodname, name]
next
end
else
unless methodname =~ /^#{name}(.+)$/
#Puppet.debug "methodname did not match"
next
end
unless obj.respond_to? $1
#Puppet.debug "methodname does not respond to %s" % $1
next
end
obj = obj.method($1)
end
if check_arity(obj, args.size)
if @service_hook.nil?
return obj.call(*args)
else
return @service_hook.call(obj, *args)
end
else
Puppet.debug "arity is incorrect"
end
end
if @default_handler.nil?
raise XMLRPC::FaultException.new(
ERR_METHOD_MISSING,
"Method #{methodname} missing or wrong number of parameters!"
)
else
@default_handler.call(methodname, *args)
end
end
end
end
# $Id$

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

@ -0,0 +1,153 @@
require 'puppet'
require 'puppet/daemon'
require 'webrick'
require 'webrick/https'
require 'puppet/sslcertificates/support'
require 'puppet/network/xmlrpc/webrick_servlet'
require 'puppet/network/server'
require 'puppet/network/client'
module Puppet
class ServerError < RuntimeError; end
module Network
# The old-school, pure ruby webrick server, which is the default serving
# mechanism.
class Server::WEBrick < WEBrick::HTTPServer
include Puppet::Daemon
include Puppet::SSLCertificates::Support
# Read the CA cert and CRL and populate an OpenSSL::X509::Store
# with them, with flags appropriate for checking client
# certificates for revocation
def x509store
if Puppet[:cacrl] == 'none'
# No CRL, no store needed
return nil
end
unless File.exist?(Puppet[:cacrl])
raise Puppet::Error, "Could not find CRL"
end
crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
store = OpenSSL::X509::Store.new
store.purpose = OpenSSL::X509::PURPOSE_ANY
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
unless self.ca_cert
raise Puppet::Error, "No CA certificate"
end
store.add_file(Puppet[:localcacert])
store.add_crl(crl)
return store
end
# Set up the http log.
def httplog
args = []
# yuck; separate http logs
file = nil
Puppet.config.use(:puppet, :certificates, Puppet.name)
if Puppet[:name] == "puppetmasterd"
file = Puppet[:masterhttplog]
else
file = Puppet[:httplog]
end
args << file
if Puppet[:debug]
args << WEBrick::Log::DEBUG
end
log = WEBrick::Log.new(*args)
return log
end
# Create our server, yo.
def initialize(hash = {})
Puppet.info "Starting server for Puppet version %s" % Puppet.version
if handlers = hash[:Handlers]
handler_instances = setup_handlers(handlers)
else
raise ServerError, "A server must have handlers"
end
unless self.read_cert
if ca = handler_instances.find { |handler| handler.is_a?(Puppet::Network::Handler.ca) }
request_cert(ca)
else
raise Puppet::Error, "No certificate and no CA; cannot get cert"
end
end
setup_webrick(hash)
super(hash)
Puppet.info "Listening on port %s" % hash[:Port]
# this creates a new servlet for every connection,
# but all servlets have the same list of handlers
# thus, the servlets can have their own state -- passing
# around the requests and such -- but the handlers
# have a global state
# mount has to be called after the server is initialized
servlet = Puppet::Network::XMLRPC::WEBrickServlet.new(
handler_instances)
self.mount("/RPC2", servlet)
end
# Create a ca client to set up our cert for us.
def request_cert(ca)
client = Puppet::Network::Client.ca.new(:CA => ca)
unless client.request_cert
raise Puppet::Error, "Could get certificate"
end
end
# Create all of our handler instances.
def setup_handlers(handlers)
unless handlers.is_a?(Hash)
raise ServerError, "Handlers must have arguments"
end
handlers.collect { |handler, args|
hclass = nil
unless hclass = Handler.handler(handler)
raise ServerError, "Invalid handler %s" % handler
end
hclass.new(args)
}
end
# Handle all of the many webrick arguments.
def setup_webrick(hash)
hash[:Port] ||= Puppet[:masterport]
hash[:Logger] ||= self.httplog
hash[:AccessLog] ||= [
[ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
[ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
]
hash[:SSLCertificateStore] = x509store
hash[:SSLCertificate] = self.cert
hash[:SSLPrivateKey] = self.key
hash[:SSLStartImmediately] = true
hash[:SSLEnable] = true
hash[:SSLCACertificateFile] = Puppet[:localcacert]
hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
hash[:SSLCertName] = nil
if addr = Puppet[:bindaddress] and addr != ""
hash[:BindAddress] = addr
end
end
end
end
end
# $Id$

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

@ -0,0 +1,129 @@
require 'puppet/sslcertificates'
require 'openssl'
require 'puppet/external/base64'
require 'xmlrpc/client'
require 'yaml'
module Puppet::Network
class ClientError < Puppet::Error; end
class XMLRPCClientError < Puppet::Error; end
class XMLRPCClient < ::XMLRPC::Client
attr_accessor :puppet_server, :puppet_port
@clients = {}
class << self
include Puppet::Util
include Puppet::Util::ClassGen
end
# Create a netclient for each handler
def self.mkclient(handler)
interface = handler.interface
namespace = interface.prefix
# Create a subclass for every client type. This is
# so that all of the methods are on their own class,
# so that they namespaces can define the same methods if
# they want.
constant = handler.name.to_s.capitalize
name = namespace.downcase
newclient = genclass(name, :hash => @clients,
:constant => constant)
interface.methods.each { |ary|
method = ary[0]
if public_method_defined?(method)
raise Puppet::DevError, "Method %s is already defined" %
method
end
newclient.send(:define_method,method) { |*args|
Puppet.debug "Calling %s.%s" % [namespace, method]
begin
call("%s.%s" % [namespace, method.to_s],*args)
rescue OpenSSL::SSL::SSLError => detail
raise XMLRPCClientError,
"Certificates were not trusted: %s" % detail
rescue ::XMLRPC::FaultException => detail
#Puppet.err "Could not call %s.%s: %s" %
# [namespace, method, detail.faultString]
#raise XMLRPCClientError,
# "XMLRPC Error: %s" % detail.faultString
raise XMLRPCClientError, detail.faultString
rescue Errno::ECONNREFUSED => detail
msg = "Could not connect to %s on port %s" %
[@host, @port]
raise XMLRPCClientError, msg
rescue SocketError => detail
Puppet.err "Could not find server %s: %s" %
[@puppet_server, detail.to_s]
error = XMLRPCClientError.new(
"Could not find server %s" % @puppet_server
)
error.set_backtrace detail.backtrace
raise error
rescue => detail
Puppet.err "Could not call %s.%s: %s" %
[namespace, method, detail.inspect]
error = XMLRPCClientError.new(detail.to_s)
error.set_backtrace detail.backtrace
raise error
end
}
}
return newclient
end
def self.handler_class(handler)
@clients[handler] || self.mkclient(handler)
end
# Use cert information from a Puppet client to set up the http object.
def cert_setup(client)
unless FileTest.exists?(Puppet[:localcacert])
raise Puppet::SSLCertificates::Support::MissingCertificate,
"Could not find ca certificate %s" % Puppet[:localcacert]
end
@http.ca_file = Puppet[:localcacert]
store = OpenSSL::X509::Store.new
store.add_file Puppet[:localcacert]
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
@http.cert_store = store
@http.cert = client.cert
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
@http.key = client.key
end
def initialize(hash = {})
hash[:Path] ||= "/RPC2"
hash[:Server] ||= Puppet[:server]
hash[:Port] ||= Puppet[:masterport]
@puppet_server = hash[:Server]
@puppet_port = hash[:Port]
super(
hash[:Server],
hash[:Path],
hash[:Port],
nil, # proxy_host
nil, # proxy_port
nil, # user
nil, # password
true, # use_ssl
120 # a two minute timeout, instead of 30 seconds
)
end
def local
false
end
def local?
false
end
end
end
# $Id$

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

@ -0,0 +1,91 @@
require 'puppet/network/authorization'
require 'xmlrpc/server'
# Just silly.
class ::XMLRPC::FaultException
def to_s
self.message
end
end
module Puppet::Network
# Most of our subclassing is just so that we can get
# access to information from the request object, like
# the client name and IP address.
module XMLRPCProcessor
include Puppet::Network::Authorization
ERR_UNAUTHORIZED = 30
def add_handler(interface, handler)
@loadedhandlers << interface.prefix
super(interface, handler)
end
def handler_loaded?(handler)
@loadedhandlers.include?(handler.to_s)
end
# Convert our data and client request into xmlrpc calls, and verify
# they're authorized and such-like. This method differs from the
# default in that it expects a ClientRequest object in addition to the
# data.
def process(data, request)
call, params = parser().parseMethodCall(data)
params << request.name << request.ip
handler, method = call.split(".")
request.handler = handler
request.method = method
begin
verify(request)
rescue InvalidClientRequest => detail
raise ::XMLRPC::FaultException.new(ERR_UNAUTHORIZED, detail.to_s)
end
handle(request.call, *params)
end
private
# Provide error handling for method calls.
def protect_service(obj, *args)
begin
obj.call(*args)
rescue ::XMLRPC::FaultException
raise
rescue Puppet::AuthorizationError => detail
Puppet.err "Permission denied: %s" % detail.to_s
raise ::XMLRPC::FaultException.new(
1, detail.to_s
)
rescue Puppet::Error => detail
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err detail.to_s
error = ::XMLRPC::FaultException.new(
1, detail.to_s
)
error.set_backtrace detail.backtrace
raise error
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err "Could not call: %s" % detail.to_s
error = ::XMLRPC::FaultException.new(1, detail.to_s)
error.set_backtrace detail.backtrace
raise error
end
end
# Set up our service hook and init our handler list.
def setup_processor
@loadedhandlers = []
self.set_service_hook do |obj, *args|
protect_service(obj, *args)
end
end
end
end
# $Id$

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

@ -0,0 +1,20 @@
require 'xmlrpc/server'
require 'puppet/network/authorization'
require 'puppet/network/xmlrpc/processor'
module Puppet::Network
# Most of our subclassing is just so that we can get
# access to information from the request object, like
# the client name and IP address.
class XMLRPCServer < ::XMLRPC::BasicServer
include Puppet::Util
include Puppet::Network::XMLRPCProcessor
def initialize
super()
setup_processor()
end
end
end
# $Id$

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

@ -0,0 +1,121 @@
require 'xmlrpc/server'
require 'puppet/network/authorization'
require 'puppet/network/xmlrpc/processor'
module Puppet::Network::XMLRPC
class ServletError < RuntimeError; end
class WEBrickServlet < ::XMLRPC::WEBrickServlet
include Puppet::Network::XMLRPCProcessor
# This is a hackish way to avoid an auth message every time we have a
# normal operation
def self.log(msg)
unless defined? @logs
@logs = {}
end
if @logs.include?(msg)
@logs[msg] += 1
else
Puppet.info msg
@logs[msg] = 1
end
end
# Accept a list of handlers and register them all.
def initialize(handlers)
# the servlet base class does not consume any arguments
# and its BasicServer base class only accepts a 'class_delim'
# option which won't change in Puppet at all
# thus, we don't need to pass any args to our base class,
# and we can consume them all ourselves
super()
setup_processor()
# Set up each of the passed handlers.
handlers.each do |handler|
add_handler(handler.class.interface, handler)
end
end
# Handle the actual request. We can't use the super() method, because
# we need to pass a ClientRequest object to process() so we can do
# authorization. It's the only way to stay thread-safe.
def service(request, response)
if @valid_ip
raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
end
if request.request_method != "POST"
raise WEBrick::HTTPStatus::MethodNotAllowed,
"unsupported method `#{request.request_method}'."
end
if parse_content_type(request['Content-type']).first != "text/xml"
raise WEBrick::HTTPStatus::BadRequest
end
length = (request['Content-length'] || 0).to_i
raise WEBrick::HTTPStatus::LengthRequired unless length > 0
data = request.body
if data.nil? or data.size != length
raise WEBrick::HTTPStatus::BadRequest
end
resp = process(data, client_request(request))
if resp.nil? or resp.size <= 0
raise WEBrick::HTTPStatus::InternalServerError
end
response.status = 200
response['Content-Length'] = resp.size
response['Content-Type'] = "text/xml; charset=utf-8"
response.body = resp
end
private
# Generate a ClientRequest object for later validation.
def client_request(request)
if peer = request.peeraddr
client = peer[2]
clientip = peer[3]
else
raise ::XMLRPC::FaultException.new(
ERR_UNCAUGHT_EXCEPTION,
"Could not retrieve client information"
)
end
# If they have a certificate (which will almost always be true)
# then we get the hostname from the cert, instead of via IP
# info
valid = false
if cert = request.client_cert
nameary = cert.subject.to_a.find { |ary|
ary[0] == "CN"
}
if nameary.nil?
Puppet.warning "Could not retrieve server name from cert"
else
unless client == nameary[1]
Puppet.debug "Overriding %s with cert name %s" %
[client, nameary[1]]
client = nameary[1]
end
valid = true
end
end
info = Puppet::Network::ClientRequest.new(client, clientip, valid)
return info
end
end
end
# $Id$

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

@ -54,8 +54,7 @@ class Puppet::Parser::AST
# Evaluate the actual statements; this only gets called if
# our option matched.
def evaluate(hash)
scope = hash[:scope]
return @statements.safeevaluate(:scope => scope)
return @statements.safeevaluate(hash)
end
def tree(indent = 0)

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

@ -18,6 +18,7 @@ class Puppet::Parser::AST
found = false
# Iterate across the options looking for a match.
default = nil
@options.each { |option|
option.eachvalue(scope) { |opval|
opval = opval.downcase if ! sensitive and opval.respond_to?(:downcase)
@ -32,12 +33,16 @@ class Puppet::Parser::AST
retvalue = option.safeevaluate(:scope => scope)
break
end
if option.default?
default = option
end
}
# Unless we found something, look for the default.
unless found
if defined? @default
retvalue = @default.safeevaluate(:scope => scope)
if default
retvalue = default.safeevaluate(:scope => scope)
else
Puppet.debug "No true answers and no default"
retvalue = nil
@ -46,33 +51,6 @@ class Puppet::Parser::AST
return retvalue
end
# Do some input validation on our options.
def initialize(hash)
values = {}
super
# This won't work if we move away from only allowing
# constants here, but for now, it's fine and useful.
@options.each { |option|
unless option.is_a?(CaseOpt)
raise Puppet::DevError, "Option is not a CaseOpt"
end
if option.default?
@default = option
end
option.eachvalue(nil) { |val|
if values.include?(val)
raise Puppet::ParseError,
"Value %s appears twice in case statement" %
val
else
values[val] = true
end
}
}
end
def tree(indent = 0)
rettree = [
@test.tree(indent + 1),
@ -87,5 +65,6 @@ class Puppet::Parser::AST
[@test,@options].each { |child| yield child }
end
end
end
# $Id$

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

@ -552,7 +552,7 @@ class Puppet::Parser::Scope
if ss.matched == '\\$'
out << '$'
else # look the variable up
out << lookupvar(ss[1] || ss[2]) || ""
out << lookupvar(ss[1] || ss[2]).to_s || ""
end
elsif ss.scan(/^\\(.)/)
# Puppet.debug("Got escape: pos:%d; m:%s" % [ss.pos, ss.matched])

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

@ -29,6 +29,27 @@ module Puppet::Rails
}
)
def self.connect
# This global init does not work for testing, because we remove
# the state dir on every test.
unless ActiveRecord::Base.connected?
Puppet.config.use(:puppet)
ActiveRecord::Base.logger = Logger.new(Puppet[:railslog])
ActiveRecord::Base.allow_concurrency = true
ActiveRecord::Base.verify_active_connections!
begin
ActiveRecord::Base.establish_connection(database_arguments())
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
raise Puppet::Error, "Could not connect to database: %s" % detail
end
end
end
# The arguments for initializing the database connection.
def self.database_arguments
args = {:adapter => Puppet[:dbadapter]}
@ -54,24 +75,7 @@ module Puppet::Rails
raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails"
end
# This global init does not work for testing, because we remove
# the state dir on every test.
unless ActiveRecord::Base.connected?
Puppet.config.use(:puppet)
ActiveRecord::Base.logger = Logger.new(Puppet[:railslog])
ActiveRecord::Base.allow_concurrency = true
ActiveRecord::Base.verify_active_connections!
begin
ActiveRecord::Base.establish_connection(database_arguments())
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
raise Puppet::Error, "Could not connect to database: %s" % detail
end
end
connect()
unless ActiveRecord::Base.connection.tables.include?("resources")
require 'puppet/rails/database/schema'

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

@ -1,6 +1,6 @@
require 'puppet'
Puppet::Network::Server::Report.newreport(:log) do
Puppet::Network::Handler.report.newreport(:log) do
desc "Send all received logs to the local log destinations."
def process

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

@ -1,6 +1,6 @@
require 'puppet'
Puppet::Network::Server::Report.newreport(:rrdgraph) do
Puppet::Network::Handler.report.newreport(:rrdgraph) do
desc "Graph all available data about hosts using the RRD library. You
must have the RRD binary library installed to use this report, which
you can get from [Tobias Oetiker's site](http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/pub/contrib/).

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

@ -1,6 +1,6 @@
require 'puppet'
Puppet::Network::Server::Report.newreport(:store, :useyaml => true) do
Puppet::Network::Handler.report.newreport(:store, :useyaml => true) do
Puppet.config.use(:reporting)
desc "Store the yaml report on disk. Each host sends its report as a YAML dump

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

@ -1,20 +1,9 @@
require 'puppet'
require 'pp'
Puppet.config.setdefaults(:reporting,
:tagmap => ["$confdir/tagmail.conf",
"The mapping between reporting tags and email addresses."],
:sendmail => [%x{which sendmail 2>/dev/null}.chomp,
"Where to find the sendmail binary with which to send email."],
:reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."),
"The 'from' email address for the reports."],
:smtpserver => ["none",
"The server through which to send email reports."]
)
require 'net/smtp'
Puppet::Network::Server::Report.newreport(:tagmail) do
Puppet::Network::Handler.report.newreport(:tagmail) do
desc "This report sends specific log messages to specific email addresses
based on the tags in the log messages. See the
[tag documentation](/trac/puppet/wiki/UsingTags) for more information

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

@ -11,13 +11,15 @@ end
module Puppet::SSLCertificates
hostname = Facter["hostname"].value
domain = Facter["domain"].value
if !domain || domain.empty? then
fqdn = hostname
else
if domain and domain != ""
fqdn = [hostname, domain].join(".")
else
fqdn = hostname
end
Puppet.setdefaults("certificates",
:certname => [fqdn, "The name to use when handling certificates. Defaults
to the fully qualified domain name."],
:certdir => ["$ssldir/certs", "The certificate directory."],
:publickeydir => ["$ssldir/public_keys", "The public key directory."],
:privatekeydir => { :default => "$ssldir/private_keys",
@ -33,15 +35,19 @@ module Puppet::SSLCertificates
:desc => "Where puppetd stores the password for its private key.
Generally unused."
},
:hostcert => { :default => "$certdir/#{fqdn}.pem",
:hostcsr => { :default => "$ssldir/csr_$certname.pem",
:mode => 0644,
:desc => "Where individual hosts store and look for their certificates."
},
:hostprivkey => { :default => "$privatekeydir/#{fqdn}.pem",
:hostcert => { :default => "$certdir/$certname.pem",
:mode => 0644,
:desc => "Where individual hosts store and look for their certificates."
},
:hostprivkey => { :default => "$privatekeydir/$certname.pem",
:mode => 0600,
:desc => "Where individual hosts store and look for their private key."
},
:hostpubkey => { :default => "$publickeydir/#{fqdn}.pem",
:hostpubkey => { :default => "$publickeydir/$certname.pem",
:mode => 0644,
:desc => "Where individual hosts store and look for their public key."
},

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

@ -5,8 +5,6 @@ class Puppet::SSLCertificates::CA
attr_accessor :keyfile, :file, :config, :dir, :cert, :crl
Puppet.setdefaults(:ca,
:ca => [true,
"Whether a CA should be started in puppetmasterd."],
:cadir => { :default => "$ssldir/ca",
:owner => "$user",
:group => "$group",
@ -97,7 +95,7 @@ class Puppet::SSLCertificates::CA
if FileTest.exists?(file)
begin
if Puppet.execname == "puppetca"
if Puppet[:name] == "puppetca"
puts "Removing %s" % file
else
Puppet.info "Removing %s" % file

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

@ -0,0 +1,128 @@
require 'puppet/sslcertificates'
# A module to handle reading of certificates.
module Puppet::SSLCertificates::Support
class MissingCertificate < Puppet::Error; end
class InvalidCertificate < Puppet::Error; end
attr_reader :cacert
# Some metaprogramming to create methods for retrieving and creating keys.
# This probably isn't fewer lines than defining each separately...
def self.keytype(name, options, &block)
var = "@%s" % name
maker = "mk_%s" % name
reader = "read_%s" % name
unless param = options[:param]
raise ArgumentError, "You must specify the parameter for the key"
end
unless klass = options[:class]
raise ArgumentError, "You must specify the class for the key"
end
# Define the method that creates it.
define_method(maker, &block)
# Define the reading method.
define_method(reader) do
return nil unless FileTest.exists?(Puppet[param])
begin
instance_variable_set(var,
klass.new(File.read(Puppet[param])))
rescue => detail
raise InvalidCertificate, "Could not read %s: %s" %
[param, detail]
end
end
# Define the overall method, which just calls the reader and maker
# as appropriate.
define_method(name) do
unless instance_variable_get(var)
unless cert = send(reader)
cert = send(maker)
Puppet.config.write(param) { |f| f.puts cert.to_pem }
end
instance_variable_set(var, cert)
end
instance_variable_get(var)
end
end
# The key pair.
keytype :key, :param => :hostprivkey, :class => OpenSSL::PKey::RSA do
Puppet.info "Creating a new SSL key at %s" % Puppet[:hostprivkey]
key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
# Our key meta programming can only handle one file, so we have
# to separately write out the public key.
Puppet.config.write(:hostpubkey) do |f|
f.print key.public_key.to_pem
end
return key
end
# Our certificate request
keytype :csr, :param => :hostcsr, :class => OpenSSL::X509::Request do
Puppet.info "Creating a new certificate request for %s" %
Puppet[:certname]
csr = OpenSSL::X509::Request.new
csr.version = 0
csr.subject = OpenSSL::X509::Name.new([["CN", Puppet[:certname]]])
csr.public_key = key.public_key
csr.sign(key, OpenSSL::Digest::MD5.new)
return csr
end
keytype :cert, :param => :hostcert, :class => OpenSSL::X509::Certificate do
raise MissingCertificate, "No host certificate"
end
keytype :ca_cert, :param => :localcacert, :class => OpenSSL::X509::Certificate do
raise MissingCertificate, "No CA certificate"
end
# Request a certificate from the remote system. This does all of the work
# of creating the cert request, contacting the remote system, and
# storing the cert locally.
def requestcert
begin
cert, cacert = caclient.getcert(@csr.to_pem)
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
raise Puppet::Error.new("Certificate retrieval failed: %s" %
detail)
end
if cert.nil? or cert == ""
return nil
end
Puppet.config.write(:hostcert) do |f| f.print cert end
Puppet.config.write(:localcacert) do |f| f.print cacert end
#File.open(@certfile, "w", 0644) { |f| f.print cert }
#File.open(@cacertfile, "w", 0644) { |f| f.print cacert }
begin
@cert = OpenSSL::X509::Certificate.new(cert)
@cacert = OpenSSL::X509::Certificate.new(cacert)
retrieved = true
rescue => detail
raise Puppet::Error.new(
"Invalid certificate: %s" % detail
)
end
unless @cert.check_private_key(@key)
raise Puppet::DevError, "Received invalid certificate"
end
return retrieved
end
end
# $Id$

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

@ -4,7 +4,7 @@ require 'etc'
require 'uri'
require 'fileutils'
require 'puppet/type/property'
require 'puppet/network/server/fileserver'
require 'puppet/network/handler'
module Puppet
newtype(:file) do
@ -104,7 +104,7 @@ module Puppet
@parent.bucket = value
value
end
when Puppet::Network::Client::Dipper:
when Puppet::Network::Client.client(:Dipper):
@parent.bucket = value
value.name
else
@ -311,7 +311,7 @@ module Puppet
# This sets the @value on :backup, too
self.bucket = obj
elsif bucket == "puppet"
obj = Puppet::Network::Client::Dipper.new(
obj = Puppet::Network::Client.client(:Dipper).new(
:Path => Puppet[:clientbucketdir]
)
self.bucket = obj
@ -322,7 +322,7 @@ module Puppet
else
self.fail "Could not find filebucket %s" % bucket
end
when Puppet::Network::Client::Dipper: # things are hunky-dorey
when Puppet::Network::Client.client(:Dipper): # things are hunky-dorey
else
self.fail "Invalid bucket type %s" % bucket.class
end
@ -357,7 +357,7 @@ module Puppet
else
backup = self.bucket || self[:backup]
case backup
when Puppet::Network::Client::Dipper:
when Puppet::Network::Client.client(:Dipper):
notice "Recursively backing up to filebucket"
require 'find'
Find.find(self[:path]) do |f|
@ -396,7 +396,7 @@ module Puppet
when "file":
backup = self.bucket || self[:backup]
case backup
when Puppet::Network::Client::Dipper:
when Puppet::Network::Client.client(:Dipper):
sum = backup.backup(file)
self.info "Filebucketed to %s with sum %s" %
[backup.name, sum]
@ -975,7 +975,7 @@ module Puppet
case uri.scheme
when "file":
unless defined? @@localfileserver
@@localfileserver = Puppet::Network::Server::FileServer.new(
@@localfileserver = Puppet::Network::Handler.handler(:fileserver).new(
:Local => true,
:Mount => { "/" => "localhost" },
:Config => false
@ -992,7 +992,7 @@ module Puppet
# FIXME We should cache a copy of this server
#sourceobj.server = Puppet::Network::NetworkClient.new(args)
unless @clients.include?(source)
@clients[source] = Puppet::Network::Client::FileClient.new(args)
@clients[source] = Puppet::Network::Client.file.new(args)
end
sourceobj.server = @clients[source]

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

@ -1,5 +1,3 @@
require 'puppet/network/server/fileserver'
module Puppet
# Copy files from a local or remote source. This state *only* does any work
# when the remote file is an actual file; in that case, this state copies
@ -7,7 +5,6 @@ module Puppet
# this state, during retrieval, modifies the appropriate other states
# so that things get taken care of appropriately.
Puppet.type(:file).newproperty(:source) do
PINPARAMS = Puppet::Network::Server::FileServer::CHECKPARAMS
attr_accessor :source, :local
desc "Copy a file over the current file. Uses ``checksum`` to
@ -86,14 +83,14 @@ module Puppet
begin
desc = server.describe(path, @parent[:links])
rescue Puppet::Network::NetworkClientError => detail
rescue Puppet::Network::XMLRPCClientError => detail
self.err "Could not describe %s: %s" %
[path, detail]
return nil
end
args = {}
PINPARAMS.zip(
pinparams.zip(
desc.split("\t")
).each { |param, value|
if value =~ /^[0-9]+$/
@ -144,6 +141,10 @@ module Puppet
# Now, we just check to see if the checksums are the same
return @parent.is(:checksum) == @stats[:checksum]
end
def pinparams
Puppet::Network::Handler.handler(:fileserver).params
end
# This basically calls describe() on our file, and then sets all
# of the local states appropriately. If the remote file is a normal
@ -209,7 +210,7 @@ module Puppet
def should=(value)
super
checks = (PINPARAMS + [:ensure])
checks = (pinparams + [:ensure])
checks.delete(:checksum)
@parent[:check] = checks
@ -231,7 +232,7 @@ module Puppet
begin
contents = sourceobj.server.retrieve(path, @parent[:links])
rescue Puppet::Network::NetworkClientError => detail
rescue Puppet::Network::XMLRPCClientError => detail
self.err "Could not retrieve %s: %s" %
[path, detail]
return nil

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

@ -1,5 +1,3 @@
require 'puppet/network/server/filebucket'
module Puppet
newtype(:filebucket) do
@doc = "A repository for backing up files. If no filebucket is
@ -86,7 +84,7 @@ module Puppet
def mkbucket
if self[:server]
begin
@bucket = Puppet::Network::Client::Dipper.new(
@bucket = Puppet::Network::Client.client(:Dipper).new(
:Server => self[:server],
:Port => self[:port]
)
@ -97,7 +95,7 @@ module Puppet
end
else
begin
@bucket = Puppet::Network::Client::Dipper.new(
@bucket = Puppet::Network::Client.client(:Dipper).new(
:Path => self[:path]
)
rescue => detail

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

@ -301,7 +301,7 @@ class Puppet::Util::Config
# the group can be set in the config file. The problem
# is that we're using the word 'group' twice, which is
# confusing.
if var == :group and section == Puppet.execname and @config.include?(:group)
if var == :group and section == Puppet[:name] and @config.include?(:group)
@config[:group].value = value
end
next
@ -519,7 +519,7 @@ class Puppet::Util::Config
# Convert our list of objects into a configuration file.
def to_config
str = %{The configuration file for #{Puppet.execname}. Note that this file
str = %{The configuration file for #{Puppet[:name]}. Note that this file
is likely to have unused configuration parameters in it; any parameter that's
valid anywhere in Puppet can be in any config file, even if it's not used.
@ -719,18 +719,16 @@ Generated on #{Time.now}.
def convert(value)
return value unless value
return value unless value.is_a? String
if value =~ /\$(\w+)/
parent = $1
if pval = @parent[parent]
newval = value.to_s.sub(/\$#{parent.to_s}/, pval.to_s)
#return File.join(newval.split("/"))
return newval
newval = value.gsub(/\$(\w+)|\$\{(\w+)\}/) do |value|
varname = $2 || $1
if pval = @parent[varname]
pval
else
raise Puppet::DevError, "Could not find value for %s" % parent
end
else
return value
end
return newval
end
def desc=(value)

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

@ -167,7 +167,7 @@ class Puppet::Util::Log
if Syslog.opened?
Syslog.close
end
name = Puppet.execname
name = Puppet[:name]
name = "puppet-#{name}" unless name =~ /puppet/
options = Syslog::LOG_PID | Syslog::LOG_NDELAY

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

@ -0,0 +1,83 @@
# A module for loading subclasses into an array and retrieving
# them by name. Also sets up a method for each class so
# that you can just do Klass.subclass, rather than Klass.subclass(:subclass).
module Puppet::Util::SubclassLoader
attr_accessor :loader, :classloader
# Iterate over each of the subclasses.
def each
@subclasses ||= []
@subclasses.each { |c| yield c }
end
# The hook method that sets up subclass loading. We need the name
# of the method to create and the path in which to look for them.
def handle_subclasses(name, path)
unless self.is_a?(Class)
raise ArgumentError, "Must be a class to use SubclassLoader"
end
@subclasses = []
@loader = Puppet::Util::Autoload.new(self,
path, :wrap => false
)
@subclassname = name
@classloader = self
# Now create a method for retrieving these subclasses by name. Note
# that we're defining a class method here, not an instance.
meta_def(name) do |subname|
subname = subname.to_s.downcase
unless c = @subclasses.find { |c| c.name.to_s.downcase == subname }
loader.load(subname)
c = @subclasses.find { |c| c.name.to_s.downcase == subname }
# Now make the method that returns this subclass. This way we
# normally avoid the method_missing method.
if c and ! respond_to?(subname)
define_method(subname) { c }
end
end
return c
end
end
# Add a new class to our list. Note that this has to handle subclasses of
# subclasses, thus the reason we're keeping track of the @@classloader.
def inherited(sub)
@subclasses ||= []
@subclasses << sub
sub.classloader = self.classloader
if self.classloader == self
@subclasses << sub
else
@classloader.inherited(sub)
end
end
# See if we can load a class.
def method_missing(method, *args)
unless self == self.classloader
super
end
return nil unless defined? @subclassname
if c = self.send(@subclassname, method)
return c
else
return nil
end
end
# Retrieve or calculate a name.
def name
unless defined? @name
@name = self.to_s.sub(/.+::/, '').intern
end
return @name
end
end
# $Id$

81
test/certmgr/support.rb Executable file
Просмотреть файл

@ -0,0 +1,81 @@
#!/usr/bin/env ruby
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/sslcertificates/support'
class TestCertSupport < Test::Unit::TestCase
include PuppetTest
MissingCertificate = Puppet::SSLCertificates::Support::MissingCertificate
class CertUser
include Puppet::SSLCertificates::Support
end
def setup
super
@user = CertUser.new
@ca = Puppet::SSLCertificates::CA.new
@client = Puppet::Network::Client.ca.new(:CA => @ca)
end
# Yay, metaprogramming
def test_keytype
[:key, :csr, :cert, :ca_cert].each do |name|
assert(Puppet::SSLCertificates::Support.method_defined?(name),
"No retrieval method for %s" % name)
maker = "mk_%s" % name
assert(Puppet::SSLCertificates::Support.method_defined?(maker),
"No maker method for %s" % name)
end
end
def test_keys
keys = [:hostprivkey, :hostpubkey].each { |n| Puppet[n] = tempfile }
key = nil
assert_nothing_raised do
key = @user.key
end
assert_logged(:info, /Creating a new SSL/, "Did not log about new key")
keys.each do |file|
assert(FileTest.exists?(Puppet[file]),
"Did not create %s key file" % file)
end
# Make sure it's a valid key
assert_nothing_raised("Created key is invalid") do
OpenSSL::PKey::RSA.new(File.read(Puppet[:hostprivkey]))
end
# now make sure we can read it in
other = CertUser.new
assert_nothing_raised("Could not read key in") do
other.key
end
assert_equal(@user.key.to_s, other.key.to_s, "Keys are not equal")
end
def test_csr
csr = nil
assert_nothing_raised("Could not create csr") do
csr = @user.csr
end
assert(FileTest.exists?(Puppet[:hostcsr]), "did not create csr file")
assert_instance_of(OpenSSL::X509::Request, csr)
end
def test_cacert
@user = CertUser.new
assert_raise(MissingCertificate, "Did not fail when missing cacert") do
@user.ca_cert
end
end
end
# $Id$

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

@ -2,9 +2,6 @@
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet'
require 'puppet/network/server'
require 'puppet/sslcertificates'
require 'puppettest'
class TestPuppetBin < Test::Unit::TestCase

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

@ -2,9 +2,6 @@
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet'
require 'puppet/network/server'
require 'puppet/sslcertificates'
require 'puppettest'
class TestPuppetCA < Test::Unit::TestCase
@ -16,7 +13,7 @@ class TestPuppetCA < Test::Unit::TestCase
end
def mkca
Puppet::Network::Server::CA.new()
Puppet::Network::Handler.ca.new()
end
def mkcert(hostname)

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

@ -3,7 +3,7 @@
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet'
require 'puppet/network/server'
require 'puppet/network/client'
require 'puppettest'
require 'socket'
require 'facter'
@ -15,10 +15,10 @@ class TestPuppetDExe < Test::Unit::TestCase
file = startmasterd
# create the client
client = Puppet::Network::Client::MasterClient.new(:Server => "localhost", :Port => @@port)
client = Puppet::Network::Client.master.new(:Server => "localhost", :Port => @@port)
# make a new fqdn
fqdn = client.fqdn.sub(/^\w+\./, "testing.")
fqdn = Puppet[:certname].sub(/^\w+\./, "testing.")
cmd = "puppetd"
cmd += " --verbose"

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

@ -3,11 +3,9 @@
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet'
require 'puppet/network/server'
require 'puppet/daemon'
require 'puppet/network/client'
require 'puppettest'
require 'socket'
require 'facter'
class TestPuppetMasterD < Test::Unit::TestCase
include PuppetTest::ExeTest
@ -35,7 +33,7 @@ class TestPuppetMasterD < Test::Unit::TestCase
client = nil
assert_nothing_raised() {
client = Puppet::Network::Client::StatusClient.new(
client = Puppet::Network::Client.status.new(
:Server => "localhost",
:Port => @@port
)
@ -47,14 +45,14 @@ class TestPuppetMasterD < Test::Unit::TestCase
FileUtils.mkdir_p(File.dirname(Puppet[:autosign]))
File.open(Puppet[:autosign], "w") { |f|
f.puts client.fqdn
f.puts Puppet[:certname]
}
retval = nil
# init the client certs
assert_nothing_raised() {
client.initcerts
client.cert
}
# call status
@ -65,7 +63,7 @@ class TestPuppetMasterD < Test::Unit::TestCase
# this client shoulduse the same certs
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Server => "localhost",
:Port => @@port
)

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

@ -2,9 +2,6 @@
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet'
require 'puppet/network/server'
require 'puppet/sslcertificates'
require 'puppettest'
class TestPuppetModule < Test::Unit::TestCase

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

@ -114,7 +114,7 @@ class TestASTHostClass < Test::Unit::TestCase
newscope = klass.subscope(scope)
assert_equal("funtest", newscope.namespace,
assert_equal(["funtest"], newscope.namespaces,
"Scope did not inherit namespace")
# Now make sure we can find the define

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

@ -6,7 +6,7 @@ require 'puppet'
require 'puppet/parser/interpreter'
require 'puppet/parser/parser'
require 'puppet/network/client'
require 'puppet/network/server'
require 'puppet/network/handler'
require 'puppettest'
class TestSnippets < Test::Unit::TestCase
@ -492,11 +492,11 @@ class TestSnippets < Test::Unit::TestCase
testname = ("test_" + mname).intern
self.send(:define_method, testname) {
# first parse the file
server = Puppet::Network::Server::Master.new(
server = Puppet::Network::Handler.master.new(
:Manifest => snippet(file),
:Local => true
)
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => server,
:Cache => false
)
@ -506,7 +506,7 @@ class TestSnippets < Test::Unit::TestCase
client.getconfig()
}
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => server,
:Cache => false
)

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

@ -22,8 +22,8 @@ module Mocha
add_failure(e.message, e.backtrace)
rescue Test::Unit::AssertionFailedError => e
add_failure(e.message, e.backtrace)
rescue StandardError, ScriptError
add_error($!)
rescue StandardError, ScriptError => e
add_error(e)
ensure
begin
teardown
@ -46,4 +46,4 @@ module Mocha
end
end
end

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

@ -8,7 +8,8 @@ require 'test/unit'
# Yay; hackish but it works
if ARGV.include?("-d")
Puppet.debug = true
ARGV.delete("-d")
$console = true
end
module PuppetTest
@ -150,20 +151,25 @@ module PuppetTest
@@cleaners = []
@logs = []
# If we're running under rake, then disable debugging and such.
#if rake? or ! Puppet[:debug]
if defined?($puppet_debug) or ! rake?
if textmate?
Puppet[:color] = false
end
Puppet::Util::Log.newdestination :console
Puppet::Util::Log.newdestination(@logs)
if defined? $console
Puppet.info @method_name
Puppet::Util::Log.newdestination(:console)
end
Puppet::Util::Log.level = :debug
#$VERBOSE = 1
Puppet.info @method_name
Puppet[:trace] = true
else
Puppet::Util::Log.close
Puppet::Util::Log.newdestination tempfile()
Puppet::Util::Log.newdestination(@logs)
Puppet[:httplog] = tempfile()
end
@ -251,6 +257,7 @@ module PuppetTest
# reset all of the logs
Puppet::Util::Log.close
@logs.clear
# Just in case there are processes waiting to die...
require 'timeout'
@ -282,5 +289,6 @@ require 'puppettest/fakes'
require 'puppettest/exetest'
require 'puppettest/parsertesting'
require 'puppettest/servertest'
require 'puppettest/testcase'
# $Id$

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

@ -1,4 +1,5 @@
require 'puppettest'
require 'puppet/network/server/webrick'
module PuppetTest::ServerTest
include PuppetTest
@ -31,6 +32,7 @@ module PuppetTest::ServerTest
# create a server, forked into the background
def mkserver(handlers = nil)
Puppet[:name] = "puppetmasterd"
# our default handlers
unless handlers
handlers = {
@ -45,7 +47,7 @@ module PuppetTest::ServerTest
# then create the actual server
server = nil
assert_nothing_raised {
server = Puppet::Network::Server.new(
server = Puppet::Network::Server::WEBrick.new(
:Port => @@port,
:Handlers => handlers
)

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

@ -2,6 +2,13 @@ require 'puppettest'
require 'fileutils'
module PuppetTest
def assert_logged(level, regex, msg = nil)
# Skip verifying logs that we're not supposed to send.
return unless Puppet::Util::Log.sendlevel?(level)
r = @logs.detect { |l| l.level == level and l.message =~ regex }
@logs.clear
assert(r, msg)
end
def assert_uid_gid(uid, gid, filename)
flunk "Must be uid 0 to run these tests" unless Process.uid == 0

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

@ -0,0 +1,47 @@
#!/usr/bin/env ruby
#
# Created by Luke A. Kanies on 2006-11-24.
# Copyright (c) 2006. All rights reserved.
require 'puppettest'
class PuppetTest::TestCase < Test::Unit::TestCase
def self.confine(hash)
@confines ||= {}
hash.each do |message, result|
@confines[message] = result
end
end
def self.runnable?
@messages ||= []
return false unless @messages.empty?
return true unless defined? @confines
@confines.find_all do |message, result|
! result
end.each do |message, result|
@messages << message
end
return @messages.empty?
end
def self.suite
# Always skip this parent class. It'd be nice if there were a
# "supported" way to do this.
if self == PuppetTest::TestCase
suite = Test::Unit::TestSuite.new(name)
return suite
elsif self.runnable?
return super
else
if defined? $console
puts "Skipping %s: %s" % [name, @messages.join(", ")]
end
suite = Test::Unit::TestSuite.new(name)
return suite
end
end
end
# $Id$

72
test/network/authconfig.rb Executable file
Просмотреть файл

@ -0,0 +1,72 @@
#!/usr/bin/env ruby
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/authconfig'
class TestAuthConfig < Test::Unit::TestCase
include PuppetTest
def request(call, client, ip)
r = Puppet::Network::ClientRequest.new(client, ip, false)
h, m = call.split(".")
r.handler = h
r.method = m
r
end
def test_parsingconfigfile
file = tempfile()
assert(Puppet[:authconfig], "No config path")
Puppet[:authconfig] = file
File.open(file, "w") { |f|
f.puts "[pelementserver.describe]
allow *.madstop.com
deny 10.10.1.1
[fileserver]
allow *.madstop.com
deny 10.10.1.1
[fileserver.list]
allow 10.10.1.1
"
}
config = nil
assert_nothing_raised {
config = Puppet::Network::AuthConfig.new(file)
}
assert_nothing_raised {
assert(config.allowed?(request("pelementserver.describe",
"culain.madstop.com", "1.1.1.1")), "Did not allow host")
assert(! config.allowed?(request("pelementserver.describe",
"culain.madstop.com", "10.10.1.1")), "Allowed host")
assert(config.allowed?(request("fileserver.yay",
"culain.madstop.com", "10.1.1.1")), "Did not allow host to fs")
assert(! config.allowed?(request("fileserver.yay",
"culain.madstop.com", "10.10.1.1")), "Allowed host to fs")
assert(config.allowed?(request("fileserver.list",
"culain.madstop.com", "10.10.1.1")), "Did not allow host to fs.list")
}
end
def test_singleton
auth = nil
assert_nothing_raised { auth = Puppet::Network::AuthConfig.main }
assert(auth, "did not get main authconfig")
other = nil
assert_nothing_raised { other = Puppet::Network::AuthConfig.main }
assert_equal(auth.object_id, other.object_id,
"did not get same authconfig from class")
end
end
# $Id$

138
test/network/authorization.rb Executable file
Просмотреть файл

@ -0,0 +1,138 @@
#!/usr/bin/env ruby
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/authorization'
require 'mocha'
class TestAuthConfig < Test::Unit::TestCase
include PuppetTest
# A mock class for authconfig
class FakeAuth
class << self
attr_accessor :allow, :exists
end
def allowed?(req)
self.class.allow
end
def exists?
self.class.exists
end
end
class AuthTest
include Puppet::Network::Authorization
def clear
@loaded.clear
end
def load(name)
@loaded ||= []
@loaded << name
end
def handler_loaded?(name)
@loaded ||= []
@loaded.include?(name)
end
end
def setup
super
@obj = AuthTest.new
# Override the authconfig to make life easier
class << @obj
def authconfig
@authconfig ||= FakeAuth.new
@authconfig
end
end
@request = Puppet::Network::ClientRequest.new("host", "ip", false)
@request.handler = "foo"
@request.method = "bar"
end
def test_authconfig
obj = AuthTest.new
auth = nil
assert_nothing_raised { auth = obj.send(:authconfig) }
assert(auth, "did not get auth")
assert_equal(Puppet::Network::AuthConfig.main.object_id, auth.object_id,
"did not get main authconfig")
end
def test_authorize
# Make sure that unauthenticated clients can do puppetca stuff, but
# nothing else.
@request.handler = "puppetca"
@request.method = "yay"
assert(@obj.authorized?(@request), "Did not allow unauthenticated ca call")
assert_logged(:notice, /Allowing/, "did not log call")
@request.handler = "other"
assert(! @obj.authorized?(@request), "Allowed unauthencated other call")
assert_logged(:notice, /Denying/, "did not log call")
@request.authenticated = true
# We start without the namespace auth file, so everything should
# start out denied
assert(! @obj.authorized?(@request), "Allowed call with no config file")
assert_logged(:notice, /Denying/, "did not log call")
# Now set our name to the master, so calls are allowed
Puppet[:name] = "puppetmasterd"
assert(@obj.authorized?(@request),
"Denied call with no config file and master")
assert_logged(:debug, /Allowing/, "did not log call")
# Now "create" the file, so we do real tests
FakeAuth.exists = true
# We start out denying
assert(! @obj.authorized?(@request), "Allowed call when denying")
assert_logged(:notice, /Denying/, "did not log call")
FakeAuth.allow = true
assert(@obj.authorized?(@request), "Denied call when allowing")
assert_logged(:debug, /Allowing/, "did not log call")
end
def test_available?
# Start out false
assert(! @obj.available?(@request), "Defaulted to true")
assert_logged(:warning, /requested unavailable/, "did not log call")
@obj.load(@request.handler)
assert(@obj.available?(@request), "did not see it loaded")
end
# Make sure we raise things appropriately
def test_verify
# Start out unavailabl
assert_raise(Puppet::Network::InvalidClientRequest) do
@obj.verify(@request)
end
class << @obj
def available?(req)
true
end
end
assert_raise(Puppet::Network::InvalidClientRequest) do
@obj.verify(@request)
end
class << @obj
def authorized?(req)
true
end
end
assert_nothing_raised do
@obj.verify(@request)
end
end
end
# $Id$

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

@ -1,6 +1,6 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'

34
test/network/client/ca.rb Executable file
Просмотреть файл

@ -0,0 +1,34 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/client/ca'
require 'puppet/sslcertificates/support'
class TestClientCA < Test::Unit::TestCase
include PuppetTest::ServerTest
def setup
super
@ca = Puppet::Network::Handler.ca.new
@client = Puppet::Network::Client.ca.new :CA => @ca
end
def test_request_cert
assert_nothing_raised("Could not request cert") do
@client.request_cert
end
[:hostprivkey, :hostcert, :localcacert].each do |name|
assert(FileTest.exists?(Puppet.config[name]),
"Did not create cert %s" % name)
end
end
# Make sure the ca defaults to specific ports and names
def test_ca_server
end
end
# $Id$

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

@ -8,7 +8,7 @@ require 'puppet/network/client'
class TestClient < Test::Unit::TestCase
include PuppetTest::ServerTest
# a single run through of connect, auth, etc.
def test_sslInitWithAutosigningLocalServer
def disabled_test_sslInitWithAutosigningLocalServer
# autosign everything, for simplicity
Puppet[:autosign] = true
@ -18,7 +18,7 @@ class TestClient < Test::Unit::TestCase
# create our client
client = nil
assert_nothing_raised {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Server => "localhost",
:Port => @@port
)
@ -55,13 +55,13 @@ class TestClient < Test::Unit::TestCase
# here we create two servers; we
def test_failureWithUntrustedCerts
def disabled_test_failureWithUntrustedCerts
Puppet[:autosign] = true
# create a pair of clients with no certs
nonemaster = nil
assert_nothing_raised {
nonemaster = Puppet::Network::Client::MasterClient.new(
nonemaster = Puppet::Network::Client.master.new(
:Server => "localhost",
:Port => @@port
)
@ -69,7 +69,7 @@ class TestClient < Test::Unit::TestCase
nonebucket = nil
assert_nothing_raised {
nonebucket = Puppet::Network::Client::Dipper.new(
nonebucket = Puppet::Network::Client.dipper.new(
:Server => "localhost",
:Port => @@port
)
@ -79,7 +79,7 @@ class TestClient < Test::Unit::TestCase
# make a new ssldir for it
ca = nil
assert_nothing_raised {
ca = Puppet::Network::Client::CA.new(
ca = Puppet::Network::Client.ca.new(
:CA => true, :Local => true
)
ca.requestcert
@ -88,7 +88,7 @@ class TestClient < Test::Unit::TestCase
# initialize our clients with this set of certs
certmaster = nil
assert_nothing_raised {
certmaster = Puppet::Network::Client::MasterClient.new(
certmaster = Puppet::Network::Client.master.new(
:Server => "localhost",
:Port => @@port
)
@ -96,7 +96,7 @@ class TestClient < Test::Unit::TestCase
certbucket = nil
assert_nothing_raised {
certbucket = Puppet::Network::Client::Dipper.new(
certbucket = Puppet::Network::Client.dipper.new(
:Server => "localhost",
:Port => @@port
)
@ -122,11 +122,11 @@ class TestClient < Test::Unit::TestCase
certmaster.getconfig
}
assert_raise(Puppet::Network::NetworkClientError,
assert_raise(Puppet::Network::XMLRPCClientError,
"Client was allowed to call backup with no certs") {
nonebucket.backup("/etc/passwd")
}
assert_raise(Puppet::Network::NetworkClientError,
assert_raise(Puppet::Network::XMLRPCClientError,
"Client was allowed to call backup with untrusted certs") {
certbucket.backup("/etc/passwd")
}
@ -141,14 +141,14 @@ class TestClient < Test::Unit::TestCase
master = client = nil
assert_nothing_raised() {
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => manifest,
:UseNodes => false,
:Local => false
)
}
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => master
)
}
@ -167,26 +167,57 @@ class TestClient < Test::Unit::TestCase
assert_equal(%w{bootest yaytest}, classes.sort)
end
def test_setpidfile
FileUtils.mkdir_p(Puppet[:rundir])
$clientrun = false
newclass = Class.new(Puppet::Network::Client) do
def run
$clientrun = true
end
def test_client_loading
# Make sure we don't get a failure but that we also get nothing back
assert_nothing_raised do
assert_nil(Puppet::Network::Client.client(:fake),
"Got something back from a missing client")
assert_nil(Puppet::Network::Client.fake,
"Got something back from missing client method")
end
# Make a fake client
dir = tempfile()
libdir = File.join([dir, %w{puppet network client}].flatten)
FileUtils.mkdir_p(libdir)
def initialize
file = File.join(libdir, "fake.rb")
File.open(file, "w") do |f|
f.puts %{class Puppet::Network::Client
class Fake < Client
end
end
}
end
inst = newclass.new
$: << dir
cleanup { $:.delete(dir) if $:.include?(dir) }
assert_nothing_raised {
inst.start
}
client = nil
assert_nothing_raised do
client = Puppet::Network::Client.client(:fake)
end
assert_nothing_raised do
assert_equal(client, Puppet::Network::Client.fake,
"Did not get client back from client method")
end
assert(client, "did not load client")
assert(FileTest.exists?(inst.pidfile),
"PID file was not created")
# Now make sure the client behaves correctly
assert_equal(:Fake, client.name, "name was not calculated correctly")
end
# Make sure we get a client class for each handler type.
def test_loading_all_clients
%w{ca dipper file logger master report resource runner status}.each do |name|
client = nil
assert_nothing_raised do
client = Puppet::Network::Client.client(name)
end
assert(client, "did not get client for %s" % name)
[:name, :handler, :drivername].each do |thing|
assert(client.send(thing), "did not get %s for %s" % [thing, name])
end
end
end
end

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

@ -46,7 +46,7 @@ class TestMasterClient < Test::Unit::TestCase
# create our master
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => false,
:Local => true
@ -59,7 +59,7 @@ class TestMasterClient < Test::Unit::TestCase
master ||= mkmaster()
client = nil
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => master
)
}
@ -68,8 +68,8 @@ class TestMasterClient < Test::Unit::TestCase
end
def mk_fake_client
server = Puppet::Network::Server::Master.new :Code => ""
master = Puppet::Network::Client::MasterClient.new :Server => server, :Local => true
server = Puppet::Network::Handler.master.new :Code => ""
master = Puppet::Network::Client.master.new :Server => server, :Local => true
# Now create some objects
objects = FakeComponent.new
@ -208,7 +208,7 @@ class TestMasterClient < Test::Unit::TestCase
def test_clientversionfact
facts = nil
assert_nothing_raised {
facts = Puppet::Network::Client::MasterClient.facts
facts = Puppet::Network::Client.master.facts
}
assert_equal(Puppet.version.to_s, facts["clientversion"])
@ -245,7 +245,7 @@ class TestMasterClient < Test::Unit::TestCase
files = []
assert_nothing_raised do
files = Puppet::Network::Client::MasterClient.download(:dest => dest, :source => source, :name => "testing")
files = Puppet::Network::Client.master.download(:dest => dest, :source => source, :name => "testing")
end
assert(FileTest.directory?(dest), "dest dir was not created")
@ -269,7 +269,7 @@ end
end
assert_nothing_raised {
Puppet::Network::Client::MasterClient.getplugins
Puppet::Network::Client.master.getplugins
}
destfile = File.join(Puppet[:plugindest], "myplugin.rb")
@ -297,7 +297,7 @@ end
end
assert_nothing_raised {
Puppet::Network::Client::MasterClient.getplugins
Puppet::Network::Client.master.getplugins
}
destfile = File.join(Puppet[:pluginpath], "myplugin.rb")
@ -317,7 +317,7 @@ end
# Now try it again, to make sure we don't have any objects lying around
assert_nothing_raised {
Puppet::Network::Client::MasterClient.getplugins
Puppet::Network::Client.master.getplugins
}
end
@ -335,7 +335,7 @@ end
end
assert_nothing_raised {
Puppet::Network::Client::MasterClient.getfacts
Puppet::Network::Client.master.getfacts
}
destfile = File.join(Puppet[:factdest], "myfact.rb")
@ -356,7 +356,7 @@ end
end
assert_nothing_raised {
Puppet::Network::Client::MasterClient.getfacts
Puppet::Network::Client.master.getfacts
}
assert_equal("funtest", Facter.value(:myfact),
@ -366,7 +366,7 @@ end
# Now run it again and make sure the fact still loads
assert_nothing_raised {
Puppet::Network::Client::MasterClient.getfacts
Puppet::Network::Client.master.getfacts
}
assert_equal("funtest", Facter.value(:myfact),
@ -400,7 +400,7 @@ end
end
assert_nothing_raised {
Puppet::Network::Client::MasterClient.loadfacts
Puppet::Network::Client.master.loadfacts
}
names.each do |name|
@ -429,7 +429,7 @@ end
assert_nothing_raised {
Puppet::Network::Client::MasterClient.download(:dest => dest, :source => dir,
Puppet::Network::Client.master.download(:dest => dest, :source => dir,
:name => "testing"
) {}
}
@ -446,7 +446,7 @@ end
def test_facts
facts = nil
assert_nothing_raised do
facts = Puppet::Network::Client::MasterClient.facts
facts = Puppet::Network::Client.master.facts
end
Facter.to_hash.each do |fact, value|
assert_equal(facts[fact.downcase], value, "%s is not equal" % fact.inspect)

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

@ -1,18 +0,0 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/client'
class TestClient < Test::Unit::TestCase
def test_set_backtrace
error = Puppet::Network::NetworkClientError.new("An error")
assert_nothing_raised do
error.set_backtrace ["caller"]
end
end
end
# $Id$

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

@ -9,22 +9,11 @@ class TestResourceClient < Test::Unit::TestCase
include PuppetTest::ServerTest
def mkresourceserver
handlers = {
:CA => {}, # so that certs autogenerate
:Resource => {},
}
return mkserver(handlers)
Puppet::Network::Handler.resource.new
end
def mkclient
client = nil
assert_nothing_raised {
client = Puppet::Network::Client::Resource.new(:Server => "localhost",
:Port => @@port)
}
return client
client = Puppet::Network::Client.resource.new(:Resource => mkresourceserver)
end
def test_resources

39
test/network/client_request.rb Executable file
Просмотреть файл

@ -0,0 +1,39 @@
#!/usr/bin/env ruby
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/client_request'
class TestClientRequest < Test::Unit::TestCase
include PuppetTest
def test_initialize
req = nil
assert_nothing_raised do
req = Puppet::Network::ClientRequest.new("name", "ip", false)
end
assert_equal("name", req.name, "host name was not set correctly")
assert_equal("ip", req.ip, "host ip was not set correctly")
assert_equal(false, req.authenticated, "host auth was not set correctly")
assert(! req.authenticated, "host was incorrectly considered authenticated")
req.authenticated = true
assert(req.authenticated, "host was not considered authenticated")
assert_raise(ArgumentError) do
req.call
end
req.handler = "yay"
req.method = "foo"
assert_equal("yay.foo", req.call, "call was not built correctly")
assert_equal("name(ip)", req.to_s, "request string not correct")
end
end
# $Id$

71
test/network/daemon.rb Executable file
Просмотреть файл

@ -0,0 +1,71 @@
#!/usr/bin/env ruby
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/daemon'
class TestDaemon < Test::Unit::TestCase
include PuppetTest
class FakeDaemon
include Puppet::Daemon
end
def test_pidfile
daemon = FakeDaemon.new
assert_nothing_raised("removing non-existent file failed") do
daemon.rmpidfile
end
Puppet[:pidfile] = tempfile()
assert_nothing_raised "could not lock" do
daemon.setpidfile
end
assert(FileTest.exists?(daemon.pidfile),
"did not create pidfile")
assert_nothing_raised("removing non-existent file failed") do
daemon.rmpidfile
end
assert(! FileTest.exists?(daemon.pidfile),
"did not remove pidfile")
end
def test_daemonize
daemon = FakeDaemon.new
Puppet[:pidfile] = tempfile()
exiter = tempfile()
assert_nothing_raised("Could not fork and daemonize") do
fork do
daemon.send(:daemonize)
# Wait a max of 5 secs
50.times do
if FileTest.exists?(exiter)
daemon.rmpidfile
exit(0)
end
sleep 0.1
end
exit(0)
end
end
sleep(0.1)
assert(FileTest.exists?(Puppet[:pidfile]),
"did not create pidfile on daemonize")
File.open(exiter, "w") { |f| f.puts "" }
sleep(0.2)
assert(! FileTest.exists?(Puppet[:pidfile]),
"did not remove pidfile on process death")
end
end
# $Id$

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

@ -3,6 +3,7 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/handler/filebucket'
require 'base64'
class TestBucket < Test::Unit::TestCase
@ -22,8 +23,6 @@ class TestBucket < Test::Unit::TestCase
# run through all of the files and exercise the filebucket methods
def checkfiles(client)
files = filelist()
#files = %w{/usr/local/bin/vim /etc/motd /etc/motd /etc/motd /etc/motd}
#files = %w{/usr/local/bin/vim}
# iterate across all of the files
files.each { |file|
@ -47,11 +46,11 @@ class TestBucket < Test::Unit::TestCase
tsum = nil
nsum = nil
out
assert_nothing_raised {
assert_nothing_raised("Could not back up file") {
osum = client.backup(file)
}
out
assert_nothing_raised {
assert_nothing_raised("Could not back up second file") {
tsum = client.backup(tmppath)
}
out
@ -148,7 +147,7 @@ class TestBucket < Test::Unit::TestCase
files = filelist()
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileBucket.new(
server = Puppet::Network::Handler.filebucket.new(
:Bucket => @bucket
)
}
@ -187,14 +186,14 @@ class TestBucket < Test::Unit::TestCase
client = nil
threads = []
assert_nothing_raised {
bucket = Puppet::Network::Server::FileBucket.new(
bucket = Puppet::Network::Handler.filebucket.new(
:Bucket => @bucket
)
}
#sleep(30)
assert_nothing_raised {
client = Puppet::Network::Client::Dipper.new(
client = Puppet::Network::Client.dipper.new(
:Bucket => bucket
)
}
@ -218,7 +217,7 @@ class TestBucket < Test::Unit::TestCase
pid = mkserver(:CA => {}, :FileBucket => { :Bucket => @bucket})
assert_nothing_raised {
client = Puppet::Network::Client::Dipper.new(
client = Puppet::Network::Client.dipper.new(
:Server => "localhost",
:Port => @@port
)
@ -235,7 +234,7 @@ class TestBucket < Test::Unit::TestCase
def test_no_path_duplicates
bucket = nil
assert_nothing_raised {
bucket = Puppet::Network::Server::FileBucket.new(
bucket = Puppet::Network::Handler.filebucket.new(
:Bucket => @bucket
)
}

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

@ -2,10 +2,8 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet/network/server/ca'
require 'puppet/sslcertificates'
# $Id$
require 'puppettest'
require 'puppet/network/handler/ca'
if ARGV.length > 0 and ARGV[0] == "short"
$short = true
@ -22,7 +20,7 @@ class TestCA < Test::Unit::TestCase
# create our ca
assert_nothing_raised {
ca = Puppet::Network::Server::CA.new(:autosign => true)
ca = Puppet::Network::Handler.ca.new(:autosign => true)
}
# create a cert with a fake name
@ -78,7 +76,7 @@ class TestCA < Test::Unit::TestCase
# make our CA server
assert_nothing_raised {
caserv = Puppet::Network::Server::CA.new(:autosign => false)
caserv = Puppet::Network::Handler.ca.new(:autosign => false)
}
# retrieve the actual ca object
@ -156,7 +154,7 @@ class TestCA < Test::Unit::TestCase
caserv = nil
assert_nothing_raised {
caserv = Puppet::Network::Server::CA.new(:autosign => autosign)
caserv = Puppet::Network::Handler.ca.new(:autosign => autosign)
}
# make sure we know what's going on
@ -170,7 +168,7 @@ class TestCA < Test::Unit::TestCase
def test_nodefaultautosign
caserv = nil
assert_nothing_raised {
caserv = Puppet::Network::Server::CA.new()
caserv = Puppet::Network::Handler.ca.new()
}
# make sure we know what's going on
@ -184,8 +182,9 @@ class TestCA < Test::Unit::TestCase
# the puppetmasterd CA does not autostart.
def test_caautosign
server = nil
Puppet[:name] = "puppetmasterd"
assert_nothing_raised {
server = Puppet::Network::Server.new(
server = Puppet::Network::Server::WEBrick.new(
:Port => @@port,
:Handlers => {
:CA => {}, # so that certs autogenerate
@ -199,7 +198,7 @@ class TestCA < Test::Unit::TestCase
def test_autosign_true_beats_file
caserv = nil
assert_nothing_raised {
caserv = Puppet::Network::Server::CA.new()
caserv = Puppet::Network::Handler.ca.new()
}
host = "hostname.domain.com"
@ -231,3 +230,5 @@ class TestCA < Test::Unit::TestCase
assert(! caserv.autosign?("other.yay.com"), "Host was autosigned")
end
end
# $Id$

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

@ -3,7 +3,7 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/server/fileserver'
require 'puppet/network/handler/fileserver'
class TestFileServer < Test::Unit::TestCase
include PuppetTest
@ -18,7 +18,7 @@ class TestFileServer < Test::Unit::TestCase
# Create a test file
File.open(File.join(base, "file"), "w") { |f| f.puts "bazoo" }
assert_nothing_raised {
mount = Puppet::Network::Server::FileServer::Mount.new(name, base)
mount = Puppet::Network::Handler.fileserver::Mount.new(name, base)
}
return mount
@ -72,25 +72,25 @@ class TestFileServer < Test::Unit::TestCase
def test_namefailures
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
}
assert_raise(Puppet::Network::Server::FileServerError) {
assert_raise(Puppet::Network::Handler::FileServerError) {
server.mount("/tmp", "invalid+name")
}
assert_raise(Puppet::Network::Server::FileServerError) {
assert_raise(Puppet::Network::Handler::FileServerError) {
server.mount("/tmp", "invalid-name")
}
assert_raise(Puppet::Network::Server::FileServerError) {
assert_raise(Puppet::Network::Handler::FileServerError) {
server.mount("/tmp", "invalid name")
}
assert_raise(Puppet::Network::Server::FileServerError) {
assert_raise(Puppet::Network::Handler::FileServerError) {
server.mount("/tmp", "")
}
end
@ -101,11 +101,11 @@ class TestFileServer < Test::Unit::TestCase
testdir, pattern, tmpfile = mktestdir()
file = nil
checks = Puppet::Network::Server::FileServer::CHECKPARAMS
checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
# and make our fileserver
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -139,7 +139,7 @@ class TestFileServer < Test::Unit::TestCase
file = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -194,10 +194,10 @@ class TestFileServer < Test::Unit::TestCase
# go through the whole schtick again...
file = nil
checks = Puppet::Network::Server::FileServer::CHECKPARAMS
checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -235,7 +235,7 @@ class TestFileServer < Test::Unit::TestCase
def test_zmountroot
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -264,7 +264,7 @@ class TestFileServer < Test::Unit::TestCase
def test_recursionlevels
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -315,7 +315,7 @@ class TestFileServer < Test::Unit::TestCase
def test_listedpath
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -358,7 +358,7 @@ class TestFileServer < Test::Unit::TestCase
def test_widelists
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -395,10 +395,10 @@ class TestFileServer < Test::Unit::TestCase
files = mktestfiles(testdir)
file = nil
checks = Puppet::Network::Server::FileServer::CHECKPARAMS
checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -439,7 +439,7 @@ class TestFileServer < Test::Unit::TestCase
# Now try to describe some sources that don't even exist
retval = nil
assert_raise(Puppet::Network::Server::FileServerError,
assert_raise(Puppet::Network::Handler::FileServerError,
"Describing non-existent mount did not raise an error") {
retval = server.describe("/notmounted/" + "noexisties")
}
@ -491,7 +491,7 @@ class TestFileServer < Test::Unit::TestCase
# create a server with the file
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => false,
:Config => conffile
)
@ -604,13 +604,13 @@ class TestFileServer < Test::Unit::TestCase
# create a server with the file
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => conffile
)
}
assert_raise(Puppet::Network::Server::FileServerError,
assert_raise(Puppet::Network::Handler::FileServerError,
"Invalid mount was mounted") {
server.list(mount, :ignore)
}
@ -624,9 +624,9 @@ class TestFileServer < Test::Unit::TestCase
# create a server with the file
server = nil
assert_raise(Puppet::Network::Server::FileServerError,
assert_raise(Puppet::Network::Handler::FileServerError,
"Invalid config %s did not raise error" % i) {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => conffile
)
@ -656,7 +656,7 @@ class TestFileServer < Test::Unit::TestCase
# start our server with a fast timeout
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => false,
:Config => conffile
)
@ -705,7 +705,7 @@ class TestFileServer < Test::Unit::TestCase
name = "yaytest"
path = tmpdir()
assert_nothing_raised {
mount = Puppet::Network::Server::FileServer::Mount.new(name, path)
mount = Puppet::Network::Handler.fileserver::Mount.new(name, path)
}
assert_equal("mount[#{name}]", mount.to_s)
@ -720,7 +720,7 @@ class TestFileServer < Test::Unit::TestCase
File.open(file, "w") { |f| f.puts "yay" }
File.symlink(file, link)
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)
@ -734,7 +734,7 @@ class TestFileServer < Test::Unit::TestCase
results = {}
assert_nothing_raised {
server.describe("/mount/link", :follow).split("\t").zip(
Puppet::Network::Server::FileServer::CHECKPARAMS
Puppet::Network::Handler.fileserver::CHECKPARAMS
).each { |v,p| results[p] = v }
}
@ -744,7 +744,7 @@ class TestFileServer < Test::Unit::TestCase
results = {}
assert_nothing_raised {
server.describe("/mount/link", :ignore).split("\t").zip(
Puppet::Network::Server::FileServer::CHECKPARAMS
Puppet::Network::Handler.fileserver::CHECKPARAMS
).each { |v,p| results[p] = v }
}
@ -799,7 +799,7 @@ allow *
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => conffile
)
@ -917,7 +917,7 @@ allow *
# This isn't a valid replacement pattern, so it should throw an error
# because the dir doesn't exist
assert_raise(Puppet::Network::Server::FileServerError) {
assert_raise(Puppet::Network::Handler::FileServerError) {
mount.path = "/dir/a%"
}
@ -971,7 +971,7 @@ allow *
def test_fileserver_expansion
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::FileServer.new(
server = Puppet::Network::Handler.fileserver.new(
:Local => true,
:Config => false
)

64
test/network/handler/handler.rb Executable file
Просмотреть файл

@ -0,0 +1,64 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/handler'
class TestHandler < Test::Unit::TestCase
include PuppetTest::ServerTest
def test_load_handlers
# Make sure we don't get a failure but that we also get nothing back
assert_nothing_raised do
assert_nil(Puppet::Network::Handler.handler(:fake),
"Got something back from a missing handler")
end
# Make a fake handler
dir = tempfile()
libdir = File.join([dir, %w{puppet network handler}].flatten)
FileUtils.mkdir_p(libdir)
file = File.join(libdir, "fake.rb")
File.open(file, "w") do |f|
f.puts %{class Puppet::Network::Handler
class Fake < Handler
end
end
}
end
$: << dir
cleanup { $:.delete(dir) if $:.include?(dir) }
handler = nil
assert_nothing_raised do
handler = Puppet::Network::Handler.handler(:fake)
end
assert(handler, "did not load handler")
# Now make sure the handler behaves correctly
assert_equal(:Fake, handler.name, "name was not calculated correctly")
Puppet[:trace] = false
assert_raise(Puppet::DevError,
"did not throw an error on missing interface") do
handler.interface
end
end
def test_handlers_by_name
%w{ca filebucket fileserver logger master report resource runner status}.each do |name|
handler = nil
assert_nothing_raised do
handler = Puppet::Network::Handler.handler(name)
end
assert(handler, "did not get handler for %s" % name)
assert(handler.name, "did not get name for %s" % name)
assert(handler.interface, "did not get interface for %s" % name)
assert(handler.interface.prefix, "did not get interface prefix for %s" % name)
end
end
end
# $Id$

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

@ -3,6 +3,7 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/handler/logger'
require 'base64'
require 'cgi'
@ -11,15 +12,18 @@ class TestLogger < Test::Unit::TestCase
def setup
super
#Puppet[:debug] = true
Puppet::Util::Log.newdestination :console
# Send the logs to an array, yo.
Puppet::Util::Log.close
@logs = []
Puppet::Util::Log.newdestination @logs
end
# Test the log driver manually
def test_localaddlog
logger = nil
assert_nothing_raised {
logger = Puppet::Network::Server::Logger.new
logger = Puppet::Network::Handler.logger.new
}
msg = nil
@ -39,7 +43,7 @@ class TestLogger < Test::Unit::TestCase
def test_remoteaddlog
logger = nil
assert_nothing_raised {
logger = Puppet::Network::Server::Logger.new
logger = Puppet::Network::Handler.logger.new
}
msg = nil
@ -62,7 +66,7 @@ class TestLogger < Test::Unit::TestCase
def test_localclient
client = nil
assert_nothing_raised {
client = Puppet::Network::Client::LogClient.new(:Logger => true)
client = Puppet::Network::Client.logger.new(:Logger => true)
}
msg = nil
@ -121,7 +125,7 @@ class TestLogger < Test::Unit::TestCase
# Start a raw xmlrpc client
client = nil
assert_nothing_raised() {
client = Puppet::Network::Client::LogClient.new(
client = Puppet::Network::Client.logger.new(
:Server => "localhost",
:Port => @@port
)

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

@ -3,7 +3,7 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/server'
require 'puppet/network/handler/master'
class TestMaster < Test::Unit::TestCase
include PuppetTest::ServerTest
@ -24,7 +24,7 @@ class TestMaster < Test::Unit::TestCase
# create our master
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => false,
:Local => true
@ -33,7 +33,7 @@ class TestMaster < Test::Unit::TestCase
# and our client
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => master
)
}
@ -69,14 +69,14 @@ class TestMaster < Test::Unit::TestCase
master = nil
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => false,
:Local => true
)
}
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => master
)
}
@ -103,18 +103,19 @@ class TestMaster < Test::Unit::TestCase
client = master = nil
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => manifest,
:UseNodes => false,
:Local => true
)
}
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => master
)
}
assert(client, "did not create master client")
# The client doesn't have a config, so it can't be up to date
assert(! client.fresh?, "Client is incorrectly up to date")
@ -170,7 +171,7 @@ class TestMaster < Test::Unit::TestCase
# create our master
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => false,
:Local => true
@ -209,7 +210,7 @@ class TestMaster < Test::Unit::TestCase
# create our master
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => true,
:Local => true
@ -259,7 +260,7 @@ class TestMaster < Test::Unit::TestCase
# create our master
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => true,
:Local => true
@ -304,7 +305,7 @@ class TestMaster < Test::Unit::TestCase
Puppet[:storeconfigs] = true
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Code => "",
:UseNodes => true,
:Local => true

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

@ -3,20 +3,20 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/server/report'
require 'puppet/network/handler/report'
require 'puppettest/reporttesting'
class TestReportServer < Test::Unit::TestCase
include PuppetTest
include PuppetTest::Reporttesting
Report = Puppet::Network::Server::Report
Report = Puppet::Network::Handler.report
Puppet::Util.logmethods(self)
def mkserver
server = nil
assert_nothing_raised {
server = Puppet::Network::Server::Report.new()
server = Puppet::Network::Handler.report.new()
}
server
end
@ -25,7 +25,7 @@ class TestReportServer < Test::Unit::TestCase
server ||= mkserver()
client = nil
assert_nothing_raised {
client = Puppet::Network::Client::Reporter.new(:Report => server)
client = Puppet::Network::Client.report.new(:Report => server)
}
client
@ -43,7 +43,7 @@ class TestReportServer < Test::Unit::TestCase
$myreportrun = false
file = File.join(libdir, "myreport.rb")
File.open(file, "w") { |f| f.puts %{
Puppet::Network::Server::Report.newreport(:myreport) do
Puppet::Network::Handler.report.newreport(:myreport) do
def process(report)
$myreportrun = true
return report
@ -54,18 +54,18 @@ class TestReportServer < Test::Unit::TestCase
Puppet[:reports] = "myreport"
# Create a server
server = Puppet::Network::Server::Report.new
server = Puppet::Network::Handler.report.new
report = nil
assert_nothing_raised {
report = Puppet::Network::Server::Report.report(:myreport)
report = Puppet::Network::Handler.report.report(:myreport)
}
assert(report, "Did not get report")
end
def test_process
server = Puppet::Network::Server::Report.new
server = Puppet::Network::Handler.report.new
# We have to run multiple reports to make sure there's no conflict
reports = []
@ -102,7 +102,7 @@ class TestReportServer < Test::Unit::TestCase
# Make sure reports can specify whether to use yaml or not
def test_useyaml
server = Puppet::Network::Server::Report.new
server = Puppet::Network::Handler.report.new
Report.newreport(:yamlyes, :useyaml => true) do
def process(report)
@ -133,7 +133,7 @@ class TestReportServer < Test::Unit::TestCase
Puppet[:reports] = "myreport"
# Create a server
server = Puppet::Network::Server::Report.new
server = Puppet::Network::Handler.report.new
{"myreport" => ["myreport"],
" fake, another, yay " => ["fake", "another", "yay"]
@ -172,7 +172,7 @@ class TestReportServer < Test::Unit::TestCase
def test_report_list
list = nil
assert_nothing_raised do
list = Puppet::Network::Server::Report.reports
list = Puppet::Network::Handler.report.reports
end
[:rrdgraph, :store, :tagmail].each do |name|

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

@ -3,7 +3,6 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/server/resource'
require 'base64'
require 'cgi'
@ -38,7 +37,7 @@ class TestResourceServer < Test::Unit::TestCase
server = nil
assert_nothing_raised do
server = Puppet::Network::Server::Resource.new()
server = Puppet::Network::Handler.resource.new()
end
# The first run we create the file on the copy, the second run
@ -118,7 +117,7 @@ class TestResourceServer < Test::Unit::TestCase
server = nil
assert_nothing_raised do
server = Puppet::Network::Server::Resource.new()
server = Puppet::Network::Handler.resource.new()
end
[ [nil],
@ -176,7 +175,7 @@ class TestResourceServer < Test::Unit::TestCase
#Puppet.err Puppet::Type::ParsedType::Port.path
server = nil
assert_nothing_raised do
server = Puppet::Network::Server::Resource.new()
server = Puppet::Network::Handler.resource.new()
end
require 'etc'
@ -238,7 +237,7 @@ class TestResourceServer < Test::Unit::TestCase
def test_apply
server = nil
assert_nothing_raised do
server = Puppet::Network::Server::Resource.new()
server = Puppet::Network::Handler.resource.new()
end
file = tempfile()

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

@ -2,10 +2,9 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet/network/server/runner'
require 'puppettest'
class TestServerRunner < Test::Unit::TestCase
class TestHandlerRunner < Test::Unit::TestCase
include PuppetTest
def mkclient(file)
@ -14,7 +13,7 @@ class TestServerRunner < Test::Unit::TestCase
# create our master
assert_nothing_raised() {
# this is the default server setup
master = Puppet::Network::Server::Master.new(
master = Puppet::Network::Handler.master.new(
:Manifest => file,
:UseNodes => false,
:Local => true
@ -23,7 +22,7 @@ class TestServerRunner < Test::Unit::TestCase
# and our client
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
client = Puppet::Network::Client.master.new(
:Master => master
)
}
@ -51,7 +50,7 @@ class TestServerRunner < Test::Unit::TestCase
runner = nil
assert_nothing_raised {
runner = Puppet::Network::Server::Runner.new
runner = Puppet::Network::Handler.runner.new
}
# First: tags
# Second: ignore schedules true/false

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

@ -1,6 +1,6 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
$:.unshift("../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/rights'

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

@ -1,53 +0,0 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/authconfig'
class TestAuthConfig < Test::Unit::TestCase
include PuppetTest
def test_parsingconfigfile
file = tempfile()
assert(Puppet[:authconfig], "No config path")
Puppet[:authconfig] = file
File.open(file, "w") { |f|
f.puts "[pelementserver.describe]
allow *.madstop.com
deny 10.10.1.1
[fileserver]
allow *.madstop.com
deny 10.10.1.1
[fileserver.list]
allow 10.10.1.1
"
}
config = nil
assert_nothing_raised {
config = Puppet::Network::AuthConfig.new(file)
}
assert_nothing_raised {
assert(config.allowed?("pelementserver.describe",
"culain.madstop.com", "1.1.1.1"), "Did not allow host")
assert(! config.allowed?("pelementserver.describe",
"culain.madstop.com", "10.10.1.1"), "Allowed host")
assert(config.allowed?("fileserver.yay",
"culain.madstop.com", "10.1.1.1"), "Did not allow host to fs")
assert(! config.allowed?("fileserver.yay",
"culain.madstop.com", "10.10.1.1"), "Allowed host to fs")
assert(config.allowed?("fileserver.list",
"culain.madstop.com", "10.10.1.1"), "Did not allow host to fs.list")
}
end
end
# $Id$

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

@ -3,17 +3,39 @@
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/server'
if ARGV.length > 0 and ARGV[0] == "short"
$short = true
else
$short = false
end
require 'puppet/network/server/webrick'
class TestServer < Test::Unit::TestCase
include PuppetTest::ServerTest
# Make sure we can create a server, and that it knows how to create its
# certs by default.
def test_basics
server = nil
assert_raise(Puppet::Error, "server succeeded with no cert") do
server = Puppet::Network::Server::WEBrick.new(
:Port => @@port,
:Handlers => {
:Status => nil
}
)
end
assert_nothing_raised("Could not create simple server") do
server = Puppet::Network::Server::WEBrick.new(
:Port => @@port,
:Handlers => {
:CA => {}, # so that certs autogenerate
:Status => nil
}
)
end
assert(server, "did not create server")
assert(server.cert, "did not retrieve cert")
end
# test that we can connect to the server
# we have to use fork here, because we apparently can't use threads
# to talk to other threads
@ -24,95 +46,15 @@ class TestServer < Test::Unit::TestCase
# create a status client, and verify it can talk
client = mk_status_client
assert(client.cert, "did not get cert for client")
retval = nil
assert_nothing_raised() {
assert_nothing_raised("Could not connect to server") {
retval = client.status
}
assert_equal(1, retval)
end
# similar to the last test, but this time actually run getconfig
def test_getconfig_with_fork
Puppet[:autosign] = true
serverpid = nil
file = mktestmanifest()
server = nil
# make our server again
assert_nothing_raised() {
server = Puppet::Network::Server.new(
:Port => @@port,
:Handlers => {
:CA => {}, # so that certs autogenerate
:Master => {
:UseNodes => false,
:Manifest => file
},
:Status => nil
}
)
}
serverpid = fork {
assert_nothing_raised() {
#trap(:INT) { server.shutdown; Kernel.exit! }
trap(:INT) { server.shutdown }
server.start
}
}
@@tmppids << serverpid
client = nil
# and then start a masterclient
assert_nothing_raised() {
client = Puppet::Network::Client::MasterClient.new(
:Server => "localhost",
:Port => @@port
)
}
retval = nil
# and run getconfig a couple of times
assert_nothing_raised() {
retval = client.getconfig
}
# Try it again, just for kicks
assert_nothing_raised() {
retval = client.getconfig
}
end
def test_setpidfile_setting
Puppet[:setpidfile] = false
server = nil
assert_nothing_raised() {
server = Puppet::Network::Server.new(
:Port => @@port,
:Handlers => {
:CA => {}, # so that certs autogenerate
:Status => nil
}
)
}
assert_nothing_raised {
server.setpidfile
}
assert(! FileTest.exists?(server.pidfile), "PID file was created")
Puppet[:setpidfile] = true
assert_nothing_raised {
server.setpidfile
}
assert(FileTest.exists?(server.pidfile), "PID file was not created")
end
# Test that a client whose cert has been revoked really can't connect
def test_certificate_revocation
Puppet[:autosign] = true
@ -130,8 +72,7 @@ class TestServer < Test::Unit::TestCase
# Revoke the client's cert
ca = Puppet::SSLCertificates::CA.new()
fqdn = client.fqdn
ca.revoke(ca.getclientcert(fqdn)[0].serial)
ca.revoke(ca.getclientcert(Puppet[:certname])[0].serial)
# Restart the server
@@port += 1
@ -141,7 +82,7 @@ class TestServer < Test::Unit::TestCase
client = mk_status_client
# This time the client should be denied
assert_raise(Puppet::Network::NetworkClientError) {
assert_raise(Puppet::Network::XMLRPCClientError) {
client.status
}
end
@ -153,7 +94,7 @@ class TestServer < Test::Unit::TestCase
Puppet::Type::allclear
assert_nothing_raised() {
client = Puppet::Network::Client::StatusClient.new(
client = Puppet::Network::Client.status.new(
:Server => "localhost",
:Port => @@port
)
@ -164,7 +105,7 @@ class TestServer < Test::Unit::TestCase
def mk_status_server
server = nil
assert_nothing_raised() {
server = Puppet::Network::Server.new(
server = Puppet::Network::Server::WEBrick.new(
:Port => @@port,
:Handlers => {
:CA => {}, # so that certs autogenerate
@ -173,7 +114,9 @@ class TestServer < Test::Unit::TestCase
)
}
pid = fork {
Puppet[:name] = "puppetmasterd"
assert_nothing_raised() {
trap(:INT) { server.shutdown }
server.start

68
test/network/xmlrpc/client.rb Executable file
Просмотреть файл

@ -0,0 +1,68 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/xmlrpc/client'
require 'mocha'
class TestXMLRPCClient < Test::Unit::TestCase
def test_set_backtrace
error = Puppet::Network::XMLRPCClientError.new("An error")
assert_nothing_raised do
error.set_backtrace ["caller"]
end
assert_equal(["caller"], error.backtrace)
end
# Make sure we correctly generate a netclient
def test_handler_class
# Create a test handler
klass = Puppet::Network::XMLRPCClient
yay = Class.new(Puppet::Network::Handler) do
@interface = XMLRPC::Service::Interface.new("yay") { |iface|
iface.add_method("array getcert(csr)")
}
@name = :Yay
end
Object.const_set("Yay", yay)
net = nil
assert_nothing_raised("Failed when retrieving client for handler") do
net = klass.handler_class(yay)
end
assert(net, "did not get net client")
end
# Make sure the xmlrpc client is correctly reading all of the cert stuff
# and setting it into the @http var
def test_cert_setup
client = nil
assert_nothing_raised do
client = Puppet::Network::XMLRPCClient.new()
end
ca = Puppet::Network::Handler.ca.new
caclient = Puppet::Network::Client.ca.new :CA => ca
caclient.request_cert
class << client
attr_accessor :http
end
client.http.expects(:ca_file=).with(Puppet[:localcacert])
client.http.expects(:cert=).with(caclient.cert)
client.http.expects(:key=).with(caclient.key)
client.http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
client.http.expects(:cert_store=)
assert_nothing_raised do
client.cert_setup(caclient)
end
end
end
# $Id$

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

@ -0,0 +1,80 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/xmlrpc/processor'
require 'mocha'
class TestXMLRPCProcessor < Test::Unit::TestCase
class BaseProcessor
def add_handler(interface, handler)
@handlers ||= {}
@handlers[interface] = handler
end
end
# We use a base class just so super() works with add_handler.
class Processor < BaseProcessor
include Puppet::Network::XMLRPCProcessor
def set_service_hook(&block)
meta_def(:service, &block)
end
end
def setup
super
@processor = Processor.new
end
def test_handlers
ca = Puppet::Network::Handler.ca
@processor.send(:setup_processor)
assert(! @processor.handler_loaded?(:ca), "already have ca handler loaded")
assert_nothing_raised do
@processor.add_handler(ca.interface, ca.new())
end
assert(@processor.handler_loaded?(:puppetca), "ca handler not loaded by symbol")
assert(@processor.handler_loaded?("puppetca"), "ca handler not loaded by string")
end
def test_process
ca = Puppet::Network::Handler.ca
@processor.send(:setup_processor)
assert_nothing_raised do
@processor.add_handler(ca.interface, ca.new())
end
fakeparser = Class.new do
def parseMethodCall(data)
return data
end
end
request = Puppet::Network::ClientRequest.new("fake", "192.168.0.1", false)
request.handler = "myhandler"
request.method = "mymethod"
@processor.expects(:parser).returns(fakeparser.new)
request.expects(:handler=).with("myhandler")
request.expects(:method=).with("mymethod")
# I can't get this expectation to take with the argument, for some reason.
@processor.expects(:verify)
@processor.expects(:handle).with(request.call,
"params", request.name, request.ip)
@processor.send(:process, ["myhandler.mymethod", ["params"]], request)
end
def test_setup_processor
@processor.expects(:set_service_hook)
@processor.send(:setup_processor)
end
end
# $Id$

28
test/network/xmlrpc/server.rb Executable file
Просмотреть файл

@ -0,0 +1,28 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/xmlrpc/server'
require 'mocha'
class TestXMLRPCServer < Test::Unit::TestCase
def setup
super
assert_nothing_raised do
@server = Puppet::Network::XMLRPCServer.new
end
end
def test_initialize
assert(@server.get_service_hook, "no service hook defined")
assert_nothing_raised("Did not init @loadedhandlers") do
assert(! @server.handler_loaded?(:puppetca),
"server thinks handlers are loaded")
end
end
end
# $Id$

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

@ -0,0 +1,26 @@
#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppet/network/xmlrpc/webrick_servlet'
require 'mocha'
class TestXMLRPCWEBrickServlet < Test::Unit::TestCase
def test_basics
servlet = nil
ca = Puppet::Network::Handler.ca.new
assert_nothing_raised("Could not create servlet") do
servlet = Puppet::Network::XMLRPC::WEBrickServlet.new([ca])
end
assert(servlet.get_service_hook, "service hook was not set up")
assert(servlet.handler_loaded?(:puppetca),
"Did not load handler")
end
end
# $Id$

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше