The simplest resource class. Eventually it will function as the base class for all resource-like behaviour.
@api public
This stub class is only needed for serialization compatibility with 0.25.x. Specifically, it exists to provide a compatibility API when using YAML serialized objects loaded from StoreConfigs.
# File lib/puppet/resource.rb, line 149 def ==(other) return false unless other.respond_to?(:title) and self.type == other.type and self.title == other.title return false unless to_hash == other.to_hash true end
Return a given parameter’s value. Converts all passed names to lower-case symbols.
# File lib/puppet/resource.rb, line 145 def [](param) parameters[parameter_name(param)] end
Set a given parameter. Converts all passed names to lower-case symbols.
# File lib/puppet/resource.rb, line 138 def []=(param, value) validate_parameter(param) if validate_parameters parameters[parameter_name(param)] = value end
Compatibility method.
# File lib/puppet/resource.rb, line 157 def builtin? builtin_type? end
Is this a builtin resource type?
# File lib/puppet/resource.rb, line 162 def builtin_type? resource_type.is_a?(Class) end
# File lib/puppet/resource.rb, line 181 def class? @is_class ||= @type == "Class" end
# File lib/puppet/resource.rb, line 422 def copy_as_resource result = Puppet::Resource.new(type, title) result.file = self.file result.line = self.line result.exported = self.exported result.virtual = self.virtual result.tag(*self.tags) result.environment = environment result.instance_variable_set(:@rstype, resource_type) future_parser_not_in_use = !Puppet.future_parser?(result.environment) to_hash.each do |p, v| if v.is_a?(Puppet::Resource) v = Puppet::Resource.new(v.type, v.title) elsif v.is_a?(Array) # flatten resource references arrays v = v.flatten if v.flatten.find { |av| av.is_a?(Puppet::Resource) } v = v.collect do |av| av = Puppet::Resource.new(av.type, av.title) if av.is_a?(Puppet::Resource) av end end if future_parser_not_in_use # !Puppet.future_parser? # If the value is an array with only one value, then # convert it to a single value. This is largely so that # the database interaction doesn't have to worry about # whether it returns an array or a string. # # This behavior is not done in the future parser, but we can't issue a # deprecation warning either since there isn't anything that a user can # do about it. result[p] = if v.is_a?(Array) and v.length == 1 v[0] else v end else result[p] = v end end result end
Iterate over each param/value pair, as required for Enumerable.
# File lib/puppet/resource.rb, line 167 def each parameters.each { |p,v| yield p, v } end
# File lib/puppet/resource.rb, line 288 def environment @environment ||= if catalog catalog.environment_instance else Puppet.lookup(:current_environment) { Puppet::Node::Environment::NONE } end end
# File lib/puppet/resource.rb, line 296 def environment=(environment) @environment = environment end
# File lib/puppet/resource.rb, line 171 def include?(parameter) super || parameters.keys.include?( parameter_name(parameter) ) end
# File lib/puppet/resource.rb, line 57 def inspect "#{@type}[#{@title}]#{to_hash.inspect}" end
# File lib/puppet/resource.rb, line 317 def key_attributes resource_type.respond_to?(:key_attributes) ? resource_type.key_attributes : [:name] end
# File lib/puppet/resource.rb, line 352 def name # this is potential namespace conflict # between the notion of an "indirector name" # and a "resource name" [ type, title ].join('/') end
# File lib/puppet/resource.rb, line 505 def prune_parameters(options = {}) properties = resource_type.properties.map(&:name) dup.collect do |attribute, value| if value.to_s.empty? or Array(value).empty? delete(attribute) elsif value.to_s == "absent" and attribute.to_s != "ensure" delete(attribute) end parameters_to_include = options[:parameters_to_include] || [] delete(attribute) unless properties.include?(attribute) || parameters_to_include.include?(attribute) end self end
# File lib/puppet/resource.rb, line 260 def ref to_s end
Find our resource.
# File lib/puppet/resource.rb, line 265 def resolve catalog ? catalog.resource(to_s) : nil end
The resource’s type implementation @return [Puppet::Type, Puppet::Resource::Type] @api private
# File lib/puppet/resource.rb, line 272 def resource_type @rstype ||= case type when "Class"; environment.known_resource_types.hostclass(title == :main ? "" : title) when "Node"; environment.known_resource_types.node(title) else Puppet::Type.type(type) || environment.known_resource_types.definition(type) end end
Set the resource’s type implementation @param type [Puppet::Type, Puppet::Resource::Type] @api private
# File lib/puppet/resource.rb, line 284 def resource_type=(type) @rstype = type end
# File lib/puppet/resource.rb, line 399 def set_default_parameters(scope) return [] unless resource_type and resource_type.respond_to?(:arguments) unless is_a?(Puppet::Parser::Resource) fail Puppet::DevError, "Cannot evaluate default parameters for #{self} - not a parser resource" end missing_arguments.collect do |param, default| external_value = lookup_external_default_for(param, scope) if external_value.nil? && default.nil? next elsif external_value.nil? value = default.safeevaluate(scope) else value = external_value end self[param.to_sym] = value param end.compact end
# File lib/puppet/resource.rb, line 185 def stage? @is_stage ||= @type.to_s.downcase == "stage" end
# File lib/puppet/resource.rb, line 61 def to_data_hash data = ([:type, :title, :tags] + ATTRIBUTES).inject({}) do |hash, param| next hash unless value = self.send(param) hash[param.to_s] = value hash end data["exported"] ||= false params = self.to_hash.inject({}) do |hash, ary| param, value = ary # Don't duplicate the title as the namevar next hash if param == namevar and value == title hash[param] = Puppet::Resource.value_to_pson_data(value) hash end data["parameters"] = params unless params.empty? data end
Produce a simple hash of our parameters.
# File lib/puppet/resource.rb, line 301 def to_hash parse_title.merge parameters end
Convert our resource to Puppet code.
# File lib/puppet/resource.rb, line 322 def to_manifest # Collect list of attributes to align => and move ensure first attr = parameters.keys attr_max = attr.inject(0) { |max,k| k.to_s.length > max ? k.to_s.length : max } attr.sort! if attr.first != :ensure && attr.include?(:ensure) attr.delete(:ensure) attr.unshift(:ensure) end attributes = attr.collect { |k| v = parameters[k] " %-#{attr_max}s => %s,\n" % [k, Puppet::Parameter.format_value_for_display(v)] }.join "%s { '%s':\n%s}" % [self.type.to_s.downcase, self.title, attributes] end
# File lib/puppet/resource.rb, line 124 def to_pson(*args) to_data_hash.to_pson(*args) end
This doesn’t include document type as it is part of a catalog
# File lib/puppet/resource.rb, line 86 def to_pson_data_hash to_data_hash end
Convert our resource to a RAL resource instance. Creates component instances for resource types that don’t exist.
# File lib/puppet/resource.rb, line 347 def to_ral typeklass = Puppet::Type.type(self.type) || Puppet::Type.type(:component) typeklass.new(self) end
# File lib/puppet/resource.rb, line 341 def to_ref ref end
# File lib/puppet/resource.rb, line 305 def to_s "#{type}[#{title}]" end
Explicitly list the instance variables that should be serialized when converting to YAML.
@api private @return [Array<Symbol>] The intersection of our explicit variable list and
all of the instance variables defined on this class.
# File lib/puppet/resource.rb, line 120 def to_yaml_properties YAML_ATTRIBUTES & super end
# File lib/puppet/resource.rb, line 309 def uniqueness_key # Temporary kludge to deal with inconsistant use patters h = self.to_hash h[namevar] ||= h[:name] h[:name] ||= h[namevar] h.values_at(*key_attributes.sort_by { |k| k.to_s }) end
# File lib/puppet/resource.rb, line 469 def valid_parameter?(name) resource_type.valid_parameter?(name) end
Verify that all required arguments are either present or have been provided with defaults. Must be called after ‘#set_default_parameters’. We can’t join the methods because Type#set_parameters needs specifically ordered behavior.
# File lib/puppet/resource.rb, line 477 def validate_complete return unless resource_type and resource_type.respond_to?(:arguments) resource_type.arguments.each do |param, default| param = param.to_sym fail Puppet::ParseError, "Must pass #{param} to #{self}" unless parameters.include?(param) end # Perform optional type checking if Puppet.future_parser? # Perform type checking arg_types = resource_type.argument_types # Parameters is a map from name, to parameter, and the parameter again has name and value parameters.each do |name, value| next unless t = arg_types[name.to_s] # untyped, and parameters are symbols here (aargh, strings in the type) unless Puppet::Pops::Types::TypeCalculator.instance?(t, value.value) inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value.value) actual = Puppet::Pops::Types::TypeCalculator.generalize!(inferred_type) fail Puppet::ParseError, "Expected parameter '#{name}' of '#{self}' to have type #{t.to_s}, got #{actual.to_s}" end end end end
# File lib/puppet/resource.rb, line 501 def validate_parameter(name) raise ArgumentError, "Invalid parameter #{name}" unless valid_parameter?(name) end
# File lib/puppet/resource.rb, line 100 def yaml_property_munge(x) case x when Hash x.inject({}) { |h,kv| k,v = kv h[k] = self.class.value_to_pson_data(v) h } else self.class.value_to_pson_data(x) end end
# File lib/puppet/resource.rb, line 29 def self.from_data_hash(data) raise ArgumentError, "No resource type provided in serialized data" unless type = data['type'] raise ArgumentError, "No resource title provided in serialized data" unless title = data['title'] resource = new(type, title) if params = data['parameters'] params.each { |param, value| resource[param] = value } end if tags = data['tags'] tags.each { |tag| resource.tag(tag) } end ATTRIBUTES.each do |a| if value = data[a.to_s] resource.send(a.to_s + "=", value) end end resource end
# File lib/puppet/resource.rb, line 52 def self.from_pson(pson) Puppet.deprecation_warning("from_pson is being removed in favour of from_data_hash.") self.from_data_hash(pson) end
Construct a resource from data.
Constructs a resource instance with the given `type` and `title`. Multiple type signatures are possible for these arguments and most will result in an expensive call to {Puppet::Node::Environment#known_resource_types} in order to resolve `String` and `Symbol` Types to actual Ruby classes.
@param type [Symbol, String] The name of the Puppet Type, as a string or
symbol. The actual Type will be looked up using
{Puppet::Node::Environment#known_resource_types}. This lookup is expensive.
@param type [String] The full resource name in the form of
`"Type[Title]"`. This method of calling should only be used when `title` is `nil`.
@param type [nil] If a `nil` is passed, the title argument must be a string
of the form `"Type[Title]"`.
@param type [Class] A class that inherits from `Puppet::Type`. This method
of construction is much more efficient as it skips calls to
{Puppet::Node::Environment#known_resource_types}.
@param title [String, :main, nil] The title of the resource. If type is `nil`, may also
be the full resource name in the form of `"Type[Title]"`.
@api public
# File lib/puppet/resource.rb, line 212 def initialize(type, title = nil, attributes = {}) @parameters = {} environment = attributes[:environment] if type.is_a?(Class) && type < Puppet::Type # Set the resource type to avoid an expensive `known_resource_types` # lookup. self.resource_type = type # From this point on, the constructor behaves the same as if `type` had # been passed as a symbol. type = type.name end # Set things like strictness first. attributes.each do |attr, value| next if attr == :parameters send(attr.to_s + "=", value) end @type, @title = extract_type_and_title(type, title) @type = munge_type_name(@type) if self.class? @title = :main if @title == "" @title = munge_type_name(@title) end if params = attributes[:parameters] extract_parameters(params) end if resource_type && resource_type.respond_to?(:deprecate_params) resource_type.deprecate_params(title, attributes[:parameters]) end tag(self.type) tag(self.title) if valid_tag?(self.title) @reference = self # for serialization compatibility with 0.25.x if strict? and ! resource_type if self.class? raise ArgumentError, "Could not find declared class #{title}" else raise ArgumentError, "Invalid resource type #{type}" end end end
# File lib/puppet/resource.rb, line 90 def self.value_to_pson_data(value) if value.is_a? Array value.map{|v| value_to_pson_data(v) } elsif value.is_a? Puppet::Resource value.to_s else value end end