# class Chef::Node

### Attributes

override_runlist[RW]
recipe_list[RW]
run_context[RW]

RunContext will set itself as #run_context via this setter when initialized. This is needed so DSL::IncludeAttribute (in particular, include_recipe) can access the #run_context to determine if an attributes file has been seen yet.

run_state[RW]

### Public Class Methods

build(node_name) click to toggle source

    # File lib/chef/node.rb, line 498
    def self.build(node_name)
      node = new
      node.name(node_name)
      node.chef_environment(Chef::Config[:environment]) unless Chef::Config[:environment].nil? || Chef::Config[:environment].chop.empty?
      node
    end

find_or_create(node_name) click to toggle source

    # File lib/chef/node.rb, line 490
    def self.find_or_create(node_name)
      load(node_name)
    rescue Net::HTTPServerException => e
      raise unless e.response.code == '404'
      node = build(node_name)
      node.create
    end

json_create(o) click to toggle source

Create a Chef::Node from JSON

    # File lib/chef/node.rb, line 448
    def self.json_create(o)
      node = new
      node.name(o["name"])
      node.chef_environment(o["chef_environment"])
      if o.has_key?("attributes")
        node.normal_attrs = o["attributes"]
      end
      node.automatic_attrs = Mash.new(o["automatic"]) if o.has_key?("automatic")
      node.normal_attrs = Mash.new(o["normal"]) if o.has_key?("normal")
      node.default_attrs = Mash.new(o["default"]) if o.has_key?("default")
      node.override_attrs = Mash.new(o["override"]) if o.has_key?("override")

      if o.has_key?("run_list")
        node.run_list.reset!(o["run_list"])
      else
        o["recipes"].each { |r| node.recipes << r }
      end
      node
    end

list(inflate=false) click to toggle source

    # File lib/chef/node.rb, line 478
    def self.list(inflate=false)
      if inflate
        response = Hash.new
        Chef::Search::Query.new.search(:node) do |n|
          response[n.name] = n unless n.nil?
        end
        response
      else
        Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("nodes")
      end
    end

list_by_environment(environment, inflate=false) click to toggle source

    # File lib/chef/node.rb, line 468
    def self.list_by_environment(environment, inflate=false)
      if inflate
        response = Hash.new
        Chef::Search::Query.new.search(:node, "chef_environment:#{environment}") {|n| response[n.name] = n unless n.nil?}
        response
      else
        Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("environments/#{environment}/nodes")
      end
    end

load(name) click to toggle source

Load a node by name

    # File lib/chef/node.rb, line 506
    def self.load(name)
      Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("nodes/#{name}")
    end

new() click to toggle source

Create a new Chef::Node object.

    # File lib/chef/node.rb, line 62
    def initialize
      @name = nil

      @chef_environment = '_default'
      @primary_runlist = Chef::RunList.new
      @override_runlist = Chef::RunList.new

      @attributes = Chef::Node::Attribute.new({}, {}, {}, {})

      @run_state = {}
    end

### Public Instance Methods

<=>(other_node) click to toggle source

    # File lib/chef/node.rb, line 542
    def <=>(other_node)
      self.name <=> other_node.name
    end

[](attrib) click to toggle source

Return an attribute of this node. Returns nil if the attribute is not found.

    # File lib/chef/node.rb, line 120
    def [](attrib)
      attributes[attrib]
    end

apply_expansion_attributes(expansion) click to toggle source

Apply the default and overrides attributes from the expansion passed in, which came from roles.

    # File lib/chef/node.rb, line 375
    def apply_expansion_attributes(expansion)
      loaded_environment = if chef_environment == "_default"
                             Chef::Environment.new.tap {|e| e.name("_default")}
                           else
                             Chef::Environment.load(chef_environment)
                           end

      attributes.env_default = loaded_environment.default_attributes
      attributes.env_override = loaded_environment.override_attributes

      attribute.role_default = expansion.default_attrs
      attributes.role_override = expansion.override_attrs
    end

attribute()
Alias for: attributes
attribute?(attrib) click to toggle source

Return true if this Node has a given attribute, false if not. Takes either a symbol or a string.

Only works on the top level. Preferred way is to use the normal [] style lookup and call attribute?()

    # File lib/chef/node.rb, line 221
    def attribute?(attrib)
      attributes.attribute?(attrib)
    end

attributes() click to toggle source

    # File lib/chef/node.rb, line 112
    def attributes
      @attributes
    end

