summaryrefslogtreecommitdiff
path: root/lib/leap_cli/config/object_list.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/leap_cli/config/object_list.rb')
-rw-r--r--lib/leap_cli/config/object_list.rb209
1 files changed, 0 insertions, 209 deletions
diff --git a/lib/leap_cli/config/object_list.rb b/lib/leap_cli/config/object_list.rb
deleted file mode 100644
index f9299a6..0000000
--- a/lib/leap_cli/config/object_list.rb
+++ /dev/null
@@ -1,209 +0,0 @@
-require 'tsort'
-
-module LeapCli
- module Config
- #
- # A list of Config::Object instances (internally stored as a hash)
- #
- class ObjectList < Hash
- include TSort
-
- def initialize(config=nil)
- if config
- self.add(config['name'], config)
- end
- end
-
- #
- # If the key is a string, the Config::Object it references is returned.
- #
- # If the key is a hash, we treat it as a condition and filter all the Config::Objects using the condition.
- # A new ObjectList is returned.
- #
- # Examples:
- #
- # nodes['vpn1']
- # node named 'vpn1'
- #
- # nodes[:public_dns => true]
- # all nodes with public dns
- #
- # nodes[:services => 'openvpn', 'location.country_code' => 'US']
- # all nodes with services containing 'openvpn' OR country code of US
- #
- # Sometimes, you want to do an OR condition with multiple conditions
- # for the same field. Since hash keys must be unique, you can use
- # an array representation instead:
- #
- # nodes[[:services, 'openvpn'], [:services, 'tor']]
- # nodes with openvpn OR tor service
- #
- # nodes[:services => 'openvpn'][:tags => 'production']
- # nodes with openvpn AND are production
- #
- def [](key)
- if key.is_a?(Hash) || key.is_a?(Array)
- filter(key)
- else
- super key.to_s
- end
- end
-
- def exclude(node)
- list = self.dup
- list.delete(node.name)
- return list
- end
-
- def each_node(&block)
- self.keys.sort.each do |node_name|
- yield self[node_name]
- end
- end
-
- #
- # filters this object list, producing a new list.
- # filter is an array or a hash. see []
- #
- def filter(filter)
- results = Config::ObjectList.new
- filter.each do |field, match_value|
- field = field.is_a?(Symbol) ? field.to_s : field
- match_value = match_value.is_a?(Symbol) ? match_value.to_s : match_value
- if match_value.is_a?(String) && match_value =~ /^!/
- operator = :not_equal
- match_value = match_value.sub(/^!/, '')
- else
- operator = :equal
- end
- each do |name, config|
- value = config[field]
- if value.is_a? Array
- if operator == :equal && value.include?(match_value)
- results[name] = config
- elsif operator == :not_equal && !value.include?(match_value)
- results[name] = config
- end
- else
- if operator == :equal && value == match_value
- results[name] = config
- elsif operator == :not_equal && value != match_value
- results[name] = config
- end
- end
- end
- end
- results
- end
-
- def add(name, object)
- self[name] = object
- end
-
- #
- # converts the hash of configs into an array of hashes, with ONLY the specified fields
- #
- def fields(*fields)
- result = []
- keys.sort.each do |name|
- result << self[name].pick(*fields)
- end
- result
- end
-
- #
- # like fields(), but returns an array of values instead of an array of hashes.
- #
- def field(field)
- field = field.to_s
- result = []
- keys.sort.each do |name|
- result << self[name].get(field)
- end
- result
- end
-
- #
- # pick_fields(field1, field2, ...)
- #
- # generates a Hash from the object list, but with only the fields that are picked.
- #
- # If there are more than one field, then the result is a Hash of Hashes.
- # If there is just one field, it is a simple map to the value.
- #
- # For example:
- #
- # "neighbors" = "= nodes_like_me[:services => :couchdb].pick_fields('domain.full', 'ip_address')"
- #
- # generates this:
- #
- # neighbors:
- # couch1:
- # domain_full: couch1.bitmask.net
- # ip_address: "10.5.5.44"
- # couch2:
- # domain_full: couch2.bitmask.net
- # ip_address: "10.5.5.52"
- #
- # But this:
- #
- # "neighbors": "= nodes_like_me[:services => :couchdb].pick_fields('domain.full')"
- #
- # will generate this:
- #
- # neighbors:
- # couch1: couch1.bitmask.net
- # couch2: couch2.bitmask.net
- #
- def pick_fields(*fields)
- self.values.inject({}) do |hsh, node|
- value = self[node.name].pick(*fields)
- if fields.size == 1
- value = value.values.first
- end
- hsh[node.name] = value
- hsh
- end
- end
-
- #
- # Applies inherit_from! to all objects.
- #
- # 'env' specifies what environment should be for
- # each object in the list.
- #
- def inherit_from!(object_list, env)
- object_list.each do |name, object|
- if self[name]
- self[name].inherit_from!(object)
- else
- self[name] = object.duplicate(env)
- end
- end
- end
-
- #
- # topographical sort based on test dependency
- #
- def tsort_each_node(&block)
- self.each_key(&block)
- end
-
- def tsort_each_child(node_name, &block)
- if self[node_name]
- self[node_name].test_dependencies.each do |test_me_first|
- if self[test_me_first] # TODO: in the future, allow for ability to optionally pull in all dependencies.
- # not just the ones that pass the node filter.
- yield(test_me_first)
- end
- end
- end
- end
-
- def names_in_test_dependency_order
- self.tsort
- end
-
- end
- end
-end