chef 17.4.38-universal-mingw32 → 17.5.22-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/chef.gemspec +2 -0
  3. data/lib/chef/application/base.rb +11 -1
  4. data/lib/chef/client.rb +1 -2
  5. data/lib/chef/compliance/input.rb +115 -0
  6. data/lib/chef/compliance/input_collection.rb +139 -0
  7. data/lib/chef/compliance/profile.rb +122 -0
  8. data/lib/chef/compliance/profile_collection.rb +109 -0
  9. data/lib/chef/compliance/runner.rb +47 -5
  10. data/lib/chef/compliance/waiver.rb +115 -0
  11. data/lib/chef/compliance/waiver_collection.rb +143 -0
  12. data/lib/chef/dsl/compliance.rb +38 -0
  13. data/lib/chef/dsl/reader_helpers.rb +51 -0
  14. data/lib/chef/dsl/recipe.rb +4 -2
  15. data/lib/chef/dsl/secret.rb +2 -4
  16. data/lib/chef/dsl/universal.rb +2 -0
  17. data/lib/chef/event_dispatch/base.rb +44 -2
  18. data/lib/chef/formatters/doc.rb +46 -0
  19. data/lib/chef/http/basic_client.rb +15 -7
  20. data/lib/chef/http.rb +7 -3
  21. data/lib/chef/provider/file.rb +2 -0
  22. data/lib/chef/provider/link.rb +2 -2
  23. data/lib/chef/provider/registry_key.rb +3 -2
  24. data/lib/chef/provider/remote_file/http.rb +1 -1
  25. data/lib/chef/provider/template.rb +1 -1
  26. data/lib/chef/resource/archive_file.rb +17 -14
  27. data/lib/chef/resource/chef_client_scheduled_task.rb +45 -2
  28. data/lib/chef/resource/chocolatey_config.rb +13 -13
  29. data/lib/chef/resource/file/verification/json.rb +50 -0
  30. data/lib/chef/resource/file/verification/yaml.rb +52 -0
  31. data/lib/chef/resource/inspec_input.rb +128 -0
  32. data/lib/chef/resource/inspec_waiver.rb +185 -0
  33. data/lib/chef/resource/mount.rb +1 -1
  34. data/lib/chef/resource/registry_key.rb +36 -48
  35. data/lib/chef/resource/remote_file.rb +98 -2
  36. data/lib/chef/resource/timezone.rb +2 -2
  37. data/lib/chef/resource/user_ulimit.rb +1 -0
  38. data/lib/chef/resource/windows_printer.rb +1 -1
  39. data/lib/chef/resource/windows_uac.rb +3 -1
  40. data/lib/chef/resource/windows_user_privilege.rb +1 -1
  41. data/lib/chef/resources.rb +2 -0
  42. data/lib/chef/run_context/cookbook_compiler.rb +112 -28
  43. data/lib/chef/run_context.rb +31 -1
  44. data/lib/chef/secret_fetcher/akeyless_vault.rb +57 -0
  45. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +1 -1
  46. data/lib/chef/secret_fetcher/azure_key_vault.rb +1 -1
  47. data/lib/chef/secret_fetcher/base.rb +1 -1
  48. data/lib/chef/secret_fetcher/hashi_vault.rb +100 -0
  49. data/lib/chef/secret_fetcher.rb +8 -2
  50. data/lib/chef/version.rb +1 -1
  51. data/spec/data/archive_file/test_archive.tar.gz +0 -0
  52. data/spec/functional/resource/archive_file_spec.rb +87 -0
  53. data/spec/functional/resource/group_spec.rb +5 -1
  54. data/spec/functional/resource/link_spec.rb +8 -0
  55. data/spec/integration/compliance/compliance_spec.rb +60 -0
  56. data/spec/spec_helper.rb +3 -0
  57. data/spec/support/platform_helpers.rb +4 -0
  58. data/spec/support/ruby_installer.rb +51 -0
  59. data/spec/unit/compliance/input_spec.rb +104 -0
  60. data/spec/unit/compliance/profile_spec.rb +120 -0
  61. data/spec/unit/compliance/waiver_spec.rb +104 -0
  62. data/spec/unit/http/basic_client_spec.rb +30 -0
  63. data/spec/unit/http_spec.rb +8 -2
  64. data/spec/unit/provider/link_spec.rb +13 -7
  65. data/spec/unit/provider/remote_file/http_spec.rb +10 -0
  66. data/spec/unit/provider/template_spec.rb +2 -2
  67. data/spec/unit/resource/archive_file_spec.rb +414 -3
  68. data/spec/unit/resource/chef_client_scheduled_task_spec.rb +69 -0
  69. data/spec/unit/resource/file/verification/json_spec.rb +72 -0
  70. data/spec/unit/resource/file/verification/yaml_spec.rb +67 -0
  71. data/spec/unit/resource/inspec_input_spec.rb +300 -0
  72. data/spec/unit/resource/inspec_waiver_spec.rb +312 -0
  73. data/spec/unit/resource/mount_spec.rb +10 -0
  74. data/spec/unit/resource/user_ulimit_spec.rb +14 -1
  75. data/spec/unit/secret_fetcher/akeyless_vault_spec.rb +37 -0
  76. data/spec/unit/secret_fetcher/hashi_vault_spec.rb +80 -0
  77. data/tasks/rspec.rb +2 -1
  78. metadata +60 -6