Also aliased as: attribute, construct_attributes
automatic_attrs() click to toggle source

    # File lib/chef/node.rb, line 208
    def automatic_attrs
      attributes.automatic
    end

automatic_attrs=(new_values) click to toggle source

    # File lib/chef/node.rb, line 212
    def automatic_attrs=(new_values)
      attributes.automatic = new_values
    end

chef_environment(arg=nil) click to toggle source

    # File lib/chef/node.rb, line 98
    def chef_environment(arg=nil)
      set_or_return(
        :chef_environment,
        arg,
        { :regex => /^[\-[:alnum:]_]+$/, :kind_of => String }
      )
    end

Also aliased as: environment
chef_environment=(environment) click to toggle source

    # File lib/chef/node.rb, line 106
    def chef_environment=(environment)
      chef_environment(environment)
    end

chef_server_rest() click to toggle source

    # File lib/chef/node.rb, line 79
    def chef_server_rest
      Chef::REST.new(Chef::Config[:chef_server_url])
    end

construct_attributes()
Alias for: attributes
consume_attributes(attrs) click to toggle source

Consumes the combined #run_list and other attributes in `attrs`

    # File lib/chef/node.rb, line 306
    def consume_attributes(attrs)
      normal_attrs_to_merge = consume_run_list(attrs)
      Chef::Log.debug("Applying attributes from json file")
      self.normal_attrs = Chef::Mixin::DeepMerge.merge(normal_attrs,normal_attrs_to_merge)
      self.tags # make sure they're defined
    end

consume_external_attrs(ohai_data, json_cli_attrs) click to toggle source

Consume data from ohai and Attributes provided as JSON on the command line.

    # File lib/chef/node.rb, line 293
    def consume_external_attrs(ohai_data, json_cli_attrs)
      Chef::Log.debug("Extracting run list from JSON attributes provided on command line")
      consume_attributes(json_cli_attrs)

      self.automatic_attrs = ohai_data

      platform, version = Chef::Platform.find_platform_and_version(self)
      Chef::Log.debug("Platform is #{platform} version #{version}")
      self.automatic[:platform] = platform
      self.automatic[:platform_version] = version
    end

consume_run_list(attrs) click to toggle source

Extracts the run list from `attrs` and applies it. Returns the remaining attributes

    # File lib/chef/node.rb, line 328
    def consume_run_list(attrs)
      attrs = attrs ? attrs.dup : {}
      if new_run_list = attrs.delete("recipes") || attrs.delete("run_list")
        if attrs.key?("recipes") || attrs.key?("run_list")
          raise Chef::Exceptions::AmbiguousRunlistSpecification, "please set the node's run list using the 'run_list' attribute only."
        end
        Chef::Log.info("Setting the run_list to #{new_run_list.inspect} from CLI options")
        run_list(new_run_list)
      end
      attrs
    end

create() click to toggle source

Create the node via the REST API

    # File lib/chef/node.rb, line 533
    def create
      chef_server_rest.post_rest("nodes", self)
      self
    end

default() click to toggle source

Set a default of this node, but auto-vivify any Mashes that might be missing

    # File lib/chef/node.rb, line 143
    def default
      attributes.set_unless_value_present = false
      attributes.default
    end

default!() click to toggle source

Set a force default attribute. Intermediate mashes will be created by auto-vivify if necessary.

    # File lib/chef/node.rb, line 150
    def default!
      attributes.set_unless_value_present = false
      attributes.default!
    end

default_attrs() click to toggle source

    # File lib/chef/node.rb, line 192
    def default_attrs
      attributes.default
    end

default_attrs=(new_values) click to toggle source

    # File lib/chef/node.rb, line 196
    def default_attrs=(new_values)
      attributes.default = new_values
    end

default_unless() click to toggle source

Set a default attribute of this node, auto-vivifying any mashes that are missing, but if the final value already exists, don’t set it

    # File lib/chef/node.rb, line 157
    def default_unless
      attributes.set_unless_value_present = true
      attributes.default
    end

destroy() click to toggle source

Remove this node via the REST API

    # File lib/chef/node.rb, line 511
    def destroy
      chef_server_rest.delete_rest("nodes/#{name}")
    end

display_hash() click to toggle source

    # File lib/chef/node.rb, line 404
    def display_hash
      display = {}
      display["name"]             = name
      display["chef_environment"] = chef_environment
      display["automatic"]        = automatic_attrs
      display["normal"]           = normal_attrs
      display["default"]          = attributes.combined_default
      display["override"]         = attributes.combined_override
      display["run_list"]         = run_list.run_list
      display
    end

