Class: Puppet::Type

Inherits:
Object
  • Object
show all
Extended by:
Enumerable, Util::ClassGen
Includes:
Comparable, Enumerable
Defined in:
lib/puppet/type.rb

Overview

Note:

The Type class deals with multiple concerns; some methods provide an internal DSL for convenient definition of types, other methods deal with various aspects while running; wiring up a resource (expressed in Puppet DSL or Ruby DSL) with its resource type (i.e. an instance of Type) to enable validation, transformation of values (munge/unmunge), etc. Lastly, Type is also responsible for dealing with Providers; the concrete implementations of the behavior that constitutes how a particular Type behaves on a particular type of system (e.g. how commands are executed on a flavor of Linux, on Windows, etc.). This means that as you are reading through the documentation of this class, you will be switching between these concepts, as well as switching between the conceptual level “a resource is an instance of a resource-type” and the actual implementation classes (Type, Resource, Provider, and various utility and helper classes).

The base class for all Puppet types.

A type describes:

  • Attributes - properties, parameters, and meta-parameters are different types of attributes of a type.
    • Properties - these are the properties of the managed resource (attributes of the entity being managed; like a file’s owner, group and mode). A property describes two states; the ‘is’ (current state) and the ‘should’ (wanted state).
      • Ensurable - a set of traits that control the lifecycle (create, remove, etc.) of a managed entity. There is a default set of operations associated with being ensurable, but this can be changed.
      • Name/Identity - one property is the name/identity of a resource, the namevar that uniquely identifies one instance of a type from all others.
    • Parameters - additional attributes of the type (that does not directly related to an instance of the managed resource; if an operation is recursive or not, where to look for things, etc.). A Parameter (in contrast to Property) has one current value where a Property has two (current-state and wanted-state).
    • Meta-Parameters - parameters that are available across all types. A meta-parameter typically has additional semantics; like the require meta-parameter. A new type typically does not add new meta-parameters, but you need to be aware of their existence so you do not inadvertently shadow an existing meta-parameters.
  • Parent - a type can have a super type (that it inherits from).
  • Validation - If not just a basic data type, or an enumeration of symbolic values, it is possible to provide validation logic for a type, properties and parameters.
  • Munging - munging/unmunging is the process of turning a value in external representation (as used by a provider) into an internal representation and vice versa. A Type supports adding custom logic for these.
  • Auto Requirements - a type can specify automatic relationships to resources to ensure that if they are being managed, they will be processed before this type.
  • Providers - a provider is an implementation of a type’s behavior - the management of a resource in the system being managed. A provider is often platform specific and is selected at runtime based on criteria/predicates specified in the configured providers. See Provider for details.
  • Device Support - A type has some support for being applied to a device; i.e. something that is managed by running logic external to the device itself. There are several methods that deals with type applicability for these special cases such as Type.apply_to_device.

Additional Concepts:

  • Resource-type - A resource type is a term used to denote the type of a resource; internally a resource is really an instance of a Ruby class i.e. Resource which defines its behavior as “resource data”. Conceptually however, a resource is an instance of a subclass of Type (e.g. File), where such a class describes its interface (what can be said/what is known about a resource of this type),
  • Managed Entity - This is not a term in general use, but is used here when there is a need to make a distinction between a resource (a description of what/how something should be managed), and what it is managing (a file in the file system). The term managed entity is a reference to the “file in the file system”
  • Isomorphism - the quality of being isomorphic means that two resource instances with the same name refers to the same managed entity. Or put differently; an isomorphic name is the identity of a resource. As an example, exec resources (that executes some command) have the command (i.e. the command line string) as their name, and these resources are said to be non-isomorphic.

Constant Summary

Class Attribute Summary (collapse)

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Util

exit_on_fail, exit_on_fail, which, which

Methods included from MetaType::Manager

allclear, newtype, rmtype, typeloader

Methods included from Util::ClassGen

genconst_string, genthing, handleclassconst, initclass, is_constant_defined?, name2const, storeclass

Methods included from Util::ProviderFeatures

provider_feature

Class Attribute Details

