class Chef::Node

Public Instance Methods

deep_fetch(*keys) click to toggle source

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 [Node#deep_fetch!]

# File lib/chef/sugar/node.rb, line 54
def deep_fetch(*keys)
  Chef::Sugar::Deprecation.deprecated "the chef-sugar deep_fetch method is deprecated and should be replaced by node.read"
  deep_fetch!(*keys)
rescue NoMethodError, AttributeDoesNotExistError
  nil
end
deep_fetch!(*keys) click to toggle source

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}.

@example Fetch a deeply nested key

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

@param [Array<String, Symbol>] keys

the list of keys to kdeep fetch

@return [Object]

# File lib/chef/sugar/node.rb, line 77
def deep_fetch!(*keys)
  Chef::Sugar::Deprecation.deprecated "the chef-sugar deep_fetch method is deprecated and should be replaced by node.read!"
  keys.map!(&:to_s)

  keys.inject(attributes.to_hash) do |hash, key|
    if hash.key?(key)
      hash[key]
    else
      raise AttributeDoesNotExistError.new(keys, key)
    end
  end
end
in?(environment) click to toggle source

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

@param [String, Regex] environment

@return [Boolean]

# File lib/chef/sugar/node.rb, line 40
def in?(environment)
  Chef::Sugar::Deprecation.deprecated "the chef-sugar node.in? method is deprecated"
  environment === chef_environment
end
method_missing(m, *args, &block) click to toggle source

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.

@return [nil]

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

@return [Object]

If no argument is passed in, method becomes an attribute accessor
# File lib/chef/sugar/node.rb, line 167
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
Also aliased as: old_method_missing
namespace(*args, &block) click to toggle source

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

@example Define a simple namespace

namespace 'apache2' do
  # ...
end

@example Define a nested namespace

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

@example Define a complex nested namespace

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

@example Define a namespace with a custom precedence level

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

@example 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

@param [Array] args

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

@param [Proc] block

the nested evaluation context

@return [nil]

to prevent accidential method chaining if the block isn't closed
# File lib/chef/sugar/node.rb, line 140
def namespace(*args, &block)
  Chef::Sugar::Deprecation.deprecated "the chef-sugar attribute namespace setting is deprecated, please use traditional chef attribute notation"
  @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

  if @current_namespace.empty?
    @namespace_options = nil
  end
  nil
end
old_method_missing(m, *args, &block)
Alias for: method_missing

Private Instance Methods

current_namespace() click to toggle source

The current namespace. This is actually a reverse-ordered array that vivifies the correct hash.#

@return [Array<String>]

# File lib/chef/sugar/node.rb, line 202
def current_namespace
  @current_namespace ||= []
end
namespace_options() click to toggle source

The namespace options.

@return [Hash]

# File lib/chef/sugar/node.rb, line 190
def namespace_options
  @namespace_options ||= {
    precedence: default
  }
end
vivified() click to toggle source

The vivified (fake-filled) hash. It is assumed that the default value for non-existent keys in the hash is a new, empty hash.

@return [Hash<String, Hash>]

# File lib/chef/sugar/node.rb, line 212
def vivified
  current_namespace.inject(namespace_options[:precedence]) do |hash, item|
    hash[item] ||= {}
    hash[item]
  end
end