@@ -18,6 +18,7 @@
18
18
 
19
19
  require_relative "../resource"
20
20
  require_relative "../digester"
21
+ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
21
22
 
22
23
  class Chef
23
24
  class Resource
@@ -26,7 +27,7 @@ class Chef
26
27
 
27
28
  provides(:registry_key) { true }
28
29
 
29
- description "Use the **registry_key** resource to create and delete registry keys in Microsoft Windows."
30
+ description "Use the **registry_key** resource to create and delete registry keys in Microsoft Windows. Note: 64-bit versions of Microsoft Windows have a 32-bit compatibility layer in the registry that reflects and redirects certain keys (and their values) into specific locations (or logical views) of the registry hive.\n\n#{ChefUtils::Dist::Infra::PRODUCT} can access any reflected or redirected registry key. The machine architecture of the system on which #{ChefUtils::Dist::Infra::PRODUCT} is running is used as the default (non-redirected) location. Access to the SysWow64 location is redirected must be specified. Typically, this is only necessary to ensure compatibility with 32-bit applications that are running on a 64-bit operating system.\n\nFor more information, see: [Registry Reflection](https://docs.microsoft.com/en-us/windows/win32/winprog64/registry-reflection)."
30
31
  examples <<~'DOC'
31
32
  **Create a registry key**
32
33
 
@@ -66,7 +67,7 @@ class Chef
66
67
  end
67
68
  ```
68
69
 
69
- **Set proxy settings to be the same as those used by Chef Infra Client**
70
+ **Set proxy settings to be the same as those used by #{ChefUtils::Dist::Infra::PRODUCT}**
70
71
 
71
72
  ```ruby
72
73
  proxy = URI.parse(Chef::Config[:http_proxy])
@@ -115,14 +116,42 @@ class Chef
115
116
  end
