Class: Puppet::Resource

Inherits:
Object show all
Extended by:
Indirector, Util::Pson
Includes:
Enumerable, Util::Tagging
Defined in:
lib/puppet/resource.rb,
lib/puppet/resource/status.rb

Overview

The simplest resource class. Eventually it will function as the base class for all resource-like behaviour.

Direct Known Subclasses

Parser::Resource

Defined Under Namespace

Modules: TypeCollectionHelper, Validator Classes: ActiveRecord, Catalog, Ral, Rest, Status, StoreConfigs, Type, TypeCollection

Constant Summary collapse

Reference =

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.

Puppet::Resource
ATTRIBUTES =
[:file, :line, :exported]
YAML_ATTRIBUTES =
[:@file, :@line, :@exported, :@type, :@title, :@tags, :@parameters]

Constants included from Indirector

Indirector::BadNameRegexp

Constants included from Util::Tagging

Util::Tagging::ValidTagRegex

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util::Pson

pson_create

Methods included from Indirector

configure_routes, indirects

Methods included from Util::Tagging

#tag, #tagged?, #tags, #tags=

Constructor Details

#initialize(type, title = nil, attributes = {}) ⇒ Resource

Create our resource.



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/puppet/resource.rb', line 190

def initialize(type, title = nil, attributes = {})
  @parameters = {}

  # 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

  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

Instance Attribute Details

#catalogObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def catalog
  @catalog
end

#exportedObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def exported
  @exported
end

#fileObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def file
  @file
end

#lineObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def line
  @line
end

#strictObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def strict
  @strict
end

#titleObject (readonly)



21
22
23
# File 'lib/puppet/resource.rb', line 21

def title
  @title
end

#typeObject (readonly)



21
22
23
# File 'lib/puppet/resource.rb', line 21

def type
  @type
end

#validate_parametersObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def validate_parameters
  @validate_parameters
end

#virtualObject



20
21
22
# File 'lib/puppet/resource.rb', line 20

def virtual
  @virtual
end

Class Method Details

.from_data_hash(data) ⇒ Object

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 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

.from_pson(pson) ⇒ Object



52
53
54
55
# 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

.value_to_pson_data(value) ⇒ Object



90
91
92
93
94
95
96
97
98
# 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

Instance Method Details

#==(other) ⇒ Object



149
150
151
152
153
154
# 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

#[](param) ⇒ Object

Return a given parameter’s value. Converts all passed names to lower-case symbols.



145
146
147
# File 'lib/puppet/resource.rb', line 145

def [](param)
  parameters[parameter_name(param)]
end

#[]=(param, value) ⇒ Object

Set a given parameter. Converts all passed names to lower-case symbols.



138
139
140
141
# File 'lib/puppet/resource.rb', line 138

def []=(param, value)
  validate_parameter(param) if validate_parameters
  parameters[parameter_name(param)] = value
end

#builtin?Boolean

Compatibility method.

Returns:

  • (Boolean)


157
158
159
# File 'lib/puppet/resource.rb', line 157

def builtin?
  builtin_type?
end

#builtin_type?Boolean

Is this a builtin resource type?

Returns:

  • (Boolean)


162
163
164
# File 'lib/puppet/resource.rb', line 162

def builtin_type?
  resource_type.is_a?(Class)
end

#class?Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/puppet/resource.rb', line 181

def class?
  @is_class ||= @type == "Class"
end

#copy_as_resourceObject



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# File 'lib/puppet/resource.rb', line 387

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)

  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 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.
    result[p] = if v.is_a?(Array) and v.length == 1
                  v[0]
                else
                  v
                end
  end

  result
end

#eachObject

Iterate over each param/value pair, as required for Enumerable.



167
168
169
# File 'lib/puppet/resource.rb', line 167

def each
  parameters.each { |p,v| yield p, v }
end

#environmentObject



253
254
255
256
257
258
259
# File 'lib/puppet/resource.rb', line 253

def environment
  @environment ||= if catalog
                     catalog.environment_instance
                   else
                     Puppet::Node::Environment::NONE
                   end
end

#environment=(environment) ⇒ Object



261
262
263
# File 'lib/puppet/resource.rb', line 261

def environment=(environment)
  @environment = environment
end

