summaryrefslogtreecommitdiffstats
path: root/lib/puppet/node_source/external.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/node_source/external.rb')
-rw-r--r--lib/puppet/node_source/external.rb51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/puppet/node_source/external.rb b/lib/puppet/node_source/external.rb
new file mode 100644
index 000000000..54111d924
--- /dev/null
+++ b/lib/puppet/node_source/external.rb
@@ -0,0 +1,51 @@
+Puppet::Network::Handler::Node.newnode_source(:external, :fact_merge => true) do
+ desc "Call an external program to get node information."
+
+ include Puppet::Util
+ # Look for external node definitions.
+ def nodesearch(name)
+ return nil unless Puppet[:external_nodes] != "none"
+
+ # This is a very cheap way to do this, since it will break on
+ # commands that have spaces in the arguments. But it's good
+ # enough for most cases.
+ external_node_command = Puppet[:external_nodes].split
+ external_node_command << name
+ begin
+ output = Puppet::Util.execute(external_node_command)
+ rescue Puppet::ExecutionFailure => detail
+ if $?.exitstatus == 1
+ return nil
+ else
+ Puppet.err "Could not retrieve external node information for %s: %s" % [name, detail]
+ end
+ return nil
+ end
+
+ if output =~ /\A\s*\Z/ # all whitespace
+ Puppet.debug "Empty response for %s from external node source" % name
+ return nil
+ end
+
+ begin
+ result = YAML.load(output).inject({}) { |hash, data| hash[symbolize(data[0])] = data[1]; hash }
+ rescue => detail
+ raise Puppet::Error, "Could not load external node results for %s: %s" % [name, detail]
+ end
+
+ node = newnode(name)
+ set = false
+ [:parameters, :classes].each do |param|
+ if value = result[param]
+ node.send(param.to_s + "=", value)
+ set = true
+ end
+ end
+
+ if set
+ return node
+ else
+ return nil
+ end
+ end
+end