116
117
  ```
117
118
 
118
- Note: Be careful when using the :delete_key action with the recursive attribute. This will delete the registry key, all of its values and all of the names, types, and data associated with them. This cannot be undone by Chef Infra Client.
119
+ Note: Be careful when using the :delete_key action with the recursive attribute. This will delete the registry key, all of its values and all of the names, types, and data associated with them. This cannot be undone by #{ChefUtils::Dist::Infra::PRODUCT}.
119
120
  DOC
120
121
 
121
- state_attrs :values
122
-
123
122
  default_action :create
124
123
  allowed_actions :create, :create_if_missing, :delete, :delete_key
125
124
 
125
+ VALID_VALUE_HASH_KEYS = %i{name type data}.freeze
126
+
127
+ property :key, String, name_property: true
128
+ property :values, [Hash, Array],
129
+ default: [],
130
+ coerce: proc { |v|
131
+ @unscrubbed_values =
132
+ case v
133
+ when Hash
134
+ [ Mash.new(v).symbolize_keys ]
135
+ when Array
136
+ v.map { |value| Mash.new(value).symbolize_keys }
137
+ else
138
+ raise ArgumentError, "Bad type for RegistryKey resource, use Hash or Array"
139
+ end
140
+ scrub_values(@unscrubbed_values)
141
+ },
142
+ callbacks: {
143
+ "Missing name key in RegistryKey values hash" => lambda { |v| v.all? { |value| value.key?(:name) } },
144
+ "Bad key in RegistryKey values hash. Should be one of: #{VALID_VALUE_HASH_KEYS}" => lambda do |v|
145
+ v.all? do |value|
146
+ value.keys.all? { |key| VALID_VALUE_HASH_KEYS.include?(key) }
147
+ end
148
+ end,
149
+ "Type of name should be a string" => lambda { |v| v.all? { |value| value[:name].is_a?(String) } },
150
+ "Type of type should be a symbol" => lambda { |v| v.all? { |value| value[:type] ? value[:type].is_a?(Symbol) : true } },
151
+ }
152
+ property :recursive, [TrueClass, FalseClass], default: false
153
+ property :architecture, Symbol, default: :machine, equal_to: %i{machine x86_64 i386}
154
+
126
155
  # Some registry key data types may not be safely reported as json.
127
156
  # Example (CHEF-5323):
128
157
  #
@@ -152,51 +181,10 @@ class Chef
152
181
  # may want to extend the state_attrs API with the ability to rename POST'd attrs.
153
182
  #
154
183
  # See lib/chef/resource_reporter.rb for more information.
155
- attr_reader :unscrubbed_values
156
-
157
- def initialize(name, run_context = nil)
158
- super
159
- @values, @unscrubbed_values = [], []
160
- end
161
-
162
- property :key, String, name_property: true
163
-
164
- VALID_VALUE_HASH_KEYS = %i{name type data}.freeze
165
-
166
- def values(arg = nil)
167
- if not arg.nil?
168
- if arg.is_a?(Hash)
169
- @values = [ Mash.new(arg).symbolize_keys ]
170
- elsif arg.is_a?(Array)
171
- @values = []
172
- arg.each do |value|
173
- @values << Mash.new(value).symbolize_keys
174
- end
175
- else
176
- raise ArgumentError, "Bad type for RegistryKey resource, use Hash or Array"
177
- end
178
-
179
- @values.each do |v|
180
- raise ArgumentError, "Missing name key in RegistryKey values hash" unless v.key?(:name)
181
-
182
- v.each_key do |key|
183
- raise ArgumentError, "Bad key #{key} in RegistryKey values hash" unless VALID_VALUE_HASH_KEYS.include?(key)
184
- end
185
- raise ArgumentError, "Type of name => #{v[:name]} should be string" unless v[:name].is_a?(String)
186
-
187
- if v[:type]
188
- raise ArgumentError, "Type of type => #{v[:type]} should be symbol" unless v[:type].is_a?(Symbol)
189
- end
190
- end
191
- @unscrubbed_values = @values
192
- elsif instance_variable_defined?(:@values)
193
- scrub_values(@values)
194
- end
184
+ def unscrubbed_values
185
+ @unscrubbed_values ||= []
195
186
  end
196
187
 
197
- property :recursive, [TrueClass, FalseClass], default: false
198
- property :architecture, Symbol, default: :machine, equal_to: %i{machine x86_64 i386}
199
-
200
188
  private
201
189
 
202
190
  def scrub_values(values)
@@ -34,6 +34,78 @@ class Chef
34
34
 
35
35
  description "Use the **remote_file** resource to transfer a file from a remote location using file specificity. This resource is similar to the **file** resource. Note: Fetching files from the `files/` directory in a cookbook should be done with the **cookbook_file** resource."
36
36
 
37
+ examples <<~'DOC'
38
+ **Download a file without checking the checksum**:
39
+
40
+ ```ruby
41
+ remote_file '/tmp/remote.txt' do
42
+ source 'https://example.org/remote.txt'
43
+ end
44
+ ```
45
+
46
+ **Download a file with a checksum to validate**:
47
+
48
+ ```ruby
49
+ remote_file '/tmp/test_file' do
50
+ source 'http://www.example.com/tempfiles/test_file'
51
+ mode '0755'
52
+ checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file.
53
+ end
54
+ ```
55
+
56
+ **Download a file only if it's not already present**:
57
+
58
+ ```ruby
59
+ remote_file '/tmp/remote.txt' do
60
+ source 'https://example.org/remote.txt'
61
+ checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file.
62
+ action :create_if_missing
63
+ end
64
+ ```
65
+
66
+ **Using HTTP Basic Authentication in Headers**:
67
+
68
+ ```ruby
69
+ remote_file '/tmp/remote.txt' do
70
+ source 'https://example.org/remote.txt'
71
+ headers('Authorization' => "Basic #{Base64.encode64("USERNAME_VALUE:PASSWORD_VALUE").delete("\n")}")
72
+ checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file.
73
+ action :create_if_missing
74
+ end
75
+ ```
76
+
77
+ **Downloading a file to the Chef file cache dir for execution**:
78
+
79
+ ```ruby
80
+ remote_file '#{Chef::Config['file_cache_path']}/install.sh' do
81
+ source 'https://example.org/install.sh'
82
+ action :create_if_missing
83
+ end
84
+
85
+ execute '#{Chef::Config['file_cache_path']}/install.sh'
86
+ ```
87
+
88
+ **Specify advanced HTTP connection options including Net::HTTP (nethttp) options:**
89
+
90
+ ```ruby
91
+ remote_file '/tmp/remote.txt' do
92
+ source 'https://example.org/remote.txt'
93
+ http_options({
94
+ http_retry_delay: 0,
95
+ http_retry_count: 0,
96
+ keepalives: false,
97
+ nethttp: {
98
+ continue_timeout: 5,
99
+ max_retries: 5,
100
+ read_timeout: 5,
101
+ write_timeout: 5,
102
+ ssl_timeout: 5,
103
+ },
104
+ })
105
+ end
106
+ ```
107
+ DOC
108
+
37
109
  def initialize(name, run_context = nil)
38
110
  super
39
111
  @source = []
@@ -96,9 +168,29 @@ class Chef
96
168
  description: "Whether #{ChefUtils::Dist::Infra::PRODUCT} uses active or passive FTP. Set to `true` to use active FTP."
97
169
 
98
170
  property :headers, Hash, default: {},
99
- description: "A Hash of custom HTTP headers."
171
+ description: <<~'DOCS'
172
+ A Hash of custom headers. For example:
173
+
174
+ ```ruby
175
+ headers({ "Cookie" => "user=some_user; pass=p@ssw0rd!" })
176
+ ```
100
177
 
101
- property :show_progress, [ TrueClass, FalseClass ], default: false
178
+ or:
179
+
180
+ ```ruby
181
+ headers({ "Referer" => "#{header}" })
182
+ ```
183
+
184
+ or:
185
+
186
+ ```ruby
187
+ headers( "Authorization"=>"Basic #{ Base64.encode64("#{username}:#{password}").gsub("\n", "") }" )
188
+ ```
189
+ DOCS
190
+
191
+ property :show_progress, [ TrueClass, FalseClass ],
192
+ description: "Displays the progress of the file download.",
193
+ default: false
102
194
 
103
195
  property :ssl_verify_mode, Symbol, equal_to: %i{verify_none verify_peer},
104
196
  introduced: "16.2",
@@ -118,6 +210,10 @@ class Chef
118
210
 
119
211
  property :authentication, Symbol, equal_to: %i{remote local}, default: :remote
120
212
 
213
+ property :http_options, Hash, default: {},
214
+ introduced: "17.5",
215
+ description: "A Hash of custom HTTP options. For example: `http_options({ http_retry_count: 0, http_retry_delay: 2 })`"
216
+
121
217
  def after_created
122
218
  validate_identity_platform(remote_user, remote_password, remote_domain)
123
219
  identity = qualify_user(remote_user, remote_password, remote_domain)
@@ -38,7 +38,7 @@ class Chef
38
38
  **Set the timezone to America/Los_Angeles with a friendly resource name on Linux/macOS**
39
39
 
40
40
  ```ruby
41
- timezone 'Set the host's timezone to America/Los_Angeles' do
41
+ timezone "Set the host's timezone to America/Los_Angeles" do
42
42
  timezone 'America/Los_Angeles'
43
43
  end
44
44
  ```
@@ -46,7 +46,7 @@ class Chef
46
46
  **Set the timezone to PST with a friendly resource name on Windows**
47
47
 
48
48
  ```ruby
49
- timezone 'Set the host's timezone to PST' do
49
+ timezone "Set the host's timezone to PST" do
50
50
  timezone 'Pacific Standard time'
51
51
  end
52
52
  ```
@@ -83,6 +83,7 @@ class Chef
83
83
  source ::File.expand_path("support/ulimit.erb", __dir__)
84
84
  local true
85
85
  mode "0644"
86
+ sensitive new_resource.sensitive
86
87
  variables(
87
88
  ulimit_user: new_resource.username,
88
89
  filehandle_limit: new_resource.filehandle_limit,
@@ -33,7 +33,7 @@ class Chef
33
33
 
34
34
  provides(:windows_printer) { true }
35
35
 
36
- description "Use the **windows_printer** resource to setup Windows printers. This resource will automatically install the driver specified in the `driver_name` property and will automatically create a printer port using either the `ipv4_address` property or the `port_name property."
36
+ description "Use the **windows_printer** resource to setup Windows printers. This resource will automatically install the driver specified in the `driver_name` property and will automatically create a printer port using either the `ipv4_address` property or the `port_name` property."
37
37
  introduced "14.0"
38
38
  examples <<~DOC
39
39
  **Create a printer**:
@@ -104,7 +104,9 @@ class Chef
104
104
  #
105
105
  # @return [Integer]
106
106
  def consent_behavior_users_symbol_to_reg(sym)
107
- %i{auto_deny secure_prompt_for_creds prompt_for_creds}.index(sym)
107
+ # Since 2 isn't a valid value for ConsentPromptBehaviorUser, assign the value at index as nil.
108
+ # https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#registry-key-settings
109
+ [:auto_deny, :secure_prompt_for_creds, nil, :prompt_for_creds].index(sym)
108
110
  end
109
111
  end
110
112
  end
@@ -139,7 +139,7 @@ class Chef
139
139
  coerce: proc { |v| Array(v) },
140
140
  callbacks: {
141
141
  "Privilege property restricted to the following values: #{PRIVILEGE_OPTS}" => lambda { |n| (n - PRIVILEGE_OPTS).empty? },
142
- }
142
+ }, identity: true
143
143
 
