summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-04-28 04:08:38 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-04-28 04:08:38 +0000
commitbcfc469e4aa36ab8b98af57b1314e26d5d7a0a18 (patch)
tree0671fccd17cfa5764a5b7e7707d5424cf09420e4 /lib
parent9539dbb5c8b54805a6c26f84f15abd6fdb5532b2 (diff)
downloadpuppet-bcfc469e4aa36ab8b98af57b1314e26d5d7a0a18.tar.gz
puppet-bcfc469e4aa36ab8b98af57b1314e26d5d7a0a18.tar.xz
puppet-bcfc469e4aa36ab8b98af57b1314e26d5d7a0a18.zip
Adding in all of the patches necessary to make a prototype rails interface to puppet nodes work. The biggest change is that there is now a separate NetworkClient class for every Client subclass, because otherwise you get namespace collisions. Most everything other change is a relatively minor patch.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1145 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/client.rb16
-rw-r--r--lib/puppet/client/dipper.rb2
-rw-r--r--lib/puppet/client/master.rb2
-rw-r--r--lib/puppet/client/pelement.rb61
-rw-r--r--lib/puppet/client/proxy.rb3
-rwxr-xr-xlib/puppet/daemon.rb8
-rw-r--r--lib/puppet/log.rb4
-rw-r--r--lib/puppet/networkclient.rb106
-rw-r--r--lib/puppet/server.rb7
-rw-r--r--lib/puppet/server/authconfig.rb6
-rwxr-xr-xlib/puppet/server/pelement.rb42
-rw-r--r--lib/puppet/server/servlet.rb32
-rw-r--r--lib/puppet/sslcertificates/ca.rb6
-rw-r--r--lib/puppet/transportable.rb15
-rw-r--r--lib/puppet/type.rb8
15 files changed, 231 insertions, 87 deletions
diff --git a/lib/puppet/client.rb b/lib/puppet/client.rb
index ae7449240..495e190f9 100644
--- a/lib/puppet/client.rb
+++ b/lib/puppet/client.rb
@@ -22,7 +22,8 @@ module Puppet
attr_accessor :schedule, :lastrun, :local, :stopping
class << self
- attr_reader :drivername
+ attr_reader :drivername, :handler
+ attr_accessor :netclient
end
def initcerts
@@ -75,7 +76,17 @@ module Puppet
args[:CAFile] = @cacertfile
end
- @driver = Puppet::NetworkClient.new(args)
+ 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::NetworkClient.netclient(namespace)
+ self.class.netclient = netclient
+ end
+ @driver = netclient.new(args)
@local = false
elsif hash.include?(driverparam)
@driver = hash[driverparam]
@@ -161,6 +172,7 @@ module Puppet
require 'puppet/client/log'
require 'puppet/client/master'
require 'puppet/client/status'
+ require 'puppet/client/pelement'
end
end
diff --git a/lib/puppet/client/dipper.rb b/lib/puppet/client/dipper.rb
index 5965c6b7d..7271eded9 100644
--- a/lib/puppet/client/dipper.rb
+++ b/lib/puppet/client/dipper.rb
@@ -3,6 +3,8 @@ module Puppet
# The client class for filebuckets.
class Dipper < Puppet::Client
@drivername = :Bucket
+
+ @handler = Puppet::Server::FileBucket
attr_accessor :name
diff --git a/lib/puppet/client/master.rb b/lib/puppet/client/master.rb
index c56946650..b1da61405 100644
--- a/lib/puppet/client/master.rb
+++ b/lib/puppet/client/master.rb
@@ -6,6 +6,8 @@ class Puppet::Client::MasterClient < Puppet::Client
@@sync = Sync.new
end
+ @handler = Puppet::Server::Master
+
Puppet.setdefaults("puppetd",
:puppetdlockfile => [ "$statedir/puppetdlock",
"A lock file to temporarily stop puppetd from doing anything."],
diff --git a/lib/puppet/client/pelement.rb b/lib/puppet/client/pelement.rb
index 116624003..1dda36ddc 100644
--- a/lib/puppet/client/pelement.rb
+++ b/lib/puppet/client/pelement.rb
@@ -1,20 +1,65 @@
-class Puppet::Client::FileClient < Puppet::Client::ProxyClient
- @drivername = :FileServer
+class Puppet::Client::PElement < Puppet::Client
+ @drivername = :PElementServer
- # set up the appropriate interface methods
- @handler = Puppet::Server::FileServer
+ @handler = Puppet::Server::PElement
- self.mkmethods
+ def apply(bucket)
+
+ case bucket
+ when Puppet::TransObject
+ tmp = Puppet::TransBucket.new
+ tmp.push bucket
+ bucket = tmp
+ bucket.name = Facter["hostname"].value
+ bucket.type = "pelement"
+ when Puppet::TransBucket
+ # nothing
+ else
+ raise Puppet::DevError, "You must pass a transportable object, not a %s" %
+ bucket.class
+ end
+
+ unless @local
+ bucket = Base64.encode64(YAML::dump(bucket))
+ end
+ report = @driver.apply(bucket, "yaml")
+
+ return report
+ end
+
+ def describe(type, name, retrieve = false, ignore = false)
+ Puppet.info "Describing %s[%s]" % [type, name]
+ text = @driver.describe(type, name, retrieve, ignore, "yaml")
+
+ object = nil
+ if @local
+ object = text
+ else
+ object = YAML::load(Base64.decode64(text))
+ end
+
+ return object
+ end
def initialize(hash = {})
- if hash.include?(:FileServer)
- unless hash[:FileServer].is_a?(Puppet::Server::FileServer)
- raise Puppet::DevError, "Must pass an actual FS object"
+ if hash.include?(:PElementServer)
+ unless hash[:PElementServer].is_a?(Puppet::Server::PElement)
+ 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")
+
+ unless @local
+ bucket = YAML::load(Base64.decode64(bucket))
+ end
+
+ return bucket
+ end
end
# $Id$
diff --git a/lib/puppet/client/proxy.rb b/lib/puppet/client/proxy.rb
index 2ea0a87f9..6aff635f4 100644
--- a/lib/puppet/client/proxy.rb
+++ b/lib/puppet/client/proxy.rb
@@ -6,10 +6,11 @@ class Puppet::Client::ProxyClient < Puppet::Client
interface = @handler.interface
namespace = interface.prefix
+
interface.methods.each { |ary|
method = ary[0]
Puppet.debug "%s: defining %s.%s" % [self, namespace, method]
- self.send(:define_method,method) { |*args|
+ define_method(method) { |*args|
begin
@driver.send(method, *args)
rescue XMLRPC::FaultException => detail
diff --git a/lib/puppet/daemon.rb b/lib/puppet/daemon.rb
index c4aeefadb..4b9e1f6f0 100755
--- a/lib/puppet/daemon.rb
+++ b/lib/puppet/daemon.rb
@@ -89,6 +89,10 @@ module Puppet
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("."))
@@ -120,6 +124,10 @@ module Puppet
# 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
diff --git a/lib/puppet/log.rb b/lib/puppet/log.rb
index d6d2f9090..9c3c8fc5f 100644
--- a/lib/puppet/log.rb
+++ b/lib/puppet/log.rb
@@ -138,7 +138,7 @@ module Puppet
Puppet.info "Creating log directory %s" %
File.dirname(dest)
rescue => detail
- Log.destination = :console
+ Log.newdestination(:console)
Puppet.err "Could not create log directory: %s" %
detail
return
@@ -149,7 +149,7 @@ module Puppet
# create the log file, if it doesn't already exist
file = File.open(dest,File::WRONLY|File::CREAT|File::APPEND)
rescue => detail
- Log.destination = :console
+ Log.newdestination(:console)
Puppet.err "Could not create log file: %s" %
detail
return
diff --git a/lib/puppet/networkclient.rb b/lib/puppet/networkclient.rb
index 766acef1b..2fbb85f59 100644
--- a/lib/puppet/networkclient.rb
+++ b/lib/puppet/networkclient.rb
@@ -30,52 +30,72 @@ module Puppet
Puppet.err "Could not load client network libs: %s" % $noclientnetworking
else
class NetworkClient < XMLRPC::Client
- #include Puppet::Daemon
-
- # add the methods associated with each namespace
- Puppet::Server::Handler.each { |handler|
- interface = handler.interface
- namespace = interface.prefix
-
- interface.methods.each { |ary|
- method = ary[0]
- Puppet.info "Defining %s.%s" % [namespace, method]
- self.send(:define_method,method) { |*args|
- #Puppet.info "Calling %s" % 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
- #Puppet.err "Could not call %s.%s: Untrusted certificates" %
- # [namespace, method]
- raise NetworkClientError,
- "Certificates were not trusted"
- 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]
- #Puppet.err msg
- raise NetworkClientError, msg
- rescue SocketError => detail
- Puppet.err "Could not find server %s" % @puppetserver
- exit(12)
- rescue => detail
- Puppet.err "Could not call %s.%s: %s" %
- [namespace, method, detail.inspect]
- #raise NetworkClientError.new(detail.to_s)
- if Puppet[:debug]
- puts detail.backtrace
- end
- raise
+ @clients = {}
+
+ # Create a netclient for each handler
+ def self.mkclients
+ # add the methods associated with each namespace
+ Puppet::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.
+ newclient = Class.new(self)
+ @clients[namespace] = newclient
+
+ interface.methods.each { |ary|
+ method = ary[0]
+ Puppet.info "Defining %s.%s" % [namespace, method]
+ if public_method_defined?(method)
+ raise Puppet::DevError, "Method %s is already defined" %
+ method
end
+ newclient.send(:define_method,method) { |*args|
+ #Puppet.info "Calling %s" % 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"
+ 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
+ Puppet.err "Could not find server %s" % @puppetserver
+ exit(12)
+ rescue => detail
+ Puppet.err "Could not call %s.%s: %s" %
+ [namespace, method, detail.inspect]
+ #raise NetworkClientError.new(detail.to_s)
+ if Puppet[:debug]
+ puts detail.backtrace
+ end
+ raise
+ end
+ }
}
}
- }
+ end
+
+ def self.netclient(namespace)
+ if @clients.empty?
+ self.mkclients()
+ end
+
+ @clients[namespace]
+ end
def ca_file=(cafile)
@http.ca_file = cafile
diff --git a/lib/puppet/server.rb b/lib/puppet/server.rb
index 911785e3f..51aaef185 100644
--- a/lib/puppet/server.rb
+++ b/lib/puppet/server.rb
@@ -75,6 +75,12 @@ module Puppet
@driver = ca
@secureinit = true
self.fqdn
+ else
+ if hash.include?(:NoSecureInit)
+ @secureinit = false
+ else
+ @secureinit = true
+ end
end
unless self.readcert
@@ -174,6 +180,7 @@ require 'puppet/server/master'
require 'puppet/server/ca'
require 'puppet/server/fileserver'
require 'puppet/server/filebucket'
+require 'puppet/server/pelement'
require 'puppet/server/logger'
require 'puppet/client'
diff --git a/lib/puppet/server/authconfig.rb b/lib/puppet/server/authconfig.rb
index 05901a207..bc5d713e0 100644
--- a/lib/puppet/server/authconfig.rb
+++ b/lib/puppet/server/authconfig.rb
@@ -51,8 +51,12 @@ class AuthConfig < Puppet::ParsedFile
def initialize(file = nil, parsenow = true)
@file ||= Puppet[:authconfig]
+
+ unless @file
+ raise Puppet::DevError, "No authconfig file defined"
+ end
return unless self.exists?
- super(file)
+ super(@file)
@rights = Rights.new
@configstamp = @configtimeout = @configstatted = nil
diff --git a/lib/puppet/server/pelement.rb b/lib/puppet/server/pelement.rb
index b7fe35f7c..3001cd9a1 100755
--- a/lib/puppet/server/pelement.rb
+++ b/lib/puppet/server/pelement.rb
@@ -19,8 +19,7 @@ class Server::PElement < Server::Handler
begin
case format
when "yaml":
- tmp = YAML::load(CGI.unescape(bucket))
- bucket = tmp
+ bucket = YAML::load(Base64.decode64(bucket))
else
raise Puppet::Error, "Unsupported format '%s'" % format
end
@@ -50,6 +49,7 @@ class Server::PElement < Server::Handler
# Describe a given object. This returns the 'is' values for every state
# available on the object type.
def describe(type, name, retrieve = nil, ignore = [], format = "yaml", client = nil, clientip = nil)
+ Puppet.info "Describing %s[%s]" % [type, name]
@local = true unless client
typeklass = nil
unless typeklass = Puppet.type(type)
@@ -59,6 +59,7 @@ class Server::PElement < Server::Handler
obj = nil
retrieve ||= :all
+ ignore ||= []
if obj = typeklass[name]
obj[:check] = retrieve
@@ -71,6 +72,12 @@ class Server::PElement < Server::Handler
end
end
+ unless obj
+ raise XMLRPC::FaultException.new(
+ 1, "Could not create %s[%s]" % [type, name]
+ )
+ end
+
trans = obj.to_trans
# Now get rid of any attributes they specifically don't want
@@ -87,20 +94,18 @@ class Server::PElement < Server::Handler
end
end
- if @local
- return trans
- else
- str = nil
+ unless @local
case format
when "yaml":
- str = CGI.escape(YAML::dump(trans))
+ trans = Base64.encode64(YAML::dump(trans))
else
raise XMLRPC::FaultException.new(
1, "Unavailable config format %s" % format
)
end
- return CGI.escape(str)
end
+
+ return trans
end
# Create a new fileserving module.
@@ -113,13 +118,15 @@ class Server::PElement < Server::Handler
end
# List all of the elements of a given type.
- def list(type, ignore = [], base = nil, client = nil, clientip = nil)
+ def list(type, ignore = [], base = nil, format = "yaml", client = nil, clientip = nil)
@local = true unless client
typeklass = nil
unless typeklass = Puppet.type(type)
raise Puppet::Error, "Puppet type %s is unsupported" % type
end
+ # They can pass in false
+ ignore ||= []
ignore = [ignore] unless ignore.is_a? Array
bucket = TransBucket.new
bucket.type = typeklass.name
@@ -131,20 +138,25 @@ class Server::PElement < Server::Handler
bucket << object
end
- if @local
- return bucket
- else
- str = nil
+ unless @local
case format
when "yaml":
- str = YAML.dump(bucket)
+ begin
+ bucket = Base64.encode64(YAML::dump(bucket))
+ rescue => detail
+ Puppet.err detail
+ raise XMLRPC::FaultException.new(
+ 1, detail.to_s
+ )
+ end
else
raise XMLRPC::FaultException.new(
1, "Unavailable config format %s" % format
)
end
- return CGI.escape(str)
end
+
+ return bucket
end
private
diff --git a/lib/puppet/server/servlet.rb b/lib/puppet/server/servlet.rb
index dd34fcd03..2ea599c1a 100644
--- a/lib/puppet/server/servlet.rb
+++ b/lib/puppet/server/servlet.rb
@@ -38,25 +38,45 @@ class Server
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
+ begin
if @puppetserver.authconfig.exists?
- return @puppetserver.authconfig.allowed?(method, client, ip)
+ allowed = @puppetserver.authconfig.allowed?(method, client, ip)
+
+ if allowed
+ Puppet.info "Allowing %s(%s) trusted access to %s" %
+ [client, ip, method]
+ return true
+ else
+ Puppet.info "Denying %s(%s) trusted access to %s" %
+ [client, ip, method]
+ return false
+ end
else
+ Puppet.info "No #{@puppetserver.authconfig.file}"
# 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.name == "puppetmasterd" or defined? Test::Unit::TestCase
- Servlet.log "Allowing %s(%s) trusted access to %s" %
+ Puppet.info "Allowing %s(%s) trusted access to %s" %
[client, ip, method]
return true
else
- Servlet.log "Denying %s(%s) trusted access to %s on %s" %
+ Puppet.info "Denying %s(%s) trusted access to %s on %s" %
[client, ip, method, Puppet.name]
return false
end
end
+ rescue => detail
+ puts detail
+ puts detail.backtrace
+ raise
+ end
else
if method =~ /^puppetca\./
Puppet.notice "Allowing %s(%s) untrusted access to CA methods" %
@@ -106,10 +126,8 @@ class Server
@clientip = nil
self.set_service_hook { |obj, *args|
- #raise "crap!"
if @client and @clientip
args.push(@client, @clientip)
- #obj.call(args, @request)
end
begin
obj.call(*args)
@@ -173,10 +191,6 @@ class Server
end
end
end
- #if request.server_cert
- # Puppet.info "server cert is %s" % @request.server_cert
- #end
- #p @request
begin
super
rescue => detail
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index 4e4cd8ba8..72b073378 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -79,7 +79,11 @@ class Puppet::SSLCertificates::CA
if FileTest.exists?(file)
begin
- puts "Removing %s" % file
+ if Puppet.name == "puppetca"
+ puts "Removing %s" % file
+ else
+ Puppet.info "Removing %s" % file
+ end
File.unlink(file)
rescue => detail
raise Puppet::Error, "Could not delete %s: %s" %
diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb
index 0e3c3bb3a..75f40bd08 100644
--- a/lib/puppet/transportable.rb
+++ b/lib/puppet/transportable.rb
@@ -61,10 +61,17 @@ module Puppet
def to_type(parent = nil)
retobj = nil
if type = Puppet::Type.type(self.type)
- unless retobj = type.create(self)
- #Puppet.notice "Could not create %s[%s]" %
- # [self.type, self.name]
- return nil
+ # FIXME This should really be done differently, but...
+ if retobj = type[self.name]
+ self.each do |param, val|
+ retobj[param] = val
+ end
+ else
+ unless retobj = type.create(self)
+ #Puppet.notice "Could not create %s[%s]" %
+ # [self.type, self.name]
+ return nil
+ end
end
#retobj.file = @file
#retobj.line = @line
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 0d727c522..1490c1528 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -2094,7 +2094,13 @@ class Type < Puppet::Element
end
next if @parent.statedefined?(state)
- next unless @parent.class.validstate?(state).checkable?
+ stateklass = @parent.class.validstate?(state)
+
+ unless stateklass
+ raise Puppet::Error, "%s is not a valid attribute for %s" %
+ [state, self.class.name]
+ end
+ next unless stateklass.checkable?
@parent.newstate(state)
}