Sweet!

I thought we'd never get this in, this is really awesome.

On Apr 12, 2011, at 2:52 PM, Nick Lewis wrote:

> 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
> 
> Signed-off-by: Nick Lewis <n...@puppetlabs.com>
> ---
> Local-branch: ticket/next/2150
> lib/puppet/application.rb     |   22 +++++++++++----
> lib/puppet/defaults.rb        |    1 +
> lib/puppet/indirector.rb      |   16 +++++++++++
> spec/unit/application_spec.rb |   50 ++++++++++++++++++++++++++++++++++
> 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 57bd888..4c5a5a9 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 76c4082..89f3e16 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 9effc5c..7267ac7 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 d8491bb..740b76f 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 c7d42c7..cca86e2 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
> -- 
> 1.7.4.1
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Puppet Developers" group.
> To post to this group, send email to puppet-dev@googlegroups.com.
> To unsubscribe from this group, send email to 
> puppet-dev+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/puppet-dev?hl=en.
> 


-- 
The people who are regarded as moral luminaries are those who forego
ordinary pleasures themselves and find compensation in interfering
with the pleasures of others.   -- Bertrand Russell
---------------------------------------------------------------------
Luke Kanies  -|-   http://puppetlabs.com   -|-   http://about.me/lak




-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to