144
144
  load_current_value do |new_resource|
145
145
  if new_resource.principal && (new_resource.action.include?(:add) || new_resource.action.include?(:remove))
@@ -73,6 +73,8 @@ require_relative "resource/homebrew_package"
73
73
  require_relative "resource/homebrew_tap"
74
74
  require_relative "resource/homebrew_update"
75
75
  require_relative "resource/ifconfig"
76
+ require_relative "resource/inspec_input"
77
+ require_relative "resource/inspec_waiver"
76
78
  require_relative "resource/inspec_waiver_file_entry"
77
79
  require_relative "resource/kernel_module"
78
80
  require_relative "resource/ksh"
@@ -32,6 +32,7 @@ class Chef
32
32
  attr_reader :events
33
33
  attr_reader :run_list_expansion
34
34
  attr_reader :logger
35
+ attr_reader :run_context
35
36
 
36
37
  def initialize(run_context, run_list_expansion, events)
37
38
  @run_context = run_context
@@ -43,23 +44,51 @@ class Chef
43
44
 
44
45
  # Chef::Node object for the current run.
45
46
  def node
46
- @run_context.node
47
+ run_context.node
47
48
  end
48
49
 
49
50
  # Chef::CookbookCollection object for the current run
50
51
  def cookbook_collection
