blob: 46ca7dc7ba64bfffff5de7ea8bc3e46ffd42e9f6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
require_relative "automate"
class Chef
module Compliance
module Reporter
#
# Used to send inspec reports to Chef Automate server via Chef Server
#
class ChefServerAutomate < Chef::Compliance::Reporter::Automate
attr_reader :url
def initialize(opts)
@entity_uuid = opts[:entity_uuid]
@run_id = opts[:run_id]
@node_name = opts[:node_info][:node]
@insecure = opts[:insecure]
@environment = opts[:node_info][:environment]
@roles = opts[:node_info][:roles]
@recipes = opts[:node_info][:recipes]
@url = opts[:url]
@chef_tags = opts[:node_info][:chef_tags]
@policy_group = opts[:node_info][:policy_group]
@policy_name = opts[:node_info][:policy_name]
@source_fqdn = opts[:node_info][:source_fqdn]
@organization_name = opts[:node_info][:organization_name]
@ipaddress = opts[:node_info][:ipaddress]
@fqdn = opts[:node_info][:fqdn]
@control_results_limit = opts[:control_results_limit]
@timestamp = opts.fetch(:timestamp) { Time.now }
end
def send_report(report)
unless @entity_uuid && @run_id
Chef::Log.error "entity_uuid(#{@entity_uuid}) or run_id(#{@run_id}) can't be nil, not sending report to #{ChefUtils::Dist::Automate::PRODUCT}"
return false
end
automate_report = truncate_controls_results(enriched_report(report), @control_results_limit)
report_size = Chef::JSONCompat.to_json(automate_report, validate_utf8: false).bytesize
# this is set to slightly less than the oc_erchef limit
if report_size > 900 * 1024
Chef::Log.warn "Generated report size is #{(report_size / (1024 * 1024.0)).round(2)} MB. #{ChefUtils::Dist::Server::PRODUCT} < 13.0 defaults to a limit of ~1MB, 13.0+ defaults to a limit of ~2MB."
end
Chef::Log.info "Report to #{ChefUtils::Dist::Automate::PRODUCT} via #{ChefUtils::Dist::Server::PRODUCT}: #{@url}"
with_http_rescue do
http_client.post(@url, automate_report)
return true
end
false
end
def http_client
config = if @insecure
Chef::Config.merge(ssl_verify_mode: :verify_none)
else
Chef::Config
end
Chef::ServerAPI.new(@url, config)
end
def with_http_rescue
response = yield
if response.respond_to?(:code)
# handle non 200 error codes, they are not raised as Net::HTTPClientException
handle_http_error_code(response.code) if response.code.to_i >= 300
end
response
rescue Net::HTTPClientException => e
Chef::Log.error e
handle_http_error_code(e.response.code)
end
def handle_http_error_code(code)
case code
when /401|403/
Chef::Log.error "Auth issue: see the Compliance Phase troubleshooting documentation (http://docs.chef.io/chef_compliance_phase/#troubleshooting)."
when /404/
Chef::Log.error "Object does not exist on remote server."
when /413/
Chef::Log.error "You most likely hit the erchef request size in #{ChefUtils::Dist::Server::PRODUCT} that defaults to ~2MB. To increase this limit see the Compliance Phase troubleshooting documentation (http://docs.chef.io/chef_compliance_phase/#troubleshooting) or the Chef Infra Server configuration documentation (https://docs.chef.io/server/config_rb_server/)"
when /429/
Chef::Log.error "This error typically means the data sent was larger than #{ChefUtils::Dist::Automate::PRODUCT}'s limit (4 MB). Run InSpec locally to identify any controls producing large diffs."
end
msg = "Received HTTP error #{code}"
Chef::Log.error msg
raise msg
end
end
end
end
end
|