+ (Object) providerloader  private

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 loader of providers to use when loading providers from disk. Although it looks like this attribute provides a way to operate with different loaders of providers that is not the case; the attribute is written when a new type is created, and should not be changed thereafter.



1632
1633
1634
# File 'lib/puppet/type.rb', line 1632

def providerloader
  @providerloader
end

Instance Attribute Details

- (Hash) original_parameters (readonly) private

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.

Hash of parameters originally defined

Returns:

  • (Hash)

    hash of parameters originally defined



2152
2153
2154
# File 'lib/puppet/type.rb', line 2152

def original_parameters
  @original_parameters
end

Class Method Details

+ (Symbol) apply_to  private

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.

Makes this type apply to :host if not already applied to something else.

Returns:

  • (Symbol)

    a :device, :host, or :both enumeration



245
246
247
# File 'lib/puppet/type.rb', line 245

def self.apply_to
  @apply_to ||= :host
end

+ (Symbol) apply_to_all  private

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.

Makes this type applicable to :both (i.e. :host and :device).

Returns:

  • (Symbol)

    Returns :both



238
239
240
# File 'lib/puppet/type.rb', line 238

def self.apply_to_all
  @apply_to = :both
end

+ (Symbol) apply_to_device  private

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.

Makes this type applicable to :device.

Returns:

  • (Symbol)

    Returns :device



222
223
224
# File 'lib/puppet/type.rb', line 222

def self.apply_to_device
  @apply_to = :device
end

+ (Symbol) apply_to_host  private

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.

Makes this type applicable to :host.

Returns:

  • (Symbol)

    Returns :host



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

def self.apply_to_host
  @apply_to = :host
end

+ autorequire(name) {| | ... } DSL

TODO:

original = “Specify a block for generating a list of objects to autorequire. This makes it so that you don’t have to manually specify things that you clearly require.”

This method returns an undefined value.

Adds a block producing a single name (or list of names) of the given resource type name to autorequire.

Examples:

Autorequire the files File[‘foo’, ‘bar’]

