Class: Chef::Node

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
DSL::IncludeAttribute, DSL::Universal, Mixin::FromFile, Mixin::ParamsValidate
Defined in:
lib/chef/node.rb,
lib/chef/node/attribute.rb,
lib/chef/node/common_api.rb,
lib/chef/node/mixin/mashy_array.rb,
lib/chef/node/mixin/state_tracking.rb,
lib/chef/node/attribute_collections.rb,
lib/chef/node/immutable_collections.rb,
lib/chef/node/mixin/deep_merge_cache.rb,
lib/chef/node/mixin/immutablize_hash.rb,
lib/chef/node/mixin/immutablize_array.rb,
lib/chef/node/mixin/state_tracking_array.rb

Defined Under Namespace

Modules: CommonAPI, Immutablize, Mixin Classes: AttrArray, Attribute, ImmutableArray, ImmutableMash, VividMash

Instance Attribute Summary collapse

Attributes included from Mixin::FromFile

#source_file

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ParamsValidate

#lazy, #set_or_return, #validate

Methods included from Mixin::LazyModuleInclude

#descendants, #include, #included

Methods included from Mixin::PowershellOut

#powershell_out, #powershell_out!

Methods included from Mixin::WindowsArchitectureHelper

#assert_valid_windows_architecture!, #disable_wow64_file_redirection, #forced_32bit_override_required?, #is_i386_process_on_x86_64_windows?, #node_supports_windows_architecture?, #node_windows_architecture, #restore_wow64_file_redirection, #valid_windows_architecture?, #with_os_architecture, #wow64_architecture_override_required?, #wow64_directory

Methods included from DSL::Secret

#default_secret_config, #default_secret_service, #secret, #with_secret_config, #with_secret_service

Methods included from DSL::RenderHelpers

#render_json, #render_toml, #render_yaml

Methods included from DSL::ReaderHelpers

#parse_file, #parse_json, #parse_toml, #parse_yaml

Methods included from DSL::Powershell

#ps_credential

Methods included from DSL::RegistryHelper

#registry_data_exists?, #registry_get_subkeys, #registry_get_values, #registry_has_subkeys?, #registry_key_exists?, #registry_value_exists?

Methods included from DSL::ChefVault

#chef_vault, #chef_vault_item, #chef_vault_item_for_environment

Methods included from DSL::DataQuery

#data_bag, #data_bag_item, #search, #tagged?

Methods included from EncryptedDataBagItem::CheckEncrypted

#encrypted?

Methods included from DSL::PlatformIntrospection

#older_than_win_2012_or_8?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family

Methods included from DSL::IncludeAttribute

#include_attribute, #parse_attribute_file_spec

Methods included from Mixin::FromFile

#class_from_file, #from_file

Constructor Details

#initialize(chef_server_rest: nil, logger: nil) ⇒ Node

Create a new Chef::Node object.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/chef/node.rb', line 70

def initialize(chef_server_rest: nil, logger: nil)
  @chef_server_rest = chef_server_rest
  @name = nil
  @logger = logger || Chef::Log.with_child(subsystem: "node")

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

  @policy_name = nil
  @policy_group = nil

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

  @run_state = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

Only works for attribute fetches, setting is no longer supported XXX: this should be deprecated



263
264
265
# File 'lib/chef/node.rb', line 263

def method_missing(method, *args, &block)
  attributes.public_send(method, *args, &block)
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



53
54
55
# File 'lib/chef/node.rb', line 53

def logger
  @logger
end

#recipe_listObject

Returns the value of attribute recipe_list.



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

def recipe_list
  @recipe_list
end

#run_contextObject

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.

TODO: This is a pretty ugly way to solve that problem.



61
62
63
# File 'lib/chef/node.rb', line 61

def run_context
  @run_context
end

#run_stateObject

Returns the value of attribute run_state.



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

def run_state
  @run_state
end

Class Method Details

.build(node_name) ⇒ Object



644
645
646
647
648
649
# File 'lib/chef/node.rb', line 644

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].chomp.empty?
  node
end

.find_or_create(node_name) ⇒ Object



635
636
637
638
639
640
641
642
# File 'lib/chef/node.rb', line 635

def self.find_or_create(node_name)
  load(node_name)
