diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2017-12-08 11:00:41 -0800 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2017-12-08 11:00:41 -0800 |
commit | 9620ba27646edf81782e643c3ad04be4a7bc8a35 (patch) | |
tree | 502f60815c34f70fc650fc6d55e7c947997e58eb | |
parent | bcdb1efcb33c580c89a96b50688d6872741ed7ae (diff) | |
download | chef-9620ba27646edf81782e643c3ad04be4a7bc8a35.tar.gz |
simplify node_map logic
flattens out the internal data structure and removes some excessive
defensive coding.
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
-rw-r--r-- | lib/chef/node_map.rb | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index 0d7d986653..5cc24b9d25 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -20,18 +20,16 @@ # example of a NodeMap entry for the user resource (as typed on the DSL): # # :user=> -# [{:value=>Chef::Resource::User::AixUser, :filters=>{:os=>"aix"}}, -# {:value=>Chef::Resource::User::DsclUser, :filters=>{:os=>"darwin"}}, -# {:value=>Chef::Resource::User::PwUser, :filters=>{:os=>"freebsd"}}, -# {:value=>Chef::Resource::User::LinuxUser, :filters=>{:os=>"linux"}}, -# {:value=>Chef::Resource::User::SolarisUser, -# :filters=>{:os=>["omnios", "solaris2"]}}, -# {:value=>Chef::Resource::User::WindowsUser, :filters=>{:os=>"windows"}}], -# -# if a block filter were to appear it would be a :block argument (XXX: turn into a filter?) +# [{:klass=>Chef::Resource::User::AixUser, :os=>"aix"}, +# {:klass=>Chef::Resource::User::DsclUser, :os=>"darwin"}, +# {:klass=>Chef::Resource::User::PwUser, :os=>"freebsd"}, +# {:klass=>Chef::Resource::User::LinuxUser, :os=>"linux"}, +# {:klass=>Chef::Resource::User::SolarisUser, +# :os=>["omnios", "solaris2"]}, +# {:klass=>Chef::Resource::User::WindowsUser, :os=>"windows"}], # # the entries in the array are pre-sorted into priority order (blocks/platform_version/platform/platform_family/os/none) so that -# the first entry's :value that matches the filter is returned when doing a get. +# the first entry's :klass that matches the filter is returned when doing a get. # # note that as this examples show filter values may be a scalar string or an array of scalar strings. # @@ -50,13 +48,12 @@ class Chef # # @return [NodeMap] Returns self for possible chaining # - def set(key, value, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, &block) - filters = {} - filters[:platform] = platform if platform - filters[:platform_version] = platform_version if platform_version - filters[:platform_family] = platform_family if platform_family - filters[:os] = os if os - new_matcher = { value: value, filters: filters } + def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, &block) + 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 @@ -90,13 +87,12 @@ class Chef # @param canonical [Boolean] `true` or `false` to match canonical or # non-canonical values only. `nil` to ignore canonicality. Default: `nil` # - # @return [Object] Value + # @return [Object] Class # def get(node, key, canonical: nil) - raise ArgumentError, "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) || node.nil? return nil unless map.has_key?(key) map[key].map do |matcher| - return matcher[:value] if node_matches?(node, matcher) && canonical_matches?(canonical, matcher) + return matcher[:klass] if node_matches?(node, matcher) && canonical_matches?(canonical, matcher) end nil end @@ -111,23 +107,22 @@ class Chef # @param canonical [Boolean] `true` or `false` to match canonical or # non-canonical values only. `nil` to ignore canonicality. Default: `nil` # - # @return [Object] Value + # @return [Object] Class # def list(node, key, canonical: nil) - raise ArgumentError, "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) || node.nil? return [] unless map.has_key?(key) map[key].select do |matcher| node_matches?(node, matcher) && canonical_matches?(canonical, matcher) - end.map { |matcher| matcher[:value] } + end.map { |matcher| matcher[:klass] } end # Seriously, don't use this, it's nearly certain to change on you # @return remaining # @api private - def delete_canonical(key, value) + def delete_canonical(key, klass) remaining = map[key] if remaining - remaining.delete_if { |matcher| matcher[:canonical] && Array(matcher[:value]) == Array(value) } + remaining.delete_if { |matcher| matcher[:canonical] && Array(matcher[:klass]) == Array(klass) } if remaining.empty? map.delete(key) remaining = nil @@ -187,7 +182,7 @@ class Chef def node_matches?(node, matcher) return true if !node - filters_match?(node, matcher[:filters]) && block_matches?(node, matcher[:block]) + filters_match?(node, matcher) && block_matches?(node, matcher[:block]) end def canonical_matches?(canonical, matcher) @@ -199,13 +194,13 @@ class Chef def dispatch_compare_matchers(key, new_matcher, matcher) cmp = compare_matcher_properties(new_matcher[:block], matcher[:block]) return cmp if cmp != 0 - cmp = compare_matcher_properties(new_matcher[:filters][:platform_version], matcher[:filters][:platform_version]) + cmp = compare_matcher_properties(new_matcher[:platform_version], matcher[:platform_version]) return cmp if cmp != 0 - cmp = compare_matcher_properties(new_matcher[:filters][:platform], matcher[:filters][:platform]) + cmp = compare_matcher_properties(new_matcher[:platform], matcher[:platform]) return cmp if cmp != 0 - cmp = compare_matcher_properties(new_matcher[:filters][:platform_family], matcher[:filters][:platform_family]) + cmp = compare_matcher_properties(new_matcher[:platform_family], matcher[:platform_family]) return cmp if cmp != 0 - cmp = compare_matcher_properties(new_matcher[:filters][:os], matcher[:filters][:os]) + cmp = compare_matcher_properties(new_matcher[:os], matcher[:os]) return cmp if cmp != 0 cmp = compare_matcher_properties(new_matcher[:override], matcher[:override]) return cmp if cmp != 0 @@ -222,8 +217,12 @@ class Chef # Sort by class name (ascending) as well, if all other properties # are exactly equal # XXX: remove this in Chef-14 and use last-writer-wins (prepend if they match) - if new_matcher[:value].is_a?(Class) && !new_matcher[:override] - cmp = compare_matcher_properties(new_matcher[:value].name, matcher[:value].name) + if !new_matcher[:override] + if new_matcher[:klass].is_a?(Class) + cmp = compare_matcher_properties(new_matcher[:klass].name, matcher[:klass].name) + else + cmp = compare_matcher_properties(new_matcher[:klass], matcher[:klass]) + end end end cmp |