each(&block) click to toggle source

Yield each key of the top level to the block.

    # File lib/chef/node.rb, line 226
    def each(&block)
      attributes.each(&block)
    end

each_attribute(&block) click to toggle source

Iterates over each attribute, passing the attribute and value to the block.

    # File lib/chef/node.rb, line 231
    def each_attribute(&block)
      attributes.each_attribute(&block)
    end

environment(arg=nil)
Alias for: chef_environment
expand!(data_source = 'server') click to toggle source

Expands the node’s run list and sets the default and override attributes. Also applies stored attributes (from json provided on the command line)

Returns the fully-expanded list of recipes, a RunListExpansion.

    # File lib/chef/node.rb, line 359
    def expand!(data_source = 'server')
      expansion = run_list.expand(chef_environment, data_source)
      raise Chef::Exceptions::MissingRole, expansion if expansion.errors?

      self.tags # make sure they're defined

      automatic_attrs[:recipes] = expansion.recipes
      automatic_attrs[:roles] = expansion.roles

      apply_expansion_attributes(expansion)

      expansion
    end

for_json() click to toggle source

    # File lib/chef/node.rb, line 421
    def for_json
      result = {
        "name" => name,
        "chef_environment" => chef_environment,
        'json_class' => self.class.name,
        "automatic" => attributes.automatic,
        "normal" => attributes.normal,
        "chef_type" => "node",
        "default" => attributes.combined_default,
        "override" => attributes.combined_override,
        #Render correctly for run_list items so malformed json does not result
        "run_list" => @primary_runlist.run_list.map { |item| item.to_s }
      }
      result
    end

loaded_recipe(cookbook, recipe) click to toggle source

used by include_recipe to add recipes to the expanded #run_list to be saved back to the node and be searchable

    # File lib/chef/node.rb, line 253
    def loaded_recipe(cookbook, recipe)
      fully_qualified_recipe = "#{cookbook}::#{recipe}"
      automatic_attrs[:recipes] << fully_qualified_recipe unless Array(self[:recipes]).include?(fully_qualified_recipe)
    end

method_missing(symbol, *args) click to toggle source

Only works for attribute fetches, setting is no longer supported

    # File lib/chef/node.rb, line 236
    def method_missing(symbol, *args)
      attributes.send(symbol, *args)
    end

name(arg=nil) click to toggle source

Set the name of this Node, or return the current name.

    # File lib/chef/node.rb, line 84
    def name(arg=nil)
      if arg != nil
        validate(
                 {:name => arg },
                 {:name => { :kind_of => String,
                     :cannot_be => :blank,
                     :regex => /^[\-[:alnum:]_:.]+$/}
                 })
        @name = arg
      else
        @name
      end
    end

node() click to toggle source

Used by DSL

    # File lib/chef/node.rb, line 75
    def node
      self
    end

normal() click to toggle source

Set a normal attribute of this node, but auto-vivify any Mashes that might be missing

    # File lib/chef/node.rb, line 126
    def normal
      attributes.set_unless_value_present = false
      attributes.normal
    end

Also aliased as: set
normal_attrs() click to toggle source

    # File lib/chef/node.rb, line 200
    def normal_attrs
      attributes.normal
    end

normal_attrs=(new_values) click to toggle source

    # File lib/chef/node.rb, line 204
    def normal_attrs=(new_values)
      attributes.normal = new_values
    end

normal_unless() click to toggle source

Set a normal attribute of this node, auto-vivifying any mashes that are missing, but if the final value already exists, don’t set it

    # File lib/chef/node.rb, line 135
    def normal_unless
      attributes.set_unless_value_present = true
      attributes.normal
    end

Also aliased as: set_unless
override() click to toggle source

Set an override attribute of this node, but auto-vivify any Mashes that might be missing

    # File lib/chef/node.rb, line 164
    def override
      attributes.set_unless_value_present = false
      attributes.override
    end

override!() click to toggle source

Set a force override attribute. Intermediate mashes will be created by auto-vivify if needed.

    # File lib/chef/node.rb, line 171
    def override!
      attributes.set_unless_value_present = false
      attributes.override!
    end

override_attrs() click to toggle source

    # File lib/chef/node.rb, line 184
    def override_attrs
     attributes.override
    end

override_attrs=(new_values) click to toggle source

    # File lib/chef/node.rb, line 188
    def override_attrs=(new_values)
      attributes.override = new_values
    end

override_unless() click to toggle source