rescue Net::HTTPClientException => e
  raise unless e.response.code == "404"

  node = build(node_name)
  node.create
end

.from_hash(o) ⇒ Object



580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'lib/chef/node.rb', line 580

def self.from_hash(o)
  return o if o.is_a? Chef::Node

  node = new
  node.name(o["name"])

  node.policy_name = o["policy_name"] if o.key?("policy_name")
  node.policy_group = o["policy_group"] if o.key?("policy_group")

  unless node.policy_group.nil?
    node.chef_environment(o["policy_group"])
  else
    node.chef_environment(o["chef_environment"])
  end

  if o.key?("attributes")
    node.normal_attrs = o["attributes"]
  end
  node.automatic_attrs = Mash.new(o["automatic"]) if o.key?("automatic")
  node.normal_attrs = Mash.new(o["normal"]) if o.key?("normal")
  node.default_attrs = Mash.new(o["default"]) if o.key?("default")
  node.override_attrs = Mash.new(o["override"]) if o.key?("override")

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

  node
end

.list(inflate = false) ⇒ Object



622
623
624
625
626
627
628
629
630
631
632
633
# File 'lib/chef/node.rb', line 622

def self.list(inflate = false)
  if inflate
    response = {}
    Chef::Search::Query.new.search(:node) do |n|
      n = Chef::Node.from_hash(n)
      response[n.name] = n unless n.nil?
    end
    response
  else
    Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("nodes")
  end
end

.list_by_environment(environment, inflate = false) ⇒ Object



612
613
614
615
616
617
618
619
620
# File 'lib/chef/node.rb', line 612

def self.list_by_environment(environment, inflate = false)
  if inflate
    response = {}
    Chef::Search::Query.new.search(:node, "chef_environment:#{environment}") { |n| response[n.name] = n unless n.nil? }
    response
  else
    Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("environments/#{environment}/nodes")
  end
end

.load(name) ⇒ Object

Load a node by name



652
653
654
# File 'lib/chef/node.rb', line 652

def self.load(name)
  from_hash(Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("nodes/#{name}"))
end

Instance Method Details

#<=>(other) ⇒ Object



708
709
710
# File 'lib/chef/node.rb', line 708

def <=>(other)
  name <=> other.name
end

#==(other) ⇒ Object



700
701
702
703
704
705
706
# File 'lib/chef/node.rb', line 700

def ==(other)
  if other.is_a?(self.class)
    name == other.name
  else
    false
  end
end

#[](attrib) ⇒ Object

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



196
197
198
# File 'lib/chef/node.rb', line 196

def [](attrib)
  attributes[attrib]
end

#apply_expansion_attributes(expansion) ⇒ Object

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



503
504
505
506
507
508
509
510
511
512
513
514
515
# File 'lib/chef/node.rb', line 503

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?(attrib) ⇒ Boolean

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?()

Returns:

  • (Boolean)


247
248
249
# File 'lib/chef/node.rb', line 247

def attribute?(attrib)
  attributes.attribute?(attrib)
end

#attributesObject Also known as: attribute, construct_attributes



188
189
190
# File 'lib/chef/node.rb', line 188

def attributes
  @attributes
end

#automatic_attrsObject



234
235
236
# File 'lib/chef/node.rb', line 234

def automatic_attrs
  attributes.automatic
end

#automatic_attrs=(new_values) ⇒ Object



238
239
240
# File 'lib/chef/node.rb', line 238

def automatic_attrs=(new_values)
  attributes.automatic = new_values
end

#chef_environment(arg = nil) ⇒ Object Also known as: environment



128
129
130
131
132
133
134
# File 'lib/chef/node.rb', line 128

def chef_environment(arg = nil)
  set_or_return(
    :chef_environment,
    arg,
    { regex: /^[\-[:alnum:]_]+$/, kind_of: String }
  )
end

#chef_environment=(environment) ⇒ Object



136
137
138
# File 'lib/chef/node.rb', line 136

def chef_environment=(environment)
  chef_environment(environment)
end

#chef_server_restObject



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/chef/node.rb', line 100

def chef_server_rest
  # for saving node data we use validate_utf8: false which will not
  # raise an exception on bad utf8 data, but will replace the bad
  # characters and render valid JSON.
  @chef_server_rest ||= Chef::ServerAPI.new(
    Chef::Config[:chef_server_url],
    client_name: Chef::Config[:node_name],
    signing_key_filename: Chef::Config[:client_key],
    validate_utf8: false
  )
