diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2007-01-05 04:44:24 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2007-01-05 04:44:24 +0000 |
commit | f6beef5c57381973c68468be9d4b1cac593a037c (patch) | |
tree | 1da3355c6f5c3e09e176124b5c44711f54050efe | |
parent | f8f7c57b9e10477fc14f6bc655ad194598c91980 (diff) | |
download | puppet-f6beef5c57381973c68468be9d4b1cac593a037c.tar.gz puppet-f6beef5c57381973c68468be9d4b1cac593a037c.tar.xz puppet-f6beef5c57381973c68468be9d4b1cac593a037c.zip |
Fixing #407. You can use external_node to specify a command to retrieve your node information.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2049 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r-- | lib/puppet/parser/interpreter.rb | 50 | ||||
-rwxr-xr-x | test/language/interpreter.rb | 62 |
2 files changed, 111 insertions, 1 deletions
diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb index a00b10042..0117ac2dd 100644 --- a/lib/puppet/parser/interpreter.rb +++ b/lib/puppet/parser/interpreter.rb @@ -15,7 +15,16 @@ class Puppet::Parser::Interpreter :casesensitive => [false, "Whether matching in case statements and selectors should be case-sensitive. Case insensitivity is - handled by downcasing all values before comparison."]) + handled by downcasing all values before comparison."], + :external_nodes => ["none", + "An external command that can produce node information. The + first line of output must be either the parent node or blank, + and if there is a second line of output it should be a list of + whitespace-separated classes to include on that node. This command + makes it straightforward to store your node mapping information + in other data sources like databases. + + For unknown nodes, the commands should exit with an exit code of 1."]) Puppet.setdefaults("ldap", :ldapnodes => [false, @@ -642,6 +651,45 @@ class Puppet::Parser::Interpreter def nodesearch_code(name) @nodetable[name] end + + # Look for external node definitions. + def nodesearch_external(name) + return nil unless Puppet[:external_nodes] != "none" + + begin + output = Puppet::Util.execute([Puppet[:external_nodes], name]) + 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 + puts "empty response for %s" % name + return nil + end + + lines = output.split("\n") + + args = {} + parent = lines[0].gsub(/\s+/, '') + args[:parentnode] = parent unless parent == "" + + if lines[1] + classes = lines[1].sub(/^\s+/,'').sub(/\s+$/,'').split(/\s+/) + args[:classes] = classes unless classes.empty? + end + + if args.empty? + Puppet.warning "Somehow got a node with no information" + return nil + else + return gennode(name, args) + end + end # Look for our node in ldap. def nodesearch_ldap(node) diff --git a/test/language/interpreter.rb b/test/language/interpreter.rb index 93d9b3720..c1c16b441 100755 --- a/test/language/interpreter.rb +++ b/test/language/interpreter.rb @@ -931,6 +931,68 @@ class TestInterpreter < Test::Unit::TestCase assert_equal("root", pvalue[:value]) end end + + def test_nodesearch_external + interp = mkinterp + + # Make a fake gennode method + class << interp + def gennode(name, args) + args[:name] = name + return args + end + end + + # First, make sure our nodesearch command works as we expect + # Make a nodemapper + mapper = tempfile() + ruby = %x{which ruby}.chomp + File.open(mapper, "w") { |f| + f.puts "#!#{ruby} + name = ARGV[0] + if name =~ /a/ + puts ARGV[0].gsub('a', 'b') + else + puts '' + end + if name =~ /p/ + puts [1,2,3].collect { |n| ARGV[0] + n.to_s }.join(' ') + else + puts '' + end + " + } + File.chmod(0755, mapper) + + # Make sure it gives the right response + assert_equal("bpple\napple1 apple2 apple3\n", + %x{#{mapper} apple}) + + # First make sure we get nil back by default + assert_nothing_raised { + assert_nil(interp.nodesearch_external("apple"), + "Interp#nodesearch_external defaulted to a non-nil response") + } + assert_nothing_raised { Puppet[:external_nodes] = mapper } + + node = nil + assert_nothing_raised { node = interp.nodesearch_external("apple") } + + assert_equal({:name => "apple", :classes => %w{apple1 apple2 apple3}, :parentnode => "bpple"}, + node) + + assert_nothing_raised { node = interp.nodesearch_external("plum")} # no a's, thus no parent + assert_equal({:name => "plum", :classes => %w{plum1 plum2 plum3}}, + node) + + assert_nothing_raised { node = interp.nodesearch_external("guava")} # no p's, thus no classes + assert_equal({:name => "guava", :parentnode => "gubvb"}, + node) + + assert_nothing_raised { node = interp.nodesearch_external("honeydew")} # neither, thus nil + assert_nil(node) + + end end # $Id$ |