Set an override attribute of this node, auto-vivifying any mashes that are missing, but if the final value already exists, don’t set it

    # File lib/chef/node.rb, line 178
    def override_unless
      attributes.set_unless_value_present = true
      attributes.override
    end

primary_runlist() click to toggle source

    # File lib/chef/node.rb, line 263
    def primary_runlist
      @primary_runlist
    end

recipe?(recipe_name) click to toggle source

Returns true if this Node expects a given recipe, false if not.

First, the run list is consulted to see whether the recipe is explicitly included. If it’s not there, it looks in `node`, which is populated when the #run_list is expanded

NOTE: It’s used by cookbook authors

    # File lib/chef/node.rb, line 247
    def recipe?(recipe_name)
      run_list.include?(recipe_name) || Array(self[:recipes]).include?(recipe_name)
    end

reset_defaults_and_overrides() click to toggle source

Clear defaults and overrides, so that any deleted attributes between runs are still gone.

    # File lib/chef/node.rb, line 342
    def reset_defaults_and_overrides
      self.default.clear
      self.override.clear
    end

role?(role_name) click to toggle source

Returns true if this Node expects a given role, false if not.

    # File lib/chef/node.rb, line 259
    def role?(role_name)
      run_list.include?("role[#{role_name}]")
    end

run_list(*args) click to toggle source

Returns an Array of roles and recipes, in the order they will be applied. If you call it with arguments, they will become the new list of roles and recipes.

    # File lib/chef/node.rb, line 277
    def run_list(*args)
      rl = select_run_list
      args.length > 0 ? rl.reset!(args) : rl
    end

run_list=(list) click to toggle source

    # File lib/chef/node.rb, line 282
    def run_list=(list)
      rl = select_run_list
      rl = list
    end

run_list?(item) click to toggle source

Returns true if this Node expects a given role, false if not.

    # File lib/chef/node.rb, line 288
    def run_list?(item)
      run_list.detect { |r| r == item } ? true : false
    end

save() click to toggle source

Save this node via the REST API

    # File lib/chef/node.rb, line 516
    def save
      # Try PUT. If the node doesn't yet exist, PUT will return 404,
      # so then POST to create.
      begin
        if Chef::Config[:why_run]
          Chef::Log.warn("In whyrun mode, so NOT performing node save.")
        else
          chef_server_rest.put_rest("nodes/#{name}", self)
        end
      rescue Net::HTTPServerException => e
        raise e unless e.response.code == "404"
        chef_server_rest.post_rest("nodes", self)
      end
      self
    end

select_run_list() click to toggle source

    # File lib/chef/node.rb, line 271
    def select_run_list
      @override_runlist.empty? ? @primary_runlist : @override_runlist
    end

set()
Alias for: normal
set_unless()
Alias for: normal_unless
tag(*tags) click to toggle source

    # File lib/chef/node.rb, line 319
    def tag(*tags)
      tags.each do |tag|
        self.normal[:tags].push(tag.to_s) unless self[:tags].include? tag.to_s
      end

      self[:tags]
    end

tags() click to toggle source

Lazy initializer for tags attribute

    # File lib/chef/node.rb, line 314
    def tags
      normal[:tags] = [] unless attribute?(:tags)
      normal[:tags]
    end

to_hash() click to toggle source

Transform the node to a Hash

    # File lib/chef/node.rb, line 390
    def to_hash
      index_hash = Hash.new
      index_hash["chef_type"] = "node"
      index_hash["name"] = name
      index_hash["chef_environment"] = chef_environment
      attribute.each do |key, value|
        index_hash[key] = value
      end
      index_hash["recipe"] = run_list.recipe_names if run_list.recipe_names.length > 0
      index_hash["role"] = run_list.role_names if run_list.role_names.length > 0
      index_hash["run_list"] = run_list.run_list if run_list.run_list.length > 0
      index_hash
    end

to_json(*a) click to toggle source

Serialize this object as a hash

    # File lib/chef/node.rb, line 417
    def to_json(*a)
      for_json.to_json(*a)
    end

to_s() click to toggle source

    # File lib/chef/node.rb, line 538
    def to_s
      "node[#{name}]"
    end

update_from!(o) click to toggle source

    # File lib/chef/node.rb, line 437
    def update_from!(o)
      run_list.reset!(o.run_list)
      self.automatic_attrs = o.automatic_attrs
      self.normal_attrs = o.normal_attrs
      self.override_attrs = o.override_attrs
      self.default_attrs = o.default_attrs
      chef_environment(o.chef_environment)
      self
    end