summaryrefslogtreecommitdiff
path: root/lib/chef/blacklist.rb
diff options
context:
space:
mode:
authorRobert Mullins <rmullins@secureworks.com>2017-03-03 14:39:07 -0500
committerRobert Mullins <rmullins@secureworks.com>2017-03-08 11:41:56 -0500
commit848fbf3c081dabe4a7f18a42597b1a68f68b6009 (patch)
treec7d49291f920dbde14b43c70953b3c1f9bc800b1 /lib/chef/blacklist.rb
parent5dc375d6dd7acb1d32f06b3ee663201d0a119ccf (diff)
downloadchef-848fbf3c081dabe4a7f18a42597b1a68f68b6009.tar.gz
Add the ability to blacklist attributes
Signed-off-by: Robert Mullins <rmullins@secureworks.com>
Diffstat (limited to 'lib/chef/blacklist.rb')
-rw-r--r--lib/chef/blacklist.rb81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/chef/blacklist.rb b/lib/chef/blacklist.rb
new file mode 100644
index 0000000000..a60e0318cd
--- /dev/null
+++ b/lib/chef/blacklist.rb
@@ -0,0 +1,81 @@
+
+require "chef/exceptions"
+
+class Chef
+ class Blacklist
+
+ # filter takes two arguments - the data you want to filter, and a blacklisted array
+ # of keys you want discluded. 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.
+ #
+ # Blacklist.filter(
+ # { "filesystem" => {
+ # "/dev/disk" => {
+ # "size" => "10mb"
+ # },
+ # "map - autohome" => {
+ # "size" => "10mb"
+ # }
+ # },
+ # "network" => {
+ # "interfaces" => {
+ # "eth0" => {...},
+ # "eth1" => {...}
+ # }
+ # }
+ # },
+ # ["network/interfaces/eth0", ["filesystem", "/dev/disk"]])
+ # will exclude the eth0 and /dev/disk subtrees.
+ def self.filter(data, blacklist = nil)
+ return data if blacklist.nil?
+
+ blacklist.each do |item|
+ Chef::Log.warn("Removing item #{item}")
+ remove_data(data, item)
+ end
+ data
+ end
+
+ # Walk the data according to the keys provided by the blacklisted item
+ # and add the data to the whitelisting result.
+ def self.remove_data(data, item)
+ parts = to_array(item)
+
+ item_ref = data
+ parts[0..-2].each do |part|
+ unless item_ref[part]
+ Chef::Log.warn("Could not find blacklist attribute #{item}.")
+ return nil
+ end
+
+ item_ref = item_ref[part]
+ end
+
+ unless item_ref.key?(parts[-1])
+ Chef::Log.warn("Could not find blacklist attribute #{item}.")
+ return nil
+ end
+
+ item_ref[parts[-1]] = nil
+ data
+ end
+
+ private_class_method :remove_data
+
+ # 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
+
+ private_class_method :to_array
+
+ end
+end