summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-03-07 12:28:58 -0600
committerLuke Kanies <luke@madstop.com>2008-03-07 12:28:58 -0600
commit9f8bb7e42aeea4670d9292f935529f8db5d57bc5 (patch)
treeb3b746e516d62d10368d19a197749dd25a54307e
parentc2b33acd5c1e6fe4021d7609f806b7bd8af834f8 (diff)
parente8029cc61a1956263935a0df469cc77b8e80a102 (diff)
downloadpuppet-9f8bb7e42aeea4670d9292f935529f8db5d57bc5.tar.gz
puppet-9f8bb7e42aeea4670d9292f935529f8db5d57bc5.tar.xz
puppet-9f8bb7e42aeea4670d9292f935529f8db5d57bc5.zip
Merge branch '0.24.x'
-rw-r--r--CHANGELOG19
-rw-r--r--conf/gentoo/puppet/puppet.conf58
-rw-r--r--ext/ldap/puppet.schema7
-rw-r--r--lib/puppet/defaults.rb1
-rw-r--r--lib/puppet/indirector/node/exec.rb2
-rw-r--r--lib/puppet/indirector/node/ldap.rb5
-rw-r--r--lib/puppet/node/catalog.rb10
-rw-r--r--lib/puppet/parser/compiler.rb1
-rw-r--r--lib/puppet/parser/resource.rb37
-rw-r--r--lib/puppet/provider/package/portage.rb8
-rw-r--r--lib/puppet/sslcertificates/ca.rb30
-rwxr-xr-xlib/puppet/type/file/checksum.rb3
-rwxr-xr-xlib/puppet/type/tidy.rb2
-rw-r--r--lib/puppet/util/settings.rb96
-rwxr-xr-xspec/unit/indirector/node/exec.rb6
-rwxr-xr-xspec/unit/indirector/node/ldap.rb195
-rwxr-xr-xspec/unit/node/catalog.rb2
-rwxr-xr-xspec/unit/parser/resource.rb161
-rwxr-xr-xtest/language/resource.rb159
19 files changed, 422 insertions, 380 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 3348d8959..365e21805 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,22 @@
+ The change in checksums from 'timestamp' to 'mtime' no longer
+ result in updates on every run (#1116).
+
+ Aliases again work in relationships (#1094).
+
+ The CA serial file will no longer ever be owned by
+ root (#1041).
+
+ Fixing the rest of #1113: External node commands can specify
+ an environment and Puppet will now use it.
+
+ Partially fixing #1113: LDAP nodes now support environments,
+ and the schema has been updated accordingly.
+
+ Always duplicating resource defaults in the parser, so that
+ stacked metaparameter values do not result in all resources
+ that receive a given default also getting those stacked
+ values.
+
0.24.2
Fixing #1062 by moving the yamldir setting to its own yaml
section. This should keep the yamldir from being created
diff --git a/conf/gentoo/puppet/puppet.conf b/conf/gentoo/puppet/puppet.conf
index 1d62c90e4..70dcb02da 100644
--- a/conf/gentoo/puppet/puppet.conf
+++ b/conf/gentoo/puppet/puppet.conf
@@ -1,29 +1,29 @@
-[main]
- # Where Puppet stores dynamic and growing data.
- # The default value is '/var/puppet'.
- vardir = /var/lib/puppet
-
- # The Puppet log directory.
- # The default value is '$vardir/log'.
- logdir = /var/log/puppet
-
- # Where Puppet PID files are kept.
- # The default value is '$vardir/run'.
- rundir = /var/run/puppet
-
- # Where SSL certificates are kept.
- # The default value is '$confdir/ssl'.
- ssldir = $vardir/ssl
-
-[puppetd]
- # The file in which puppetd stores a list of the classes
- # associated with the retrieved configuratiion. Can be loaded in
- # the separate ``puppet`` executable using the ``--loadclasses``
- # option.
- # The default value is '$confdir/classes.txt'.
- classfile = $vardir/classes.txt
-
- # Where puppetd caches the local configuration. An
- # extension indicating the cache format is added automatically.
- # The default value is '$confdir/localconfig'.
- localconfig = $vardir/localconfig
+[main]
+ # Where Puppet stores dynamic and growing data.
+ # The default value is '/var/puppet'.
+ vardir = /var/lib/puppet
+
+ # The Puppet log directory.
+ # The default value is '$vardir/log'.
+ logdir = /var/log/puppet
+
+ # Where Puppet PID files are kept.
+ # The default value is '$vardir/run'.
+ rundir = /var/run/puppet
+
+ # Where SSL certificates are kept.
+ # The default value is '$confdir/ssl'.
+ ssldir = $vardir/ssl
+
+[puppetd]
+ # The file in which puppetd stores a list of the classes
+ # associated with the retrieved configuratiion. Can be loaded in
+ # the separate ``puppet`` executable using the ``--loadclasses``
+ # option.
+ # The default value is '$confdir/classes.txt'.
+ classfile = $vardir/classes.txt
+
+ # Where puppetd caches the local configuration. An
+ # extension indicating the cache format is added automatically.
+ # The default value is '$confdir/localconfig'.
+ localconfig = $vardir/localconfig
diff --git a/ext/ldap/puppet.schema b/ext/ldap/puppet.schema
index b7c715ec2..bbad23eab 100644
--- a/ext/ldap/puppet.schema
+++ b/ext/ldap/puppet.schema
@@ -12,6 +12,11 @@ attributetype ( 1.1.3.9 NAME 'parentnode'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+attributetype ( 1.1.3.9 NAME 'environment'
+ DESC 'Puppet Node Environment'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
objectclass ( 1.1.1.2 NAME 'puppetClient' SUP top AUXILIARY
DESC 'Puppet Client objectclass'
- MAY ( puppetclass $ parentnode ))
+ MAY ( puppetclass $ parentnode $ environment ))
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index 6dbd7d043..2f5992d22 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -258,6 +258,7 @@ module Puppet
:serial => { :default => "$cadir/serial",
:owner => "$user",
:group => "$group",
+ :mode => 0600,
:desc => "Where the serial number for certificates is stored."
},
:autosign => { :default => "$confdir/autosign.conf",
diff --git a/lib/puppet/indirector/node/exec.rb b/lib/puppet/indirector/node/exec.rb
index ed76bce94..71f4fa8e1 100644
--- a/lib/puppet/indirector/node/exec.rb
+++ b/lib/puppet/indirector/node/exec.rb
@@ -30,7 +30,7 @@ class Puppet::Node::Exec < Puppet::Indirector::Exec
def create_node(name, result)
node = Puppet::Node.new(name)
set = false
- [:parameters, :classes].each do |param|
+ [:parameters, :classes, :environment].each do |param|
if value = result[param]
node.send(param.to_s + "=", value)
set = true
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index dd11f4e9b..9320f3ba1 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -36,11 +36,14 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
information[:parameters][param] = value unless information[:parameters].include?(param)
end
+ information[:environment] ||= parent_info[:environment]
+
parent = parent_info[:parent]
end
node.classes = information[:classes].uniq unless information[:classes].empty?
node.parameters = information[:parameters] unless information[:parameters].empty?
+ node.environment = information[:environment] if information[:environment]
node.fact_merge
return node
@@ -87,6 +90,8 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
hash
end
+ result[:environment] = result[:parameters]["environment"] if result[:parameters]["environment"]
+
return result
end
diff --git a/lib/puppet/node/catalog.rb b/lib/puppet/node/catalog.rb
index f885a41ee..ecda472be 100644
--- a/lib/puppet/node/catalog.rb
+++ b/lib/puppet/node/catalog.rb
@@ -84,6 +84,7 @@ class Puppet::Node::Catalog < Puppet::PGraph
# Create an alias for a resource.
def alias(resource, name)
+ #set $1
resource.ref =~ /^(.+)\[/
newref = "%s[%s]" % [$1 || resource.class.name, name]
@@ -475,6 +476,15 @@ class Puppet::Node::Catalog < Puppet::PGraph
vertices.each do |resource|
next if resource.respond_to?(:virtual?) and resource.virtual?
+ #This is hackity hack for 1094
+ #Aliases aren't working in the ral catalog because the current instance of the resource
+ #has a reference to the catalog being converted. . . So, give it a reference to the new one
+ #problem solved. . .
+ if resource.is_a?(Puppet::TransObject)
+ resource = resource.dup
+ resource.catalog = result
+ end
+
newres = resource.send(convert)
# We can't guarantee that resources don't munge their names
diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
index 70cd6e11a..8fba41121 100644
--- a/lib/puppet/parser/compiler.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -366,7 +366,6 @@ class Puppet::Parser::Compiler
# Make sure all of our resources and such have done any last work
# necessary.
def finish
- #@catalog.resources.each do |name|
@catalog.vertices.each do |resource|
# Add in any resource overrides.
if overrides = resource_overrides(resource)
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index b001e165b..4b48ff6cf 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -233,6 +233,20 @@ class Puppet::Parser::Resource
@ref.to_s
end
+ # Define a parameter in our resource.
+ def set_parameter(param, value = nil)
+ if value
+ param = Puppet::Parser::Resource::Param.new(
+ :name => param, :value => value, :source => self.source
+ )
+ elsif ! param.is_a?(Puppet::Parser::Resource::Param)
+ raise ArgumentError, "Must pass a parameter or all necessary values"
+ end
+
+ # And store it in our parameter hash.
+ @params[param.name] = param
+ end
+
def to_hash
@params.inject({}) do |hash, ary|
param = ary[1]
@@ -331,7 +345,7 @@ class Puppet::Parser::Resource
unless @params.include?(name)
self.debug "Adding default for %s" % name
- @params[name] = param
+ @params[name] = param.dup
end
end
end
@@ -370,11 +384,8 @@ class Puppet::Parser::Resource
# The parameter is already set. Fail if they're not allowed to override it.
unless param.source.child_of?(current.source)
- if Puppet[:trace]
- puts caller
- end
- msg = "Parameter '%s' is already set on %s" %
- [param.name, self.to_s]
+ puts caller if Puppet[:trace]
+ msg = "Parameter '%s' is already set on %s" % [param.name, self.to_s]
if current.source.to_s != ""
msg += " by %s" % current.source
end
@@ -426,20 +437,6 @@ class Puppet::Parser::Resource
end
end
- # Define a parameter in our resource.
- def set_parameter(param, value = nil)
- if value
- param = Puppet::Parser::Resource::Param.new(
- :name => param, :value => value, :source => self.source
- )
- elsif ! param.is_a?(Puppet::Parser::Resource::Param)
- raise ArgumentError, "Must pass a parameter or all necessary values"
- end
-
- # And store it in our parameter hash.
- @params[param.name] = param
- end
-
# Make sure the resource's parameters are all valid for the type.
def validate
@params.each do |name, param|
diff --git a/lib/puppet/provider/package/portage.rb b/lib/puppet/provider/package/portage.rb
index dccfeaf56..f795d0302 100644
--- a/lib/puppet/provider/package/portage.rb
+++ b/lib/puppet/provider/package/portage.rb
@@ -10,8 +10,8 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
defaultfor :operatingsystem => :gentoo
def self.instances
- result_format = /(\S+) (\S+) \[([^\[]*)(\[[^\]]*\])?\] \[[^0-9]*([^\s:\[]*)(\[[^\]]*\])?(:\S*)?\] ([\S]*) (.*)/
- result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :overlay, :slot, :vendor, :description]
+ result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
+ result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
search_format = "{installedversionsshort}<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>{}"
@@ -67,8 +67,8 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
end
def query
- result_format = /(\S+) (\S+) \[([^\[]*)(\[[^\]]*\])?\] \[[^0-9]*([^\s:\[]*)(\[[^\]]*\])?(:\S*)?\] ([\S]*) (.*)/
- result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :overlay, :slot, :vendor, :description]
+ result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
+ result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
search_field = @resource[:category] ? "--category-name" : "--name"
search_value = package_name
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index 888bcf5b2..7386318f4 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -238,33 +238,6 @@ class Puppet::SSLCertificates::CA
}
end
- # Create an exclusive lock for reading and writing, and do the
- # writing in a tmp file.
- def readwritelock(file, mode = 0600)
- tmpfile = file + ".tmp"
- sync = Sync.new
- unless FileTest.directory?(File.dirname(tmpfile))
- raise Puppet::DevError, "Cannot create %s; directory %s does not exist" %
- [file, File.dirname(file)]
- end
- sync.synchronize(Sync::EX) do
- File.open(file, "r+", mode) do |rf|
- rf.lock_exclusive do
- File.open(tmpfile, "w", mode) do |tf|
- yield tf
- end
- begin
- File.rename(tmpfile, file)
- rescue => detail
- Puppet.err "Could not rename %s to %s: %s" %
- [file, tmpfile, detail]
- end
- end
- end
- end
- end
-
-
# Sign a given certificate request.
def sign(csr)
unless csr.is_a?(OpenSSL::X509::Request)
@@ -278,9 +251,8 @@ class Puppet::SSLCertificates::CA
end
serial = nil
- readwritelock(@config[:serial]) { |f|
+ Puppet.settings.readwritelock(:serial) { |f|
serial = File.read(@config[:serial]).chomp.hex
-
# increment the serial
f << "%04X" % (serial + 1)
}
diff --git a/lib/puppet/type/file/checksum.rb b/lib/puppet/type/file/checksum.rb
index debb5a7db..3be147cb7 100755
--- a/lib/puppet/type/file/checksum.rb
+++ b/lib/puppet/type/file/checksum.rb
@@ -66,6 +66,9 @@ Puppet::Type.type(:file).newproperty(:checksum) do
raise ArgumentError, "A type must be specified to cache a checksum"
end
type = symbolize(type)
+ type = :mtime if type == :timestamp
+ type = :ctime if type == :time
+
unless state = @resource.cached(:checksums)
self.debug "Initializing checksum hash"
state = {}
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index dacf037ac..fe8bde9ab 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -1,5 +1,5 @@
module Puppet
- newtype(:tidy, Puppet.type(:file)) do
+ newtype(:tidy, :parent => Puppet.type(:file)) do
@doc = "Remove unwanted files based on specific criteria. Multiple
criteria are OR'd together, so a file that is too large but is not
old enough will still get tidied."
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index 5f4a98558..f4055c304 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -243,14 +243,7 @@ class Puppet::Util::Settings
# Make a directory with the appropriate user, group, and mode
def mkdir(default)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default %s" % default
- end
-
- unless obj.is_a? CFile
- raise ArgumentError, "Default %s is not a file" % default
- end
+ obj = get_config_file_default(default)
Puppet::Util::SUIDManager.asuser(obj.owner, obj.group) do
mode = obj.mode || 0750
@@ -649,49 +642,15 @@ Generated on #{Time.now}.
end
# Open a file with the appropriate user, group, and mode
- def write(default, *args)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default %s" % default
- end
-
- unless obj.is_a? CFile
- raise ArgumentError, "Default %s is not a file" % default
- end
-
- chown = nil
- if Puppet::Util::SUIDManager.uid == 0
- chown = [obj.owner, obj.group]
- else
- chown = [nil, nil]
- end
- Puppet::Util::SUIDManager.asuser(*chown) do
- mode = obj.mode || 0640
-
- if args.empty?
- args << "w"
- end
-
- args << mode
-
- File.open(value(obj.name), *args) do |file|
- yield file
- end
- end
+ def write(default, *args, &bloc)
+ obj = get_config_file_default(default)
+ writesub(default, value(obj.name), *args, &bloc)
end
# Open a non-default file under a default dir with the appropriate user,
# group, and mode
- def writesub(default, file, *args)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default %s" % default
- end
-
- unless obj.is_a? CFile
- raise ArgumentError, "Default %s is not a file" % default
- end
-
+ def writesub(default, file, *args, &bloc)
+ obj = get_config_file_default(default)
chown = nil
if Puppet::Util::SUIDManager.uid == 0
chown = [obj.owner, obj.group]
@@ -716,8 +675,51 @@ Generated on #{Time.now}.
end
end
+ def readwritelock(default, *args, &bloc)
+ file = value(get_config_file_default(default).name)
+ tmpfile = file + ".tmp"
+ sync = Sync.new
+ unless FileTest.directory?(File.dirname(tmpfile))
+ raise Puppet::DevError, "Cannot create %s; directory %s does not exist" %
+ [file, File.dirname(file)]
+ end
+
+ sync.synchronize(Sync::EX) do
+ File.open(file, "r+", 0600) do |rf|
+ rf.lock_exclusive do
+ if File.exist?(tmpfile)
+ raise Puppet::Error, ".tmp file already exists for %s; Aborting locked write. Check the .tmp file and delete if appropriate" %
+ [file]
+ end
+
+ writesub(default, tmpfile, *args, &bloc)
+
+ begin
+ File.rename(tmpfile, file)
+ rescue => detail
+ Puppet.err "Could not rename %s to %s: %s" %
+ [file, tmpfile, detail]
+ end
+ end
+ end
+ end
+ end
+
private
+ def get_config_file_default(default)
+ obj = nil
+ unless obj = @config[default]
+ raise ArgumentError, "Unknown default %s" % default
+ end
+
+ unless obj.is_a? CFile
+ raise ArgumentError, "Default %s is not a file" % default
+ end
+
+ return obj
+ end
+
# Create the transportable objects for users and groups.
def add_user_resources(section, obj, done)
resources = []
diff --git a/spec/unit/indirector/node/exec.rb b/spec/unit/indirector/node/exec.rb
index 744a32b0a..5e6a9b1da 100755
--- a/spec/unit/indirector/node/exec.rb
+++ b/spec/unit/indirector/node/exec.rb
@@ -59,4 +59,10 @@ describe Puppet::Node::Exec, " when handling the results of the command" do
@node.expects(:fact_merge)
@searcher.find(@name)
end
+
+ it "should set the node's environment if one is provided" do
+ @result[:environment] = "yay"
+ @node.expects(:environment=).with "yay"
+ @searcher.find(@name)
+ end
end
diff --git a/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
index 95b73de60..2a4f240ed 100755
--- a/spec/unit/indirector/node/ldap.rb
+++ b/spec/unit/indirector/node/ldap.rb
@@ -5,27 +5,26 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
describe Puppet::Node::Ldap do
- before :each do
- @searcher = Puppet::Node::Ldap.new
- @entries = {}
- entries = @entries
-
- @connection = mock 'connection'
- @entry = mock 'entry'
- @connection.stubs(:search).yields(@entry)
- @searcher.stubs(:connection).returns(@connection)
- @searcher.stubs(:class_attributes).returns([])
- @searcher.stubs(:parent_attribute).returns(nil)
- @searcher.stubs(:search_base).returns(:yay)
- @searcher.stubs(:search_filter).returns(:filter)
-
- @node = mock 'node'
- @node.stubs(:fact_merge)
- @name = "mynode"
- Puppet::Node.stubs(:new).with(@name).returns(@node)
- end
-
- describe Puppet::Node::Ldap, " when searching for nodes" do
+ describe "when searching for nodes" do
+ before :each do
+ @searcher = Puppet::Node::Ldap.new
+ @entries = {}
+ entries = @entries
+
+ @connection = mock 'connection'
+ @entry = mock 'entry'
+ @connection.stubs(:search).yields(@entry)
+ @searcher.stubs(:connection).returns(@connection)
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.stubs(:search_base).returns(:yay)
+ @searcher.stubs(:search_filter).returns(:filter)
+
+ @node = mock 'node'
+ @node.stubs(:fact_merge)
+ @name = "mynode"
+ Puppet::Node.stubs(:new).with(@name).returns(@node)
+ end
it "should return nil if no results are found in ldap" do
@connection.stubs(:search)
@@ -61,6 +60,13 @@ describe Puppet::Node::Ldap do
@searcher.find("mynode")
end
+ it "should set the node's environment to the environment of the results" do
+ @entry.stubs(:to_hash).returns("environment" => ["test"])
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("test")
+ @searcher.find("mynode")
+ end
+
it "should retain false parameter values" do
@entry.stubs(:to_hash).returns("one" => [false])
@node.expects(:parameters=).with("one" => false)
@@ -78,91 +84,114 @@ describe Puppet::Node::Ldap do
@node.expects(:parameters=).with("one" => ["a", "b"])
@searcher.find("mynode")
end
- end
- describe Puppet::Node::Ldap, " when a parent node is specified" do
+ describe "and a parent node is specified" do
+ before do
+ @parent = mock 'parent'
+ @parent_parent = mock 'parent_parent'
- before do
- @parent = mock 'parent'
- @parent_parent = mock 'parent_parent'
+ @searcher.meta_def(:search_filter) do |name|
+ return name
+ end
+ @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent_parent' }.yields(@parent_parent)
- @searcher.meta_def(:search_filter) do |name|
- return name
+ @searcher.stubs(:parent_attribute).returns(:parent)
end
- @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
- @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
- @connection.stubs(:search).with { |*args| args[2] == 'parent_parent' }.yields(@parent_parent)
- @searcher.stubs(:parent_attribute).returns(:parent)
- end
+ it "should fail if the parent cannot be found" do
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.returns("whatever")
- it "should fail if the parent cannot be found" do
- @connection.stubs(:search).with { |*args| args[2] == 'parent' }.returns("whatever")
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @entry.stubs(:to_hash).returns({})
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
+ end
- proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
- end
+ it "should add any parent classes to the node's classes" do
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @entry.stubs(:vals).with("classes").returns(%w{a b})
- it "should add any parent classes to the node's classes" do
- @entry.stubs(:to_hash).returns({})
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @entry.stubs(:vals).with("classes").returns(%w{a b})
+ @parent.stubs(:to_hash).returns({})
+ @parent.stubs(:vals).with("classes").returns(%w{c d})
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @parent.stubs(:to_hash).returns({})
- @parent.stubs(:vals).with("classes").returns(%w{c d})
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @searcher.stubs(:class_attributes).returns(%w{classes})
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find("mynode")
+ end
- @searcher.stubs(:class_attributes).returns(%w{classes})
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
- end
+ it "should add any parent parameters to the node's parameters" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- it "should add any parent parameters to the node's parameters" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find("mynode")
+ end
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
- end
+ it "should prefer node parameters over parent parameters" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- it "should prefer node parameters over parent parameters" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @parent.stubs(:to_hash).returns("one" => "three")
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @parent.stubs(:to_hash).returns("one" => "three")
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @node.expects(:parameters=).with("one" => "two")
+ @searcher.find("mynode")
+ end
- @node.expects(:parameters=).with("one" => "two")
- @searcher.find("mynode")
- end
+ it "should use the parent's environment if the node has none" do
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- it "should recursively look up parent information" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @parent.stubs(:to_hash).returns("environment" => ["parent"])
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns(['parent_parent'])
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("parent")
+ @searcher.find("mynode")
+ end
- @parent_parent.stubs(:to_hash).returns("five" => "six")
- @parent_parent.stubs(:vals).with(:parent).returns(nil)
- @parent_parent.stubs(:vals).with(:parent).returns(nil)
+ it "should prefer the node's environment to the parent's" do
+ @entry.stubs(:to_hash).returns("environment" => %w{child})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
- @searcher.find("mynode")
- end
+ @parent.stubs(:to_hash).returns("environment" => ["parent"])
+ @parent.stubs(:vals).with(:parent).returns(nil)
+
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("child")
+ @searcher.find("mynode")
+ end
+
+ it "should recursively look up parent information" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns(['parent_parent'])
- it "should not allow loops in parent declarations" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @parent_parent.stubs(:to_hash).returns("five" => "six")
+ @parent_parent.stubs(:vals).with(:parent).returns(nil)
+ @parent_parent.stubs(:vals).with(:parent).returns(nil)
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns([@name])
- proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
+ @searcher.find("mynode")
+ end
+
+ it "should not allow loops in parent declarations" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns([@name])
+ proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ end
end
end
end
diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb
index 604dabbb6..360dd87f2 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -304,6 +304,8 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
resource = stub 'resource', :name => "changer2", :title => "changer2", :ref => "Test[changer2]", :catalog= => nil, :remove => nil
+ #changer is going to get duplicated as part of a fix for aliases 1094
+ changer.expects(:dup).returns(changer)
changer.expects(:to_type).returns(resource)
newconfig = nil
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index 9ce7b391b..1948a3c07 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -14,6 +14,36 @@ describe Puppet::Parser::Resource do
@scope = @compiler.topscope
end
+ def mkresource(args = {})
+ args[:source] ||= "source"
+ args[:scope] ||= stub('scope', :source => mock('source'))
+
+ {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value|
+ args[param] ||= value
+ end
+
+ params = args[:params] || {:one => "yay", :three => "rah"}
+ if args[:params] == :none
+ args.delete(:params)
+ else
+ args[:params] = paramify(args[:source], params)
+ end
+
+ Puppet::Parser::Resource.new(args)
+ end
+
+ def param(name, value, source)
+ Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source)
+ end
+
+ def paramify(source, hash)
+ hash.collect do |name, value|
+ Puppet::Parser::Resource::Param.new(
+ :name => name, :value => value, :source => source
+ )
+ end
+ end
+
it "should be isomorphic if it is builtin and models an isomorphic type" do
Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
@resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
@@ -29,6 +59,30 @@ describe Puppet::Parser::Resource do
@resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
end
+ it "should have a array-indexing method for retrieving parameter values" do
+ @resource = mkresource
+ @resource[:one].should == "yay"
+ end
+
+ describe "when initializing" do
+ before do
+ @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))}
+ end
+
+ [:type, :title, :scope].each do |name|
+ it "should fail unless #{name.to_s} is specified" do
+ try = @arguments.dup
+ try.delete(name)
+ lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError)
+ end
+ end
+
+ it "should set the reference correctly" do
+ res = Puppet::Parser::Resource.new(@arguments)
+ res.ref.should == "Resource[testing]"
+ end
+ end
+
describe "when evaluating" do
before do
@type = Puppet::Parser::Resource
@@ -60,11 +114,10 @@ describe Puppet::Parser::Resource do
describe "when finishing" do
before do
- @definition = @parser.newdefine "mydefine"
@class = @parser.newclass "myclass"
@nodedef = @parser.newnode("mynode")[0]
- @resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source)
end
it "should do nothing if it has already been finished" do
@@ -73,6 +126,32 @@ describe Puppet::Parser::Resource do
@resource.finish
end
+ it "should add all defaults available from the scope" do
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source))
+ @resource.finish
+
+ @resource[:owner].should == "default"
+ end
+
+ it "should not replace existing parameters with defaults" do
+ @resource.set_parameter :owner, "oldvalue"
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced)
+ @resource.finish
+
+ @resource[:owner].should == "oldvalue"
+ end
+
+ it "should add a copy of each default, rather than the actual default parameter instance" do
+ newparam = param(:owner, "default", @resource.source)
+ other = newparam.dup
+ other.value = "other"
+ newparam.expects(:dup).returns(other)
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam)
+ @resource.finish
+
+ @resource[:owner].should == "other"
+ end
+
it "should copy metaparams from its scope" do
@scope.setvar("noop", "true")
@@ -82,7 +161,7 @@ describe Puppet::Parser::Resource do
end
it "should not copy metaparams that it already has" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("noop", "false") }
+ @resource.set_parameter("noop", "false")
@scope.setvar("noop", "true")
@resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
@@ -91,7 +170,7 @@ describe Puppet::Parser::Resource do
end
it "should stack relationship metaparams from its container if it already has them" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", "resource") }
+ @resource.set_parameter("require", "resource")
@scope.setvar("require", "container")
@resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
@@ -100,7 +179,7 @@ describe Puppet::Parser::Resource do
end
it "should flatten the array resulting from stacking relationship metaparams" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", ["resource1", "resource2"]) }
+ @resource.set_parameter("require", ["resource1", "resource2"])
@scope.setvar("require", %w{container1 container2})
@resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
@@ -167,4 +246,76 @@ describe Puppet::Parser::Resource do
lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
end
end
+
+ describe "when merging overrides" do
+ before do
+ @source = "source1"
+ @resource = mkresource :source => @source
+ @override = mkresource :source => @source
+ end
+
+ it "should fail when the override was not created by a parent class" do
+ @override.source = "source2"
+ @override.source.expects(:child_of?).with("source1").returns(false)
+ assert_raise(Puppet::ParseError, "Allowed unrelated resources to override") do
+ @resource.merge(@override)
+ end
+ end
+
+ it "should succeed when the override was created in the current scope" do
+ @resource.source = "source3"
+ @override.source = @resource.source
+ @override.source.expects(:child_of?).with("source3").never
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should succeed when a parent class created the override" do
+ @resource.source = "source3"
+ @override.source = "source4"
+ @override.source.expects(:child_of?).with("source3").returns(true)
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should add new parameters when the parameter is not set" do
+ @source.stubs(:child_of?).returns true
+ @override.set_parameter(:testing, "value")
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should replace existing parameter values" do
+ @source.stubs(:child_of?).returns true
+ @resource.set_parameter(:testing, "old")
+ @override.set_parameter(:testing, "value")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should add values to the parameter when the override was created with the '+>' syntax" do
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source)
+ param.add = true
+
+ @override.set_parameter(param)
+
+ @resource.set_parameter(:testing, "other")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == %w{other testing}
+ end
+
+
+ end
end
diff --git a/test/language/resource.rb b/test/language/resource.rb
index 608e7c995..b3eaf0390 100755
--- a/test/language/resource.rb
+++ b/test/language/resource.rb
@@ -23,95 +23,6 @@ class TestResource < PuppetTest::TestCase
mocha_verify
end
- def test_initialize
- args = {:type => "resource", :title => "testing",
- :scope => mkscope}
- # Check our arg requirements
- args.each do |name, value|
- try = args.dup
- try.delete(name)
- assert_raise(ArgumentError, "Did not fail when %s was missing" % name) do
- Parser::Resource.new(try)
- end
- end
-
- res = nil
- assert_nothing_raised do
- res = Parser::Resource.new(args)
- end
-
- ref = res.instance_variable_get("@ref")
- assert_equal("Resource", ref.type, "did not set resource type")
- assert_equal("testing", ref.title, "did not set resource title")
- end
-
- def test_merge
- res = mkresource
- other = mkresource
-
- # First try the case where the resource is not allowed to override
- res.source = "source1"
- other.source = "source2"
- other.source.expects(:child_of?).with("source1").returns(false)
- assert_raise(Puppet::ParseError, "Allowed unrelated resources to override") do
- res.merge(other)
- end
-
- # Next try it when the sources are equal.
- res.source = "source3"
- other.source = res.source
- other.source.expects(:child_of?).with("source3").never
- params = {:a => :b, :c => :d}
- other.expects(:params).returns(params)
- res.expects(:override_parameter).with(:b)
- res.expects(:override_parameter).with(:d)
- res.merge(other)
-
- # And then parentage is involved
- other = mkresource
- res.source = "source3"
- other.source = "source4"
- other.source.expects(:child_of?).with("source3").returns(true)
- params = {:a => :b, :c => :d}
- other.expects(:params).returns(params)
- res.expects(:override_parameter).with(:b)
- res.expects(:override_parameter).with(:d)
- res.merge(other)
- end
-
- # the [] method
- def test_array_accessors
- res = mkresource
- params = res.instance_variable_get("@params")
- assert_nil(res[:missing], "Found a missing parameter somehow")
- params[:something] = stub(:value => "yay")
- assert_equal("yay", res[:something], "Did not correctly call value on the parameter")
-
- res.expects(:title).returns(:mytitle)
- assert_equal(:mytitle, res[:title], "Did not call title when asked for it as a param")
- end
-
- # Make sure any defaults stored in the scope get added to our resource.
- def test_add_defaults
- res = mkresource
- params = res.instance_variable_get("@params")
- params[:a] = :b
- res.scope.expects(:lookupdefaults).with(res.type).returns(:a => :replaced, :c => :d)
- res.expects(:debug)
-
- res.send(:add_defaults)
- assert_equal(:d, params[:c], "Did not set default")
- assert_equal(:b, params[:a], "Replaced parameter with default")
- end
-
- def test_finish
- res = mkresource
- res.expects(:add_defaults)
- res.expects(:add_metaparams)
- res.expects(:validate)
- res.finish
- end
-
# Make sure we paramcheck our params
def test_validate
res = mkresource
@@ -123,43 +34,6 @@ class TestResource < PuppetTest::TestCase
res.send(:validate)
end
- def test_override_parameter
- res = mkresource
- params = res.instance_variable_get("@params")
-
- # There are three cases, with the second having two options:
-
- # No existing parameter.
- param = stub(:name => "myparam")
- res.send(:override_parameter, param)
- assert_equal(param, params["myparam"], "Override was not added to param list")
-
- # An existing parameter that we can override.
- source = stub(:child_of? => true)
- # Start out without addition
- params["param2"] = stub(:source => :whatever)
- param = stub(:name => "param2", :source => source, :add => false)
- res.send(:override_parameter, param)
- assert_equal(param, params["param2"], "Override was not added to param list")
-
- # Try with addition.
- params["param2"] = stub(:value => :a, :source => :whatever)
- param = stub(:name => "param2", :source => source, :add => true, :value => :b)
- param.expects(:value=).with([:a, :b])
- res.send(:override_parameter, param)
- assert_equal(param, params["param2"], "Override was not added to param list")
-
- # And finally, make sure we throw an exception when the sources aren't related
- source = stub(:child_of? => false)
- params["param2"] = stub(:source => :whatever, :file => :f, :line => :l)
- old = params["param2"]
- param = stub(:name => "param2", :source => source, :file => :f, :line => :l)
- assert_raise(Puppet::ParseError, "Did not fail when params conflicted") do
- res.send(:override_parameter, param)
- end
- assert_equal(old, params["param2"], "Param was replaced irrespective of conflict")
- end
-
def test_set_parameter
res = mkresource
params = res.instance_variable_get("@params")
@@ -420,37 +294,4 @@ class TestResource < PuppetTest::TestCase
assert(newres.exported?, "Exported defined resource generated non-exported resources")
assert(newres.virtual?, "Exported defined resource generated non-virtual resources")
end
-
- # Make sure tags behave appropriately.
- def test_tags
- scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
- scope = stub 'scope', :resource => scope_resource
- resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => scope, :source => mock('source'))
-
- # Make sure we get the type and title
- %w{yay file}.each do |tag|
- assert(resource.tags.include?(tag), "Did not tag resource with %s" % tag)
- end
-
- # make sure we can only set legal tags
- ["an invalid tag", "-anotherinvalid", "bad*tag"].each do |tag|
- assert_raise(Puppet::ParseError, "Tag #{tag} was considered valid") do
- resource.tag tag
- end
- end
-
- # make sure good tags make it through.
- tags = %w{good-tag yaytag GoodTag another_tag a ab A}
- tags.each do |tag|
- assert_nothing_raised("Tag #{tag} was considered invalid") do
- resource.tag tag
- end
- end
-
- # make sure we get each of them.
- ptags = resource.tags
- tags.each do |tag|
- assert(ptags.include?(tag.downcase), "missing #{tag}")
- end
- end
end