summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/resource.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/parser/resource.rb')
-rw-r--r--lib/puppet/parser/resource.rb319
1 files changed, 164 insertions, 155 deletions
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index 371f56ec1..eace88645 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -10,9 +10,9 @@ class Puppet::Parser::Resource
include Puppet::Util::Logging
attr_accessor :source, :line, :file, :scope, :rails_id
- attr_accessor :virtual, :override, :params, :translated
+ attr_accessor :virtual, :override, :translated
- attr_reader :exported
+ attr_reader :exported, :evaluated, :params
attr_writer :tags
@@ -24,7 +24,7 @@ class Puppet::Parser::Resource
end
# Set up some boolean test methods
- [:exported, :translated, :override].each do |method|
+ [:exported, :translated, :override, :virtual, :evaluated].each do |method|
newmeth = (method.to_s + "?").intern
define_method(newmeth) do
self.send(method)
@@ -43,47 +43,6 @@ class Puppet::Parser::Resource
end
end
- # Add default values from our definition.
- def adddefaults
- defaults = scope.lookupdefaults(self.type)
-
- defaults.each do |name, param|
- unless @params.include?(param.name)
- self.debug "Adding default for %s" % param.name
-
- @params[param.name] = param
- end
- end
- end
-
- # Add any metaparams defined in our scope. This actually adds any metaparams
- # from any parent scope, and there's currently no way to turn that off.
- def addmetaparams
- Puppet::Type.eachmetaparam do |name|
- next if self[name]
- if val = scope.lookupvar(name.to_s, false)
- unless val == :undefined
- set Param.new(:name => name, :value => val,
- :source => scope.source)
- end
- end
- end
- end
-
- # Add any overrides for this object.
- def addoverrides
- overrides = scope.configuration.resource_overrides(self)
- raise "fix this test"
-
- overrides.each do |over|
- self.merge(over)
- end
-
- # Remove the overrides, so that the configuration knows there
- # are none left.
- overrides.clear
- end
-
def builtin=(bool)
@ref.builtin = bool
end
@@ -92,7 +51,7 @@ class Puppet::Parser::Resource
def evaluate
if klass = @ref.definedtype
finish()
- scope.deleteresource(self)
+ scope.configuration.delete_resource(self)
return klass.evaluate(:scope => scope,
:type => self.type,
:title => self.title,
@@ -110,6 +69,8 @@ class Puppet::Parser::Resource
@evaluated = true
end
+ # Mark this resource as both exported and virtual,
+ # or remove the exported mark.
def exported=(value)
if value
@virtual = true
@@ -119,63 +80,71 @@ class Puppet::Parser::Resource
end
end
- def evaluated?
- if defined? @evaluated and @evaluated
- true
- else
- false
- end
- end
-
# Do any finishing work on this object, called before evaluation or
# before storage/translation.
def finish
- addoverrides()
- adddefaults()
- addmetaparams()
+ add_overrides()
+ add_defaults()
+ add_metaparams()
+ validate()
end
def initialize(options)
- options = symbolize_options(options)
-
- # Collect the options necessary to make the reference.
- refopts = [:type, :title].inject({}) do |hash, param|
- hash[param] = options[param]
- options.delete(param)
- hash
+ # Set all of the options we can.
+ options.each do |option, value|
+ if respond_to?(option.to_s + "=")
+ send(option.to_s + "=", value)
+ options.delete(option)
+ end
end
- @params = {}
- tmpparams = nil
- if tmpparams = options[:params]
- options.delete(:params)
+ [:scope, :source].each do |attribute|
+ unless self.send(attribute)
+ raise ArgumentError, "Resources require a %s" % attribute
+ end
end
- # Now set the rest of the options.
- set_options(options)
-
- @ref = Reference.new(refopts)
+ # Set up our reference.
+ if type = options[:type] and title = options[:title]
+ options.delete(:type)
+ options.delete(:title)
+ else
+ raise ArgumentError, "Resources require a type and title"
+ end
- requiredopts(:scope, :source)
+ @ref = Reference.new(:type => type, :title => title, :scope => self.scope)
- @ref.scope = self.scope
+ @params = {}
- if tmpparams
- tmpparams.each do |param|
- # We use the method here, because it does type-checking.
- set(param)
+ # Define all of the parameters
+ if params = options[:params]
+ options.delete(:params)
+ params.each do |param|
+ set_parameter(param)
end
end
+
+ # Throw an exception if we've got any arguments left to set.
+ unless options.empty?
+ raise ArgumentError, "Resources do not accept %s" % options.keys.collect { |k| k.to_s }.join(", ")
+ end
end
- # Merge an override resource in.
+ # Merge an override resource in. This will throw exceptions if
+ # any overrides aren't allowed.
def merge(resource)
+ # Test the resource scope, to make sure the resource is even allowed
+ # to override.
+ unless self.source.object_id == resource.source.object_id || resource.source.child_of?(self.source)
+ raise Puppet::ParseError.new("Only subclasses can override parameters", resource.line, resource.file)
+ end
# Some of these might fail, but they'll fail in the way we want.
resource.params.each do |name, param|
- set(param)
+ override_parameter(param)
end
end
+ # Modify this resource in the Rails database. Poor design, yo.
def modify_rails(db_resource)
args = rails_args
args.each do |param, value|
@@ -226,23 +195,6 @@ class Puppet::Parser::Resource
@@paramcheck
end
- # Verify that all passed parameters are valid. This throws an error if
- # there's a problem, so we don't have to worry about the return value.
- def paramcheck(param)
- param = param.to_s
- # Now make sure it's a valid argument to our class. These checks
- # are organized in order of commonhood -- most types, it's a valid
- # argument and paramcheck is enabled.
- if @ref.typeclass.validattr?(param)
- true
- elsif %w{name title}.include?(param) # always allow these
- true
- elsif paramcheck?
- self.fail Puppet::ParseError, "Invalid parameter '%s' for type '%s'" %
- [param.inspect, @ref.type]
- end
- end
-
# A temporary occasion, until I get paths in the scopes figured out.
def path
to_s
@@ -253,59 +205,6 @@ class Puppet::Parser::Resource
@ref.to_s
end
- # You have to pass a Resource::Param to this.
- def set(param, value = nil, source = nil)
- if value and source
- param = Puppet::Parser::Resource::Param.new(
- :name => param, :value => value, :source => source
- )
- elsif ! param.is_a?(Puppet::Parser::Resource::Param)
- raise ArgumentError, "Must pass a parameter or all necessary values"
- end
- # Because definitions are now parse-time, I can paramcheck immediately.
- paramcheck(param.name)
-
- if current = @params[param.name]
- # This is where we'd ignore any equivalent values if we wanted to,
- # but that would introduce a lot of really bad ordering issues.
- if param.source.child_of?(current.source)
- if param.add
- # Merge with previous value.
- param.value = [ current.value, param.value ].flatten
- end
-
- # Replace it, keeping all of its info.
- @params[param.name] = param
- else
- if Puppet[:trace]
- puts caller
- end
- msg = "Parameter '%s' is already set on %s" %
- [param.name, self.to_s]
- if current.source.to_s != ""
- msg += " by %s" % current.source
- end
- if current.file or current.line
- fields = []
- fields << current.file if current.file
- fields << current.line.to_s if current.line
- msg += " at %s" % fields.join(":")
- end
- msg += "; cannot redefine"
- error = Puppet::ParseError.new(msg)
- error.file = param.file if param.file
- error.line = param.line if param.line
- raise error
- end
- else
- if self.source == param.source or param.source.child_of?(self.source)
- @params[param.name] = param
- else
- fail Puppet::ParseError, "Only subclasses can set parameters"
- end
- end
- end
-
def tags
unless defined? @tags
@tags = scope.tags
@@ -387,12 +286,102 @@ class Puppet::Parser::Resource
return obj
end
-
- def virtual?
- self.virtual
- end
private
+
+ # Add default values from our definition.
+ def add_defaults
+ scope.lookupdefaults(self.type).each do |name, param|
+ unless @params.include?(name)
+ self.debug "Adding default for %s" % name
+
+ @params[name] = param
+ end
+ end
+ end
+
+ # Add any metaparams defined in our scope. This actually adds any metaparams
+ # from any parent scope, and there's currently no way to turn that off.
+ def add_metaparams
+ Puppet::Type.eachmetaparam do |name|
+ # Skip metaparams that we already have defined.
+ next if @params[name]
+ if val = scope.lookupvar(name.to_s, false)
+ unless val == :undefined
+ set_parameter(name, val)
+ end
+ end
+ end
+ end
+
+ # Add any overrides for this object.
+ def add_overrides
+ if overrides = scope.configuration.resource_overrides(self)
+ overrides.each do |over|
+ self.merge(over)
+ end
+
+ # Remove the overrides, so that the configuration knows there
+ # are none left.
+ overrides.clear
+ end
+ end
+
+ # Accept a parameter from an override.
+ def override_parameter(param)
+ # This can happen if the override is defining a new parameter, rather
+ # than replacing an existing one.
+ unless current = @params[param.name]
+ @params[param.name] = param
+ return
+ end
+
+ # The parameter is already set. See if they're allowed to override it.
+ if param.source.child_of?(current.source)
+ if param.add
+ # Merge with previous value.
+ param.value = [ current.value, param.value ].flatten
+ end
+
+ # Replace it, keeping all of its info.
+ @params[param.name] = param
+ else
+ if Puppet[:trace]
+ puts caller
+ end
+ msg = "Parameter '%s' is already set on %s" %
+ [param.name, self.to_s]
+ if current.source.to_s != ""
+ msg += " by %s" % current.source
+ end
+ if current.file or current.line
+ fields = []
+ fields << current.file if current.file
+ fields << current.line.to_s if current.line
+ msg += " at %s" % fields.join(":")
+ end
+ msg += "; cannot redefine"
+ raise Puppet::ParseError.new(msg, param.line, param.file)
+ end
+ end
+
+ # Verify that all passed parameters are valid. This throws an error if
+ # there's a problem, so we don't have to worry about the return value.
+ def paramcheck(param)
+ param = param.to_s
+ # Now make sure it's a valid argument to our class. These checks
+ # are organized in order of commonhood -- most types, it's a valid
+ # argument and paramcheck is enabled.
+ if @ref.typeclass.validattr?(param)
+ true
+ elsif %w{name title}.include?(param) # always allow these
+ true
+ elsif paramcheck?
+ self.fail Puppet::ParseError, "Invalid parameter '%s' for type '%s'" %
+ [param, @ref.type]
+ end
+ end
+
def rails_args
return [:type, :title, :line, :exported].inject({}) do |hash, param|
# 'type' isn't a valid column name, so we have to use another name.
@@ -403,6 +392,26 @@ class Puppet::Parser::Resource
hash
end
end
-end
-# $Id$
+ # 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|
+ # Make sure it's a valid parameter.
+ paramcheck(name)
+ end
+ end
+end