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:
Родитель
68233706a9
Коммит
46d344b9da
1
bin/pi
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
|
||||
)
|
||||
|
|
29
bin/puppetd
29
bin/puppetd
|
@ -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$
|
|
@ -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$
|
|
@ -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$
|
||||
|
|
@ -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'
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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$
|
||||
|
|
@ -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
|
||||
)
|
|
@ -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
|
|
@ -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$
|
||||
|
|
@ -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$
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче