Parent

Namespace

Class/Module Index [+]

Quicksearch

Chef::Node

Constants

DESIGN_DOCUMENT

Attributes

automatic_attrs[RW]
cookbook_collection[RW]

TODO: 5/18/2010 cw/timh. cookbook_collection should be removed from here and for any place it's needed, it should be accessed through a Chef::RunContext

couchdb[RW]
couchdb_id[R]
couchdb_rev[RW]
default_attrs[RW]
normal_attrs[RW]
override_attrs[RW]
recipe_list[RW]
run_list[RW]
run_state[RW]

Public Class Methods

build(node_name) click to toggle source
# File lib/chef/node.rb, line 595
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
cdb_list(inflate=false, couchdb=nil) click to toggle source

List all the Chef::Node objects in the CouchDB. If inflate is set to true, you will get the full list of all Nodes, fully inflated.

# File lib/chef/node.rb, line 556
def self.cdb_list(inflate=false, couchdb=nil)
  rs =(couchdb || Chef::CouchDB.new).list("nodes", inflate)
  lookup = (inflate ? "value" : "key")
  rs["rows"].collect { |r| r[lookup] }
end
cdb_list_by_environment(environment, inflate=false, couchdb=nil) click to toggle source
# File lib/chef/node.rb, line 539
def self.cdb_list_by_environment(environment, inflate=false, couchdb=nil)
  rs = (couchdb || Chef::CouchDB.new).get_view("nodes", "by_environment", :include_docs => inflate, :startkey => environment, :endkey => environment)
  inflate ? rs["rows"].collect {|r| r["doc"]} : rs["rows"].collect {|r| r["value"]}
end
cdb_load(name, couchdb=nil) click to toggle source

Load a node by name from CouchDB

# File lib/chef/node.rb, line 575
def self.cdb_load(name, couchdb=nil)
  (couchdb || Chef::CouchDB.new).load("node", name)
end
create_design_document(couchdb=nil) click to toggle source

Set up our CouchDB design document

# File lib/chef/node.rb, line 646
def self.create_design_document(couchdb=nil)
  (couchdb || Chef::CouchDB.new).create_design_document("nodes", DESIGN_DOCUMENT)
end
exists?(nodename, couchdb) click to toggle source
# File lib/chef/node.rb, line 579
def self.exists?(nodename, couchdb)
  begin
    self.cdb_load(nodename, couchdb)
  rescue Chef::Exceptions::CouchDBNotFound
    nil
  end
end
find_or_create(node_name) click to toggle source
# File lib/chef/node.rb, line 587
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 516
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.couchdb_rev = o["_rev"] if o.has_key?("_rev")
  node.couchdb_id = o["_id"] if o.has_key?("_id")
  node.index_id = node.couchdb_id
  node
end
list(inflate=false) click to toggle source
# File lib/chef/node.rb, line 562
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 544
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 603
def self.load(name)
  Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("nodes/#{name}")
end
new(couchdb=nil) click to toggle source

Create a new Chef::Node object.

# File lib/chef/node.rb, line 157
def initialize(couchdb=nil)
  @name = nil

  @chef_environment = '_default'
  @normal_attrs = Mash.new
  @override_attrs = Mash.new
  @default_attrs = Mash.new
  @automatic_attrs = Mash.new
  @run_list = Chef::RunList.new

  @couchdb_rev = nil
  @couchdb_id = nil
  @couchdb = couchdb || Chef::CouchDB.new

  @run_state = {
    :template_cache => Hash.new,
    :seen_recipes => Hash.new,
    :seen_attributes => Hash.new
  }
  # TODO: 5/20/2010 need this here as long as other objects try to access
  # the cookbook collection via Node, otherwise get NoMethodError on nil.
  @cookbook_collection = CookbookCollection.new
end

Public Instance Methods

[](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 250
def [](attrib)
  construct_attributes[attrib]
end
[]=(attrib, value) click to toggle source

Set an attribute of this node

# File lib/chef/node.rb, line 255
def []=(attrib, value)
  construct_attributes[attrib] = value
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 450
def apply_expansion_attributes(expansion)
  load_chef_environment_object = (chef_environment == "_default" ? nil : Chef::Environment.load(chef_environment))
  environment_default_attrs = load_chef_environment_object.nil? ? {} : load_chef_environment_object.default_attributes
  default_before_roles = Chef::Mixin::DeepMerge.merge(default_attrs, environment_default_attrs)
  @default_attrs = Chef::Mixin::DeepMerge.merge(default_before_roles, expansion.default_attrs)
  environment_override_attrs = load_chef_environment_object.nil? ? {} : load_chef_environment_object.override_attributes
  overrides_before_environments = Chef::Mixin::DeepMerge.merge(override_attrs, expansion.override_attrs)
  @override_attrs = Chef::Mixin::DeepMerge.merge(overrides_before_environments, environment_override_attrs)
end
attribute() click to toggle source

Used by the DSL

# File lib/chef/node.rb, line 237
def attribute
  construct_attributes
end
attribute=(value) click to toggle source
# File lib/chef/node.rb, line 245
def attribute=(value)
  self.normal_attrs = value
end
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 328
def attribute?(attrib)
  construct_attributes.attribute?(attrib)
end
cdb_destroy() click to toggle source

Remove this node from the CouchDB

# File lib/chef/node.rb, line 608
def cdb_destroy
  couchdb.delete("node", name, couchdb_rev)
end
cdb_save() click to toggle source

Save this node to the CouchDB

# File lib/chef/node.rb, line 618
def cdb_save
  @couchdb_rev = couchdb.store("node", name, self)["rev"]
end
chef_environment(arg=nil) click to toggle source
# File lib/chef/node.rb, line 228
def chef_environment(arg=nil)
  set_or_return(
    :chef_environment,
    arg,
    { :regex => /^[\-[:alnum:]_]+$/, :kind_of => String }
  )
end
chef_server_rest() click to toggle source
# File lib/chef/node.rb, line 191
def chef_server_rest
  Chef::REST.new(Chef::Config[:chef_server_url])
end
construct_attributes() click to toggle source
# File lib/chef/node.rb, line 241
def construct_attributes
  Chef::Node::Attribute.new(normal_attrs, default_attrs, override_attrs, automatic_attrs)
end
consume_attributes(attrs) click to toggle source

Consumes the combined run_list and other attributes in attrs

# File lib/chef/node.rb, line 391
def consume_attributes(attrs)
  normal_attrs_to_merge = consume_run_list(attrs)
  Chef::Log.debug("Applying attributes from json file")
  @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 378
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)

  @automatic_attrs = ohai_data

  platform, version = Chef::Platform.find_platform_and_version(self)
  Chef::Log.debug("Platform is #{platform} version #{version}")
  @automatic_attrs[:platform] = platform
  @automatic_attrs[: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 405
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 JSON")
    run_list(new_run_list)
  end
  attrs
end
couchdb_id=(value) click to toggle source
# File lib/chef/node.rb, line 181
def couchdb_id=(value)
  @couchdb_id = value
  @index_id = value
end
create() click to toggle source

Create the node via the REST API

# File lib/chef/node.rb, line 640
def create
  chef_server_rest.post_rest("nodes", self)
  self
end
default() click to toggle source

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

# File lib/chef/node.rb, line 287
def default
  attrs = construct_attributes
  attrs.set_type = :default
  attrs.auto_vivifiy_on_read = true
  attrs
end
default_unless() click to toggle source

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

# File lib/chef/node.rb, line 296
def default_unless
  attrs = construct_attributes
  attrs.set_type = :default
  attrs.auto_vivifiy_on_read = true
  attrs.set_unless_value_present = true
  attrs
end
destroy() click to toggle source

Remove this node via the REST API

# File lib/chef/node.rb, line 613
def destroy
  chef_server_rest.delete_rest("nodes/#{name}")
end
display_hash() click to toggle source
# File lib/chef/node.rb, line 475
def display_hash
  display = {}
  display["name"]             = name
  display["chef_environment"] = chef_environment
  display["automatic"]        = automatic_attrs
  display["normal"]           = normal_attrs
  display["default"]          = default_attrs
  display["override"]         = override_attrs
  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 333
def each(&block)
  construct_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 338
def each_attribute(&block)
  construct_attributes.each_attribute(&block)
end
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 436
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

  expansion
end
find_file(fqdn) click to toggle source

Find a recipe for this Chef::Node by fqdn. Will search first for Chef::Config, then hostname.rb, then default.rb.

Returns a new Chef::Node object.

Raises an ArgumentError if it cannot find the node.

# File lib/chef/node.rb, line 201
def find_file(fqdn)
  host_parts = fqdn.split(".")
  hostname = host_parts[0]

  [fqdn, hostname, "default"].each { |fname|
   node_file = File.join(Chef::Config[:node_path], "#{fname.to_s}.rb")
   return self.from_file(node_file) if File.exists?(node_file)
 }

  raise ArgumentError, "Cannot find a node matching #{fqdn}, not even with default.rb!"
end
load_attribute_by_short_filename(name, src_cookbook_name) click to toggle source

Used by DSL. Loads the attribute file specified by the short name of the file, e.g., loads specified cookbook's

"attributes/mailservers.rb"

if passed

"mailservers"
# File lib/chef/node.rb, line 671
def load_attribute_by_short_filename(name, src_cookbook_name)
  src_cookbook = cookbook_collection[src_cookbook_name]
  raise Chef::Exceptions::CookbookNotFound, "could not find cookbook #{src_cookbook_name} while loading attribute #{name}" unless src_cookbook

  attribute_filename = src_cookbook.attribute_filenames_by_short_filename[name]
  raise Chef::Exceptions::AttributeNotFound, "could not find filename for attribute #{name} in cookbook #{src_cookbook_name}" unless attribute_filename

  self.from_file(attribute_filename)
  self
end
load_attributes() click to toggle source

Load all attribute files for all cookbooks associated with this node.

# File lib/chef/node.rb, line 656
def load_attributes
  cookbook_collection.values.each do |cookbook|
    cookbook.segment_filenames(:attributes).each do |segment_filename|
      Chef::Log.debug("Node #{name} loading cookbook #{cookbook.name}'s attribute file #{segment_filename}")
      self.from_file(segment_filename)
    end
  end
end
method_missing(symbol, *args) click to toggle source

Encouraged to only get used for lookups - while you can do sets from here, it's not as explicit as using the normal/default/override interface.

# File lib/chef/node.rb, line 344
def method_missing(symbol, *args)
  attrs = construct_attributes
  attrs.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 214
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 187
def node
  self
end
normal() click to toggle source

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

# File lib/chef/node.rb, line 265
def normal
  attrs = construct_attributes
  attrs.set_type = :normal
  attrs.auto_vivifiy_on_read = true
  attrs
end
Also aliased as: set
normal_unless() click to toggle source

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

# File lib/chef/node.rb, line 276
def normal_unless
  attrs = construct_attributes
  attrs.set_type = :normal
  attrs.auto_vivifiy_on_read = true
  attrs.set_unless_value_present = true
  attrs
end
Also aliased as: set_unless
override() click to toggle source

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

# File lib/chef/node.rb, line 306
def override
  attrs = construct_attributes
  attrs.set_type = :override
  attrs.auto_vivifiy_on_read = true
  attrs
end
override_unless() click to toggle source

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

# File lib/chef/node.rb, line 315
def override_unless
  attrs = construct_attributes
  attrs.set_type = :override
  attrs.auto_vivifiy_on_read = true
  attrs.set_unless_value_present = true
  attrs
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 run_state, which is populated by include_recipe statements in the DSL (and thus would not be in the run list).

NOTE: It's used by cookbook authors

# File lib/chef/node.rb, line 357
def recipe?(recipe_name)
  run_list.include?(recipe_name) || run_state[:seen_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 419
def reset_defaults_and_overrides
  @default_attrs = Mash.new
  @override_attrs = Mash.new
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 362
def role?(role_name)
  run_list.include?("role[#{role_name}]")
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 373
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 623
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
set() click to toggle source
Alias for: normal
set_unless() click to toggle source
Alias for: normal_unless
store(attrib, value) click to toggle source
# File lib/chef/node.rb, line 259
def store(attrib, value)
  self[attrib] = value
end
tags() click to toggle source

Lazy initializer for tags attribute

# File lib/chef/node.rb, line 399
def tags
  self.set[:tags] = [] unless attribute?(:tags)
  self[:tags]
end
to_hash() click to toggle source

Transform the node to a Hash

# File lib/chef/node.rb, line 461
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 488
def to_json(*a)
  result = {
    "name" => name,
    "chef_environment" => chef_environment,
    'json_class' => self.class.name,
    "automatic" => automatic_attrs,
    "normal" => normal_attrs,
    "chef_type" => "node",
    "default" => default_attrs,
    "override" => override_attrs,
    #Render correctly for run_list items so malformed json does not result
    "run_list" => run_list.run_list.map { |item| item.to_s }
  }
  result["_rev"] = couchdb_rev if couchdb_rev
  result.to_json(*a)
end
to_s() click to toggle source
# File lib/chef/node.rb, line 650
def to_s
  "node[#{name}]"
end
update_from!(o) click to toggle source
# File lib/chef/node.rb, line 505
def update_from!(o)
  run_list.reset!(o.run_list)
  @automatic_attrs = o.automatic_attrs
  @normal_attrs = o.normal_attrs
  @override_attrs = o.override_attrs
  @default_attrs = o.default_attrs
  chef_environment(o.chef_environment)
  self
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.