Class: Chef::NodeMap
- Inherits:
-
Object
- Object
- Chef::NodeMap
- Defined in:
- lib/chef/node_map.rb
Direct Known Subclasses
Platform::PriorityMap, Platform::ProviderHandlerMap, Platform::ResourceHandlerMap
Constant Summary collapse
- COLLISION_WARNING_14 =
"%{type_caps} %{key} has been loaded from a cookbook. The %{type} %{key} is now\nincluded in Chef and will take precedence over the existing cookbook %{type} in the\nnext major release of Chef (15.0, April 2019). You may be able to remove this cookbook dependency from\nyour runlist if you do not use other recipes/resources/libraries from the cookbook.\nAlternatively there may be a newer version of this cookbook without the %{key} %{type}.\n".gsub(/\s+/, " ").strip
- COLLISION_WARNING_15 =
"%{type_caps} %{key} attempted to load from a cookbook. The %{type} %{key} is now\nincluded in Chef and takes precedence over the existing cookbook %{type}\nwhich will be ignored. You may be able to remove this cookbook dependency from\nyour runlist if you do not use other recipes/resources/libraries from the cookbook.\nAlternatively there may be a newer version of this cookbook without the %{key} %{type}.\n".gsub(/\s+/, " ").strip
Instance Method Summary collapse
-
#delete_canonical(key, klass) ⇒ Object
private
Seriously, don’t use this, it’s nearly certain to change on you.
-
#delete_class(klass) ⇒ Hash
Remove a class from all its matchers in the node_map, will remove mappings completely if its the last matcher left.
-
#get(node, key, canonical: nil) ⇒ Object
Get a value from the NodeMap via applying the node to the filters that were set on the key.
-
#list(node, key, canonical: nil) ⇒ Object
List all matches for the given node and key from the NodeMap, from most-recently added to oldest.
-
#lock! ⇒ void
Set this map to locked mode.
-
#locked? ⇒ Boolean
Check if this map has been locked.
-
#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.
Instance Method Details
#delete_canonical(key, klass) ⇒ 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.
Seriously, don’t use this, it’s nearly certain to change on you
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/chef/node_map.rb', line 196 def delete_canonical(key, klass) remaining = map[key] if remaining remaining.delete_if { |matcher| matcher[:canonical] && Array(matcher[:klass]) == Array(klass) } if remaining.empty? map.delete(key) remaining = nil end end remaining end |
#delete_class(klass) ⇒ Hash
Remove a class from all its matchers in the node_map, will remove mappings completely if its the last matcher left
Note that this leaks the internal structure out a bit, but the main consumer of this (poise/halite) cares only about the keys in the returned Hash.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/chef/node_map.rb', line 175 def delete_class(klass) raise "please use a Class type for the klass argument" unless klass.is_a?(Class) deleted = {} map.each do |key, matchers| deleted_matchers = [] matchers.delete_if do |matcher| # because matcher[:klass] may be a string (which needs to die), coerce both to strings to compare somewhat canonically if matcher[:klass].to_s == klass.to_s deleted_matchers << matcher true end end deleted[key] = deleted_matchers unless deleted_matchers.empty? map.delete(key) if matchers.empty? end deleted end |
#get(node, key, canonical: nil) ⇒ Object
Get a value from the NodeMap via applying the node to the filters that were set on the key.
140 141 142 143 144 145 146 |
# File 'lib/chef/node_map.rb', line 140 def get(node, key, canonical: nil) return nil unless map.key?(key) map[key].map do |matcher| return matcher[:klass] if node_matches?(node, matcher) && canonical_matches?(canonical, matcher) end nil end |
#list(node, key, canonical: nil) ⇒ Object
List all matches for the given node and key from the NodeMap, from most-recently added to oldest.
160 161 162 163 164 165 |
# File 'lib/chef/node_map.rb', line 160 def list(node, key, canonical: nil) return [] unless map.key?(key) map[key].select do |matcher| node_matches?(node, matcher) && canonical_matches?(canonical, matcher) end.map { |matcher| matcher[:klass] } end |
#lock! ⇒ void
This method returns an undefined value.
Set this map to locked mode. This is used to prevent future overwriting of existing names.
227 228 229 230 231 232 233 234 |
# File 'lib/chef/node_map.rb', line 227 def lock! map.each do |key, matchers| matchers.each do |matcher| matcher[:locked] = true end end @locked = true end |
#locked? ⇒ Boolean
Check if this map has been locked.
213 214 215 216 217 218 219 |
# File 'lib/chef/node_map.rb', line 213 def locked? if defined?(@locked) @locked else false end end |
#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.
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 |