diff options
-rw-r--r-- | lib/puppet/application/inspect.rb | 80 | ||||
-rw-r--r-- | lib/puppet/transaction/report.rb | 5 | ||||
-rw-r--r-- | spec/unit/application/inspect_spec.rb | 79 | ||||
-rwxr-xr-x | spec/unit/transaction/report_spec.rb | 8 |
4 files changed, 170 insertions, 2 deletions
diff --git a/lib/puppet/application/inspect.rb b/lib/puppet/application/inspect.rb new file mode 100644 index 000000000..c28fef326 --- /dev/null +++ b/lib/puppet/application/inspect.rb @@ -0,0 +1,80 @@ +require 'puppet/application' + +class Puppet::Application::Inspect < Puppet::Application + + should_parse_config + run_mode :agent + + option("--debug","-d") + option("--verbose","-v") + + option("--logdest LOGDEST", "-l") do |arg| + begin + Puppet::Util::Log.newdestination(arg) + options[:logset] = true + rescue => detail + $stderr.puts detail.to_s + end + end + + def setup + exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs? + + raise "Inspect requires reporting to be enabled. Set report=true in puppet.conf to enable reporting." unless Puppet[:report] + + @report = Puppet::Transaction::Report.new("inspect") + + Puppet::Util::Log.newdestination(@report) + Puppet::Util::Log.newdestination(:console) unless options[:logset] + + trap(:INT) do + $stderr.puts "Exiting" + exit(1) + end + + if options[:debug] + Puppet::Util::Log.level = :debug + elsif options[:verbose] + Puppet::Util::Log.level = :info + end + + Puppet::Transaction::Report.terminus_class = :rest + Puppet::Resource::Catalog.terminus_class = :yaml + end + + def run_command + retrieval_starttime = Time.now + + unless catalog = Puppet::Resource::Catalog.find(Puppet[:certname]) + raise "Could not find catalog for #{Puppet[:certname]}" + end + + retrieval_time = Time.now - retrieval_starttime + @report.add_times("config_retrieval", retrieval_time) + + starttime = Time.now + + catalog.to_ral.resources.each do |ral_resource| + audited_attributes = ral_resource[:audit] + next unless audited_attributes + + audited_resource = ral_resource.to_resource + + status = Puppet::Resource::Status.new(ral_resource) + audited_attributes.each do |name| + event = ral_resource.event(:previous_value => audited_resource[name], :property => name, :status => "audit", :message => "inspected value is #{audited_resource[name].inspect}") + status.add_event(event) + end + @report.add_resource_status(status) + end + + @report.add_metric(:time, {"config_retrieval" => retrieval_time, "inspect" => Time.now - starttime}) + + begin + @report.save + rescue => detail + puts detail.backtrace if Puppet[:trace] + Puppet.err "Could not send report: #{detail}" + end + end +end diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb index e6d1e0528..75c08fc7a 100644 --- a/lib/puppet/transaction/report.rb +++ b/lib/puppet/transaction/report.rb @@ -10,7 +10,7 @@ class Puppet::Transaction::Report indirects :report, :terminus_class => :processor - attr_reader :resource_statuses, :logs, :metrics, :host, :time + attr_reader :resource_statuses, :logs, :metrics, :host, :time, :kind # This is necessary since Marshall doesn't know how to # dump hash with default proc (see below @records) @@ -49,13 +49,14 @@ class Puppet::Transaction::Report calculate_event_metrics end - def initialize + def initialize(kind = "apply") @metrics = {} @logs = [] @resource_statuses = {} @external_times ||= {} @host = Puppet[:certname] @time = Time.now + @kind = kind end def name diff --git a/spec/unit/application/inspect_spec.rb b/spec/unit/application/inspect_spec.rb new file mode 100644 index 000000000..a3cc74d86 --- /dev/null +++ b/spec/unit/application/inspect_spec.rb @@ -0,0 +1,79 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/application/inspect' +require 'puppet/resource/catalog' +require 'puppet/indirector/catalog/yaml' +require 'puppet/indirector/report/rest' + +describe Puppet::Application::Inspect do + before :each do + @inspect = Puppet::Application[:inspect] + end + + describe "during setup" do + it "should print its configuration if asked" do + Puppet[:configprint] = "all" + + Puppet.settings.expects(:print_configs).returns(true) + lambda { @inspect.setup }.should raise_error(SystemExit) + end + + it "should fail if reporting is turned off" do + Puppet[:report] = false + lambda { @inspect.setup }.should raise_error(/report=true/) + end + end + + describe "when executing" do + before :each do + Puppet[:report] = true + Puppet::Util::Log.stubs(:newdestination) + Puppet::Transaction::Report::Rest.any_instance.stubs(:save) + @inspect.setup + end + + it "should retrieve the local catalog" do + Puppet::Resource::Catalog::Yaml.any_instance.expects(:find).with {|request| request.key == Puppet[:certname] }.returns(Puppet::Resource::Catalog.new) + + @inspect.run_command + end + + it "should save the report to REST" do + Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(Puppet::Resource::Catalog.new) + Puppet::Transaction::Report::Rest.any_instance.expects(:save).with {|request| request.instance.host == Puppet[:certname] } + + @inspect.run_command + end + + it "should audit the specified properties" do + catalog = Puppet::Resource::Catalog.new + file = Tempfile.new("foo") + file.puts("file contents") + file.flush + resource = Puppet::Resource.new(:file, file.path, :parameters => {:audit => "all"}) + catalog.add_resource(resource) + Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog) + + events = nil + + Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request| + events = request.instance.resource_statuses.values.first.events + end + + @inspect.run_command + + properties = events.inject({}) do |property_values, event| + property_values.merge(event.property => event.previous_value) + end + properties["ensure"].should == :file + properties["content"].should == "{md5}#{Digest::MD5.hexdigest("file contents\n")}" + end + end + + after :all do + Puppet::Resource::Catalog.indirection.reset_terminus_class + Puppet::Transaction::Report.indirection.terminus_class = :processor + end +end diff --git a/spec/unit/transaction/report_spec.rb b/spec/unit/transaction/report_spec.rb index 7e0b0554b..77f82159b 100755 --- a/spec/unit/transaction/report_spec.rb +++ b/spec/unit/transaction/report_spec.rb @@ -24,6 +24,14 @@ describe Puppet::Transaction::Report do Puppet::Transaction::Report.new.time.should == "mytime" end + it "should have a default 'kind' of 'apply'" do + Puppet::Transaction::Report.new.kind.should == "apply" + end + + it "should take a 'kind' as an argument" do + Puppet::Transaction::Report.new("inspect").kind.should == "inspect" + end + describe "when accepting logs" do before do @report = Puppet::Transaction::Report.new |