autorequire( 'file', {||

Parameters:

  • name (String)

    the name of a type of which one or several resources should be autorequired e.g. “file”

Yields:

  • ( )

    a block returning list of names of given type to auto require

Yield Returns:

  • (String, Array<String>)

    one or several resource names for the named type

DSL:

  • type



1927
1928
1929
1930
# File 'lib/puppet/type.rb', line 1927

def self.autorequire(name, &block)
  @autorequires ||= {}
  @autorequires[name] = block
end

+ (Boolean) can_apply_to(target)  private

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.

Returns true if this type is applicable to the given target.

Parameters:

  • target (Symbol)

    should be :device, :host or :target, if anything else, :host is enforced

Returns:

  • (Boolean)

    true



254
255
256
# File 'lib/puppet/type.rb', line 254

def self.can_apply_to(target)
  [ target == :device ? :device : :host, :both ].include?(apply_to)
end

+ ensurable  DSL + ensurable({|| ... })  DSL

Note:

This method will be automatically called without a block if the type implements the methods specified by ensurable?. It is recommended to always call this method and not rely on this automatic specification to clearly state that the type is ensurable.

This method returns an undefined value.

Creates a new ensure property with configured default values or with configuration by an optional block. This method is a convenience method for creating a property ensure with default accepted values. If no block is specified, the new ensure property will accept the default symbolic values :present, and :absent - see Property::Ensure. If something else is wanted, pass a block and make calls to Property.newvalue from this block to define each possible value. If a block is passed, the defaults are not automatically added to the set of valid values.

Yields:

  • ()

    A block evaluated in scope of the new Parameter

Yield Returns:

  • (void)

DSL:

  • type



186
187
188
189
190
191
192
193
194
# File 'lib/puppet/type.rb', line 186

def self.ensurable(&block)
  if block_given?
    self.newproperty(:ensure, :parent => Puppet::Property::Ensure, &block)
  else
    self.newproperty(:ensure, :parent => Puppet::Property::Ensure) do
      self.defaultvalues
    end
  end
end

+ (Class<inherits Puppet::Parameter>) newmetaparam(name, options = {}) {|| ... } DSL

TODO:

Verify that this description is ok

Creates a new meta-parameter. This creates a new meta-parameter that is added to all types.

Parameters:

  • name (Symbol)

    the name of the parameter

  • options (Hash) (defaults to: {})

    a hash with options.

Options Hash (options):

  • :parent (Class<inherits Puppet::Parameter>) — default: Puppet::Parameter

    the super class of this parameter

  • :attributes (Hash{String => Object})

    a hash that is applied to the generated class by calling setter methods corresponding to this hash’s keys/value pairs. This is done before the given block is evaluated.

  • :boolean (Boolean) — default: false

    specifies if this is a boolean parameter

  • :namevar (Boolean) — default: false

    specifies if this parameter is the namevar

  • :required_features (Symbol, Array<Symbol>)

    specifies required provider features by name

Yields:

  • ()

    a required block that is evaluated in the scope of the new meta-parameter

Returns:

DSL:

  • type



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/puppet/type.rb', line 329

def self.newmetaparam(name, options = {}, &block)
  @@metaparams ||= []
  @@metaparamhash ||= {}
  name = name.intern

  param = genclass(
    name,
    :parent => options[:parent] || Puppet::Parameter,
    :prefix => "MetaParam",
    :hash => @@metaparamhash,
    :array => @@metaparams,
    :attributes => options[:attributes],
    &block
  )

  # Grr.
  param.required_features = options[:required_features] if options[:required_features]

  handle_param_options(name, options)

  param.metaparam = true

  param
end

+ (Class<inherits Puppet::Parameter>) newparam(name, options = {}) {|| ... } DSL

Creates a new parameter.

Parameters:

  • name (Symbol)

    the name of the parameter

  • options (Hash) (defaults to: {})

    a hash with options.

Options Hash (options):

  • :parent (Class<inherits Puppet::Parameter>) — default: Puppet::Parameter

    the super class of this parameter

  • :attributes (Hash{String => Object})

    a hash that is applied to the generated class by calling setter methods corresponding to this hash’s keys/value pairs. This is done before the given block is evaluated.

  • :boolean (Boolean) — default: false

    specifies if this is a boolean parameter

  • :namevar (Boolean) — default: false

    specifies if this parameter is the namevar

  • :required_features (Symbol, Array<Symbol>)

    specifies required provider features by name

Yields:

  • ()

    a required block that is evaluated in the scope of the new parameter

Returns:

DSL:

  • type



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/puppet/type.rb', line 437

def self.newparam(name, options = {}, &block)
  options[:attributes] ||= {}

  param = genclass(
    name,
    :parent     => options[:parent] || Puppet::Parameter,
    :attributes => options[:attributes],
    :block      => block,
    :prefix     => "Parameter",
    :array      => @parameters,
    :hash       => @paramhash
  )

  handle_param_options(name, options)

  # Grr.
  param.required_features = options[:required_features] if options[:required_features]

  param.isnamevar if options[:namevar]

  param
end

+ (Class<inherits Puppet::Property>) newproperty(name, options = {}) {|| ... } DSL

Creates a new property.

Parameters:

  • name (Symbol)

    the name of the property

  • options (Hash) (defaults to: {})

    a hash with options.

Options Hash (options):

  • :array_matching (Symbol) — default: :first

    specifies how the current state is matched against the wanted state. Use :first if the property is single valued, and (:all) otherwise.

  • :parent (Class<inherits Puppet::Property>) — default: Puppet::Property

    the super class of this property

  • :attributes (Hash{String => Object})

    a hash that is applied to the generated class by calling setter methods corresponding to this hash’s keys/value pairs. This is done before the given block is evaluated.

  • :boolean (Boolean) — default: false

    specifies if this is a boolean parameter

  • :retrieve (Symbol)

    the method to call on the provider (or parent if provider is not set) to retrieve the current value of this property.

  • :required_features (Symbol, Array<Symbol>)

    specifies required provider features by name

Yields:

  • ()

    a required block that is evaluated in the scope of the new property

Returns:

Raises:

  • (Puppet::DevError)

DSL:

  • type



478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'lib/puppet/type.rb', line 478

def self.newproperty(name, options = {}, &block)
  name = name.intern

  # This is here for types that might still have the old method of defining
  # a parent class.
  unless options.is_a? Hash
    raise Puppet::DevError,
      "Options must be a hash, not #{options.inspect}"
  end

  raise Puppet::DevError, "Class #{self.name} already has a property named #{name}" if @validproperties.include?(name)

  if parent = options[:parent]
    options.delete(:parent)
  else
    parent = Puppet::Property
  end

  # We have to create our own, new block here because we want to define
  # an initial :retrieve method, if told to, and then eval the passed
  # block if available.
  prop = genclass(name, :parent => parent, :hash => @validproperties, :attributes => options) do
    # If they've passed a retrieve method, then override the retrieve
    # method on the class.
    if options[:retrieve]
      define_method(:retrieve) do
        provider.send(options[:retrieve])
      end
    end

    class_eval(&block) if block
  end

  # If it's the 'ensure' property, always put it first.
  if name == :ensure
    @properties.unshift prop
  else
    @properties << prop
  end

  prop
end

+ (Array<Array<Regexp, Array<Array <Symbol, Proc>>>>?) title_patterns  private

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.

Note:

Advanced: some logic requires this mapping to be done differently, using a different validation/pattern, breaking up the title into several parts assigning each to an individual attribute, or even use a composite identity where all namevars are seen as part of the unique identity (such computation is done by the #uniqueness method. These advanced options are rarely used (only one of the built in puppet types use this, and then only a small part of the available functionality), and the support for these advanced mappings is not implemented in a straight forward way. For these reasons, this method has been marked as private).

Returns a mapping from the title string to setting of attribute value(s). This default implementation provides a mapping of title to the one and only namevar present in the type’s definition.

Returns:

  • (Array<Array<Regexp, Array<Array <Symbol, Proc>>>>, nil)

    a structure with a regexp and the first key_attribute ???

Raises:

  • (Puppet::DevError)

    if there is no title pattern and there are two or more key attributes



404
405
406
407
408
409
410
411
412
# File 'lib/puppet/type.rb', line 404

def self.title_patterns
  case key_attributes.length
  when 0; []
  when 1;
    [ [ /(.*)/m, [ [key_attributes.first] ] ] ]
  else
    raise Puppet::DevError,"you must specify title patterns when there are two or more key attributes"
  end
end

+ validate {|| ... } DSL

This method returns an undefined value.

Creates a validate method that is used to validate a resource before it is operated on. The validation should raise exceptions if the validation finds errors. (It is not recommended to issue warnings as this typically just ends up in a logfile - you should fail if a validation fails). The easiest way to raise an appropriate exception is to call the method Util::Errors.fail with the message as an argument.

Yields:

  • ()

    a required block called with self set to the instance of a Type class representing a resource.

DSL:

  • type



2108
2109
2110
2111
# File 'lib/puppet/type.rb', line 2108

def self.validate(&block)
  define_method(:validate, &block)
  #@validate = block
end

Instance Method Details

- (Boolean) appliable_to_device?  private

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.

TODO:

Explain what this means

Returns whether the resource is applicable to :device

Returns:

  • (Boolean)

    Returns whether the resource is applicable to :device



2404
2405
2406
# File 'lib/puppet/type.rb', line 2404

def appliable_to_device?
  self.class.can_apply_to(:device)
end

- (Boolean) appliable_to_host?  private

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.

TODO:

Explain what this means

Returns whether the resource is applicable to :host

Returns:

  • (Boolean)

    Returns whether the resource is applicable to :host



2411
2412
2413
# File 'lib/puppet/type.rb', line 2411

def appliable_to_host?
  self.class.can_apply_to(:host)
end

- (Object) pathbuilder  private

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.

TODO:

“and such?”, what?

Creates the path for logging and such.



1172
1173
1174
1175
1176
1177
1178
# File 'lib/puppet/type.rb', line 1172

def pathbuilder
  if p = parent
    [p.pathbuilder, self.ref].flatten
  else
    [self.ref]
  end
end