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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -5
  3. data/README.md +2 -2
  4. data/chef.gemspec +12 -2
  5. data/distro/ruby_bin_folder/AMD64/Chef.PowerShell.Wrapper.dll +0 -0
  6. data/distro/ruby_bin_folder/AMD64/Chef.PowerShell.dll +0 -0
  7. data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.PowerShell.Wrapper.Core.dll +0 -0
  8. data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.dll +0 -0
  9. data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.pdb +0 -0
  10. data/distro/ruby_bin_folder/x86/Chef.PowerShell.dll +0 -0
  11. data/distro/ruby_bin_folder/x86/Chef.Powershell.Wrapper.dll +0 -0
  12. data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.PowerShell.Wrapper.Core.dll +0 -0
  13. data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.dll +0 -0
  14. data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.pdb +0 -0
  15. data/lib/chef/application/base.rb +1 -1
  16. data/lib/chef/client.rb +3 -0
  17. data/lib/chef/compliance/default_attributes.rb +93 -0
  18. data/lib/chef/compliance/fetcher/automate.rb +69 -0
  19. data/lib/chef/compliance/fetcher/chef_server.rb +134 -0
  20. data/lib/chef/compliance/reporter/automate.rb +201 -0
  21. data/lib/chef/compliance/reporter/chef_server_automate.rb +94 -0
  22. data/lib/chef/compliance/reporter/compliance_enforcer.rb +20 -0
  23. data/lib/chef/compliance/reporter/json_file.rb +19 -0
  24. data/lib/chef/compliance/runner.rb +262 -0
  25. data/lib/chef/cookbook_manifest.rb +1 -0
  26. data/lib/chef/encrypted_data_bag_item/assertions.rb +1 -1
  27. data/lib/chef/exceptions.rb +4 -0
  28. data/lib/chef/http/ssl_policies.rb +33 -14
  29. data/lib/chef/knife/bootstrap/train_connector.rb +1 -1
  30. data/lib/chef/knife/core/formatting_options.rb +49 -0
  31. data/lib/chef/knife/core/node_presenter.rb +0 -25
  32. data/lib/chef/knife/core/status_presenter.rb +1 -26
  33. data/lib/chef/knife/core/ui.rb +4 -1
  34. data/lib/chef/knife/core/windows_bootstrap_context.rb +1 -1
  35. data/lib/chef/knife/node_show.rb +2 -1
  36. data/lib/chef/knife/search.rb +2 -1
  37. data/lib/chef/knife/ssh.rb +3 -1
  38. data/lib/chef/knife/status.rb +8 -11
  39. data/lib/chef/mixin/powershell_exec.rb +3 -1
  40. data/lib/chef/platform/query_helpers.rb +4 -4
  41. data/lib/chef/policy_builder/policyfile.rb +1 -1
  42. data/lib/chef/powershell.rb +2 -0
  43. data/lib/chef/provider/dsc_resource.rb +12 -24
  44. data/lib/chef/provider/dsc_script.rb +16 -20
  45. data/lib/chef/provider/git.rb +5 -5
  46. data/lib/chef/provider/package.rb +53 -19
  47. data/lib/chef/provider/package/dnf.rb +39 -12
  48. data/lib/chef/provider/package/dnf/dnf_helper.py +18 -5
  49. data/lib/chef/provider/package/dnf/python_helper.rb +6 -6
  50. data/lib/chef/provider/package/freebsd/pkgng.rb +3 -1
  51. data/lib/chef/provider/yum_repository.rb +2 -2
  52. data/lib/chef/resource/chef_client_config.rb +1 -1
  53. data/lib/chef/resource/chef_gem.rb +2 -2
  54. data/lib/chef/resource/cron/cron_d.rb +1 -0
  55. data/lib/chef/resource/dsc_script.rb +8 -1
  56. data/lib/chef/resource/file.rb +1 -1
  57. data/lib/chef/resource/gem_package.rb +2 -2
  58. data/lib/chef/resource/homebrew_cask.rb +3 -3
  59. data/lib/chef/resource/hostname.rb +3 -3
  60. data/lib/chef/resource/http_request.rb +1 -1
  61. data/lib/chef/resource/locale.rb +1 -1
  62. data/lib/chef/resource/mdadm.rb +2 -2
  63. data/lib/chef/resource/osx_profile.rb +7 -7
  64. data/lib/chef/resource/remote_directory.rb +1 -1
  65. data/lib/chef/resource/ruby.rb +1 -5
  66. data/lib/chef/resource/ruby_block.rb +1 -1
  67. data/lib/chef/resource/template.rb +2 -2
  68. data/lib/chef/resource/user/windows_user.rb +5 -0
  69. data/lib/chef/resource/windows_certificate.rb +9 -13
  70. data/lib/chef/resource/yum_repository.rb +5 -0
  71. data/lib/chef/resource_collection/resource_set.rb +1 -1
  72. data/lib/chef/util/dsc/configuration_generator.rb +52 -11
  73. data/lib/chef/util/dsc/lcm_output_parser.rb +3 -4
  74. data/lib/chef/util/dsc/local_configuration_manager.rb +17 -14
  75. data/lib/chef/util/dsc/resource_store.rb +5 -11
  76. data/lib/chef/version.rb +1 -1
  77. data/lib/chef/win32/api/file.rb +4 -0
  78. data/spec/data/rubygems.org/latest_specs.4.8.gz +0 -0
  79. data/spec/data/rubygems.org/nonexistent_gem +0 -0
  80. data/spec/data/rubygems.org/sexp_processor +0 -0
  81. data/spec/data/rubygems.org/sexp_processor-4.15.1.gemspec.rz +0 -0
  82. data/spec/data/ssl/binary/chef-rspec-der.cert +0 -0
  83. data/spec/data/ssl/binary/chef-rspec-der.key +0 -0
  84. data/spec/functional/resource/dnf_package_spec.rb +319 -16
  85. data/spec/functional/resource/dsc_script_spec.rb +3 -6
  86. data/spec/functional/resource/windows_certificate_spec.rb +204 -384
  87. data/spec/integration/client/client_spec.rb +2 -1
  88. data/spec/integration/compliance/compliance_spec.rb +81 -0
  89. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -0
  90. data/spec/spec_helper.rb +1 -1
  91. data/spec/unit/client_spec.rb +1 -0
  92. data/spec/unit/compliance/fetcher/automate_spec.rb +134 -0
  93. data/spec/unit/compliance/fetcher/chef_server_spec.rb +93 -0
  94. data/spec/unit/compliance/reporter/automate_spec.rb +427 -0
  95. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +177 -0
  96. data/spec/unit/compliance/reporter/compliance_enforcer_spec.rb +48 -0
  97. data/spec/unit/compliance/runner_spec.rb +167 -0
  98. data/spec/unit/http/ssl_policies_spec.rb +107 -68
  99. data/spec/unit/knife/bootstrap_spec.rb +5 -17
  100. data/spec/unit/knife/core/node_editor_spec.rb +1 -1
  101. data/spec/unit/knife/core/status_presenter_spec.rb +54 -0
  102. data/spec/unit/mixin/openssl_helper_spec.rb +0 -7
  103. data/spec/unit/mixin/powershell_exec_spec.rb +1 -1
  104. data/spec/unit/platform/query_helpers_spec.rb +11 -12
  105. data/spec/unit/provider/dsc_resource_spec.rb +10 -27
  106. data/spec/unit/provider/dsc_script_spec.rb +1 -1
  107. data/spec/unit/provider/mount/windows_spec.rb +1 -0
  108. data/spec/unit/provider/package/freebsd/pkgng_spec.rb +1 -1
  109. data/spec/unit/provider/package/rubygems_spec.rb +39 -7
  110. data/spec/unit/provider/systemd_unit_spec.rb +1 -1
  111. data/spec/unit/resource/user/windows_user_spec.rb +36 -0
  112. data/spec/unit/resource/windows_certificate_spec.rb +12 -0
  113. data/spec/unit/util/dsc/configuration_generator_spec.rb +79 -0
  114. data/spec/unit/util/dsc/local_configuration_manager_spec.rb +27 -35
  115. metadata +55 -18
  116. data/lib/chef/util/powershell/cmdlet.rb +0 -169
  117. data/lib/chef/util/powershell/cmdlet_result.rb +0 -61
  118. data/spec/data/trusted_certs_empty/.gitkeep +0 -0
  119. data/spec/data/trusted_certs_empty/README.md +0 -1
  120. data/spec/functional/util/powershell/cmdlet_spec.rb +0 -111
  121. data/spec/scripts/ssl-serve.rb +0 -47
  122. 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
@@ -317,6 +317,7 @@ class Chef
317
317
  end
318
318
 
319
319
  end
320
+
320
321
  class CookbookManifestVersions
321
322
 
322
323
  extend Chef::Mixin::VersionedAPIFactory
@@ -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
- "but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'"
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
 
@@ -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 = OpenSSL::X509::Certificate.new(File.read(cert_file))
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
- if config[:ssl_client_cert] || config[:ssl_client_key]
92
- unless config[:ssl_client_cert] && config[:ssl_client_key]
93
- raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
94
- end
95
- unless ::File.exists?(config[:ssl_client_cert])
96
- raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
97
- end
98
- unless ::File.exists?(config[:ssl_client_key])
99
- raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
100
- end
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
- http_client.cert = OpenSSL::X509::Certificate.new(::File.read(config[:ssl_client_cert]))
103
- http_client.key = OpenSSL::PKey::RSA.new(::File.read(config[:ssl_client_key]))
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