chef 16.7.61-universal-mingw32 → 16.9.20-universal-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -5
- data/README.md +2 -2
- data/chef.gemspec +12 -2
- data/distro/ruby_bin_folder/AMD64/Chef.PowerShell.Wrapper.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/Chef.PowerShell.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.PowerShell.Wrapper.Core.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.pdb +0 -0
- data/distro/ruby_bin_folder/x86/Chef.PowerShell.dll +0 -0
- data/distro/ruby_bin_folder/x86/Chef.Powershell.Wrapper.dll +0 -0
- data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.PowerShell.Wrapper.Core.dll +0 -0
- data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.dll +0 -0
- data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.pdb +0 -0
- data/lib/chef/application/base.rb +1 -1
- data/lib/chef/client.rb +3 -0
- data/lib/chef/compliance/default_attributes.rb +93 -0
- data/lib/chef/compliance/fetcher/automate.rb +69 -0
- data/lib/chef/compliance/fetcher/chef_server.rb +134 -0
- data/lib/chef/compliance/reporter/automate.rb +201 -0
- data/lib/chef/compliance/reporter/chef_server_automate.rb +94 -0
- data/lib/chef/compliance/reporter/compliance_enforcer.rb +20 -0
- data/lib/chef/compliance/reporter/json_file.rb +19 -0
- data/lib/chef/compliance/runner.rb +262 -0
- data/lib/chef/cookbook_manifest.rb +1 -0
- data/lib/chef/encrypted_data_bag_item/assertions.rb +1 -1
- data/lib/chef/exceptions.rb +4 -0
- data/lib/chef/http/ssl_policies.rb +33 -14
- data/lib/chef/knife/bootstrap/train_connector.rb +1 -1
- data/lib/chef/knife/core/formatting_options.rb +49 -0
- data/lib/chef/knife/core/node_presenter.rb +0 -25
- data/lib/chef/knife/core/status_presenter.rb +1 -26
- data/lib/chef/knife/core/ui.rb +4 -1
- data/lib/chef/knife/core/windows_bootstrap_context.rb +1 -1
- data/lib/chef/knife/node_show.rb +2 -1
- data/lib/chef/knife/search.rb +2 -1
- data/lib/chef/knife/ssh.rb +3 -1
- data/lib/chef/knife/status.rb +8 -11
- data/lib/chef/mixin/powershell_exec.rb +3 -1
- data/lib/chef/platform/query_helpers.rb +4 -4
- data/lib/chef/policy_builder/policyfile.rb +1 -1
- data/lib/chef/powershell.rb +2 -0
- data/lib/chef/provider/dsc_resource.rb +12 -24
- data/lib/chef/provider/dsc_script.rb +16 -20
- data/lib/chef/provider/git.rb +5 -5
- data/lib/chef/provider/package.rb +53 -19
- data/lib/chef/provider/package/dnf.rb +39 -12
- data/lib/chef/provider/package/dnf/dnf_helper.py +18 -5
- data/lib/chef/provider/package/dnf/python_helper.rb +6 -6
- data/lib/chef/provider/package/freebsd/pkgng.rb +3 -1
- data/lib/chef/provider/yum_repository.rb +2 -2
- data/lib/chef/resource/chef_client_config.rb +1 -1
- data/lib/chef/resource/chef_gem.rb +2 -2
- data/lib/chef/resource/cron/cron_d.rb +1 -0
- data/lib/chef/resource/dsc_script.rb +8 -1
- data/lib/chef/resource/file.rb +1 -1
- data/lib/chef/resource/gem_package.rb +2 -2
- data/lib/chef/resource/homebrew_cask.rb +3 -3
- data/lib/chef/resource/hostname.rb +3 -3
- data/lib/chef/resource/http_request.rb +1 -1
- data/lib/chef/resource/locale.rb +1 -1
- data/lib/chef/resource/mdadm.rb +2 -2
- data/lib/chef/resource/osx_profile.rb +7 -7
- data/lib/chef/resource/remote_directory.rb +1 -1
- data/lib/chef/resource/ruby.rb +1 -5
- data/lib/chef/resource/ruby_block.rb +1 -1
- data/lib/chef/resource/template.rb +2 -2
- data/lib/chef/resource/user/windows_user.rb +5 -0
- data/lib/chef/resource/windows_certificate.rb +9 -13
- data/lib/chef/resource/yum_repository.rb +5 -0
- data/lib/chef/resource_collection/resource_set.rb +1 -1
- data/lib/chef/util/dsc/configuration_generator.rb +52 -11
- data/lib/chef/util/dsc/lcm_output_parser.rb +3 -4
- data/lib/chef/util/dsc/local_configuration_manager.rb +17 -14
- data/lib/chef/util/dsc/resource_store.rb +5 -11
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/file.rb +4 -0
- data/spec/data/rubygems.org/latest_specs.4.8.gz +0 -0
- data/spec/data/rubygems.org/nonexistent_gem +0 -0
- data/spec/data/rubygems.org/sexp_processor +0 -0
- data/spec/data/rubygems.org/sexp_processor-4.15.1.gemspec.rz +0 -0
- data/spec/data/ssl/binary/chef-rspec-der.cert +0 -0
- data/spec/data/ssl/binary/chef-rspec-der.key +0 -0
- data/spec/functional/resource/dnf_package_spec.rb +319 -16
- data/spec/functional/resource/dsc_script_spec.rb +3 -6
- data/spec/functional/resource/windows_certificate_spec.rb +204 -384
- data/spec/integration/client/client_spec.rb +2 -1
- data/spec/integration/compliance/compliance_spec.rb +81 -0
- data/spec/integration/recipes/recipe_dsl_spec.rb +1 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/client_spec.rb +1 -0
- data/spec/unit/compliance/fetcher/automate_spec.rb +134 -0
- data/spec/unit/compliance/fetcher/chef_server_spec.rb +93 -0
- data/spec/unit/compliance/reporter/automate_spec.rb +427 -0
- data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +177 -0
- data/spec/unit/compliance/reporter/compliance_enforcer_spec.rb +48 -0
- data/spec/unit/compliance/runner_spec.rb +167 -0
- data/spec/unit/http/ssl_policies_spec.rb +107 -68
- data/spec/unit/knife/bootstrap_spec.rb +5 -17
- data/spec/unit/knife/core/node_editor_spec.rb +1 -1
- data/spec/unit/knife/core/status_presenter_spec.rb +54 -0
- data/spec/unit/mixin/openssl_helper_spec.rb +0 -7
- data/spec/unit/mixin/powershell_exec_spec.rb +1 -1
- data/spec/unit/platform/query_helpers_spec.rb +11 -12
- data/spec/unit/provider/dsc_resource_spec.rb +10 -27
- data/spec/unit/provider/dsc_script_spec.rb +1 -1
- data/spec/unit/provider/mount/windows_spec.rb +1 -0
- data/spec/unit/provider/package/freebsd/pkgng_spec.rb +1 -1
- data/spec/unit/provider/package/rubygems_spec.rb +39 -7
- data/spec/unit/provider/systemd_unit_spec.rb +1 -1
- data/spec/unit/resource/user/windows_user_spec.rb +36 -0
- data/spec/unit/resource/windows_certificate_spec.rb +12 -0
- data/spec/unit/util/dsc/configuration_generator_spec.rb +79 -0
- data/spec/unit/util/dsc/local_configuration_manager_spec.rb +27 -35
- metadata +55 -18
- data/lib/chef/util/powershell/cmdlet.rb +0 -169
- data/lib/chef/util/powershell/cmdlet_result.rb +0 -61
- data/spec/data/trusted_certs_empty/.gitkeep +0 -0
- data/spec/data/trusted_certs_empty/README.md +0 -1
- data/spec/functional/util/powershell/cmdlet_spec.rb +0 -111
- data/spec/scripts/ssl-serve.rb +0 -47
- data/spec/unit/util/powershell/cmdlet_spec.rb +0 -106
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative "automate"
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
module Compliance
|
5
|
+
module Reporter
|
6
|
+
#
|
7
|
+
# Used to send inspec reports to Chef Automate server via Chef Server
|
8
|
+
#
|
9
|
+
class ChefServerAutomate < Chef::Compliance::Reporter::Automate
|
10
|
+
attr_reader :url
|
11
|
+
|
12
|
+
def initialize(opts)
|
13
|
+
@entity_uuid = opts[:entity_uuid]
|
14
|
+
@run_id = opts[:run_id]
|
15
|
+
@node_name = opts[:node_info][:node]
|
16
|
+
@insecure = opts[:insecure]
|
17
|
+
@environment = opts[:node_info][:environment]
|
18
|
+
@roles = opts[:node_info][:roles]
|
19
|
+
@recipes = opts[:node_info][:recipes]
|
20
|
+
@url = opts[:url]
|
21
|
+
@chef_tags = opts[:node_info][:chef_tags]
|
22
|
+
@policy_group = opts[:node_info][:policy_group]
|
23
|
+
@policy_name = opts[:node_info][:policy_name]
|
24
|
+
@source_fqdn = opts[:node_info][:source_fqdn]
|
25
|
+
@organization_name = opts[:node_info][:organization_name]
|
26
|
+
@ipaddress = opts[:node_info][:ipaddress]
|
27
|
+
@fqdn = opts[:node_info][:fqdn]
|
28
|
+
@control_results_limit = opts[:control_results_limit]
|
29
|
+
@timestamp = opts.fetch(:timestamp) { Time.now }
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_report(report)
|
33
|
+
unless @entity_uuid && @run_id
|
34
|
+
Chef::Log.error "entity_uuid(#{@entity_uuid}) or run_id(#{@run_id}) can't be nil, not sending report to #{ChefUtils::Dist::Automate::PRODUCT}"
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
|
38
|
+
automate_report = truncate_controls_results(enriched_report(report), @control_results_limit)
|
39
|
+
|
40
|
+
report_size = Chef::JSONCompat.to_json(automate_report, validate_utf8: false).bytesize
|
41
|
+
# this is set to slightly less than the oc_erchef limit
|
42
|
+
if report_size > 900 * 1024
|
43
|
+
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."
|
44
|
+
end
|
45
|
+
|
46
|
+
Chef::Log.info "Report to #{ChefUtils::Dist::Automate::PRODUCT} via #{ChefUtils::Dist::Server::PRODUCT}: #{@url}"
|
47
|
+
with_http_rescue do
|
48
|
+
http_client.post(@url, automate_report)
|
49
|
+
return true
|
50
|
+
end
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
def http_client
|
55
|
+
config = if @insecure
|
56
|
+
Chef::Config.merge(ssl_verify_mode: :verify_none)
|
57
|
+
else
|
58
|
+
Chef::Config
|
59
|
+
end
|
60
|
+
|
61
|
+
Chef::ServerAPI.new(@url, config)
|
62
|
+
end
|
63
|
+
|
64
|
+
def with_http_rescue
|
65
|
+
response = yield
|
66
|
+
if response.respond_to?(:code)
|
67
|
+
# handle non 200 error codes, they are not raised as Net::HTTPClientException
|
68
|
+
handle_http_error_code(response.code) if response.code.to_i >= 300
|
69
|
+
end
|
70
|
+
response
|
71
|
+
rescue Net::HTTPClientException => e
|
72
|
+
Chef::Log.error e
|
73
|
+
handle_http_error_code(e.response.code)
|
74
|
+
end
|
75
|
+
|
76
|
+
def handle_http_error_code(code)
|
77
|
+
case code
|
78
|
+
when /401|403/
|
79
|
+
Chef::Log.error "Auth issue: see the Compliance Phase troubleshooting documentation (http://docs.chef.io/chef_compliance_phase/#troubleshooting)."
|
80
|
+
when /404/
|
81
|
+
Chef::Log.error "Object does not exist on remote server."
|
82
|
+
when /413/
|
83
|
+
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/)"
|
84
|
+
when /429/
|
85
|
+
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."
|
86
|
+
end
|
87
|
+
msg = "Received HTTP error #{code}"
|
88
|
+
Chef::Log.error msg
|
89
|
+
raise msg
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Chef
|
2
|
+
module Compliance
|
3
|
+
module Reporter
|
4
|
+
class AuditEnforcer
|
5
|
+
class ControlFailure < StandardError; end
|
6
|
+
|
7
|
+
def send_report(report)
|
8
|
+
report.fetch(:profiles, []).each do |profile|
|
9
|
+
profile.fetch(:controls, []).each do |control|
|
10
|
+
control.fetch(:results, []).each do |result|
|
11
|
+
raise ControlFailure, "Audit #{control[:id]} has failed. Aborting #{ChefUtils::Dist::Infra::CLIENT} run." if result[:status] == "failed"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "../../json_compat"
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
module Compliance
|
5
|
+
module Reporter
|
6
|
+
class JsonFile
|
7
|
+
def initialize(opts)
|
8
|
+
@path = opts.fetch(:file)
|
9
|
+
end
|
10
|
+
|
11
|
+
def send_report(report)
|
12
|
+
FileUtils.mkdir_p(File.dirname(@path), mode: 0700)
|
13
|
+
|
14
|
+
File.write(@path, Chef::JSONCompat.to_json(report))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
autoload :Inspec, "inspec"
|
2
|
+
|
3
|
+
require_relative "default_attributes"
|
4
|
+
require_relative "reporter/automate"
|
5
|
+
require_relative "reporter/chef_server_automate"
|
6
|
+
require_relative "reporter/compliance_enforcer"
|
7
|
+
require_relative "reporter/json_file"
|
8
|
+
|
9
|
+
class Chef
|
10
|
+
module Compliance
|
11
|
+
class Runner < EventDispatch::Base
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
attr_accessor :run_id
|
15
|
+
attr_reader :node
|
16
|
+
def_delegators :node, :logger
|
17
|
+
|
18
|
+
def enabled?
|
19
|
+
audit_cookbook_present = node["recipes"].include?("audit::default")
|
20
|
+
|
21
|
+
logger.info("#{self.class}##{__method__}: #{Inspec::Dist::PRODUCT_NAME} profiles? #{inspec_profiles.any?}")
|
22
|
+
logger.info("#{self.class}##{__method__}: audit cookbook? #{audit_cookbook_present}")
|
23
|
+
|
24
|
+
inspec_profiles.any? && !audit_cookbook_present
|
25
|
+
end
|
26
|
+
|
27
|
+
def node=(node)
|
28
|
+
@node = node
|
29
|
+
node.default["audit"] = Chef::Compliance::DEFAULT_ATTRIBUTES.merge(node.default["audit"])
|
30
|
+
end
|
31
|
+
|
32
|
+
def node_load_completed(node, _expanded_run_list, _config)
|
33
|
+
self.node = node
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_started(run_status)
|
37
|
+
self.run_id = run_status.run_id
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_completed(_node, _run_status)
|
41
|
+
return unless enabled?
|
42
|
+
|
43
|
+
logger.info("#{self.class}##{__method__}: enabling Compliance Phase")
|
44
|
+
|
45
|
+
report
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_failed(_exception, _run_status)
|
49
|
+
return unless enabled?
|
50
|
+
|
51
|
+
logger.info("#{self.class}##{__method__}: enabling Compliance Phase")
|
52
|
+
|
53
|
+
report
|
54
|
+
end
|
55
|
+
|
56
|
+
### Below code adapted from audit cookbook's files/default/handler/audit_report.rb
|
57
|
+
|
58
|
+
DEPRECATED_CONFIG_VALUES = %w{
|
59
|
+
attributes_save
|
60
|
+
fail_if_not_present
|
61
|
+
inspec_gem_source
|
62
|
+
inspec_version
|
63
|
+
interval
|
64
|
+
owner
|
65
|
+
raise_if_unreachable
|
66
|
+
}.freeze
|
67
|
+
|
68
|
+
def warn_for_deprecated_config_values!
|
69
|
+
deprecated_config_values = (node["audit"].keys & DEPRECATED_CONFIG_VALUES)
|
70
|
+
|
71
|
+
if deprecated_config_values.any?
|
72
|
+
values = deprecated_config_values.sort.map { |v| "'#{v}'" }.join(", ")
|
73
|
+
logger.warn "audit cookbook config values #{values} are not supported in #{ChefUtils::Dist::Infra::PRODUCT}'s Compliance Phase."
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def report(report = generate_report)
|
78
|
+
warn_for_deprecated_config_values!
|
79
|
+
|
80
|
+
if report.empty?
|
81
|
+
logger.error "Compliance report was not generated properly, skipped reporting"
|
82
|
+
return
|
83
|
+
end
|
84
|
+
|
85
|
+
Array(node["audit"]["reporter"]).each do |reporter|
|
86
|
+
send_report(reporter, report)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def inspec_opts
|
91
|
+
inputs = node["audit"]["attributes"].to_h
|
92
|
+
if node["audit"]["chef_node_attribute_enabled"]
|
93
|
+
inputs["chef_node"] = node.to_h
|
94
|
+
inputs["chef_node"]["chef_environment"] = node.chef_environment
|
95
|
+
end
|
96
|
+
|
97
|
+
{
|
98
|
+
backend_cache: node["audit"]["inspec_backend_cache"],
|
99
|
+
inputs: inputs,
|
100
|
+
logger: logger,
|
101
|
+
output: node["audit"]["quiet"] ? ::File::NULL : STDOUT,
|
102
|
+
report: true,
|
103
|
+
reporter: ["json-automate"],
|
104
|
+
reporter_backtrace_inclusion: node["audit"]["result_include_backtrace"],
|
105
|
+
reporter_message_truncation: node["audit"]["result_message_limit"],
|
106
|
+
waiver_file: Array(node["audit"]["waiver_file"]),
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def inspec_profiles
|
111
|
+
profiles = node["audit"]["profiles"]
|
112
|
+
|
113
|
+
# TODO: Custom exception class here?
|
114
|
+
unless profiles.respond_to?(:map) && profiles.all? { |_, p| p.respond_to?(:transform_keys) && p.respond_to?(:update) }
|
115
|
+
raise "#{Inspec::Dist::PRODUCT_NAME} profiles specified in an unrecognized format, expected a hash of hashes."
|
116
|
+
end
|
117
|
+
|
118
|
+
profiles.map do |name, profile|
|
119
|
+
profile.transform_keys(&:to_sym).update(name: name)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def load_fetchers!
|
124
|
+
case node["audit"]["fetcher"]
|
125
|
+
when "chef-automate"
|
126
|
+
require_relative "fetcher/automate"
|
127
|
+
when "chef-server"
|
128
|
+
require_relative "fetcher/chef_server"
|
129
|
+
when nil
|
130
|
+
# intentionally blank
|
131
|
+
else
|
132
|
+
raise "Invalid value specified for Compliance Phase's fetcher: '#{node["audit"]["fetcher"]}'. Valid values are 'chef-automate', 'chef-server', or nil."
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def generate_report(opts: inspec_opts, profiles: inspec_profiles)
|
137
|
+
load_fetchers!
|
138
|
+
|
139
|
+
logger.debug "Options are set to: #{opts}"
|
140
|
+
runner = ::Inspec::Runner.new(opts)
|
141
|
+
|
142
|
+
if profiles.empty?
|
143
|
+
failed_report("No #{Inspec::Dist::PRODUCT_NAME} profiles are defined.")
|
144
|
+
return
|
145
|
+
end
|
146
|
+
|
147
|
+
profiles.each { |target| runner.add_target(target) }
|
148
|
+
|
149
|
+
logger.info "Running profiles from: #{profiles.inspect}"
|
150
|
+
runner.run
|
151
|
+
runner.report.tap do |r|
|
152
|
+
logger.debug "Compliance Report #{r}"
|
153
|
+
end
|
154
|
+
rescue Inspec::FetcherFailure => e
|
155
|
+
failed_report("Cannot fetch all profiles: #{profiles}. Please make sure you're authenticated and the server is reachable. #{e.message}")
|
156
|
+
rescue => e
|
157
|
+
failed_report(e.message)
|
158
|
+
end
|
159
|
+
|
160
|
+
# In case InSpec raises a runtime exception without providing a valid report,
|
161
|
+
# we make one up and add two new fields to it: `status` and `status_message`
|
162
|
+
def failed_report(err)
|
163
|
+
logger.error "#{Inspec::Dist::PRODUCT_NAME} has raised a runtime exception. Generating a minimal failed report."
|
164
|
+
logger.error err
|
165
|
+
{
|
166
|
+
"platform": {
|
167
|
+
"name": "unknown",
|
168
|
+
"release": "unknown",
|
169
|
+
},
|
170
|
+
"profiles": [],
|
171
|
+
"statistics": {
|
172
|
+
"duration": 0.0000001,
|
173
|
+
},
|
174
|
+
"version": Inspec::VERSION,
|
175
|
+
"status": "failed",
|
176
|
+
"status_message": err,
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
# extracts relevant node data
|
181
|
+
def node_info
|
182
|
+
chef_server_uri = URI(Chef::Config[:chef_server_url])
|
183
|
+
|
184
|
+
runlist_roles = node.run_list.select { |item| item.type == :role }.map(&:name)
|
185
|
+
runlist_recipes = node.run_list.select { |item| item.type == :recipe }.map(&:name)
|
186
|
+
{
|
187
|
+
node: node.name,
|
188
|
+
os: {
|
189
|
+
release: node["platform_version"],
|
190
|
+
family: node["platform"],
|
191
|
+
},
|
192
|
+
environment: node.environment,
|
193
|
+
roles: runlist_roles,
|
194
|
+
recipes: runlist_recipes,
|
195
|
+
policy_name: node.policy_name || "",
|
196
|
+
policy_group: node.policy_group || "",
|
197
|
+
chef_tags: node.tags,
|
198
|
+
organization_name: chef_server_uri.path.split("/").last || "",
|
199
|
+
source_fqdn: chef_server_uri.host || "",
|
200
|
+
ipaddress: node["ipaddress"],
|
201
|
+
fqdn: node["fqdn"],
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
def send_report(reporter_type, report)
|
206
|
+
logger.info "Reporting to #{reporter_type}"
|
207
|
+
|
208
|
+
reporter = reporter(reporter_type)
|
209
|
+
|
210
|
+
reporter.send_report(report) if reporter
|
211
|
+
end
|
212
|
+
|
213
|
+
def reporter(reporter_type)
|
214
|
+
case reporter_type
|
215
|
+
when "chef-automate"
|
216
|
+
opts = {
|
217
|
+
control_results_limit: node["audit"]["control_results_limit"],
|
218
|
+
entity_uuid: node["chef_guid"],
|
219
|
+
insecure: node["audit"]["insecure"],
|
220
|
+
node_info: node_info,
|
221
|
+
run_id: run_id,
|
222
|
+
run_time_limit: node["audit"]["run_time_limit"],
|
223
|
+
}
|
224
|
+
Chef::Compliance::Reporter::Automate.new(opts)
|
225
|
+
when "chef-server-automate"
|
226
|
+
opts = {
|
227
|
+
control_results_limit: node["audit"]["control_results_limit"],
|
228
|
+
entity_uuid: node["chef_guid"],
|
229
|
+
insecure: node["audit"]["insecure"],
|
230
|
+
node_info: node_info,
|
231
|
+
run_id: run_id,
|
232
|
+
run_time_limit: node["audit"]["run_time_limit"],
|
233
|
+
url: chef_server_automate_url,
|
234
|
+
}
|
235
|
+
Chef::Compliance::Reporter::ChefServerAutomate.new(opts)
|
236
|
+
when "json-file"
|
237
|
+
path = node["audit"]["json_file"]["location"]
|
238
|
+
logger.info "Writing compliance report to #{path}"
|
239
|
+
Chef::Compliance::Reporter::JsonFile.new(file: path)
|
240
|
+
when "audit-enforcer"
|
241
|
+
Chef::Compliance::Reporter::ComplianceEnforcer.new
|
242
|
+
else
|
243
|
+
raise "'#{reporter_type}' is not a supported reporter for Compliance Phase."
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def chef_server_automate_url
|
248
|
+
url = if node["audit"]["server"]
|
249
|
+
URI(node["audit"]["server"])
|
250
|
+
else
|
251
|
+
URI(Chef::Config[:chef_server_url]).tap do |u|
|
252
|
+
u.path = ""
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
org = Chef::Config[:chef_server_url].split("/").last
|
257
|
+
url.path = File.join(url.path, "organizations/#{org}/data-collector")
|
258
|
+
url
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
@@ -30,7 +30,7 @@ class Chef::EncryptedDataBagItem
|
|
30
30
|
unless format_version.is_a?(Integer) && format_version >= Chef::Config[:data_bag_decrypt_minimum_version]
|
31
31
|
raise UnacceptableEncryptedDataBagItemFormat,
|
32
32
|
"The encrypted data bag item has format version `#{format_version}', " +
|
33
|
-
|
33
|
+
"but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'"
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
data/lib/chef/exceptions.rb
CHANGED
@@ -84,11 +84,13 @@ class Chef
|
|
84
84
|
class InvalidPrivateKey < ArgumentError; end
|
85
85
|
class MissingKeyAttribute < ArgumentError; end
|
86
86
|
class KeyCommandInputError < ArgumentError; end
|
87
|
+
|
87
88
|
class BootstrapCommandInputError < ArgumentError
|
88
89
|
def initialize
|
89
90
|
super "You cannot pass both --json-attributes and --json-attribute-file. Please pass one or none."
|
90
91
|
end
|
91
92
|
end
|
93
|
+
|
92
94
|
class InvalidKeyArgument < ArgumentError; end
|
93
95
|
class InvalidKeyAttribute < ArgumentError; end
|
94
96
|
class InvalidUserAttribute < ArgumentError; end
|
@@ -195,6 +197,7 @@ class Chef
|
|
195
197
|
class IllegalVersionConstraint < NotImplementedError; end # rubocop:disable Lint/InheritException
|
196
198
|
|
197
199
|
class MetadataNotValid < StandardError; end
|
200
|
+
|
198
201
|
class MetadataNotFound < StandardError
|
199
202
|
attr_reader :install_path
|
200
203
|
attr_reader :cookbook_name
|
@@ -283,6 +286,7 @@ class Chef
|
|
283
286
|
end
|
284
287
|
|
285
288
|
end
|
289
|
+
|
286
290
|
# Exception class for collecting multiple failures. Used when running
|
287
291
|
# delayed notifications so that chef can process each delayed
|
288
292
|
# notification even if chef client or other notifications fail.
|
@@ -70,6 +70,12 @@ class Chef
|
|
70
70
|
end
|
71
71
|
|
72
72
|
http_client.ca_file = config[:ssl_ca_file]
|
73
|
+
elsif ENV["SSL_CERT_FILE"]
|
74
|
+
unless ::File.exist?(ENV["SSL_CERT_FILE"])
|
75
|
+
raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_file #{ENV["SSL_CERT_FILE"]} does not exist"
|
76
|
+
end
|
77
|
+
|
78
|
+
http_client.ca_file = ENV["SSL_CERT_FILE"]
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
@@ -79,28 +85,41 @@ class Chef
|
|
79
85
|
http_client.cert_store.set_default_paths
|
80
86
|
end
|
81
87
|
if config.trusted_certs_dir
|
82
|
-
certs = Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(config.trusted_certs_dir), "*.{crt,pem}"))
|
88
|
+
certs = Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob_dir(config.trusted_certs_dir), "*.{crt,pem}"))
|
83
89
|
certs.each do |cert_file|
|
84
|
-
cert =
|
90
|
+
cert = begin
|
91
|
+
OpenSSL::X509::Certificate.new(::File.binread(cert_file))
|
92
|
+
rescue OpenSSL::X509::CertificateError => e
|
93
|
+
raise Chef::Exceptions::ConfigurationError, "Error reading cert file '#{cert_file}', original error '#{e.class}: #{e.message}'"
|
94
|
+
end
|
85
95
|
add_trusted_cert(cert)
|
86
96
|
end
|
87
97
|
end
|
88
98
|
end
|
89
99
|
|
90
100
|
def set_client_credentials
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
+
return unless config[:ssl_client_cert] || config[:ssl_client_key]
|
102
|
+
|
103
|
+
unless config[:ssl_client_cert] && config[:ssl_client_key]
|
104
|
+
raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
|
105
|
+
end
|
106
|
+
unless ::File.exists?(config[:ssl_client_cert])
|
107
|
+
raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
|
108
|
+
end
|
109
|
+
unless ::File.exists?(config[:ssl_client_key])
|
110
|
+
raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
|
111
|
+
end
|
112
|
+
|
113
|
+
begin
|
114
|
+
http_client.cert = OpenSSL::X509::Certificate.new(::File.binread(config[:ssl_client_cert]))
|
115
|
+
rescue OpenSSL::X509::CertificateError => e
|
116
|
+
raise Chef::Exceptions::ConfigurationError, "Error reading cert file '#{config[:ssl_client_cert]}', original error '#{e.class}: #{e.message}'"
|
117
|
+
end
|
101
118
|
|
102
|
-
|
103
|
-
http_client.key = OpenSSL::PKey::RSA.new(::File.
|
119
|
+
begin
|
120
|
+
http_client.key = OpenSSL::PKey::RSA.new(::File.binread(config[:ssl_client_key]))
|
121
|
+
rescue OpenSSL::PKey::RSAError => e
|
122
|
+
raise Chef::Exceptions::ConfigurationError, "Error reading key file '#{config[:ssl_client_key]}', original error '#{e.class}: #{e.message}'"
|
104
123
|
end
|
105
124
|
end
|
106
125
|
|