summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortyler-ball <tyleraball@gmail.com>2014-12-02 16:09:35 -0800
committertyler-ball <tyleraball@gmail.com>2014-12-17 18:52:21 -0800
commitb079e015f4ebb8c5db600bd49641699cbbacdb10 (patch)
treefd7d81f983998b228aa8e63875f03c895716fa7a
parent19f2c6e437642db0c03b193349b13d04636cb8ee (diff)
downloadchef-b079e015f4ebb8c5db600bd49641699cbbacdb10.tar.gz
Adding cookbook and recipe information per analytics request
-rw-r--r--lib/chef/audit/audit_event_proxy.rb2
-rw-r--r--lib/chef/audit/audit_reporter.rb9
-rw-r--r--lib/chef/audit/control_group_data.rb27
-rw-r--r--lib/chef/audit/runner.rb2
-rw-r--r--lib/chef/dsl/audit.rb11
-rw-r--r--lib/chef/formatters/doc.rb27
-rw-r--r--spec/unit/dsl/audit_spec.rb8
7 files changed, 55 insertions, 31 deletions
diff --git a/lib/chef/audit/audit_event_proxy.rb b/lib/chef/audit/audit_event_proxy.rb
index 6d5591d943..36160db9bb 100644
--- a/lib/chef/audit/audit_event_proxy.rb
+++ b/lib/chef/audit/audit_event_proxy.rb
@@ -43,7 +43,7 @@ class Chef
described_class = example.metadata[:described_class]
if described_class
resource_type = described_class.class.name.split(':')[-1]
- # TODO submit github PR to expose this
+ # TODO https://github.com/serverspec/serverspec/pull/493
resource_name = described_class.instance_variable_get(:@name)
end
diff --git a/lib/chef/audit/audit_reporter.rb b/lib/chef/audit/audit_reporter.rb
index 21ffb62829..d022ac0c47 100644
--- a/lib/chef/audit/audit_reporter.rb
+++ b/lib/chef/audit/audit_reporter.rb
@@ -28,7 +28,7 @@ class Chef
attr_reader :rest_client, :audit_data, :ordered_control_groups, :run_status
private :rest_client, :audit_data, :ordered_control_groups, :run_status
- PROTOCOL_VERSION = '0.1.0'
+ PROTOCOL_VERSION = '0.1.1'
def initialize(rest_client)
@rest_client = rest_client
@@ -36,6 +36,10 @@ class Chef
@ordered_control_groups = Hash.new
end
+ def run_context
+ run_status.run_context
+ end
+
def audit_phase_start(run_status)
Chef::Log.debug("Audit Reporter starting")
@audit_data = AuditData.new(run_status.node.name, run_status.run_id)
@@ -71,7 +75,8 @@ class Chef
if ordered_control_groups.has_key?(name)
raise Chef::Exceptions::AuditControlGroupDuplicate.new(name)
end
- ordered_control_groups.store(name, ControlGroupData.new(name))
+ metadata = run_context.audits[name].metadata
+ ordered_control_groups.store(name, ControlGroupData.new(name, metadata))
end
def control_example_success(control_group_name, example_data)
diff --git a/lib/chef/audit/control_group_data.rb b/lib/chef/audit/control_group_data.rb
index 969d128c1b..42a91ef5a7 100644
--- a/lib/chef/audit/control_group_data.rb
+++ b/lib/chef/audit/control_group_data.rb
@@ -28,14 +28,15 @@ class Chef
end
class ControlGroupData
- attr_reader :name, :status, :number_succeeded, :number_failed, :controls
+ attr_reader :name, :status, :number_succeeded, :number_failed, :controls, :metadata
- def initialize(name)
+ def initialize(name, metadata={})
@status = "success"
@controls = []
@number_succeeded = 0
@number_failed = 0
@name = name
+ @metadata = metadata
end
@@ -68,20 +69,14 @@ class Chef
:number_failed => number_failed,
:controls => controls.collect { |c| c.to_hash }
}
- add_display_only_data(h)
+ # If there is a duplicate key, metadata will overwrite it
+ add_display_only_data(h).merge(metadata)
end
private
def create_control(control_data)
- name = control_data[:name]
- resource_type = control_data[:resource_type]
- resource_name = control_data[:resource_name]
- context = control_data[:context]
- line_number = control_data[:line_number]
- # TODO make this smarter with splat arguments so if we start passing in more control_data
- # I don't have to modify code in multiple places
- ControlData.new(name, resource_type, resource_name, context, line_number)
+ ControlData.new(control_data)
end
# The id and control sequence number are ephemeral data - they are not needed
@@ -103,12 +98,10 @@ class Chef
attr_reader :name, :resource_type, :resource_name, :context, :line_number
attr_accessor :status, :details
- def initialize(name, resource_type, resource_name, context, line_number)
- @context = context
- @name = name
- @resource_type = resource_type
- @resource_name = resource_name
- @line_number = line_number
+ def initialize(control_data={})
+ control_data.each do |k, v|
+ self.instance_variable_set("@#{k}", v)
+ end
end
def to_hash
diff --git a/lib/chef/audit/runner.rb b/lib/chef/audit/runner.rb
index df6b6d682f..2fd33ac0de 100644
--- a/lib/chef/audit/runner.rb
+++ b/lib/chef/audit/runner.rb
@@ -144,7 +144,7 @@ class Chef
def register_controls
add_example_group_methods
run_context.audits.each do |name, group|
- ctl_grp = RSpec::Core::ExampleGroup.__controls__(*group[:args], &group[:block])
+ ctl_grp = RSpec::Core::ExampleGroup.__controls__(*group.args, &group.block)
RSpec.world.register(ctl_grp)
end
end
diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb
index a261d38f33..022bbcce01 100644
--- a/lib/chef/dsl/audit.rb
+++ b/lib/chef/dsl/audit.rb
@@ -34,7 +34,16 @@ class Chef
raise Chef::Exceptions::AuditControlGroupDuplicate.new(name)
end
- run_context.audits[name] = { :args => args, :block => block }
+ # This DSL will only work in the Recipe class because that exposes the cookbook_name
+ cookbook_name = self.cookbook_name
+ metadata = {
+ cookbook_name: cookbook_name,
+ cookbook_version: self.run_context.cookbook_collection[cookbook_name].version,
+ recipe_name: self.recipe_name,
+ line_number: block.source_location[1]
+ }
+
+ run_context.audits[name] = Struct.new(:args, :block, :metadata).new(args, block, metadata)
end
end
diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb
index 99603965a9..4f79411ed9 100644
--- a/lib/chef/formatters/doc.rb
+++ b/lib/chef/formatters/doc.rb
@@ -8,7 +8,9 @@ class Chef
# "specdoc"
class Doc < Formatters::Base
- attr_reader :start_time, :end_time
+ attr_reader :start_time, :end_time, :successful_audits, :failed_audits
+ private :successful_audits, :failed_audits
+
cli_name(:doc)
def initialize(out, err)
@@ -16,6 +18,8 @@ class Chef
@updated_resources = 0
@up_to_date_resources = 0
+ @successful_audits = 0
+ @failed_audits = 0
@start_time = Time.now
@end_time = @start_time
end
@@ -32,12 +36,16 @@ class Chef
@up_to_date_resources + @updated_resources
end
+ def total_audits
+ successful_audits + failed_audits
+ end
+
def run_completed(node)
@end_time = Time.now
if Chef::Config[:why_run]
puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated"
else
- puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{elapsed_time} seconds"
+ puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated and #{successful_audits}/#{total_audits} audits succeeded in #{elapsed_time} seconds"
end
end
@@ -46,7 +54,7 @@ class Chef
if Chef::Config[:why_run]
puts_line "Chef Client failed. #{@updated_resources} resources would have been updated"
else
- puts_line "Chef Client failed. #{@updated_resources} resources updated in #{elapsed_time} seconds"
+ puts_line "Chef Client failed. #{@updated_resources} resources updated and #{successful_audits}/#{total_audits} audits succeeded in #{elapsed_time} seconds"
end
end
@@ -156,11 +164,6 @@ class Chef
converge_complete
end
- #############
- # TODO
- # Make all these document printers neater
- #############
-
# Called before audit phase starts
def audit_phase_start(run_status)
puts_line "Starting audit phase"
@@ -181,6 +184,14 @@ class Chef
end
end
+ def control_example_success(control_group_name, example_data)
+ @successful_audits += 1
+ end
+
+ def control_example_failure(control_group_name, example_data, error)
+ @failed_audits += 1
+ end
+
# Called before action is executed on a resource.
def resource_action_start(resource, action, notification_type=nil, notifier=nil)
if resource.cookbook_name && resource.recipe_name
diff --git a/spec/unit/dsl/audit_spec.rb b/spec/unit/dsl/audit_spec.rb
index 7ddffb4e9f..7565a42d58 100644
--- a/spec/unit/dsl/audit_spec.rb
+++ b/spec/unit/dsl/audit_spec.rb
@@ -8,6 +8,12 @@ end
describe Chef::DSL::Audit do
let(:auditor) { AuditDSLTester.new }
+ let(:run_context) { instance_double(Chef::RunContext, :audits => audits) }
+ let(:audits) { [] }
+
+ before do
+ allow(auditor).to receive(:run_context).and_return(run_context)
+ end
it "raises an error when a block of audits is not provided" do
expect{ auditor.controls "name" }.to raise_error(Chef::Exceptions::NoAuditsProvided)
@@ -18,7 +24,7 @@ describe Chef::DSL::Audit do
end
it "raises an error if the audit name is a duplicate" do
- auditor.controls "unique" do end
+ expect(audits).to receive(:has_key?).with("unique").and_return(true)
expect { auditor.controls "unique" do end }.to raise_error(Chef::Exceptions::AuditControlGroupDuplicate)
end
end