diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-04-28 04:08:38 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-04-28 04:08:38 +0000 |
commit | bcfc469e4aa36ab8b98af57b1314e26d5d7a0a18 (patch) | |
tree | 0671fccd17cfa5764a5b7e7707d5424cf09420e4 /lib | |
parent | 9539dbb5c8b54805a6c26f84f15abd6fdb5532b2 (diff) | |
download | puppet-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.rb | 16 | ||||
-rw-r--r-- | lib/puppet/client/dipper.rb | 2 | ||||
-rw-r--r-- | lib/puppet/client/master.rb | 2 | ||||
-rw-r--r-- | lib/puppet/client/pelement.rb | 61 | ||||
-rw-r--r-- | lib/puppet/client/proxy.rb | 3 | ||||
-rwxr-xr-x | lib/puppet/daemon.rb | 8 | ||||
-rw-r--r-- | lib/puppet/log.rb | 4 | ||||
-rw-r--r-- | lib/puppet/networkclient.rb | 106 | ||||
-rw-r--r-- | lib/puppet/server.rb | 7 | ||||
-rw-r--r-- | lib/puppet/server/authconfig.rb | 6 | ||||
-rwxr-xr-x | lib/puppet/server/pelement.rb | 42 | ||||
-rw-r--r-- | lib/puppet/server/servlet.rb | 32 | ||||
-rw-r--r-- | lib/puppet/sslcertificates/ca.rb | 6 | ||||
-rw-r--r-- | lib/puppet/transportable.rb | 15 | ||||
-rw-r--r-- | lib/puppet/type.rb | 8 |
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) } |