diff options
author | Nick Lewis <nick@puppetlabs.com> | 2011-04-12 14:40:12 -0700 |
---|---|---|
committer | Nick Lewis <nick@puppetlabs.com> | 2011-04-12 14:48:18 -0700 |
commit | b2831e102f4cc57d6e0101f55e208695188d426a (patch) | |
tree | 60c02e8aeafb42952a9fd9a86f68e635bf39c206 | |
parent | 2dfa0afb57ec80f451a54ef96341d413819c14c7 (diff) | |
download | puppet-b2831e102f4cc57d6e0101f55e208695188d426a.tar.gz puppet-b2831e102f4cc57d6e0101f55e208695188d426a.tar.xz puppet-b2831e102f4cc57d6e0101f55e208695188d426a.zip |
(#2150) Add routes file for indirector
Puppet[:route_file] is a YAML file specifying the termini to use for various
indirections, in the format:
agent:
catalog:
terminus: rest
cache: yaml
master:
catalog:
terminus: compiler
cache: active_record
This file is optional, and will override application defaults set in "setup",
as well as terminus settings, ie. facts_terminus.
Paired-With: Jesse Wolfe
-rw-r--r-- | lib/puppet/application.rb | 22 | ||||
-rw-r--r-- | lib/puppet/defaults.rb | 1 | ||||
-rw-r--r-- | lib/puppet/indirector.rb | 16 | ||||
-rwxr-xr-x | spec/unit/application_spec.rb | 50 | ||||
-rwxr-xr-x | spec/unit/indirector_spec.rb | 59 |
5 files changed, 142 insertions, 6 deletions
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb index 57bd88877..4c5a5a967 100644 --- a/lib/puppet/application.rb +++ b/lib/puppet/application.rb @@ -299,11 +299,12 @@ class Application # This is the main application entry point def run - exit_on_fail("initialize") { hook('preinit') { preinit } } - exit_on_fail("parse options") { hook('parse_options') { parse_options } } - exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config? - exit_on_fail("prepare for execution") { hook('setup') { setup } } - exit_on_fail("run") { hook('run_command') { run_command } } + exit_on_fail("initialize") { hook('preinit') { preinit } } + exit_on_fail("parse options") { hook('parse_options') { parse_options } } + exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config? + exit_on_fail("prepare for execution") { hook('setup') { setup } } + exit_on_fail("configure routes from #{Puppet[:route_file]}") { configure_indirector_routes } + exit_on_fail("run") { hook('run_command') { run_command } } end def main @@ -328,6 +329,15 @@ class Application Puppet::Util::Log.newdestination(:syslog) unless options[:setdest] end + def configure_indirector_routes + route_file = Puppet[:route_file] + if File.exists?(route_file) + routes = YAML.load_file(route_file) + application_routes = routes[name.to_s] + Puppet::Indirector.configure_routes(application_routes) if application_routes + end + end + def parse_options # Create an option parser option_parser = OptionParser.new(self.class.banner) @@ -394,7 +404,7 @@ class Application def exit_on_fail(message, code = 1) yield - rescue RuntimeError, NotImplementedError => detail + rescue ArgumentError, RuntimeError, NotImplementedError => detail puts detail.backtrace if Puppet[:trace] $stderr.puts "Could not #{message}: #{detail}" exit(code) diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 76c40824c..89f3e169d 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -116,6 +116,7 @@ module Puppet but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system. This is a hackish way to fail in a slightly more useful way when that happens."], + :route_file => ["$confdir/routes.yaml", "The YAML file containing indirector route configuration."], :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."], diff --git a/lib/puppet/indirector.rb b/lib/puppet/indirector.rb index 9effc5cdd..7267ac7f3 100644 --- a/lib/puppet/indirector.rb +++ b/lib/puppet/indirector.rb @@ -12,6 +12,22 @@ module Puppet::Indirector require 'puppet/indirector/envelope' require 'puppet/network/format_handler' + def self.configure_routes(application_routes) + application_routes.each do |indirection_name, termini| + indirection_name = indirection_name.to_sym + terminus_name = termini["terminus"] + cache_name = termini["cache"] + + Puppet::Indirector::Terminus.terminus_classes(indirection_name) + + indirection = Puppet::Indirector::Indirection.instance(indirection_name) + raise "Indirection #{indirection_name} does not exist" unless indirection + + indirection.terminus_class = terminus_name if terminus_name + indirection.cache_class = cache_name if cache_name + end + end + # Declare that the including class indirects its methods to # this terminus. The terminus name must be the name of a Puppet # default, not the value -- if it's the value, then it gets diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index d8491bb75..740b76f62 100755 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -12,6 +12,7 @@ describe Puppet::Application do @app = Class.new(Puppet::Application).new @appclass = @app.class + @app.stubs(:name).returns("test_app") # avoid actually trying to parse any settings Puppet.settings.stubs(:parse) end @@ -396,6 +397,55 @@ describe Puppet::Application do end + describe "when configuring routes" do + include PuppetSpec::Files + + before :each do + Puppet::Node.indirection.reset_terminus_class + end + + after :each do + Puppet::Node.indirection.reset_terminus_class + end + + it "should use the routes specified for only the active application" do + Puppet[:route_file] = tmpfile('routes') + File.open(Puppet[:route_file], 'w') do |f| + f.print <<-ROUTES + test_app: + node: + terminus: exec + other_app: + node: + terminus: plain + catalog: + terminus: invalid + ROUTES + end + + @app.configure_indirector_routes + + Puppet::Node.indirection.terminus_class.should == 'exec' + end + + it "should not fail if the route file doesn't exist" do + Puppet[:route_file] = "/dev/null/non-existent" + + expect { @app.configure_indirector_routes }.should_not raise_error + end + + it "should raise an error if the routes file is invalid" do + Puppet[:route_file] = tmpfile('routes') + File.open(Puppet[:route_file], 'w') do |f| + f.print <<-ROUTES + invalid : : yaml + ROUTES + end + + expect { @app.configure_indirector_routes }.should raise_error + end + end + describe "when running" do before :each do diff --git a/spec/unit/indirector_spec.rb b/spec/unit/indirector_spec.rb index c7d42c707..cca86e218 100755 --- a/spec/unit/indirector_spec.rb +++ b/spec/unit/indirector_spec.rb @@ -5,6 +5,65 @@ require 'spec_helper' require 'puppet/defaults' require 'puppet/indirector' +describe Puppet::Indirector, "when configuring routes" do + before :each do + Puppet::Node.indirection.reset_terminus_class + Puppet::Node.indirection.cache_class = nil + end + + after :each do + Puppet::Node.indirection.reset_terminus_class + Puppet::Node.indirection.cache_class = nil + end + + it "should configure routes as requested" do + routes = { + "node" => { + "terminus" => "exec", + "cache" => "plain" + } + } + + Puppet::Indirector.configure_routes(routes) + + Puppet::Node.indirection.terminus_class.should == "exec" + Puppet::Node.indirection.cache_class.should == "plain" + end + + it "should fail when given an invalid indirection" do + routes = { + "fake_indirection" => { + "terminus" => "exec", + "cache" => "plain" + } + } + + expect { Puppet::Indirector.configure_routes(routes) }.should raise_error(/fake_indirection does not exist/) + end + + it "should fail when given an invalid terminus" do + routes = { + "node" => { + "terminus" => "fake_terminus", + "cache" => "plain" + } + } + + expect { Puppet::Indirector.configure_routes(routes) }.should raise_error(/Could not find terminus fake_terminus/) + end + + it "should fail when given an invalid cache" do + routes = { + "node" => { + "terminus" => "exec", + "cache" => "fake_cache" + } + } + + expect { Puppet::Indirector.configure_routes(routes) }.should raise_error(/Could not find terminus fake_cache/) + end +end + describe Puppet::Indirector, " when available to a model" do before do @thingie = Class.new do |