#include?(parameter) ⇒ Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/puppet/resource.rb', line 171

def include?(parameter)
  super || parameters.keys.include?( parameter_name(parameter) )
end

#inspectObject



57
58
59
# File 'lib/puppet/resource.rb', line 57

def inspect
  "#{@type}[#{@title}]#{to_hash.inspect}"
end

#key_attributesObject



282
283
284
# File 'lib/puppet/resource.rb', line 282

def key_attributes
  resource_type.respond_to?(:key_attributes) ? resource_type.key_attributes : [:name]
end

#nameObject



317
318
319
320
321
322
# File 'lib/puppet/resource.rb', line 317

def name
  # this is potential namespace conflict
  # between the notion of an "indirector name"
  # and a "resource name"
  [ type, title ].join('/')
end

#prune_parameters(options = {}) ⇒ Object



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/puppet/resource.rb', line 445

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

#refObject



225
226
227
# File 'lib/puppet/resource.rb', line 225

def ref
  to_s
end

#resolveObject

Find our resource.



230
231
232
# File 'lib/puppet/resource.rb', line 230

def resolve
  catalog ? catalog.resource(to_s) : nil
end

#resource_typePuppet::Type, Puppet::Resource::Type

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The resource’s type implementation



237
238
239
240
241
242
243
244
# File 'lib/puppet/resource.rb', line 237

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

#resource_type=(type) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Set the resource’s type implementation

Parameters:



249
250
251
# File 'lib/puppet/resource.rb', line 249

def resource_type=(type)
  @rstype = type
end

#set_default_parameters(scope) ⇒ Object



364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/puppet/resource.rb', line 364

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

#stage?Boolean

Returns:

  • (Boolean)


185
186
187
# File 'lib/puppet/resource.rb', line 185

def stage?
  @is_stage ||= @type.to_s.downcase == "stage"
end

#to_data_hashObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 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

#to_hashObject

Produce a simple hash of our parameters.



266
267
268
# File 'lib/puppet/resource.rb', line 266

def to_hash
  parse_title.merge parameters
end

#to_manifestObject

Convert our resource to Puppet code.



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/puppet/resource.rb', line 287

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

#to_pson(*args) ⇒ Object



124
125
126
# File 'lib/puppet/resource.rb', line 124

def to_pson(*args)
  to_data_hash.to_pson(*args)
end

#to_pson_data_hashObject

This doesn’t include document type as it is part of a catalog



86
87
88
# File 'lib/puppet/resource.rb', line 86

def to_pson_data_hash
  to_data_hash
end

#to_ralObject

Convert our resource to a RAL resource instance. Creates component instances for resource types that don’t exist.



312
313
314
315
# File 'lib/puppet/resource.rb', line 312

def to_ral
  typeklass = Puppet::Type.type(self.type) || Puppet::Type.type(:component)
  typeklass.new(self)
end

#to_refObject



306
307
308
# File 'lib/puppet/resource.rb', line 306

def to_ref
  ref
end

#to_sObject



270
271
272
# File 'lib/puppet/resource.rb', line 270

def to_s
  "#{type}[#{title}]"
end

#to_yaml_propertiesArray<Symbol>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Explicitly list the instance variables that should be serialized when converting to YAML.

Returns:

  • (Array<Symbol>)

    The intersection of our explicit variable list and all of the instance variables defined on this class.



120
121
122
# File 'lib/puppet/resource.rb', line 120

def to_yaml_properties
  YAML_ATTRIBUTES & super
end

#uniqueness_keyObject



274
275
276
277
278
279
280
# File 'lib/puppet/resource.rb', line 274

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

#valid_parameter?(name) ⇒ Boolean

Returns:

  • (Boolean)


424
425
426
# File 'lib/puppet/resource.rb', line 424

def valid_parameter?(name)
  resource_type.valid_parameter?(name)
end

#validate_completeObject

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.



432
433
434
435
436
437
438
439
# File 'lib/puppet/resource.rb', line 432

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
end

#validate_parameter(name) ⇒ Object

Raises:

  • (ArgumentError)


441
442
443
# File 'lib/puppet/resource.rb', line 441

def validate_parameter(name)
  raise ArgumentError, "Invalid parameter #{name}" unless valid_parameter?(name)
end

#yaml_property_munge(x) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# 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