diff options
37 files changed, 648 insertions, 489 deletions
@@ -1,3 +1,23 @@ +0.24.1 + Updated vim filetype detection. (#900 and #963) + + Default resources like schedules no longer conflict with + managed resources. (#965) + + Removing the ability to disable http keep-alive, since + it didn't really work anyway and it should no longer + be necessary. + + Refactored http keep-alive so it actually works again. + This should be sufficient enough that we no longer need the + ability to disable keep-alive. There is now a central + module responsible for managing HTTP instances, along with + all certificates in those instances. + + Fixed a backward compatibility issue when running 0.23.x + clients against 0.24.0 servers -- relationships would + consistently not work. (#967) + Closing existing http connections when opening a new one, and closing all connections after each run. (#961) diff --git a/bin/puppet b/bin/puppet index 13e99e2a6..f5d230a7a 100755 --- a/bin/puppet +++ b/bin/puppet @@ -198,9 +198,13 @@ begin # Compile our catalog catalog = Puppet::Node::Catalog.find(node) + exit(0) if Puppet[:parseonly] + # Translate it to a RAL catalog catalog = catalog.to_ral + catalog.finalize + # And apply it catalog.apply rescue => detail diff --git a/bin/puppetca b/bin/puppetca index 987295b7a..3ad896b55 100755 --- a/bin/puppetca +++ b/bin/puppetca @@ -10,7 +10,7 @@ # # puppetca [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] # [-g|--generate] [-l|--list] [-s|--sign] [-r|--revoke] -# [-c|--clean] [host] +# [-p|--print] [-c|--clean] [--verify] [host] # # = Description # @@ -55,6 +55,9 @@ # List outstanding certificate requests. If '--all' is specified, # signed certificates are also listed, prefixed by '+'. # +# print:: +# Print the full-text version of a host's certificate. +# # revoke:: # Revoke the certificate of a client. The certificate can be specified # either by its serial number, given as a decimal number or a hexadecimal @@ -73,6 +76,9 @@ # version:: # Print the puppet version number and exit. # +# verify:: +# Verify the named certificate against the local CA certificate. +# # = Example # # $ puppetca -l @@ -99,8 +105,10 @@ options = [ [ "--generate", "-g", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--list", "-l", GetoptLong::NO_ARGUMENT ], + [ "--print", "-p", GetoptLong::NO_ARGUMENT ], [ "--revoke", "-r", GetoptLong::NO_ARGUMENT ], [ "--sign", "-s", GetoptLong::NO_ARGUMENT ], + [ "--verify", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ] ] @@ -114,13 +122,13 @@ mode = nil all = false generate = nil +modes = [:clean, :list, :revoke, :generate, :sign, :print, :verify] + begin result.each { |opt,arg| case opt when "--all" all = true - when "--clean" - mode = :clean when "--debug" Puppet::Util::Log.level = :debug when "--generate" @@ -145,7 +153,12 @@ begin when "--verbose" Puppet::Util::Log.level = :info else - Puppet.settings.handlearg(opt, arg) + tmp = opt.sub("--", '').to_sym + if modes.include?(tmp) + mode = tmp + else + Puppet.settings.handlearg(opt, arg) + end end } rescue GetoptLong::InvalidOption => detail @@ -174,7 +187,7 @@ unless mode exit(12) end -if [:generate, :clean, :revoke, :list].include?(mode) +if [:verify, :print, :generate, :clean, :revoke, :list].include?(mode) hosts = ARGV.collect { |h| h.downcase } end @@ -271,6 +284,11 @@ when :generate cert.cacert = cacert cert.write } +when :print + hosts.each { |h| + cert = ca.getclientcert(h)[0] + puts cert.to_text + } when :revoke hosts.each { |h| serial = nil @@ -291,6 +309,33 @@ when :revoke puts "Revoked certificate with serial #{serial}" end } +when :verify + unless ssl = %x{which openssl}.chomp + raise "Can't verify certificates without the openssl binary and could not find one" + end + success = true + + cacert = Puppet[:localcacert] + + hosts.each do |host| + print "%s: " % host + file = ca.host2certfile(host) + unless FileTest.exist?(file) + puts "no certificate found" + success = false + next + end + + + command = %{#{ssl} verify -CAfile #{cacert} #{file}} + output = %x{#{command}} + if $? == 0 + puts "valid" + else + puts output + success = false + end + end else $stderr.puts "Invalid mode %s" % mode exit(42) diff --git a/bin/puppetd b/bin/puppetd index 1235a36fe..297d4876d 100755 --- a/bin/puppetd +++ b/bin/puppetd @@ -328,7 +328,7 @@ if Puppet[:daemonize] client.daemonize end -unless client.read_cert +unless Puppet::Network::HttpPool.read_cert # If we don't already have the certificate, then create a client to # request one. Use the special ca stuff, don't use the normal server and port. caclient = Puppet::Network::Client.ca.new() @@ -350,7 +350,9 @@ unless client.read_cert end # Now read the new cert in. - if client.read_cert + if Puppet::Network::HttpPool.read_cert + # If we read it in, then get rid of our existing http connection. + client.recycle_connection Puppet.notice "Got signed certificate" else Puppet.err "Could not read certificates after retrieving them" diff --git a/conf/redhat/puppet.spec b/conf/redhat/puppet.spec index 863d33b4b..9811e3492 100644 --- a/conf/redhat/puppet.spec +++ b/conf/redhat/puppet.spec @@ -7,7 +7,7 @@ Summary: A network tool for managing many disparate systems Name: puppet -Version: 0.24.0 +Version: 0.24.1 Release: 1%{?dist} License: GPLv2+ Group: System Environment/Base @@ -157,6 +157,12 @@ fi rm -rf %{buildroot} %changelog +* Sat Dec 22 2007 David Lutterkort <dlutter@redhat.com> - 0.24.1-1 +- New version + +* Mon Dec 17 2007 David Lutterkort <dlutter@redhat.com> - 0.24.0-2 +- Use updated upstream tarball that contains yumhelper.py + * Fri Dec 14 2007 David Lutterkort <dlutter@redhat.com> - 0.24.0-1 - Fixed license - Munge examples/ to make rpmlint happier diff --git a/ext/vim/README b/ext/vim/README new file mode 100644 index 000000000..776bb1eb2 --- /dev/null +++ b/ext/vim/README @@ -0,0 +1,2 @@ +To install these files, copy them into ~/.vim, or the relevant +system-wide location. diff --git a/ext/vim/filetype.vim b/ext/vim/filetype.vim deleted file mode 100644 index 2d73b4bfa..000000000 --- a/ext/vim/filetype.vim +++ /dev/null @@ -1,9 +0,0 @@ -" detect puppet filetypes -" $Id$ - -if exists("did_load_filetypes") - finish -endif -augroup filetypedetect - au! BufRead,BufNewFile *.pp setfiletype puppet -augroup END diff --git a/ext/vim/ftdetect/puppet.vim b/ext/vim/ftdetect/puppet.vim new file mode 100644 index 000000000..c9d15ea53 --- /dev/null +++ b/ext/vim/ftdetect/puppet.vim @@ -0,0 +1,2 @@ +" detect puppet filetype +au BufRead,BufNewFile *.pp set filetype=puppet diff --git a/ext/vim/puppet.vim b/ext/vim/syntax/puppet.vim index a29e368e1..a29e368e1 100644 --- a/ext/vim/puppet.vim +++ b/ext/vim/syntax/puppet.vim diff --git a/lib/puppet.rb b/lib/puppet.rb index 3fc1cee2f..18037cdc1 100644 --- a/lib/puppet.rb +++ b/lib/puppet.rb @@ -25,7 +25,7 @@ require 'puppet/util/suidmanager' # it's also a place to find top-level commands like 'debug' module Puppet - PUPPETVERSION = '0.24.0' + PUPPETVERSION = '0.24.1' def Puppet.version return PUPPETVERSION diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 26afdb4f9..a767d2952 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -385,8 +385,6 @@ module Puppet may need to use a FQDN for the server hostname when using a proxy."], :http_proxy_port => [3128, "The HTTP proxy port to use for outgoing connections"], - :http_keepalive => [true, - "Whether to reuse http connections, thus enabling http-keepalive."], :http_enable_post_connection_check => [true, "Boolean; wheter or not puppetd should validate the server SSL certificate against the request hostname."], diff --git a/lib/puppet/network/client.rb b/lib/puppet/network/client.rb index 52431e227..283436e95 100644 --- a/lib/puppet/network/client.rb +++ b/lib/puppet/network/client.rb @@ -122,13 +122,8 @@ class Puppet::Network::Client end # Make sure we set the driver up when we read the cert in. - def read_cert - if super - @driver.recycle_connection(self) if @driver.respond_to?(:recycle_connection) - return true - else - return false - end + def recycle_connection + @driver.recycle_connection if @driver.respond_to?(:recycle_connection) end # A wrapper method to run and then store the last run time @@ -141,9 +136,7 @@ class Puppet::Network::Client self.run self.lastrun = Time.now.to_i rescue => detail - if Puppet[:trace] - puts detail.backtrace - end + puts detail.backtrace if Puppet[:trace] Puppet.err "Could not run %s: %s" % [self.class, detail] end end @@ -182,8 +175,11 @@ class Puppet::Network::Client :tolerance => 1, :start? => true ) do - if self.scheduled? - self.runnow + begin + self.runnow if self.scheduled? + rescue => detail + puts detail.backtrace if Puppet[:trace] + Puppet.err "Could not run client; got otherwise uncaught exception: %s" % detail end end diff --git a/lib/puppet/network/client/master.rb b/lib/puppet/network/client/master.rb index 341192740..6d1a0235f 100644 --- a/lib/puppet/network/client/master.rb +++ b/lib/puppet/network/client/master.rb @@ -1,6 +1,7 @@ # The client for interacting with the puppetmaster config server. require 'sync' require 'timeout' +require 'puppet/network/http_pool' class Puppet::Network::Client::Master < Puppet::Network::Client unless defined? @@sync @@ -69,7 +70,6 @@ class Puppet::Network::Client::Master < Puppet::Network::Client def clear @catalog.clear(true) if @catalog Puppet::Type.allclear - mkdefault_objects @catalog = nil end @@ -204,17 +204,6 @@ class Puppet::Network::Client::Master < Puppet::Network::Client self.class.instance = self @running = false - - mkdefault_objects - end - - # Make the default objects necessary for function. - def mkdefault_objects - # First create the default scheduling objects - Puppet::Type.type(:schedule).mkdefaultschedules - - # And filebuckets - Puppet::Type.type(:filebucket).mkdefaultbucket end # Mark that we should restart. The Puppet module checks whether we're running, @@ -274,7 +263,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # Now close all of our existing http connections, since there's no # reason to leave them lying open. - Puppet::Network::XMLRPCClient.clear_http_instances + Puppet::Network::HttpPool.clear_http_instances end lockfile.unlock diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb new file mode 100644 index 000000000..99f09a90c --- /dev/null +++ b/lib/puppet/network/http_pool.rb @@ -0,0 +1,92 @@ +require 'puppet/sslcertificates/support' +require 'net/https' + +# Manage Net::HTTP instances for keep-alive. +module Puppet::Network::HttpPool + # This handles reading in the key and such-like. + extend Puppet::SSLCertificates::Support + @http_cache = {} + + # Clear our http cache, closing all connections. + def self.clear_http_instances + @http_cache.each do |name, connection| + connection.finish if connection.started? + end + @http_cache.clear + @cert = nil + @key = nil + end + + # Make sure we set the driver up when we read the cert in. + def self.read_cert + if val = super # This calls read_cert from the Puppet::SSLCertificates::Support module. + # Clear out all of our connections, since they previously had no cert and now they + # should have them. + clear_http_instances + return val + else + return false + end + end + + # Use cert information from a Puppet client to set up the http object. + def self.cert_setup(http) + # Just no-op if we don't have certs. + return false unless (defined?(@cert) and @cert) or self.read_cert + + store = OpenSSL::X509::Store.new + store.add_file Puppet[:localcacert] + store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT + + http.cert_store = store + http.ca_file = Puppet[:localcacert] + http.cert = self.cert + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + http.key = self.key + end + + # Retrieve a cached http instance of caching is enabled, else return + # a new one. + def self.http_instance(host, port, reset = false) + # We overwrite the uninitialized @http here with a cached one. + key = "%s:%s" % [host, port] + + # Return our cached instance if we've got a cache, as long as we're not + # resetting the instance. + return @http_cache[key] if ! reset and @http_cache[key] + + # Clean up old connections if we have them. + if http = @http_cache[key] + @http_cache.delete(key) + http.finish if http.started? + end + + args = [host, port] + if Puppet[:http_proxy_host] == "none" + args << nil << nil + else + args << Puppet[:http_proxy_host] << Puppet[:http_proxy_port] + end + http = Net::HTTP.new(*args) + + # Pop open the http client a little; older versions of Net::HTTP(s) didn't + # give us a reader for ca_file... Grr... + class << http; attr_accessor :ca_file; end + + http.use_ssl = true + http.read_timeout = 120 + http.open_timeout = 120 + # JJM Configurable fix for #896. + if Puppet[:http_enable_post_connection_check] + http.enable_post_connection_check = true + else + http.enable_post_connection_check = false + end + + cert_setup(http) + + @http_cache[key] = http + + return http + end +end diff --git a/lib/puppet/network/http_server/webrick.rb b/lib/puppet/network/http_server/webrick.rb index d2bb7b750..3c9f72e17 100644 --- a/lib/puppet/network/http_server/webrick.rb +++ b/lib/puppet/network/http_server/webrick.rb @@ -27,14 +27,14 @@ module Puppet return nil end unless File.exist?(Puppet[:cacrl]) - raise Puppet::Error, "Could not find CRL" + raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'none' to disable CRL usage" 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" + raise Puppet::Error, "Could not find CA certificate" end store.add_file(Puppet[:localcacert]) diff --git a/lib/puppet/network/xmlrpc/client.rb b/lib/puppet/network/xmlrpc/client.rb index 5048a040a..27bb3dc5e 100644 --- a/lib/puppet/network/xmlrpc/client.rb +++ b/lib/puppet/network/xmlrpc/client.rb @@ -1,4 +1,5 @@ require 'puppet/sslcertificates' +require 'puppet/network/http_pool' require 'openssl' require 'puppet/external/base64' @@ -10,66 +11,15 @@ module Puppet::Network class ClientError < Puppet::Error; end class XMLRPCClientError < Puppet::Error; end class XMLRPCClient < ::XMLRPC::Client + attr_accessor :puppet_server, :puppet_port @clients = {} - @@http_cache = {} class << self include Puppet::Util include Puppet::Util::ClassGen end - # Clear our http cache, closing all connections. - def self.clear_http_instances - @@http_cache.each do |name, connection| - connection.finish if connection.started? - end - @@http_cache.clear - end - - # Retrieve a cached http instance of caching is enabled, else return - # a new one. - def self.http_instance(host, port, reset = false) - # We overwrite the uninitialized @http here with a cached one. - key = "%s:%s" % [host, port] - - # Return our cached instance if keepalive is enabled and we've got - # a cache, as long as we're not resetting the instance. - return @@http_cache[key] if ! reset and Puppet[:http_keepalive] and @@http_cache[key] - - # Clean up old connections if we have them. - if http = @@http_cache[key] - @@http_cache.delete(key) - http.finish if http.started? - end - - args = [host, port] - if Puppet[:http_proxy_host] == "none" - args << nil << nil - else - args << Puppet[:http_proxy_host] << Puppet[:http_proxy_port] - end - http = Net::HTTP.new(*args) - - # Pop open the http client a little; older versions of Net::HTTP(s) didn't - # give us a reader for ca_file... Grr... - class << http; attr_accessor :ca_file; end - - http.use_ssl = true - http.read_timeout = 120 - http.open_timeout = 120 - # JJM Configurable fix for #896. - if Puppet[:http_enable_post_connection_check] - http.enable_post_connection_check = true - else - http.enable_post_connection_check = false - end - - @@http_cache[key] = http if Puppet[:http_keepalive] - - return http - end - # Create a netclient for each handler def self.mkclient(handler) interface = handler.interface @@ -81,8 +31,7 @@ module Puppet::Network # they want. constant = handler.name.to_s.capitalize name = namespace.downcase - newclient = genclass(name, :hash => @clients, - :constant => constant) + newclient = genclass(name, :hash => @clients, :constant => constant) interface.methods.each { |ary| method = ary[0] @@ -97,7 +46,7 @@ module Puppet::Network rescue OpenSSL::SSL::SSLError => detail if detail.message =~ /bad write retry/ Puppet.warning "Transient SSL write error; restarting connection and retrying" - self.recycle_connection(@cert_client) + self.recycle_connection retry end raise XMLRPCClientError, @@ -118,7 +67,7 @@ module Puppet::Network raise error rescue Errno::EPIPE, EOFError Puppet.warning "Other end went away; restarting connection and retrying" - self.recycle_connection(@cert_client) + self.recycle_connection retry rescue => detail if detail.message =~ /^Wrong size\. Was \d+, should be \d+$/ @@ -141,30 +90,6 @@ module Puppet::Network @clients[handler] || self.mkclient(handler) end - # Use cert information from a Puppet client to set up the http object. - def cert_setup(client) - # Cache it for next time - @cert_client = client - - unless FileTest.exist?(Puppet[:localcacert]) - raise Puppet::SSLCertificates::Support::MissingCertificate, - "Could not find ca certificate %s" % Puppet[:localcacert] - end - - # We can't overwrite certificates, @http will freeze itself - # once started. - unless @http.ca_file - @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 - end - def initialize(hash = {}) hash[:Path] ||= "/RPC2" hash[:Server] ||= Puppet[:server] @@ -188,13 +113,15 @@ module Puppet::Network true, # use_ssl 120 # a two minute timeout, instead of 30 seconds ) - @http = self.class.http_instance(@host, @port) + @http = Puppet::Network::HttpPool.http_instance(@host, @port) end - def recycle_connection(client) - @http = self.class.http_instance(@host, @port, true) # reset the instance - - cert_setup(client) + # Get rid of our existing connection, replacing it with a new one. + # This should only happen if we lose our connection somehow (e.g., an EPIPE) + # or we've just downloaded certs and we need to create new http instances + # with the certs added. + def recycle_connection + @http = Puppet::Network::HttpPool.http_instance(@host, @port, true) # reset the instance end def start diff --git a/lib/puppet/node/catalog.rb b/lib/puppet/node/catalog.rb index a02d59ae9..c9de2019d 100644 --- a/lib/puppet/node/catalog.rb +++ b/lib/puppet/node/catalog.rb @@ -260,6 +260,8 @@ class Puppet::Node::Catalog < Puppet::PGraph # Make sure all of our resources are "finished". def finalize + make_default_resources + @resource_table.values.each { |resource| resource.finish } write_graph(:resources) @@ -287,6 +289,20 @@ class Puppet::Node::Catalog < Puppet::PGraph finalize() end end + + # Make the default objects necessary for function. + def make_default_resources + # We have to add the resources to the catalog, or else they won't get cleaned up after + # the transaction. + + # First create the default scheduling objects + Puppet::Type.type(:schedule).mkdefaultschedules.each { |res| add_resource(res) unless resource(res.ref) } + + # And filebuckets + if bucket = Puppet::Type.type(:filebucket).mkdefaultbucket + add_resource(bucket) + end + end # Create a graph of all of the relationships in our catalog. def relationship_graph @@ -367,6 +383,11 @@ class Puppet::Node::Catalog < Puppet::PGraph end end + # Return an array of all resources. + def resources + @resource_table.keys + end + # Add a tag. def tag(*names) names.each do |name| diff --git a/lib/puppet/parser/resource/reference.rb b/lib/puppet/parser/resource/reference.rb index 1dd816093..6e70d23b7 100644 --- a/lib/puppet/parser/resource/reference.rb +++ b/lib/puppet/parser/resource/reference.rb @@ -62,7 +62,13 @@ class Puppet::Parser::Resource::Reference < Puppet::ResourceReference end def to_ref - return [type.to_s,title.to_s] + # We have to return different cases to provide backward compatibility + # from 0.24.x to 0.23.x. + if builtin? + return [type.to_s.downcase, title.to_s] + else + return [type.to_s, title.to_s] + end end def typeclass diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb index 4af299283..98ca1efa6 100755 --- a/lib/puppet/provider/package/rpm.rb +++ b/lib/puppet/provider/package/rpm.rb @@ -92,6 +92,19 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr end def uninstall + query unless get(:arch) + nvr = "#{get(:name)}-#{get(:version)}-#{get(:release)}" + arch = ".#{get(:arch)}" + # If they specified an arch in the manifest, erase that Otherwise, + # erase the arch we got back from the query. If multiple arches are + # installed and only the package name is specified (without the + # arch), this will uninstall all of them on successive runs of the + # client, one after the other + if @resource[:name][-arch.size, arch.size] == arch + nvr += arch + else + nvr += ".#{get(:arch)}" + end rpm "-e", nvr end @@ -99,11 +112,6 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr self.install end - def nvr - query unless @nvr - @nvr - end - def self.nevra_to_hash(line) line.chomp! hash = {} diff --git a/lib/puppet/sslcertificates/support.rb b/lib/puppet/sslcertificates/support.rb index e63458b33..1d692c994 100644 --- a/lib/puppet/sslcertificates/support.rb +++ b/lib/puppet/sslcertificates/support.rb @@ -30,25 +30,23 @@ module Puppet::SSLCertificates::Support define_method(reader) do return nil unless FileTest.exists?(Puppet[param]) begin - instance_variable_set(var, - klass.new(File.read(Puppet[param]))) + instance_variable_set(var, klass.new(File.read(Puppet[param]))) rescue => detail - raise InvalidCertificate, "Could not read %s: %s" % - [param, 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 = instance_variable_get(var) unless cert = send(reader) cert = send(maker) Puppet.settings.write(param) { |f| f.puts cert.to_pem } end instance_variable_set(var, cert) end - instance_variable_get(var) + cert end end diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index bccdaa265..f86e1e273 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -72,12 +72,7 @@ module Puppet filebucketed files. " - defaultto do - # Make sure the default file bucket exists. - obj = Puppet::Type.type(:filebucket)["puppet"] || - Puppet::Type.type(:filebucket).create(:name => "puppet") - obj.bucket - end + defaultto { "puppet" } munge do |value| # I don't really know how this is happening. diff --git a/lib/puppet/type/pfilebucket.rb b/lib/puppet/type/pfilebucket.rb index cf4e5aac3..b268610e9 100755 --- a/lib/puppet/type/pfilebucket.rb +++ b/lib/puppet/type/pfilebucket.rb @@ -66,9 +66,9 @@ module Puppet # Create a default filebucket. def self.mkdefaultbucket unless default = self["puppet"] - default = self.create :name => "puppet", :path => Puppet[:clientbucketdir] + return self.create(:name => "puppet", :path => Puppet[:clientbucketdir]) end - default + return nil end def self.instances diff --git a/lib/puppet/util/filetype.rb b/lib/puppet/util/filetype.rb index 81d93a924..1c7734cc4 100755 --- a/lib/puppet/util/filetype.rb +++ b/lib/puppet/util/filetype.rb @@ -74,7 +74,8 @@ class Puppet::Util::FileType # Pick or create a filebucket to use. def bucket - Puppet::Type.type(:filebucket).mkdefaultbucket.bucket + filebucket = Puppet::Type.type(:filebucket) + (filebucket["puppet"] || filebucket.mkdefaultbucket).bucket end def initialize(path) diff --git a/spec/unit/network/http_pool.rb b/spec/unit/network/http_pool.rb new file mode 100755 index 000000000..49da7d8f3 --- /dev/null +++ b/spec/unit/network/http_pool.rb @@ -0,0 +1,227 @@ +#!/usr/bin/env ruby +# +# Created by Luke Kanies on 2007-11-26. +# Copyright (c) 2007. All rights reserved. + +require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/network/http_pool' + +describe Puppet::Network::HttpPool, " when adding certificate information to http instances" do + before do + @http = mock 'http' + end + + it "should do nothing if no certificate is available" do + Puppet::Network::HttpPool.expects(:read_cert).returns(false) + @http.expects(:cert=).never + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should add a certificate store" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + store = stub "store" + OpenSSL::X509::Store.expects(:new).returns(store) + store.stubs(:add_file) + store.stubs(:purpose=) + [:verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) } + @http.expects(:cert_store=).with(store) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should add the local CA cert to the certificate store" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + store = stub "store" + OpenSSL::X509::Store.expects(:new).returns(store) + store.stubs(:purpose=) + @http.stubs(:cert_store=) + Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file") + Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file") + store.expects(:add_file).with("/some/file") + [:store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) } + + Puppet::Network::HttpPool.stubs(:key).returns(:whatever) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should set the purpose of the cert store to OpenSSL::X509::PURPOSE_SSL_CLIENT" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + store = stub "store" + OpenSSL::X509::Store.expects(:new).returns(store) + store.stubs(:add_file) + [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) } + + store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should add the client certificate" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + Puppet::Network::HttpPool.stubs(:cert).returns(:mycert) + [:cert_store=, :verify_mode=, :ca_file=, :key=].each { |method| @http.stubs(method) } + + @http.expects(:cert=).with(:mycert) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should add the client key" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + Puppet::Network::HttpPool.stubs(:key).returns(:mykey) + [:cert_store=, :verify_mode=, :cert=, :ca_file=].each { |method| @http.stubs(method) } + + @http.expects(:key=).with(:mykey) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should set the verify mode to OpenSSL::SSL::VERIFY_PEER" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + [:key=, :cert=, :cert_store=, :ca_file=].each { |method| @http.stubs(method) } + + @http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should set the ca file" do + Puppet::Network::HttpPool.stubs(:read_cert).returns(true) + Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file") + [:key=, :cert=, :cert_store=, :verify_mode=].each { |method| @http.stubs(method) } + + store = stub "store" + OpenSSL::X509::Store.expects(:new).returns(store) + store.stubs(:purpose=) + store.stubs(:add_file) + + @http.expects(:ca_file=).with("/some/file") + + Puppet::Network::HttpPool.stubs(:key).returns(:whatever) + + Puppet::Network::HttpPool.cert_setup(@http) + end + + it "should set up certificate information when creating http instances" do + Puppet::Network::HttpPool.expects(:cert_setup).with { |i| i.is_a?(Net::HTTP) } + Puppet::Network::HttpPool.http_instance("one", "two") + end + + after do + Puppet::Network::HttpPool.clear_http_instances + end +end + +describe Puppet::Network::HttpPool, " when managing http instances" do + def stub_settings(settings) + settings.each do |param, value| + Puppet.settings.stubs(:value).with(param).returns(value) + end + end + + before do + # All of hte cert stuff is tested elsewhere + Puppet::Network::HttpPool.stubs(:cert_setup) + end + + it "should return an http instance created with the passed host and port" do + http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :enable_post_connection_check= => nil, :started? => false + Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http) + Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http) + end + + it "should enable ssl on the http instance" do + Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true + end + + it "should set the read timeout" do + Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120 + end + + it "should set the open timeout" do + Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120 + end + + it "should default to http_enable_post_connection_check being enabled" do + Puppet.settings[:http_enable_post_connection_check].should be_true + end + + # JJM: I'm not sure if this is correct, as this really follows the + # configuration option. + it "should set enable_post_connection_check true " do + Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@enable_post_connection_check").should be_true + end + + it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120 + end + + it "should cache http instances" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + old = Puppet::Network::HttpPool.http_instance("me", 54321) + Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old) + end + + it "should have a mechanism for getting a new http instance instead of the cached instance" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + old = Puppet::Network::HttpPool.http_instance("me", 54321) + Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old) + end + + it "should close existing, open connections when requesting a new connection" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + old = Puppet::Network::HttpPool.http_instance("me", 54321) + old.expects(:started?).returns(true) + old.expects(:finish) + Puppet::Network::HttpPool.http_instance("me", 54321, true) + end + + it "should have a mechanism for clearing the http cache" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + old = Puppet::Network::HttpPool.http_instance("me", 54321) + Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old) + old = Puppet::Network::HttpPool.http_instance("me", 54321) + Puppet::Network::HttpPool.clear_http_instances + Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old) + end + + it "should close open http connections when clearing the cache" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + one = Puppet::Network::HttpPool.http_instance("me", 54321) + one.expects(:started?).returns(true) + one.expects(:finish).returns(true) + Puppet::Network::HttpPool.clear_http_instances + end + + it "should not close unopened http connections when clearing the cache" do + stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true + one = Puppet::Network::HttpPool.http_instance("me", 54321) + one.expects(:started?).returns(false) + one.expects(:finish).never + Puppet::Network::HttpPool.clear_http_instances + end + + # We mostly have to do this for testing, since in real life people + # won't change certs within a single process. + it "should remove its loaded certificate when clearing the cache" do + Puppet::Network::HttpPool.instance_variable_set("@cert", :yay) + Puppet::Network::HttpPool.clear_http_instances + # Can't use the accessor, because it will read the cert in + Puppet::Network::HttpPool.instance_variable_get("@cert").should be_nil + end + + # We mostly have to do this for testing, since in real life people + # won't change certs within a single process. + it "should remove its loaded key when clearing the cache" do + Puppet::Network::HttpPool.instance_variable_set("@key", :yay) + Puppet::Network::HttpPool.clear_http_instances + # Can't use the accessor, because it will read the cert in + Puppet::Network::HttpPool.instance_variable_get("@key").should be_nil + end + + after do + Puppet::Network::HttpPool.clear_http_instances + end +end diff --git a/spec/unit/network/xmlrpc/client.rb b/spec/unit/network/xmlrpc/client.rb deleted file mode 100755 index b40486e13..000000000 --- a/spec/unit/network/xmlrpc/client.rb +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env ruby -# -# Created by Luke Kanies on 2007-11-26. -# Copyright (c) 2007. All rights reserved. - -require File.dirname(__FILE__) + '/../../../spec_helper' -require 'puppet/network/xmlrpc/client' - -describe Puppet::Network::XMLRPCClient, " when managing http instances" do - def stub_settings(settings) - settings.each do |param, value| - Puppet.settings.stubs(:value).with(param).returns(value) - end - end - - it "should return an http instance created with the passed host and port" do - http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :enable_post_connection_check= => nil, :started? => false - Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http) - Puppet::Network::XMLRPCClient.http_instance("me", 54321).should equal(http) - end - - it "should enable ssl on the http instance" do - Puppet::Network::XMLRPCClient.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true - end - - it "should set the read timeout" do - Puppet::Network::XMLRPCClient.http_instance("me", 54321).read_timeout.should == 120 - end - - it "should set the open timeout" do - Puppet::Network::XMLRPCClient.http_instance("me", 54321).open_timeout.should == 120 - end - - it "should default to http_enable_post_connection_check being enabled" do - Puppet.settings[:http_enable_post_connection_check].should be_true - end - - # JJM: I'm not sure if this is correct, as this really follows the - # configuration option. - it "should set enable_post_connection_check true " do - Puppet::Network::XMLRPCClient.http_instance("me", 54321).instance_variable_get("@enable_post_connection_check").should be_true - end - - it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - Puppet::Network::XMLRPCClient.http_instance("me", 54321).open_timeout.should == 120 - end - - it "should default to keep-alive being enabled" do - Puppet.settings[:http_keepalive].should be_true - end - - it "should cache http instances if keepalive is enabled" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - old = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - Puppet::Network::XMLRPCClient.http_instance("me", 54321).should equal(old) - end - - it "should not cache http instances if keepalive is not enabled" do - stub_settings :http_keepalive => false, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - old = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - Puppet::Network::XMLRPCClient.http_instance("me", 54321).should_not equal(old) - end - - it "should have a mechanism for getting a new http instance instead of the cached instance" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - old = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - Puppet::Network::XMLRPCClient.http_instance("me", 54321, true).should_not equal(old) - end - - it "should close existing, open connections when requesting a new connection" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - old = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - old.expects(:started?).returns(true) - old.expects(:finish) - Puppet::Network::XMLRPCClient.http_instance("me", 54321, true) - end - - it "should have a mechanism for clearing the http cache" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - old = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - Puppet::Network::XMLRPCClient.http_instance("me", 54321).should equal(old) - old = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - Puppet::Network::XMLRPCClient.clear_http_instances - Puppet::Network::XMLRPCClient.http_instance("me", 54321).should_not equal(old) - end - - it "should close open http connections when clearing the cache" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - one = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - one.expects(:started?).returns(true) - one.expects(:finish).returns(true) - Puppet::Network::XMLRPCClient.clear_http_instances - end - - it "should not close unopened http connections when clearing the cache" do - stub_settings :http_keepalive => true, :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true - one = Puppet::Network::XMLRPCClient.http_instance("me", 54321) - one.expects(:started?).returns(false) - one.expects(:finish).never - Puppet::Network::XMLRPCClient.clear_http_instances - end - - after do - Puppet::Network::XMLRPCClient.clear_http_instances - end -end diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb index a94ace68f..3833890f7 100755 --- a/spec/unit/node/catalog.rb +++ b/spec/unit/node/catalog.rb @@ -204,43 +204,43 @@ describe Puppet::Node::Catalog, " when converting to a transobject catalog" do @original.add_edge!(@middle, @bottom) @original.add_edge!(@bottom, @bottomobject) - @config = @original.to_transportable + @catalog = @original.to_transportable end it "should add all resources as TransObjects" do - @resources.each { |resource| @config.resource(resource.ref).should be_instance_of(Puppet::TransObject) } + @resources.each { |resource| @catalog.resource(resource.ref).should be_instance_of(Puppet::TransObject) } end it "should not extract defined virtual resources" do - @config.vertices.find { |v| v.name == "virtual" }.should be_nil + @catalog.vertices.find { |v| v.name == "virtual" }.should be_nil end it "should not extract builtin virtual resources" do - @config.vertices.find { |v| v.name == "virtualobject" }.should be_nil + @catalog.vertices.find { |v| v.name == "virtualobject" }.should be_nil end it "should copy the tag list to the new catalog" do - @config.tags.sort.should == @original.tags.sort + @catalog.tags.sort.should == @original.tags.sort end it "should copy the class list to the new catalog" do - @config.classes.should == @original.classes + @catalog.classes.should == @original.classes end it "should duplicate the original edges" do @original.edges.each do |edge| next if edge.source.virtual? or edge.target.virtual? - source = @config.resource(edge.source.ref) - target = @config.resource(edge.target.ref) + source = @catalog.resource(edge.source.ref) + target = @catalog.resource(edge.target.ref) source.should_not be_nil target.should_not be_nil - @config.edge?(source, target).should be_true + @catalog.edge?(source, target).should be_true end end it "should set itself as the catalog for each converted resource" do - @config.vertices.each { |v| v.catalog.object_id.should equal(@config.object_id) } + @catalog.vertices.each { |v| v.catalog.object_id.should equal(@catalog.object_id) } end end @@ -267,29 +267,29 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do @original.add_edge!(@middle, @bottom) @original.add_edge!(@bottom, @bottomobject) - @config = @original.to_ral + @catalog = @original.to_ral end it "should add all resources as RAL instances" do - @resources.each { |resource| @config.resource(resource.ref).should be_instance_of(Puppet::Type) } + @resources.each { |resource| @catalog.resource(resource.ref).should be_instance_of(Puppet::Type) } end it "should copy the tag list to the new catalog" do - @config.tags.sort.should == @original.tags.sort + @catalog.tags.sort.should == @original.tags.sort end it "should copy the class list to the new catalog" do - @config.classes.should == @original.classes + @catalog.classes.should == @original.classes end it "should duplicate the original edges" do @original.edges.each do |edge| - @config.edge?(@config.resource(edge.source.ref), @config.resource(edge.target.ref)).should be_true + @catalog.edge?(@catalog.resource(edge.source.ref), @catalog.resource(edge.target.ref)).should be_true end end it "should set itself as the catalog for each converted resource" do - @config.vertices.each { |v| v.catalog.object_id.should equal(@config.object_id) } + @catalog.vertices.each { |v| v.catalog.object_id.should equal(@catalog.object_id) } end # This tests #931. @@ -310,83 +310,93 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do Puppet::Type.allclear - proc { @config = config.to_ral }.should_not raise_error - @config.resource("Test[changer2]").should equal(resource) + proc { @catalog = config.to_ral }.should_not raise_error + @catalog.resource("Test[changer2]").should equal(resource) end after do # Remove all resource instances. - @config.clear(true) + @catalog.clear(true) end end describe Puppet::Node::Catalog, " when functioning as a resource container" do before do - @config = Puppet::Node::Catalog.new("host") + @catalog = Puppet::Node::Catalog.new("host") @one = stub 'resource1', :ref => "Me[one]", :catalog= => nil @two = stub 'resource2', :ref => "Me[two]", :catalog= => nil @dupe = stub 'resource3', :ref => "Me[one]", :catalog= => nil end it "should provide a method to add one or more resources" do - @config.add_resource @one, @two - @config.resource(@one.ref).should equal(@one) - @config.resource(@two.ref).should equal(@two) + @catalog.add_resource @one, @two + @catalog.resource(@one.ref).should equal(@one) + @catalog.resource(@two.ref).should equal(@two) end it "should set itself as the resource's catalog if it is not a relationship graph" do - @one.expects(:catalog=).with(@config) - @config.add_resource @one + @one.expects(:catalog=).with(@catalog) + @catalog.add_resource @one end it "should not set itself as the resource's catalog if it is a relationship graph" do @one.expects(:catalog=).never - @config.is_relationship_graph = true - @config.add_resource @one + @catalog.is_relationship_graph = true + @catalog.add_resource @one end it "should make all vertices available by resource reference" do - @config.add_resource(@one) - @config.resource(@one.ref).should equal(@one) - @config.vertices.find { |r| r.ref == @one.ref }.should equal(@one) + @catalog.add_resource(@one) + @catalog.resource(@one.ref).should equal(@one) + @catalog.vertices.find { |r| r.ref == @one.ref }.should equal(@one) end it "should canonize how resources are referred to during retrieval when both type and title are provided" do - @config.add_resource(@one) + @catalog.add_resource(@one) - @config.resource("me", "one").should equal(@one) + @catalog.resource("me", "one").should equal(@one) end it "should canonize how resources are referred to during retrieval when just the title is provided" do - @config.add_resource(@one) + @catalog.add_resource(@one) - @config.resource("me[one]", nil).should equal(@one) + @catalog.resource("me[one]", nil).should equal(@one) end it "should not allow two resources with the same resource reference" do - @config.add_resource(@one) - proc { @config.add_resource(@dupe) }.should raise_error(ArgumentError) + @catalog.add_resource(@one) + proc { @catalog.add_resource(@dupe) }.should raise_error(ArgumentError) end it "should not store objects that do not respond to :ref" do - proc { @config.add_resource("thing") }.should raise_error(ArgumentError) + proc { @catalog.add_resource("thing") }.should raise_error(ArgumentError) end it "should remove all resources when asked" do - @config.add_resource @one - @config.add_resource @two + @catalog.add_resource @one + @catalog.add_resource @two @one.expects :remove @two.expects :remove - @config.clear(true) + @catalog.clear(true) end it "should support a mechanism for finishing resources" do @one.expects :finish @two.expects :finish - @config.add_resource @one - @config.add_resource @two + @catalog.add_resource @one + @catalog.add_resource @two - @config.finalize + @catalog.finalize + end + + it "should make default resources when finalizing" do + @catalog.expects(:make_default_resources) + @catalog.finalize + end + + it "should add default resources to the catalog upon creation" do + @catalog.make_default_resources + @catalog.resource(:schedule, "daily").should_not be_nil end it "should optionally support an initialization block and should finalize after such blocks" do @@ -399,60 +409,64 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do end it "should inform the resource that it is the resource's catalog" do - @one.expects(:catalog=).with(@config) - @config.add_resource @one + @one.expects(:catalog=).with(@catalog) + @catalog.add_resource @one end it "should be able to find resources by reference" do - @config.add_resource @one - @config.resource(@one.ref).should equal(@one) + @catalog.add_resource @one + @catalog.resource(@one.ref).should equal(@one) end it "should be able to find resources by reference or by type/title tuple" do - @config.add_resource @one - @config.resource("me", "one").should equal(@one) + @catalog.add_resource @one + @catalog.resource("me", "one").should equal(@one) end it "should have a mechanism for removing resources" do - @config.add_resource @one + @catalog.add_resource @one @one.expects :remove - @config.remove_resource(@one) - @config.resource(@one.ref).should be_nil - @config.vertex?(@one).should be_false + @catalog.remove_resource(@one) + @catalog.resource(@one.ref).should be_nil + @catalog.vertex?(@one).should be_false end it "should have a method for creating aliases for resources" do - @config.add_resource @one - @config.alias(@one, "other") - @config.resource("me", "other").should equal(@one) + @catalog.add_resource @one + @catalog.alias(@one, "other") + @catalog.resource("me", "other").should equal(@one) end # This test is the same as the previous, but the behaviour should be explicit. it "should alias using the class name from the resource reference, not the resource class name" do - @config.add_resource @one - @config.alias(@one, "other") - @config.resource("me", "other").should equal(@one) + @catalog.add_resource @one + @catalog.alias(@one, "other") + @catalog.resource("me", "other").should equal(@one) end it "should fail to add an alias if the aliased name already exists" do - @config.add_resource @one - proc { @config.alias @two, "one" }.should raise_error(ArgumentError) + @catalog.add_resource @one + proc { @catalog.alias @two, "one" }.should raise_error(ArgumentError) end it "should remove resource aliases when the target resource is removed" do - @config.add_resource @one - @config.alias(@one, "other") + @catalog.add_resource @one + @catalog.alias(@one, "other") @one.expects :remove - @config.remove_resource(@one) - @config.resource("me", "other").should be_nil + @catalog.remove_resource(@one) + @catalog.resource("me", "other").should be_nil + end + + after do + Puppet::Type.allclear end end module ApplyingCatalogs def setup - @config = Puppet::Node::Catalog.new("host") + @catalog = Puppet::Node::Catalog.new("host") - @config.retrieval_duration = Time.now + @catalog.retrieval_duration = Time.now @transaction = mock 'transaction' Puppet::Transaction.stubs(:new).returns(@transaction) @transaction.stubs(:evaluate) @@ -466,7 +480,7 @@ describe Puppet::Node::Catalog, " when applying" do it "should create and evaluate a transaction" do @transaction.expects(:evaluate) - @config.apply + @catalog.apply end it "should provide the catalog time to the transaction" do @@ -474,36 +488,36 @@ describe Puppet::Node::Catalog, " when applying" do arg[:config_retrieval].should be_instance_of(Time) true end - @config.apply + @catalog.apply end it "should clean up the transaction" do @transaction.expects :cleanup - @config.apply + @catalog.apply end it "should return the transaction" do - @config.apply.should equal(@transaction) + @catalog.apply.should equal(@transaction) end it "should yield the transaction if a block is provided" do - @config.apply do |trans| + @catalog.apply do |trans| trans.should equal(@transaction) end end it "should default to not being a host catalog" do - @config.host_config.should be_nil + @catalog.host_config.should be_nil end it "should pass supplied tags on to the transaction" do @transaction.expects(:tags=).with(%w{one two}) - @config.apply(:tags => %w{one two}) + @catalog.apply(:tags => %w{one two}) end it "should set ignoreschedules on the transaction if specified in apply()" do @transaction.expects(:ignoreschedules=).with(true) - @config.apply(:ignoreschedules => true) + @catalog.apply(:ignoreschedules => true) end end @@ -512,21 +526,21 @@ describe Puppet::Node::Catalog, " when applying host catalogs" do # super() doesn't work in the setup method for some reason before do - @config.host_config = true + @catalog.host_config = true end it "should send a report if reporting is enabled" do Puppet[:report] = true @transaction.expects :send_report @transaction.stubs :any_failed? => false - @config.apply + @catalog.apply end it "should send a report if report summaries are enabled" do Puppet[:summarize] = true @transaction.expects :send_report @transaction.stubs :any_failed? => false - @config.apply + @catalog.apply end it "should initialize the state database before applying a catalog" do @@ -534,13 +548,13 @@ describe Puppet::Node::Catalog, " when applying host catalogs" do # Short-circuit the apply, so we know we're loading before the transaction Puppet::Transaction.expects(:new).raises ArgumentError - proc { @config.apply }.should raise_error(ArgumentError) + proc { @catalog.apply }.should raise_error(ArgumentError) end it "should sync the state database after applying" do Puppet::Util::Storage.expects(:store) @transaction.stubs :any_failed? => false - @config.apply + @catalog.apply end after { Puppet.settings.clear } @@ -550,20 +564,20 @@ describe Puppet::Node::Catalog, " when applying non-host catalogs" do include ApplyingCatalogs before do - @config.host_config = false + @catalog.host_config = false end it "should never send reports" do Puppet[:report] = true Puppet[:summarize] = true @transaction.expects(:send_report).never - @config.apply + @catalog.apply end it "should never modify the state database" do Puppet::Util::Storage.expects(:load).never Puppet::Util::Storage.expects(:store).never - @config.apply + @catalog.apply end after { Puppet.settings.clear } @@ -571,20 +585,20 @@ end describe Puppet::Node::Catalog, " when creating a relationship graph" do before do - @config = Puppet::Node::Catalog.new("host") + @catalog = Puppet::Node::Catalog.new("host") @compone = Puppet::Type::Component.create :name => "one" @comptwo = Puppet::Type::Component.create :name => "two", :require => ["class", "one"] @file = Puppet::Type.type(:file) @one = @file.create :path => "/one" @two = @file.create :path => "/two" - @config.add_edge! @compone, @one - @config.add_edge! @comptwo, @two + @catalog.add_edge! @compone, @one + @catalog.add_edge! @comptwo, @two @three = @file.create :path => "/three" @four = @file.create :path => "/four", :require => ["file", "/three"] @five = @file.create :path => "/five" - @config.add_resource @compone, @comptwo, @one, @two, @three, @four, @five - @relationships = @config.relationship_graph + @catalog.add_resource @compone, @comptwo, @one, @two, @three, @four, @five + @relationships = @catalog.relationship_graph end it "should fail when trying to create a relationship graph for a relationship graph" do @@ -620,54 +634,54 @@ describe Puppet::Node::Catalog, " when creating a relationship graph" do it "should get removed when the catalog is cleaned up" do @relationships.expects(:clear).with(false) - @config.clear - @config.instance_variable_get("@relationship_graph").should be_nil + @catalog.clear + @catalog.instance_variable_get("@relationship_graph").should be_nil end it "should create a new relationship graph after clearing the old one" do @relationships.expects(:clear).with(false) - @config.clear - @config.relationship_graph.should be_instance_of(Puppet::Node::Catalog) + @catalog.clear + @catalog.relationship_graph.should be_instance_of(Puppet::Node::Catalog) end it "should look up resources in the relationship graph if not found in the main catalog" do five = stub 'five', :ref => "File[five]", :catalog= => nil @relationships.add_resource five - @config.resource(five.ref).should equal(five) + @catalog.resource(five.ref).should equal(five) end it "should provide a method to create additional resources that also registers the resource" do args = {:name => "/yay", :ensure => :file} - resource = stub 'file', :ref => "File[/yay]", :catalog= => @config + resource = stub 'file', :ref => "File[/yay]", :catalog= => @catalog Puppet::Type.type(:file).expects(:create).with(args).returns(resource) - @config.create_resource :file, args - @config.resource("File[/yay]").should equal(resource) + @catalog.create_resource :file, args + @catalog.resource("File[/yay]").should equal(resource) end it "should provide a mechanism for creating implicit resources" do args = {:name => "/yay", :ensure => :file} - resource = stub 'file', :ref => "File[/yay]", :catalog= => @config + resource = stub 'file', :ref => "File[/yay]", :catalog= => @catalog Puppet::Type.type(:file).expects(:create).with(args).returns(resource) resource.expects(:implicit=).with(true) - @config.create_implicit_resource :file, args - @config.resource("File[/yay]").should equal(resource) + @catalog.create_implicit_resource :file, args + @catalog.resource("File[/yay]").should equal(resource) end it "should add implicit resources to the relationship graph if there is one" do args = {:name => "/yay", :ensure => :file} - resource = stub 'file', :ref => "File[/yay]", :catalog= => @config + resource = stub 'file', :ref => "File[/yay]", :catalog= => @catalog resource.expects(:implicit=).with(true) Puppet::Type.type(:file).expects(:create).with(args).returns(resource) # build the graph - relgraph = @config.relationship_graph + relgraph = @catalog.relationship_graph - @config.create_implicit_resource :file, args + @catalog.create_implicit_resource :file, args relgraph.resource("File[/yay]").should equal(resource) end it "should remove resources created mid-transaction" do args = {:name => "/yay", :ensure => :file} - resource = stub 'file', :ref => "File[/yay]", :catalog= => @config + resource = stub 'file', :ref => "File[/yay]", :catalog= => @catalog @transaction = mock 'transaction' Puppet::Transaction.stubs(:new).returns(@transaction) @transaction.stubs(:evaluate) @@ -675,16 +689,16 @@ describe Puppet::Node::Catalog, " when creating a relationship graph" do @transaction.stubs(:addtimes) Puppet::Type.type(:file).expects(:create).with(args).returns(resource) resource.expects :remove - @config.apply do |trans| - @config.create_resource :file, args - @config.resource("File[/yay]").should equal(resource) + @catalog.apply do |trans| + @catalog.create_resource :file, args + @catalog.resource("File[/yay]").should equal(resource) end - @config.resource("File[/yay]").should be_nil + @catalog.resource("File[/yay]").should be_nil end it "should remove resources from the relationship graph if it exists" do - @config.remove_resource(@one) - @config.relationship_graph.vertex?(@one).should be_false + @catalog.remove_resource(@one) + @catalog.relationship_graph.vertex?(@one).should be_false end after do @@ -694,30 +708,30 @@ end describe Puppet::Node::Catalog, " when writing dot files" do before do - @config = Puppet::Node::Catalog.new("host") + @catalog = Puppet::Node::Catalog.new("host") @name = :test @file = File.join(Puppet[:graphdir], @name.to_s + ".dot") end it "should only write when it is a host catalog" do File.expects(:open).with(@file).never - @config.host_config = false + @catalog.host_config = false Puppet[:graph] = true - @config.write_graph(@name) + @catalog.write_graph(@name) end it "should only write when graphing is enabled" do File.expects(:open).with(@file).never - @config.host_config = true + @catalog.host_config = true Puppet[:graph] = false - @config.write_graph(@name) + @catalog.write_graph(@name) end it "should write a dot file based on the passed name" do File.expects(:open).with(@file, "w").yields(stub("file", :puts => nil)) - @config.expects(:to_dot).with("name" => @name.to_s.capitalize) - @config.host_config = true + @catalog.expects(:to_dot).with("name" => @name.to_s.capitalize) + @catalog.host_config = true Puppet[:graph] = true - @config.write_graph(@name) + @catalog.write_graph(@name) end after do diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb index 24b70d088..e7385f796 100755 --- a/spec/unit/parser/resource/reference.rb +++ b/spec/unit/parser/resource/reference.rb @@ -21,9 +21,14 @@ describe Puppet::Parser::Resource::Reference do ref.builtintype.should equal(Puppet::Type.type(:file)) end - it "should return a relationship-style resource reference when asked" do + it "should return a downcased relationship-style resource reference for defined types" do ref = @type.new(:type => "file", :title => "/tmp/yay") - ref.to_ref.should == ["File", "/tmp/yay"] + ref.to_ref.should == ["file", "/tmp/yay"] + end + + it "should return a capitalized relationship-style resource reference for defined types" do + ref = @type.new(:type => "whatever", :title => "/tmp/yay") + ref.to_ref.should == ["Whatever", "/tmp/yay"] end it "should return a resource reference string when asked" do diff --git a/test/executables/puppetd.rb b/test/executables/puppetd.rb index 3dd3856fd..d770ff91e 100755 --- a/test/executables/puppetd.rb +++ b/test/executables/puppetd.rb @@ -12,9 +12,11 @@ class TestPuppetDExe < Test::Unit::TestCase include PuppetTest::ExeTest def setup super + Puppet[:certdnsnames] = "localhost" # start the master @manifest = startmasterd + @cmd = "puppetd" @cmd += " --verbose" @cmd += " --test" diff --git a/test/executables/puppetmasterd.rb b/test/executables/puppetmasterd.rb index 16f7f0f5c..6d4ddf56f 100755 --- a/test/executables/puppetmasterd.rb +++ b/test/executables/puppetmasterd.rb @@ -9,6 +9,11 @@ require 'socket' class TestPuppetMasterD < Test::Unit::TestCase include PuppetTest::ExeTest + def setup + super + Puppet[:certdnsnames] = "localhost" + end + def getcerts include Puppet::Daemon if self.readcerts diff --git a/test/language/resource.rb b/test/language/resource.rb index 9c030d34a..84a30b029 100755 --- a/test/language/resource.rb +++ b/test/language/resource.rb @@ -239,9 +239,9 @@ class TestResource < PuppetTest::TestCase assert_equal("nobody", obj["owner"], "Single-value string was not passed correctly") assert_equal(%w{you me}, obj["group"], "Array of strings was not passed correctly") assert_equal("svn", obj["ignore"], "Array with single string was not turned into single value") - assert_equal(["File", refs[0].title], obj["require"], "Resource reference was not passed correctly") - assert_equal([["File", refs[1].title], ["File", refs[2].title]], obj["subscribe"], "Array of resource references was not passed correctly") - assert_equal(["File", refs[3].title], obj["notify"], "Array with single resource reference was not turned into single value") + assert_equal(["file", refs[0].title], obj["require"], "Resource reference was not passed correctly") + assert_equal([["file", refs[1].title], ["file", refs[2].title]], obj["subscribe"], "Array of resource references was not passed correctly") + assert_equal(["file", refs[3].title], obj["notify"], "Array with single resource reference was not turned into single value") end # FIXME This isn't a great test, but I need to move on. @@ -332,7 +332,7 @@ class TestResource < PuppetTest::TestCase end assert_instance_of(Array, trans["require"]) - assert_equal(["File", "/tmp/ref1"], trans["require"]) + assert_equal(["file", "/tmp/ref1"], trans["require"]) # Now try it when using an array of references. two = Parser::Resource::Reference.new(:type => "file", :title => "/tmp/ref2") @@ -348,7 +348,7 @@ class TestResource < PuppetTest::TestCase assert_instance_of(Array, trans["require"][0]) trans["require"].each do |val| assert_instance_of(Array, val) - assert_equal("File", val[0]) + assert_equal("file", val[0]) assert(val[1] =~ /\/tmp\/ref[0-9]/, "Was %s instead of the file name" % val[1]) end diff --git a/test/lib/puppettest/exetest.rb b/test/lib/puppettest/exetest.rb index be148a169..05de56c0f 100644 --- a/test/lib/puppettest/exetest.rb +++ b/test/lib/puppettest/exetest.rb @@ -54,6 +54,7 @@ module PuppetTest::ExeTest args += " --confdir %s" % Puppet[:confdir] args += " --rundir %s" % File.join(Puppet[:vardir], "run") args += " --vardir %s" % Puppet[:vardir] + args += " --certdnsnames %s" % Puppet[:certdnsnames] args += " --masterport %s" % @@port args += " --user %s" % Puppet::Util::SUIDManager.uid args += " --group %s" % Puppet::Util::SUIDManager.gid diff --git a/test/network/client/client.rb b/test/network/client/client.rb index 2588b9be5..b6b915d31 100755 --- a/test/network/client/client.rb +++ b/test/network/client/client.rb @@ -221,34 +221,4 @@ class TestClient < Test::Unit::TestCase end end end - - # Make sure that reading the cert in also sets up the cert stuff for the driver - def test_read_cert - Puppet::Util::SUIDManager.stubs(:asuser).yields - - ca = Puppet::Network::Handler.ca.new - caclient = Puppet::Network::Client.ca.new :CA => ca - - caclient.request_cert - - # First make sure it doesn't get called when the driver doesn't support :cert_setup - client = FakeClient.new :Test => FakeDriver.new - driver = client.driver - - assert_nothing_raised("Could not read cert") do - client.read_cert - end - - # And then that it does when the driver supports it - client = FakeClient.new :Test => FakeDriver.new - - driver = client.driver - driver.meta_def(:recycle_connection) { |c| } - driver.expects(:recycle_connection).with(client) - - assert_nothing_raised("Could not read cert") do - client.read_cert - end - end end - diff --git a/test/network/client/master.rb b/test/network/client/master.rb index 60058aed9..696d08bfd 100755 --- a/test/network/client/master.rb +++ b/test/network/client/master.rb @@ -333,39 +333,6 @@ end assert(FileTest.exists?(file), "file was not created on second run") end - def test_default_objects - # Make sure they start out missing - assert_nil(Puppet::Type.type(:filebucket)["puppet"], - "default filebucket already exists") - assert_nil(Puppet::Type.type(:schedule)["daily"], - "default schedules already exists") - - master = mkclient() - - # Now make sure they got created - assert(Puppet::Type.type(:filebucket)["puppet"], - "default filebucket not found") - assert(Puppet::Type.type(:schedule)["daily"], - "default schedules not found") - - # clear everything, and make sure we can recreate them - Puppet::Type.allclear - assert_nil(Puppet::Type.type(:filebucket)["puppet"], - "default filebucket not removed") - assert_nil(Puppet::Type.type(:schedule)["daily"], - "default schedules not removed") - assert_nothing_raised { master.mkdefault_objects } - assert(Puppet::Type.type(:filebucket)["puppet"], - "default filebucket not found") - assert(Puppet::Type.type(:schedule)["daily"], - "default schedules not found") - - - # Make sure we've got schedules - assert(Puppet::Type.type(:schedule)["hourly"], "Could not retrieve hourly schedule") - assert(Puppet::Type.type(:filebucket)["puppet"], "Could not retrieve default bucket") - end - # #540 - make sure downloads aren't affected by noop def test_download_in_noop source = tempfile diff --git a/test/network/server/webrick.rb b/test/network/server/webrick.rb index 3561cd41a..d3408c166 100755 --- a/test/network/server/webrick.rb +++ b/test/network/server/webrick.rb @@ -14,6 +14,11 @@ class TestWebrickServer < Test::Unit::TestCase super end + def teardown + super + Puppet::Network::HttpPool.clear_http_instances + end + # Make sure we can create a server, and that it knows how to create its # certs by default. def test_basics @@ -102,7 +107,7 @@ class TestWebrickServer < Test::Unit::TestCase assert_nothing_raised() { client = Puppet::Network::Client.status.new( - :Server => Facter.value(:fqdn), + :Server => "localhost", :Port => @@port ) } @@ -111,6 +116,7 @@ class TestWebrickServer < Test::Unit::TestCase def mk_status_server server = nil + Puppet[:certdnsnames] = "localhost" assert_nothing_raised() { server = Puppet::Network::HTTPServer::WEBrick.new( :Port => @@port, diff --git a/test/network/xmlrpc/client.rb b/test/network/xmlrpc/client.rb index f6d234324..53be5ca07 100755 --- a/test/network/xmlrpc/client.rb +++ b/test/network/xmlrpc/client.rb @@ -42,43 +42,4 @@ class TestXMLRPCClient < Test::Unit::TestCase 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 - - caclient = mock 'client', :cert => :ccert, :key => :ckey - - FileTest.expects(:exist?).with(Puppet[:localcacert]).returns(true) - - store = mock 'sslstore' - OpenSSL::X509::Store.expects(:new).returns(store) - store.expects(:add_file).with(Puppet[:localcacert]) - store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT) - - class << client - attr_accessor :http - end - - http = mock 'http' - client.http = http - - http.expects(:ca_file).returns(false) - http.expects(:ca_file=).with(Puppet[:localcacert]) - http.expects(:cert=).with(:ccert) - http.expects(:key=).with(:ckey) - http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER) - http.expects(:cert_store=) - - assert_nothing_raised do - client.cert_setup(caclient) - end - end - - def test_http_cache - end end diff --git a/test/ral/types/file.rb b/test/ral/types/file.rb index fdb2eb656..a3a0c579a 100755 --- a/test/ral/types/file.rb +++ b/test/ral/types/file.rb @@ -1787,8 +1787,6 @@ class TestFile < Test::Unit::TestCase assert_instance_of(Puppet::Network::Client::Dipper, file.bucket, "did not default to a filebucket for backups") - assert_equal(Puppet::Type.type(:filebucket)["puppet"].bucket, file.bucket, - "did not default to the 'puppet' filebucket") end # #515 - make sure 'ensure' other than "link" is deleted during recursion diff --git a/test/ral/types/filesources.rb b/test/ral/types/filesources.rb index 6180eed18..02bf8a5b3 100755 --- a/test/ral/types/filesources.rb +++ b/test/ral/types/filesources.rb @@ -22,6 +22,11 @@ class TestFileSources < Test::Unit::TestCase Puppet[:filetimeout] = -1 Puppet::Util::SUIDManager.stubs(:asuser).yields end + + def teardown + super + Puppet::Network::HttpPool.clear_http_instances + end def use_storage begin @@ -547,6 +552,7 @@ class TestFileSources < Test::Unit::TestCase Puppet[:masterport] = 8762 Puppet[:name] = "puppetmasterd" + Puppet[:certdnsnames] = "localhost" serverpid = nil assert_nothing_raised() { @@ -592,6 +598,7 @@ class TestFileSources < Test::Unit::TestCase Puppet[:autosign] = true Puppet[:masterport] = @port + Puppet[:certdnsnames] = "localhost" serverpid = nil assert_nothing_raised("Could not start on port %s" % @port) { |