end

#consume_attributes(attrs) ⇒ Object

Consumes the combined run_list and other attributes in +attrs+



389
390
391
392
393
394
395
396
# File 'lib/chef/node.rb', line 389

def consume_attributes(attrs)
  normal_attrs_to_merge = consume_run_list(attrs)
  normal_attrs_to_merge = consume_chef_environment(normal_attrs_to_merge)
  # FIXME(log): should be trace
  logger.debug("Applying attributes from json file")
  self.normal_attrs = Chef::Mixin::DeepMerge.merge(normal_attrs, normal_attrs_to_merge)
  tags # make sure they're defined
end

#consume_chef_environment(attrs) ⇒ Object

chef_environment when set in -j JSON will take precedence over -E ENVIRONMENT. Ideally, IMO, the order of precedence should be (lowest to highest): config_file -j JSON -E ENVIRONMENT so that users could reuse their JSON and override the chef_environment configured within it with -E ENVIRONMENT. Because command line options are merged with Chef::Config there is currently no way to distinguish between an environment set via config from an environment set via command line.



458
459
460
461
462
463
464
# File 'lib/chef/node.rb', line 458

def consume_chef_environment(attrs)
  attrs = attrs ? attrs.dup : {}
  if env = attrs.delete("chef_environment")
    chef_environment(env)
  end
  attrs
end

#consume_external_attrs(ohai_data, json_cli_attrs) ⇒ Object

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.

Handles both the consumption of ohai data and possibly JSON attributes from the CLI



357
358
359
360
361
362
363
364
# File 'lib/chef/node.rb', line 357

def consume_external_attrs(ohai_data, json_cli_attrs)
  # FIXME(log): should be trace
  logger.debug("Extracting run list from JSON attributes provided on command line")
  consume_attributes(json_cli_attrs)

  self.automatic_attrs = ohai_data
  fix_automatic_attributes
end

#consume_ohai_data(ohai_data) ⇒ Object

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.

This is for ohai plugins to consume ohai data and have it merged, it should probably be renamed



369
370
371
372
# File 'lib/chef/node.rb', line 369

def consume_ohai_data(ohai_data)
  self.automatic_attrs = Chef::Mixin::DeepMerge.merge(automatic_attrs, ohai_data)
  fix_automatic_attributes
end

#consume_run_list(attrs) ⇒ Object

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



435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/chef/node.rb', line 435

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

    logger.info("Setting the run_list to #{new_run_list} from CLI options")
    run_list(new_run_list)
  end
  attrs
end

#createObject

Create the node via the REST API



682
683
684
685
686
687
688
689
690
691
692
693
694
# File 'lib/chef/node.rb', line 682

def create
  chef_server_rest.post("nodes", data_for_save)
  self
rescue Net::HTTPClientException => e
  # Chef Server before 12.3 rejects node JSON with 'policy_name' or
  # 'policy_group' keys, but 'policy_name' will be detected first.
  # Backcompat can be removed in 13.0
  if e.response.code == "400" && e.response.body.include?("Invalid key policy_name")
    chef_server_rest.post("nodes", data_for_save_without_policyfile_attrs)
  else
    raise
  end
end

#data_for_saveObject

Returns hash of node data with attributes based on whitelist/blacklist rules.



713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'lib/chef/node.rb', line 713

def data_for_save
  data = for_json
  %w{automatic default normal override}.each do |level|
    allowlist = allowlist_or_whitelist_config(level)
    unless allowlist.nil? # nil => save everything
      logger.info("Allowing #{level} node attributes for save.")
      data[level] = Chef::AttributeAllowlist.filter(data[level], allowlist)
    end

    blocklist = blocklist_or_blacklist_config(level)
    unless blocklist.nil? # nil => remove nothing
      logger.info("Blocking #{level} node attributes for save")
      data[level] = Chef::AttributeBlocklist.filter(data[level], blocklist)
    end
  end
  data
end

#defaultObject Also known as: default_attrs

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



208
209
210
# File 'lib/chef/node.rb', line 208

def default
  attributes.default
end

#default_attrs=(new_values) ⇒ Object



