summaryrefslogtreecommitdiff
path: root/lib/chef/whitelist.rb
diff options
context:
space:
mode:
authorClaire McQuin <claire@getchef.com>2014-05-14 16:02:06 -0700
committerClaire McQuin <claire@getchef.com>2014-05-15 14:04:59 -0700
commit1323ffb1de47b31b9e1515c8123c1b8545385a22 (patch)
treee17343bd84cb455380dc945d87bd782c4b9c8cfd /lib/chef/whitelist.rb
parent4c48ed4a014480cbb34091df3c79600bd3b7378d (diff)
downloadchef-1323ffb1de47b31b9e1515c8123c1b8545385a22.tar.gz
Change attribute whitelist filter syntax to match Ohai
Diffstat (limited to 'lib/chef/whitelist.rb')
-rw-r--r--lib/chef/whitelist.rb82
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/chef/whitelist.rb b/lib/chef/whitelist.rb
new file mode 100644
index 0000000000..ad52215f11
--- /dev/null
+++ b/lib/chef/whitelist.rb
@@ -0,0 +1,82 @@
+
+require 'chef/exceptions'
+
+class Chef
+ class Whitelist
+
+ # filter takes two arguments - the data you want to filter, and a whitelisted array
+ # of keys you want included. You can capture a subtree of the data to filter by
+ # providing a "/"-delimited string of keys. If some key includes "/"-characters,
+ # you must provide an array of keys instead.
+ #
+ # Whitelist.filter(
+ # { "filesystem" => {
+ # "/dev/disk" => {
+ # "size" => "10mb"
+ # },
+ # "map - autohome" => {
+ # "size" => "10mb"
+ # }
+ # },
+ # "network" => {
+ # "interfaces" => {
+ # "eth0" => {...},
+ # "eth1" => {...}
+ # }
+ # }
+ # },
+ # ["network/interfaces/eth0", ["filesystem", "/dev/disk"]])
+ # will capture the eth0 and /dev/disk subtrees.
+ def self.filter(data, whitelist=nil)
+ return data if whitelist.nil?
+
+ new_data = {}
+ whitelist.each do |item|
+ self.add_data(data, new_data, item)
+ end
+ new_data
+ end
+
+ private
+
+ # Walk the data has according to the keys provided by the whitelisted item
+ # and add the data to the whitelisting result.
+ def self.add_data(data, new_data, item)
+ parts = self.to_array(item)
+
+ all_data = data
+ filtered_data = new_data
+ parts[0..-2].each do |part|
+ unless all_data[part]
+ Chef::Log.warn("Could not find whitelist attribute #{item}.")
+ return nil
+ end
+
+ filtered_data[part] ||= {}
+ filtered_data = filtered_data[part]
+ all_data = all_data[part]
+ end
+
+ unless all_data[parts[-1]]
+ Chef::Log.warn("Could not find whitelist attribute #{item}.")
+ return nil
+ end
+
+ filtered_data[parts[-1]] = all_data[parts[-1]]
+ new_data
+ end
+
+ # Accepts a String or an Array, and returns an Array of String keys that
+ # are used to traverse the data hash. Strings are split on "/", Arrays are
+ # assumed to contain exact keys (that is, Array elements will not be split
+ # by "/").
+ def self.to_array(item)
+ return item if item.kind_of? Array
+
+ parts = item.split("/")
+ parts.shift if !parts.empty? && parts[0].empty?
+ parts
+ end
+
+ end
+end