51
- @run_context.cookbook_collection
52
+ run_context.cookbook_collection
52
53
  end
53
54
 
54
55
  # Resource Definitions from the compiled cookbooks. This is populated by
55
56
  # calling #compile_resource_definitions (which is called by #compile)
56
57
  def definitions
57
- @run_context.definitions
58
+ run_context.definitions
59
+ end
60
+
61
+ # The global waiver_collection hanging off of the run_context, used by
62
+ # compile_compliance and the compliance phase that runs inspec
63
+ #
64
+ # @returns [Chef::Compliance::WaiverCollection]
65
+ #
66
+ def waiver_collection
67
+ run_context.waiver_collection
68
+ end
69
+
70
+ # The global input_collection hanging off of the run_context, used by
71
+ # compile_compliance and the compliance phase that runs inspec
72
+ #
73
+ # @returns [Chef::Compliance::inputCollection]
74
+ #
75
+ def input_collection
76
+ run_context.input_collection
77
+ end
78
+
79
+ # The global profile_collection hanging off of the run_context, used by
80
+ # compile_compliance and the compliance phase that runs inspec
81
+ #
82
+ # @returns [Chef::Compliance::ProfileCollection]
83
+ #
84
+ def profile_collection
85
+ run_context.profile_collection
58
86
  end
59
87
 
60
88
  # Run the compile phase of the chef run. Loads files in the following order:
61
89
  # * Libraries
62
90
  # * Ohai
91
+ # * Compliance Profiles/Waivers
63
92
  # * Attributes
64
93
  # * LWRPs
65
94
  # * Resource Definitions
@@ -73,6 +102,7 @@ class Chef
73
102
  def compile
