# the available clients
require 'puppet'
require 'puppet/daemon'
require 'puppet/network/xmlrpc/client'
require 'puppet/util/subclass_loader'
require 'puppet/util/methodhelper'
require 'puppet/sslcertificates/support'
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
attr_accessor :schedule, :lastrun, :local, :stopping
attr_reader :driver
# 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
# Figure out the handler for our client.
def self.handler
unless defined? @handler
@handler = Puppet::Network::Handler.handler(self.name)
end
@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
if hash.include?(:Cache)
@cache = hash[:Cache]
else
@cache = true
end
driverparam = self.class.drivername
if hash.include?(:Server)
args = {:Server => hash[:Server]}
@server = hash[:Server]
args[:Port] = hash[:Port] || Puppet[:masterport]
@driver = self.class.xmlrpc_client.new(args)
if self.read_cert
@driver.cert_setup(self)
end
@local = false
elsif hash.include?(driverparam)
@driver = hash[driverparam]
if @driver == true
@driver = self.class.handler.new
end
@local = true
else
raise Puppet::Network::ClientError, "%s must be passed a Server or %s" %
[self.class, driverparam]
end
end
# Are we a local client?
def local?
if defined? @local and @local
true
else
false
end
end
# Make sure we set the driver up when we read the cert in.
def read_cert
if super
@driver.cert_setup(self) if @driver.respond_to?(:cert_setup)
return true
else
return false
end
end
# A wrapper method to run and then store the last run time
def runnow
if self.stopping
Puppet.notice "In shutdown progress; skipping run"
return
end
begin
self.run
self.lastrun = Time.now.to_i
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err "Could not run %s: %s" % [self.class, detail]
end
end
def run
raise Puppet::DevError, "Client type %s did not override run" %
self.class
end
def scheduled?
if sched = self.schedule
return sched.match?(self.lastrun)
else
return true
end
end
def shutdown
if self.stopping
Puppet.notice "Already in shutdown"
else
self.stopping = true
if self.respond_to? :running? and self.running?
Puppet::Util::Storage.store
end
rmpidfile()
end
end
# Start listening for events. We're pretty much just listening for
# timer events here.
def start
# Create our timer. Puppet will handle observing it and such.
timer = Puppet.newtimer(
:interval => Puppet[:runinterval],
:tolerance => 1,
:start? => true
) do
if self.scheduled?
self.runnow
end
end
# Run once before we start following the timer
self.runnow
end
require 'puppet/network/client/proxy'
end
# $Id: client.rb 2375 2007-03-30 23:17:40Z luke $
syntax highlighted by Code2HTML, v. 0.9.1