summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/application/inspect.rb80
-rw-r--r--lib/puppet/transaction/report.rb5
-rw-r--r--spec/unit/application/inspect_spec.rb79
-rwxr-xr-xspec/unit/transaction/report_spec.rb8
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