74
103
  compile_libraries
75
104
  compile_ohai_plugins
105
+ compile_compliance
76
106
  compile_attributes
77
107
  compile_lwrps
78
108
  compile_resource_definitions
@@ -98,7 +128,7 @@ class Chef
98
128
 
99
129
  # Loads library files from cookbooks according to #cookbook_order.
100
130
  def compile_libraries
101
- @events.library_load_start(count_files_by_segment(:libraries))
131
+ events.library_load_start(count_files_by_segment(:libraries))
102
132
  cookbook_order.each do |cookbook|
103
133
  eager_load_libraries = cookbook_collection[cookbook].metadata.eager_load_libraries
104
134
  if eager_load_libraries == true # actually true, not truthy
@@ -110,14 +140,14 @@ class Chef
110
140
  end
111
141
  end
112
142
  end
113
- @events.library_load_complete
143
+ events.library_load_complete
114
144
  end
115
145
 
116
146
  # Loads Ohai Plugins from cookbooks, and ensure any old ones are
117
147
  # properly cleaned out
118
148
  def compile_ohai_plugins
119
149
  ohai_plugin_count = count_files_by_segment(:ohai)
120
- @events.ohai_plugin_load_start(ohai_plugin_count)
150
+ events.ohai_plugin_load_start(ohai_plugin_count)
121
151
  FileUtils.rm_rf(Chef::Config[:ohai_segment_plugin_path])
122
152
 
123
153
  cookbook_order.each do |cookbook|
@@ -131,57 +161,81 @@ class Chef
131
161
  node.consume_ohai_data(ohai)
132
162
  end
133
163
 
134
- @events.ohai_plugin_load_complete
164
+ events.ohai_plugin_load_complete
165
+ end
166
+
167
+ # Loads the compliance segment files from the cookbook into the collections
168
+ # hanging off of the run_context, for later use in the compliance phase
169
+ # inspec run.
170
+ #
171
+ def compile_compliance
172
+ events.compliance_load_start
173
+ events.profiles_load_start
174
+ cookbook_order.each do |cookbook|
175
+ load_profiles_from_cookbook(cookbook)
176
+ end
177
+ events.profiles_load_complete
178
+ events.inputs_load_start
179
+ cookbook_order.each do |cookbook|
180
+ load_inputs_from_cookbook(cookbook)
181
+ end
182
+ events.inputs_load_complete
183
+ events.waivers_load_start
184
+ cookbook_order.each do |cookbook|
185
+ load_waivers_from_cookbook(cookbook)
186
+ end
187
+ events.waivers_load_complete
188
+ events.compliance_load_complete
135
189
  end
136
190
 
137
191
  # Loads attributes files from cookbooks. Attributes files are loaded
138
192
  # according to #cookbook_order; within a cookbook, +default.rb+ is loaded
139
193
  # first, then the remaining attributes files in lexical sort order.
140
194
  def compile_attributes
141
- @events.attribute_load_start(count_files_by_segment(:attributes, "attributes.rb"))
195
+ events.attribute_load_start(count_files_by_segment(:attributes, "attributes.rb"))
142
196
  cookbook_order.each do |cookbook|
143
197
  load_attributes_from_cookbook(cookbook)
144
198
  end
145
- @events.attribute_load_complete
199
+ events.attribute_load_complete
146
200
  end
147
201
 
148
202
  # Loads LWRPs according to #cookbook_order. Providers are loaded before
149
203
  # resources on a cookbook-wise basis.
150
204
  def compile_lwrps
151
205
  lwrp_file_count = count_files_by_segment(:providers) + count_files_by_segment(:resources)
152
- @events.lwrp_load_start(lwrp_file_count)
206
+ events.lwrp_load_start(lwrp_file_count)
153
207
  cookbook_order.each do |cookbook|
154
208
  load_lwrps_from_cookbook(cookbook)
155
209
  end
156
- @events.lwrp_load_complete
210
+ events.lwrp_load_complete
157
211
  end
158
212
 
159
213
  # Loads resource definitions according to #cookbook_order
160
214
  def compile_resource_definitions
161
- @events.definition_load_start(count_files_by_segment(:definitions))
215
+ events.definition_load_start(count_files_by_segment(:definitions))
162
216
  cookbook_order.each do |cookbook|
163
217
  load_resource_definitions_from_cookbook(cookbook)
164
218
  end
165
- @events.definition_load_complete
219
+ events.definition_load_complete
166
220
  end
