Class: Chef::Node

Inherits:
Object show all
Defined in:
lib/chef/sugar/node.rb

Defined Under Namespace

Classes: AttributeDoesNotExistError

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ nil, Object

Provide a nice DSL for defining attributes. method_missing is called on all the attribute names. For more information on how to use the DSL, see the class-level documentation.

Returns:

  • (nil)

    to prevent accidential method chaining if the block isn’t closed

  • (Object)

    If no argument is passed in, method becomes an attribute accessor



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/chef/sugar/node.rb', line 155

def method_missing(m, *args, &block)
  old_method_missing(m, *args, &block)
rescue NoMethodError
  # The Node Attribute's key is the method name
  key = m.to_s
  # If arguments are passed in, set node attribute with args as the value
  if args.size > 0
    vivified[key] = args.size == 1 ? args.first : args
    return nil
  # If no arguments are passed in, attempt to access corresponding attribute
  else
    deep_key = current_namespace.dup << key
    return deep_fetch!(*deep_key)
  end
end

Instance Method Details

#deep_fetch(*keys) ⇒ Object

Safely fetch a deeply nested attribute by specifying a list of keys, bypassing Ruby’s Hash notation. This method swallows NoMethodError exceptions, avoiding the most common error in Chef-land.

This method will return nil if any deeply nested key does not exist.

See Also:

  • Chef::Node.[Node[Node#deep_fetch!]


50
51
52
53
54
# File 'lib/chef/sugar/node.rb', line 50

def deep_fetch(*keys)
  deep_fetch!(*keys)
rescue NoMethodError, AttributeDoesNotExistError
  nil
end

#deep_fetch!(*keys) ⇒ Object

Deeply fetch a node attribute by specifying a list of keys, bypassing Ruby’s Hash notation.

This method will raise any exceptions, such as undefined method ‘[]’ for nil:NilClass, just as if you used the native attribute notation. If you want a safely vivified hash, see #deep_fetch.

Examples:

Fetch a deeply nested key

node.deep_fetch(:foo, :bar, :zip) #=> node['foo']['bar']['zip']

Parameters:

  • keys (Array<String, Symbol>)

    the list of keys to kdeep fetch

Returns:



72
73
74
75
76
77
78
79
80
# File 'lib/chef/sugar/node.rb', line 72

def deep_fetch!(*keys)
  keys.map!(&:to_s)

  keys.inject(attributes.to_hash) do |hash, key|
    hash[key]
  end
rescue NoMethodError
  raise AttributeDoesNotExistError.new(keys)
end

#in?(environment) ⇒ Boolean

Determine if the current node is in the given Chef environment (or matches the given regular expression).

Parameters:

Returns:

  • (Boolean)


37
38
39
# File 'lib/chef/sugar/node.rb', line 37

def in?(environment)
  environment === chef_environment
end

#namespace(*args, &block) ⇒ nil

Dynamically define the current namespace. Multiple namespaces may be nested.

Examples:

Define a simple namespace


namespace 'apache2' do
  # ...
end

Define a nested namespace


namespace 'apache2', 'config' do
  # ...
end

Define a complex nested namespace


namespace 'apache2' do
  namespace 'config' do
    # ...
  end
end

Define a namespace with a custom precedence level


namespace 'apache2', precedence: normal do
  # Attributes here will use the "normal" level
end

Define different nested precedence levels


namespace 'apache2', precedence: normal do
  # Attributes defined here will use the "normal" level

  namespace 'config', precedence: override do
    # Attributes defined  here will use the "override" level
  end
end

Parameters:

  • args (Array)

    the list of arguments (such as the namespace and precedence levels) the user gave

  • block (Proc)

    the nested evaluation context

Returns:

  • (nil)

    to prevent accidential method chaining if the block isn’t closed



132
133
134
135
136
137
138
139
140
141
142
# File 'lib/chef/sugar/node.rb', line 132

def namespace(*args, &block)
  @namespace_options = namespace_options.merge(args.last.is_a?(Hash) ? args.pop : {})

  keys = args.map(&:to_s)

  @current_namespace = current_namespace + keys
  instance_eval(&block)
  @current_namespace = current_namespace - keys

  nil
end

#old_method_missingObject



144
# File 'lib/chef/sugar/node.rb', line 144

alias_method :old_method_missing, :method_missing