Skip to content

Commit

Permalink
Enrichment is moving to logstash, report as close as possible to insp…
Browse files Browse the repository at this point in the history
…ec full json

Signed-off-by: Alex Pop <apop@chef.io>
  • Loading branch information
alexpop committed May 11, 2017
1 parent e187290 commit edc706c
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 125 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,13 @@ This method is sending the report using the `data_collector.server_url` and `dat

If you are using a self-signed certificate, please also read [how to add the Chef Automate certificate to the trusted_certs directory](https://docs.chef.io/setup_visibility_chef_automate.html#add-chef-automate-certificate-to-trusted-certs-directory)

Version compatibility matrix:

| Automate version | InSpec version | Audit Cookbook version |
|--------------------|------------------|--------------------------|
| < 0.8.0 | ≤ 1.23.0 | ≤ 3.1.0 |
| ≥ 0.8.0 | ≥ 1.24.0 | ≥ 4.0.0 |

## Profile Upload to Compliance Server

In order to support build cookbook mode, the `compliance_profile` resource has an `upload` action that allows uploading a compressed
Expand Down Expand Up @@ -464,11 +471,11 @@ Please note that all dependencies to the `inspec` gem must also be hosted in thi

Using the `inspec_version` attribute, please use the following `InSpec` version based on your Chef Compliance version:

| Chef Compliance version | InSpec version | Audit Cookbook version |
|----------------------------|----------------------------|----------------------------|
| Less or equal to 1.1.23 | 0.20.1 | 0.7.0 |
| Greater than 1.1.23 | Greater or equal to 0.22.1 | 0.8.0 |
| Greater or equal to 1.6.8 | Greater or equal to 1.2.0 | 1.0.2 |
| Chef Compliance version | InSpec version | Audit Cookbook version |
|----------------------------|-------------------|---------------------------|
| 1.1.23 | = 0.20.1 | = 0.7.0 |
| > 1.1.23 |0.22.1 | = 0.8.0 |
| 1.6.8 |1.2.0 | = 1.0.2 |

You can see all publicly available InSpec versions [here](https://rubygems.org/gems/inspec/versions)

Expand Down
14 changes: 0 additions & 14 deletions files/default/handler/audit_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,6 @@ def call(opts, profiles)
Chef::Log.info "Summary: #{passed_controls} successful, #{failed_controls} failures, #{skipped_controls} skipped in #{time} s"
end

if !r.nil? && 'json' == opts['format']
# ensure controls are never stored or shipped, since this was an accidential
# addition in InSpec and will be remove in our next major release
r.delete(:controls)

# calculate statistics
stats = count_controls(r[:profiles])

time = 0
time = r[:statistics][:duration] unless r[:statistics].nil?

# count controls
Chef::Log.info "Summary #{stats[:total]} controls: #{stats[:passed][:total]} successful, #{stats[:failed][:total]} failures, #{stats[:skipped][:total]} skipped in #{time} s"
end
Chef::Log.debug "Audit Report #{r}"
r
else
Expand Down
83 changes: 0 additions & 83 deletions libraries/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,89 +134,6 @@ def get_reporters(audit)
handle_reporters(audit['reporter'])
end

# Returns a hash with the counted controls based on their status and criticality
# This working on full-json reports
# total: count for all controls in the report, e.g. 100
# successful: count for all controls that executed successfully, e.g. 40
# skipped: count for all skipped controls, e.g. 10
# failed: count for all failed controls, e.g. 50
# minor, major, critical: split the failed count in 3 buckets based on the criticality,
# e.g. minor: 10, major: 15, critical: 25
def count_controls(profiles)
count = {
total: 0,
passed: {
total: 0,
},
skipped: {
total: 0,
},
failed: {
total: 0,
minor: 0,
major: 0,
critical: 0,
},
}
return count unless profiles.is_a?(Array)

profiles.each do |profile|
next unless profile && profile[:controls].is_a?(Array)
profile[:controls].each do |control|
count[:total] += 1
# ensure all impacts are float
control[:impact] = control[:impact].to_f
case control_status(control[:results])
when 'passed'
count[:passed][:total] += 1
when 'skipped'
count[:skipped][:total] += 1
when 'failed'
count[:failed][:total] += 1
criticality = impact_to_s(control[:impact])
count[:failed][criticality.to_sym] += 1 unless criticality.nil?
end
end
end
count
end

# Returns a complince status string based on the passed/failed/skipped controls
def compliance_status(counts)
return 'unknown' unless counts.is_a?(Hash) &&
counts[:failed].is_a?(Hash) &&
counts[:skipped].is_a?(Hash)
if counts[:failed][:total] > 0
'failed'
elsif counts[:total] == counts[:skipped][:total]
'skipped'
else
'passed'
end
end

# Returns a string with the control criticality based on the impact value
def impact_to_s(impact)
if impact < 0.4
'minor'
elsif impact < 0.7
'major'
else
'critical'
end
end

# A control can have multiple tests. Returns 'passed' unless any
# of the results has a status different than 'passed'
def control_status(results)
return unless results.is_a?(Array)
status = 'passed'
results.each do |result|
return 'failed' if result[:status] == 'failed'
status = 'skipped' if result[:status] == 'skipped'
end
status
end
end

::Chef::Recipe.send(:include, ReportHelpers)
39 changes: 17 additions & 22 deletions libraries/reporters/automate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def initialize(opts)
@entity_uuid = opts[:entity_uuid]
@run_id = opts[:run_id]
@node_name = opts[:node_info][:node]
@environment = opts[:node_info][:environment]
@insecure = opts[:insecure]

if defined?(Chef) &&
Expand Down Expand Up @@ -59,6 +60,7 @@ def send_report(report)

begin
Chef::Log.warn "Report to Chef Automate: #{@url}"
Chef::Log.debug "Audit Report: #{json_report}"
http = Chef::HTTP.new(@url)
http.post(nil, json_report, headers)
return true
Expand Down Expand Up @@ -106,33 +108,26 @@ def typed_attributes(profiles)
# revamp of the Automate expected input.
# ***************************************************************************************

def enriched_report(content)
return nil unless content.is_a?(Hash)
final_report = {}
total_duration = content[:statistics][:duration]
inspec_version = content[:version]
def enriched_report(final_report)
return nil unless final_report.is_a?(Hash)

# strip the report to leave only the profiles
final_report[:profiles] = content[:profiles]

# remove nil profiles if any
# Remove nil profiles if any
final_report[:profiles].select! { |p| p }

# set types for profile attributes
# Set types for profile attributes
final_report[:profiles] = typed_attributes(final_report[:profiles])

# add some additional fields to ease report parsing
final_report[:event_type] = 'inspec'
final_report[:event_action] = 'exec'
final_report[:compliance_summary] = count_controls(final_report[:profiles])
final_report[:compliance_summary][:status] = compliance_status(final_report[:compliance_summary])
final_report[:compliance_summary][:node_name] = @node_name
final_report[:compliance_summary][:end_time] = DateTime.now.iso8601
final_report[:compliance_summary][:duration] = total_duration
final_report[:compliance_summary][:inspec_version] = inspec_version
final_report[:entity_uuid] = @entity_uuid
final_report[:run_id] = @run_id
Chef::Log.info "Compliance Summary #{final_report[:compliance_summary]}"
# Label this content as an inspec_report
final_report[:type] = 'inspec_report'

# Ensure controls are never stored or shipped, since this was an accidential
# addition in InSpec and will be remove in the next inspec major release
final_report.delete(:controls)
final_report[:node_name] = @node_name
final_report[:end_time] = DateTime.now.iso8601
final_report[:node_uuid] = @entity_uuid
final_report[:environment] = @environment
final_report[:report_uuid] = @run_id
final_report
end
end
Expand Down
2 changes: 1 addition & 1 deletion metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
license 'Apache-2.0'
description 'Allows for fetching and executing compliance profiles, and reporting its results'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '3.1.0'
version '4.0.0'

source_url 'https://github.com/chef-cookbooks/audit'
issues_url 'https://github.com/chef-cookbooks/audit/issues'
Expand Down

0 comments on commit edc706c

Please sign in to comment.