167
221
 
168
222
  # Iterates over the expanded run_list, loading each recipe in turn.
169
223
  def compile_recipes
170
- @events.recipe_load_start(run_list_expansion.recipes.size)
224
+ events.recipe_load_start(run_list_expansion.recipes.size)
171
225
  run_list_expansion.recipes.each do |recipe|
172
226
 
173
227
  path = resolve_recipe(recipe)
174
- @run_context.load_recipe(recipe)
175
- @events.recipe_file_loaded(path, recipe)
228
+ run_context.load_recipe(recipe)
229
+ events.recipe_file_loaded(path, recipe)
176
230
  rescue Chef::Exceptions::RecipeNotFound => e
177
- @events.recipe_not_found(e)
231
+ events.recipe_not_found(e)
178
232
  raise
179
233
  rescue Exception => e
180
- @events.recipe_file_load_failed(path, e, recipe)
234
+ events.recipe_file_load_failed(path, e, recipe)
181
235
  raise
182
236
 
183
237
  end
184
- @events.recipe_load_complete
238
+ events.recipe_load_complete
185
239
  end
186
240
 
187
241
  # Whether or not a cookbook is reachable from the set of cookbook given
@@ -225,7 +279,7 @@ class Chef
225
279
  attr_file_basename = ::File.basename(filename, ".rb")
226
280
  node.include_attribute("#{cookbook_name}::#{attr_file_basename}")
227
281
  rescue Exception => e
228
- @events.attribute_file_load_failed(filename, e)
282
+ events.attribute_file_load_failed(filename, e)
229
283
  raise
230
284
  end
231
285
 
@@ -234,9 +288,9 @@ class Chef
234
288
 
235
289
  logger.trace("Loading cookbook #{cookbook_name}'s library file: #{filename}")
236
290
  Kernel.require(filename)
237
- @events.library_file_loaded(filename)
291
+ events.library_file_loaded(filename)
238
292
  rescue Exception => e
239
- @events.library_file_load_failed(filename, e)
293
+ events.library_file_load_failed(filename, e)
240
294
  raise
241
295
 
242
296
  end
@@ -260,18 +314,18 @@ class Chef
260
314
  def load_lwrp_provider(cookbook_name, filename)
261
315
  logger.trace("Loading cookbook #{cookbook_name}'s providers from #{filename}")
262
316
  Chef::Provider::LWRPBase.build_from_file(cookbook_name, filename, self)
263
- @events.lwrp_file_loaded(filename)
317
+ events.lwrp_file_loaded(filename)
264
318
  rescue Exception => e
265
- @events.lwrp_file_load_failed(filename, e)
319
+ events.lwrp_file_load_failed(filename, e)
266
320
  raise
267
321
  end
268
322
 
269
323
  def load_lwrp_resource(cookbook_name, filename)
270
324
  logger.trace("Loading cookbook #{cookbook_name}'s resources from #{filename}")
271
325
  Chef::Resource::LWRPBase.build_from_file(cookbook_name, filename, self)
272
- @events.lwrp_file_loaded(filename)
326
+ events.lwrp_file_loaded(filename)
273
327
  rescue Exception => e
274
- @events.lwrp_file_load_failed(filename, e)
328
+ events.lwrp_file_load_failed(filename, e)
275
329
  raise
276
330
  end
277
331
 
@@ -288,6 +342,36 @@ class Chef
288
342
  end
289
343
  end
290
344
 
345
+ # Load the compliance segment files from a single cookbook
346
+ #
347
+ def load_profiles_from_cookbook(cookbook_name)
348
+ # This identifies profiles by their inspec.yml file, we recurse into subdirs so the profiles may be deeply
349
+ # nested in a subdir structure for organization. You could have profiles inside of profiles but
350
+ # since that is not coherently defined, you should not.
351
+ #
352
+ each_file_in_cookbook_by_segment(cookbook_name, :compliance, [ "profiles/**/inspec.{yml,yaml}" ]) do |filename|
353
+ profile_collection.from_file(filename, cookbook_name)
354
+ end
355
+ end
356
+
357
+ def load_waivers_from_cookbook(cookbook_name)
358
+ # This identifies waiver files as any yaml files under the waivers subdir. We recurse into subdirs as well
359
+ # so that waivers may be nested in subdirs for organization. Any other files are ignored.
360
+ #
361
+ each_file_in_cookbook_by_segment(cookbook_name, :compliance, [ "waivers/**/*.{yml,yaml}" ]) do |filename|
362
+ waiver_collection.from_file(filename, cookbook_name)
363
+ end
364
+ end
365
+
366
+ def load_inputs_from_cookbook(cookbook_name)
367
+ # This identifies input files as any yaml files under the inputs subdir. We recurse into subdirs as well
368
+ # so that inputs may be nested in subdirs for organization. Any other files are ignored.
369
+ #
370
+ each_file_in_cookbook_by_segment(cookbook_name, :compliance, [ "inputs/**/*.{yml,yaml}" ]) do |filename|
371
+ input_collection.from_file(filename, cookbook_name)
372
+ end
373
+ end
374
+
291
375
  def load_resource_definitions_from_cookbook(cookbook_name)
