diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/defaults.rb | 20 | ||||
-rw-r--r-- | lib/puppet/indirector/facts/rest.rb | 2 | ||||
-rw-r--r-- | lib/puppet/indirector/indirection.rb | 1 | ||||
-rw-r--r-- | lib/puppet/indirector/inventory/yaml.rb | 81 | ||||
-rw-r--r-- | lib/puppet/network/http/api/v1.rb | 3 | ||||
-rw-r--r-- | lib/puppet/network/http/handler.rb | 2 | ||||
-rw-r--r-- | lib/puppet/node.rb | 1 | ||||
-rwxr-xr-x | lib/puppet/node/facts.rb | 8 | ||||
-rw-r--r-- | lib/puppet/node/inventory.rb | 7 |
9 files changed, 120 insertions, 5 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 687ac4eb0..8da104086 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -119,7 +119,17 @@ module Puppet :node_terminus => ["plain", "Where to find information about nodes."], :catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance, you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."], - :facts_terminus => [Puppet.application_name.to_s == "master" ? 'yaml' : 'facter', "The node facts terminus."], + :facts_terminus => { + :default => Puppet.application_name.to_s == "master" ? 'yaml' : 'facter', + :desc => "The node facts terminus.", + :hook => proc do |value| + require 'puppet/node/facts' + if value.to_s == "rest" + Puppet::Node::Facts.cache_class = :yaml + end + end + }, + :inventory_terminus => [ "$facts_terminus", "Should usually be the same as the facts terminus" ], :httplog => { :default => "$logdir/http.log", :owner => "root", :mode => 0640, @@ -582,11 +592,17 @@ module Puppet end }, :report_server => ["$server", - "The server to which to send transaction reports." + "The server to send transaction reports to." ], :report_port => ["$masterport", "The port to communicate with the report_server." ], + :inventory_server => ["$server", + "The server to send facts to." + ], + :inventory_port => ["$masterport", + "The port to communicate with the inventory_server." + ], :report => [false, "Whether to send reports after every transaction." ], diff --git a/lib/puppet/indirector/facts/rest.rb b/lib/puppet/indirector/facts/rest.rb index 07491fc77..e2afa14b2 100644 --- a/lib/puppet/indirector/facts/rest.rb +++ b/lib/puppet/indirector/facts/rest.rb @@ -3,4 +3,6 @@ require 'puppet/indirector/rest' class Puppet::Node::Facts::Rest < Puppet::Indirector::REST desc "Find and save facts about nodes over HTTP via REST." + use_server_setting(:inventory_server) + use_port_setting(:inventory_port) end 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..fe3489a95 --- /dev/null +++ b/lib/puppet/indirector/inventory/yaml.rb @@ -0,0 +1,81 @@ +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' + + return false unless node_matches_option?(type, name, operator, value, facts) + 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 + + private + + def node_matches_option?(type, name, operator, value, facts) + case type + when "meta" + case name + when "timestamp" + compare_timestamp(operator, facts.timestamp, Time.parse(value)) + end + when "facts" + compare_facts(operator, facts.values[name], value) + end + end + + def compare_facts(operator, value1, value2) + return false unless value1 + + case operator + when "eq" + value1.to_s == value2.to_s + when "le" + value1.to_f <= value2.to_f + when "ge" + value1.to_f >= value2.to_f + when "lt" + value1.to_f < value2.to_f + when "gt" + value1.to_f > value2.to_f + when "ne" + value1.to_s != value2.to_s + end + end + + def compare_timestamp(operator, value1, value2) + case operator + when "eq" + value1 == value2 + when "le" + value1 <= value2 + when "ge" + value1 >= value2 + when "lt" + value1 < value2 + when "gt" + value1 > value2 + when "ne" + value1 != value2 + end + end +end diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb index 8aa1f0ee1..0a04a465f 100644 --- a/lib/puppet/network/http/api/v1.rb +++ b/lib/puppet/network/http/api/v1.rb @@ -60,9 +60,8 @@ module Puppet::Network::HTTP::API::V1 # fix to not need this, and our goal is to move away from the complication # that leads to the fix being too long. return :singular if indirection == "facts" - - # "status" really is singular return :singular if indirection == "status" + return :plural if indirection == "inventory" result = (indirection =~ /s$/) ? :plural : :singular diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 9e9356b2f..e192613ad 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -131,7 +131,7 @@ module Puppet::Network::HTTP::Handler def do_search(indirection_request, request, response) result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash) - if result.nil? or (result.is_a?(Array) and result.empty?) + if result.nil? return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.key}'", 404) end diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb index 2453cd1d5..e8d58e6be 100644 --- a/lib/puppet/node.rb +++ b/lib/puppet/node.rb @@ -3,6 +3,7 @@ require 'puppet/indirector' # A class for managing nodes, including their facts and environment. class Puppet::Node require 'puppet/node/facts' + require 'puppet/node/inventory' require 'puppet/node/environment' # Set up indirection, so that nodes can be looked for in diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb index b77ad22d5..562690026 100755 --- a/lib/puppet/node/facts.rb +++ b/lib/puppet/node/facts.rb @@ -54,6 +54,14 @@ class Puppet::Node::Facts strip_internal == other.send(:strip_internal) end + def timestamp=(time) + self.values[:_timestamp] = time + end + + def timestamp + self.values[:_timestamp] + end + private # Add internal data to the facts for storage. diff --git a/lib/puppet/node/inventory.rb b/lib/puppet/node/inventory.rb new file mode 100644 index 000000000..fd99163b0 --- /dev/null +++ b/lib/puppet/node/inventory.rb @@ -0,0 +1,7 @@ +require 'puppet/node' +require 'puppet/indirector' + +class Puppet::Node::Inventory + extend Puppet::Indirector + indirects :inventory, :terminus_setting => :inventory_terminus +end |