Method: Chef::NodeMap#set

Defined in:
lib/chef/node_map.rb

#set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, allow_cookbook_override: false, __core_override__: false) {|node| ... } ⇒ NodeMap

Set a key/value pair on the map with a filter. The filter must be true when applied to the node in order to retrieve the value.

Parameters:

  • key (Object)

    Key to store

  • value (Object)

    Value associated with the key

  • filters (Hash)

    Node filter options to apply to key retrieval

  • allow_cookbook_override (Boolean, String) (defaults to: false)

    Allow a cookbook to add to this key even in locked mode. If a string is given, it should be a Gem::Requirement-compatible value indicating for which Chef versions an override from cookbooks is allowed.

  • __core_override__ (Boolean) (defaults to: false)

    Advanced-mode override to add to a key even in locked mode.

Yields:

  • (node)

    Arbitrary node filter as a block which takes a node argument

Returns:

  • (NodeMap)

    Returns self for possible chaining



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/chef/node_map.rb', line 74

def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, allow_cookbook_override: false, __core_override__: false, &block) # rubocop:disable Lint/UnderscorePrefixedVariableName
  new_matcher = { klass: klass }
  new_matcher[:platform] = platform if platform
  new_matcher[:platform_version] = platform_version if platform_version
  new_matcher[:platform_family] = platform_family if platform_family
  new_matcher[:os] = os if os
  new_matcher[:block] = block if block
  new_matcher[:canonical] = canonical if canonical
  new_matcher[:override] = override if override
  new_matcher[:cookbook_override] = allow_cookbook_override
  new_matcher[:core_override] = __core_override__

  # Check if the key is already present and locked, unless the override is allowed.
  # The checks to see if we should reject, in order:
  # 1. Core override mode is not set.
  # 2. The key exists.
  # 3. At least one previous `provides` is now locked.
  # 4. No previous `provides` had `allow_cookbook_override`, either set to
  #    true or with a string version matcher that still matches Chef::VERSION
  if !__core_override__ && map[key] && map[key].any? { |matcher| matcher[:locked] } && !map[key].any? { |matcher| matcher[:cookbook_override].is_a?(String) ? Chef::VERSION =~ matcher[:cookbook_override] : matcher[:cookbook_override] }
    # If we ever use locked mode on things other than the resource and provider handler maps, this probably needs a tweak.
    type_of_thing = if klass < Chef::Resource
                      "resource"
                    elsif klass < Chef::Provider
                      "provider"
                    else
                      klass.superclass.to_s
                    end
    # For now, only log the warning.
    Chef.deprecated(:map_collision, COLLISION_WARNING_14 % { type: type_of_thing, key: key, type_caps: type_of_thing.capitalize })
    # In 15.0, uncomment this and remove the log above.
    # Chef.deprecated(:map_collision, COLLISION_WARNING_15 % {type: type_of_thing, key: key, type_caps: type_of_thing.capitalize}))
    # return
  end

  # The map is sorted in order of preference already; we just need to find
  # our place in it (just before the first value with the same preference level).
  insert_at = nil
  map[key] ||= []
  map[key].each_with_index do |matcher, index|
    cmp = compare_matchers(key, new_matcher, matcher)
    if cmp && cmp <= 0
      insert_at = index
      break
    end
  end
  if insert_at
    map[key].insert(insert_at, new_matcher)
  else
    map[key] << new_matcher
  end
  map
end