226
227
228
# File 'lib/chef/node.rb', line 226

def default_attrs=(new_values)
  attributes.default = new_values
end

#destroyObject

Remove this node via the REST API



657
658
659
# File 'lib/chef/node.rb', line 657

def destroy
  chef_server_rest.delete("nodes/#{name}")
end

#display_hashObject



529
530
531
532
533
534
535
536
537
538
539
# File 'lib/chef/node.rb', line 529

def display_hash
  display = {}
  display["name"]             = name
  display["chef_environment"] = chef_environment
  display["automatic"]        = attributes.automatic.to_hash
  display["normal"]           = attributes.normal.to_hash
  display["default"]          = attributes.combined_default.to_hash
  display["override"]         = attributes.combined_override.to_hash
  display["run_list"]         = run_list.run_list_items
  display
end

#each(&block) ⇒ Object

Yield each key of the top level to the block.



252
253
254
# File 'lib/chef/node.rb', line 252

def each(&block)
  attributes.each(&block)
end

#each_attribute(&block) ⇒ Object

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



257
258
259
# File 'lib/chef/node.rb', line 257

def each_attribute(&block)
  attributes.each_attribute(&block)
end

#expand!(data_source = "server") ⇒ Object

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.

-- TODO: timh/cw, 5-14-2010: Should this method exist? Should we instead modify default_attrs and override_attrs whenever our run_list is mutated? Or perhaps do something smarter like on-demand generation of default_attrs and override_attrs, invalidated only when run_list is mutated?



485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/chef/node.rb', line 485

def expand!(data_source = "server")
  expansion = run_list.expand(chef_environment, data_source)
  raise Chef::Exceptions::MissingRole, expansion if expansion.errors?

  tags # make sure they're defined

  automatic_attrs[:recipes] = expansion.recipes.with_duplicate_names
  automatic_attrs[:expanded_run_list] = expansion.recipes.with_fully_qualified_names_and_version_constraints
  automatic_attrs[:roles] = expansion.roles

  apply_expansion_attributes(expansion)

  automatic_attrs[:chef_environment] = chef_environment
  expansion
end

#fix_automatic_attributesObject

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.

Always ensure that certain automatic attributes are populated and constructed correctly



377
378
379
380
381
382
383
384
385
386
# File 'lib/chef/node.rb', line 377

def fix_automatic_attributes
  platform, version = Chef::Platform.find_platform_and_version(self)
  # FIXME(log): should be trace
  logger.debug("Platform is #{platform} version #{version}")
  automatic[:platform] = platform
  automatic[:platform_version] = Chef::VersionString.new(version)
  automatic[:chef_guid] = Chef::Config[:chef_guid] || ( Chef::Config[:chef_guid] = node_uuid )
  automatic[:name] = name
  automatic[:chef_environment] = chef_environment
end

#for_jsonObject



546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
# File 'lib/chef/node.rb', line 546

def for_json
  result = {
    "name" => name,
    "chef_environment" => chef_environment,
    "json_class" => self.class.name,
    "automatic" => attributes.automatic.to_hash,
    "normal" => attributes.normal.to_hash,
    "chef_type" => "node",
    "default" => attributes.combined_default.to_hash,
    "override" => attributes.combined_override.to_hash,
    # Render correctly for run_list items so malformed json does not result
    "run_list" => @primary_runlist.run_list.map(&:to_s),
  }
  # Chef Server rejects node JSON with extra keys; prior to 12.3,
  # "policy_name" and "policy_group" are unknown; after 12.3 they are
  # optional, therefore only including them in the JSON if present
  # maximizes compatibility for most people.
  unless policy_group.nil? && policy_name.nil?
    result["policy_name"] = policy_name
    result["policy_group"] = policy_group
  end
  result
end

#loaded_recipe(cookbook, recipe) ⇒ Object

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



285
286
287
288
289
# File 'lib/chef/node.rb', line 285

def loaded_recipe(cookbook, recipe)
  fully_qualified_recipe = "#{cookbook}::#{recipe}"

  automatic_attrs[:recipes] << fully_qualified_recipe unless Array(automatic_attrs[:recipes]).include?(fully_qualified_recipe)
end

#name(arg = nil) ⇒ Object

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



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/chef/node.rb', line 113

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

#nodeObject

Used by DSL