292
376
  files_in_cookbook_by_segment(cookbook_name, :definitions).each do |filename|
293
377
  next unless File.extname(filename) == ".rb"
@@ -300,9 +384,9 @@ class Chef
300
384
  logger.info("Overriding duplicate definition #{key}, new definition found in #{filename}")
301
385
  newval
302
386
  end
303
- @events.definition_file_loaded(filename)
387
+ events.definition_file_loaded(filename)
304
388
  rescue Exception => e
305
- @events.definition_file_load_failed(filename, e)
389
+ events.definition_file_load_failed(filename, e)
306
390
  raise
307
391
  end
308
392
  end
@@ -25,6 +25,9 @@ require_relative "log"
25
25
  require_relative "recipe"
26
26
  require_relative "run_context/cookbook_compiler"
27
27
  require_relative "event_dispatch/events_output_stream"
28
+ require_relative "compliance/input_collection"
29
+ require_relative "compliance/waiver_collection"
30
+ require_relative "compliance/profile_collection"
28
31
  require_relative "train_transport"
29
32
  require_relative "exceptions"
30
33
  require "forwardable" unless defined?(Forwardable)
@@ -120,10 +123,28 @@ class Chef
120
123
 
121
124
  # Handle to the global action_collection of executed actions for reporting / data_collector /etc
122
125
  #
123
- # @return [Chef::ActionCollection
126
+ # @return [Chef::ActionCollection]
124
127
  #
125
128
  attr_accessor :action_collection
126
129
 
130
+ # Handle to the global profile_collection of inspec profiles for the compliance phase
131
+ #
132
+ # @return [Chef::Compliance::ProfileCollection]
133
+ #
134
+ attr_accessor :profile_collection
135
+
136
+ # Handle to the global waiver_collection of inspec waiver files for the compliance phase
137
+ #
138
+ # @return [Chef::Compliance::WaiverCollection]
139
+ #
140
+ attr_accessor :waiver_collection
141
+
142
+ # Handle to the global input_collection of inspec input files for the compliance phase
143
+ #
144
+ # @return [Chef::Compliance::inputCollection]
145
+ #
146
+ attr_accessor :input_collection
147
+
127
148
  # Pointer back to the Chef::Runner that created this
128
149
  #
129
150
  attr_accessor :runner
@@ -198,6 +219,9 @@ class Chef
198
219
  @loaded_attributes_hash = {}
199
220
  @reboot_info = {}
200
221
  @cookbook_compiler = nil
222
+ @input_collection = Chef::Compliance::InputCollection.new(events)
223
+ @waiver_collection = Chef::Compliance::WaiverCollection.new(events)
224
+ @profile_collection = Chef::Compliance::ProfileCollection.new(events)
201
225
 
202
226
  initialize_child_state
203
227
  end
@@ -674,6 +698,8 @@ class Chef
674
698
  events=
675
699
  has_cookbook_file_in_cookbook?
676
700
  has_template_in_cookbook?
701
+ input_collection
702
+ input_collection=
677
703
  load
678
704
  loaded_attribute
679
705
  loaded_attributes
@@ -688,6 +714,8 @@ class Chef
688
714
  node
689
715
  node=
690
716
  open_stream
717
+ profile_collection
718
+ profile_collection=
691
719
  reboot_info
692
720
  reboot_info=
693
721
  reboot_requested?
@@ -700,6 +728,8 @@ class Chef
700
728
  transport
701
729
  transport_connection
702
730
  unreachable_cookbook?
731
+ waiver_collection
732
+ waiver_collection=
703
733
  }
704
734
 
705
735
  def initialize(parent_run_context)