summaryrefslogtreecommitdiffstats
path: root/lib/puppet/indirector
diff options
context:
space:
mode:
authorPaul Berry <paul@puppetlabs.com>2011-02-17 14:59:59 -0800
committerPaul Berry <paul@puppetlabs.com>2011-02-17 14:59:59 -0800
commit23fc4db954c22bce2c6cc8996d5fafb175e2b747 (patch)
treefef367b2b6a94148b0207ad13acd53e42d49bea1 /lib/puppet/indirector
parentab27da7967e1e145d5fbc130e5fbcec6795ca775 (diff)
downloadpuppet-23fc4db954c22bce2c6cc8996d5fafb175e2b747.tar.gz
puppet-23fc4db954c22bce2c6cc8996d5fafb175e2b747.tar.xz
puppet-23fc4db954c22bce2c6cc8996d5fafb175e2b747.zip
(#5132) Provide a query REST interface for inventory
This REST interface returns a list of nodes that match a fact query. Fact queries can use (in)equality testing as a string comparison, and >, <, >=, <= numerical comparisons. Multiple tests can be done as AND comparisons, not OR. The fact queries need to be prefixed by facts, and the comparisons other than equality are specified with a .comparison_type after the fact name. This will be better explained in the REST documentation on the website. Searches that don't match anything now return empty array instead of a 404 error. Conflicts: spec/spec_helper.rb
Diffstat (limited to 'lib/puppet/indirector')
-rw-r--r--lib/puppet/indirector/indirection.rb1
-rw-r--r--lib/puppet/indirector/inventory/yaml.rb47
2 files changed, 48 insertions, 0 deletions
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index ec147ec69..3d17e6e47 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -248,6 +248,7 @@ class Puppet::Indirector::Indirection
if result = terminus.search(request)
raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array)
result.each do |instance|
+ next unless instance.respond_to? :expiration
instance.expiration ||= self.expiration
end
return result
diff --git a/lib/puppet/indirector/inventory/yaml.rb b/lib/puppet/indirector/inventory/yaml.rb
new file mode 100644
index 000000000..c6b1a14aa
--- /dev/null
+++ b/lib/puppet/indirector/inventory/yaml.rb
@@ -0,0 +1,47 @@
+require 'puppet/node/inventory'
+require 'puppet/indirector/yaml'
+
+class Puppet::Node::Inventory::Yaml < Puppet::Indirector::Yaml
+ desc "Return node names matching the fact query"
+
+ # Return the path to a given node's file.
+ def yaml_dir_path
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, 'facts', '*.yaml')
+ end
+
+ def node_matches?(facts, options)
+ options.each do |key, value|
+ type, name, operator = key.to_s.split(".")
+ operator ||= 'eq'
+
+ next unless type == "facts"
+ return false unless facts.values[name]
+
+ return false unless case operator
+ when "eq"
+ facts.values[name].to_s == value.to_s
+ when "le"
+ facts.values[name].to_f <= value.to_f
+ when "ge"
+ facts.values[name].to_f >= value.to_f
+ when "lt"
+ facts.values[name].to_f < value.to_f
+ when "gt"
+ facts.values[name].to_f > value.to_f
+ when "ne"
+ facts.values[name].to_s != value.to_s
+ end
+ end
+ return true
+ end
+
+ def search(request)
+ node_names = []
+ Dir.glob(yaml_dir_path).each do |file|
+ facts = YAML.load_file(file)
+ node_names << facts.name if node_matches?(facts, request.options)
+ end
+ node_names
+ end
+end