96
97
98
# File 'lib/chef/node.rb', line 96

def node
  self
end

#normalObject Also known as: normal_attrs

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



202
203
204
# File 'lib/chef/node.rb', line 202

def normal
  attributes.normal
end

#normal_attrs=(new_values) ⇒ Object



230
231
232
# File 'lib/chef/node.rb', line 230

def normal_attrs=(new_values)
  attributes.normal = new_values
end

#overrideObject Also known as: override_attrs

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



214
215
216
# File 'lib/chef/node.rb', line 214

def override
  attributes.override
end

#override_attrs=(new_values) ⇒ Object



222
223
224
# File 'lib/chef/node.rb', line 222

def override_attrs=(new_values)
  attributes.override = new_values
end

#override_runlist(*args) ⇒ Chef::RunList

Accessor for override_runlist (this cannot set an empty override run list)

Returns:



317
318
319
320
321
322
# File 'lib/chef/node.rb', line 317

def override_runlist(*args)
  return @override_runlist if args.length == 0

  @override_runlist_set = true
  @override_runlist.reset!(args)
end

#override_runlist=(array) ⇒ Chef::RunList

Setter for override_runlist which allows setting an empty override run list and marking it to be used

Returns:



328
329
330
331
# File 'lib/chef/node.rb', line 328

def override_runlist=(array)
  @override_runlist_set = true
  @override_runlist.reset!(array)
end

#override_runlist_set?Boolean

This boolean can be useful to determine if an override_runlist is set, it can be true even if the override_runlist is empty.

(Mutators can set the override_runlist so any non-empty override_runlist is considered set)

Returns:

  • (Boolean)

    if the override run list has been set



309
310
311
# File 'lib/chef/node.rb', line 309

def override_runlist_set?
  !!@override_runlist_set || !override_runlist.empty?
end

#policy_group(arg = NOT_PASSED) ⇒ String

The policy_group for this node. Setting this to a non-nil value will enable policyfile mode when chef-client is run. If set in the config file or in node json, running chef-client will update this value.

Parameters:

  • arg (String) (defaults to: NOT_PASSED)

    the new policy_group value

Returns:

  • (String)

    the current policy_group, or the one you just set

See Also:



174
175
176
177
178
179
# File 'lib/chef/node.rb', line 174

def policy_group(arg = NOT_PASSED)
  return @policy_group if arg.equal?(NOT_PASSED)

  validate({ policy_group: arg }, { policy_group: { kind_of: [ String, NilClass ], regex: /^[\-:.[:alnum:]_]+$/ } })
  @policy_group = arg
end

#policy_group=(policy_group) ⇒ Object

A "non-DSL-style" setter for policy_group

See Also:



184
185
186
# File 'lib/chef/node.rb', line 184

def policy_group=(policy_group)
  policy_group(policy_group)
end

#policy_name(arg = NOT_PASSED) ⇒ String

The policy_name for this node. Setting this to a non-nil value will enable policyfile mode when chef-client is run. If set in the config file or in node json, running chef-client will update this value.

Parameters:

  • arg (String) (defaults to: NOT_PASSED)

    the new policy_name value

Returns:

  • (String)

    the current policy_name, or the one you just set

See Also:



151
152
153
154
155
156
# File 'lib/chef/node.rb', line 151

def policy_name(arg = NOT_PASSED)
  return @policy_name if arg.equal?(NOT_PASSED)

  validate({ policy_name: arg }, { policy_name: { kind_of: [ String, NilClass ], regex: /^[\-:.[:alnum:]_]+$/ } })
  @policy_name = arg
end

#policy_name=(policy_name) ⇒ Object

A "non-DSL-style" setter for policy_name

See Also:



161
162
163
# File 'lib/chef/node.rb', line 161

def policy_name=(policy_name)
  policy_name(policy_name)
end

#primary_runlistObject



299
300
301
# File 'lib/chef/node.rb', line 299

def primary_runlist
  @primary_runlist
end

#recipe?(recipe_name) ⇒ Boolean

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[:recipes], which is populated when the run_list is expanded

NOTE: It's used by cookbook authors

Returns:

  • (Boolean)


279
280
281
# File 'lib/chef/node.rb', line 279

def recipe?(recipe_name)
  run_list.include?(recipe_name) || Array(self[:recipes]).include?(recipe_name)
end

#reset_defaults_and_overridesObject

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



468
469
470
471
# File 'lib/chef/node.rb', line 468

def reset_defaults_and_overrides
  default.clear
  override.clear
end

#respond_to_missing?(method, include_private = false) ⇒ Boolean

Fix respond_to + method so that it works with method_missing delegation

Returns:

  • (Boolean)


268
269
270
# File 'lib/chef/node.rb', line 268

def respond_to_missing?(method, include_private = false)
  attributes.respond_to?(method, false)
end

#role?(role_name) ⇒ Boolean

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

Parameters:

  • role_name (String)

    Role to check for

Returns:

  • (Boolean)


295
296
297
# File 'lib/chef/node.rb', line 295

def role?(role_name)
  Array(self[:roles]).include?(role_name)
end

#run_list(*args) ⇒ Object

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.



339
340
341
342
# File 'lib/chef/node.rb', line 339

def run_list(*args)
  rl = select_run_list
  args.length > 0 ? rl.reset!(args) : rl
end

#run_list=(list) ⇒ Object



344
345
346
347
# File 'lib/chef/node.rb', line 344

def run_list=(list)
  rl = select_run_list
  rl = list
end

#run_list?(item) ⇒ Boolean

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

Returns:

  • (Boolean)


350
351
352
# File 'lib/chef/node.rb', line 350

def run_list?(item)
  run_list.detect { |r| r == item } ? true : false
end

#saveObject

Save this node via the REST API



662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
# File 'lib/chef/node.rb', line 662

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]
      logger.warn("In why-run mode, so NOT performing node save.")
    else
      chef_server_rest.put("nodes/#{name}", data_for_save)
    end
  rescue Net::HTTPClientException => e
    if e.response.code == "404"
      chef_server_rest.post("nodes", data_for_save)
    else
      raise
    end
  end
  self
end

#select_run_listObject



333
334
335
# File 'lib/chef/node.rb', line 333

def select_run_list
  override_runlist_set? ? @override_runlist : @primary_runlist
end

#set_cookbook_attributeObject

after the run_context has been set on the node, go through the cookbook_collection and setup the node[:cookbooks] attribute so that it is published in the node object



89
90
91
92
93
# File 'lib/chef/node.rb', line 89

def set_cookbook_attribute
  run_context.cookbook_collection.each do |cookbook_name, cookbook|
    automatic_attrs[:cookbooks][cookbook_name][:version] = cookbook.version
  end
end

#tag(*args) ⇒ Object

Add the list of tags to the node.

=== Parameters tags:: A list of tags

=== Returns tags:: The current list of run_context.node.tags



411
412
413
414
415
416
417
# File 'lib/chef/node.rb', line 411

def tag(*args)
  args.each do |tag|
    tags.push(tag.to_s) unless tags.include? tag.to_s
  end

  tags
end

#tagsObject

Lazy initializer for tags attribute



399
400
401
402
# File 'lib/chef/node.rb', line 399

def tags
  normal[:tags] = Array(normal[:tags])
  normal[:tags]
end

#to_hashObject

Transform the node to a Hash



518
519
520
521
522
523
524
525
526
527
# File 'lib/chef/node.rb', line 518

def to_hash
  index_hash = attributes.to_hash
  index_hash["chef_type"] = "node"
  index_hash["name"] = name
  index_hash["chef_environment"] = chef_environment
  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_items
  index_hash
end

#to_json(*a) ⇒ Object

Serialize this object as a hash



542
543
544
# File 'lib/chef/node.rb', line 542

def to_json(*a)
  Chef::JSONCompat.to_json(for_json, *a)
end

#to_sObject



696
697
698
# File 'lib/chef/node.rb', line 696

def to_s
  "node[#{name}]"
end

#untag(*args) ⇒ Object

Removes the list of tags from the node.

=== Parameters tags:: A list of tags

=== Returns tags:: The current list of run_context.node.tags



426
427
428
429
430
431
432
# File 'lib/chef/node.rb', line 426

def untag(*args)
  args.each do |tag|
    tags.delete(tag.to_s)
  end

  tags
end

#update_from!(o) ⇒ Object



570
571
572
573
574
575
576
577
578
# File 'lib/chef/node.rb', line 570

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