chef 17.4.38-universal-mingw32 → 17.7.22-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/chef.gemspec +3 -0
  4. data/lib/chef/application/base.rb +11 -1
  5. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  6. data/lib/chef/chef_fs/path_utils.rb +1 -1
  7. data/lib/chef/client.rb +1 -2
  8. data/lib/chef/compliance/input.rb +115 -0
  9. data/lib/chef/compliance/input_collection.rb +139 -0
  10. data/lib/chef/compliance/profile.rb +122 -0
  11. data/lib/chef/compliance/profile_collection.rb +109 -0
  12. data/lib/chef/compliance/runner.rb +47 -5
  13. data/lib/chef/compliance/waiver.rb +115 -0
  14. data/lib/chef/compliance/waiver_collection.rb +143 -0
  15. data/lib/chef/data_collector/run_end_message.rb +1 -1
  16. data/lib/chef/dsl/compliance.rb +38 -0
  17. data/lib/chef/dsl/reader_helpers.rb +51 -0
  18. data/lib/chef/dsl/reboot_pending.rb +1 -1
  19. data/lib/chef/dsl/recipe.rb +4 -2
  20. data/lib/chef/dsl/secret.rb +2 -4
  21. data/lib/chef/dsl/universal.rb +2 -0
  22. data/lib/chef/event_dispatch/base.rb +44 -2
  23. data/lib/chef/exceptions.rb +10 -0
  24. data/lib/chef/formatters/doc.rb +46 -0
  25. data/lib/chef/http/basic_client.rb +15 -7
  26. data/lib/chef/http.rb +7 -3
  27. data/lib/chef/provider/cron.rb +4 -1
  28. data/lib/chef/provider/file.rb +2 -0
  29. data/lib/chef/provider/git.rb +1 -1
  30. data/lib/chef/provider/ifconfig/debian.rb +1 -1
  31. data/lib/chef/provider/link.rb +2 -2
  32. data/lib/chef/provider/registry_key.rb +3 -2
  33. data/lib/chef/provider/remote_file/http.rb +1 -1
  34. data/lib/chef/provider/subversion.rb +5 -5
  35. data/lib/chef/provider/template.rb +1 -1
  36. data/lib/chef/resource/archive_file.rb +17 -14
  37. data/lib/chef/resource/chef_client_scheduled_task.rb +45 -2
  38. data/lib/chef/resource/chocolatey_config.rb +14 -14
  39. data/lib/chef/resource/chocolatey_feature.rb +1 -1
  40. data/lib/chef/resource/chocolatey_source.rb +24 -2
  41. data/lib/chef/resource/directory.rb +1 -1
  42. data/lib/chef/resource/file/verification/json.rb +50 -0
  43. data/lib/chef/resource/file/verification/yaml.rb +52 -0
  44. data/lib/chef/resource/habitat_install.rb +3 -3
  45. data/lib/chef/resource/inspec_input.rb +127 -0
  46. data/lib/chef/resource/inspec_waiver.rb +184 -0
  47. data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
  48. data/lib/chef/resource/kernel_module.rb +27 -2
  49. data/lib/chef/resource/macos_userdefaults.rb +43 -128
  50. data/lib/chef/resource/mount.rb +1 -1
  51. data/lib/chef/resource/openssl_x509_certificate.rb +1 -1
  52. data/lib/chef/resource/powershell_package_source.rb +234 -70
  53. data/lib/chef/resource/registry_key.rb +36 -48
  54. data/lib/chef/resource/remote_file.rb +98 -2
  55. data/lib/chef/resource/timezone.rb +2 -2
  56. data/lib/chef/resource/user_ulimit.rb +1 -0
  57. data/lib/chef/resource/windows_auto_run.rb +1 -1
  58. data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
  59. data/lib/chef/resource/windows_printer.rb +1 -1
  60. data/lib/chef/resource/windows_uac.rb +3 -1
  61. data/lib/chef/resource/windows_update_settings.rb +3 -3
  62. data/lib/chef/resource/windows_user_privilege.rb +1 -1
  63. data/lib/chef/resource.rb +1 -1
  64. data/lib/chef/resource_reporter.rb +1 -1
  65. data/lib/chef/resources.rb +2 -0
  66. data/lib/chef/run_context/cookbook_compiler.rb +112 -28
  67. data/lib/chef/run_context.rb +31 -1
  68. data/lib/chef/secret_fetcher/akeyless_vault.rb +57 -0
  69. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +1 -1
  70. data/lib/chef/secret_fetcher/azure_key_vault.rb +63 -9
  71. data/lib/chef/secret_fetcher/base.rb +1 -1
  72. data/lib/chef/secret_fetcher/hashi_vault.rb +100 -0
  73. data/lib/chef/secret_fetcher.rb +8 -3
  74. data/lib/chef/version.rb +1 -1
  75. data/lib/chef/win32/version.rb +2 -1
  76. data/spec/data/archive_file/test_archive.tar.gz +0 -0
  77. data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
  78. data/spec/functional/dsl/registry_helper_spec.rb +1 -1
  79. data/spec/functional/resource/archive_file_spec.rb +87 -0
  80. data/spec/functional/resource/dsc_script_spec.rb +2 -2
  81. data/spec/functional/resource/group_spec.rb +5 -1
  82. data/spec/functional/resource/link_spec.rb +8 -0
  83. data/spec/functional/resource/macos_userdefaults_spec.rb +119 -0
  84. data/spec/functional/resource/powershell_package_source_spec.rb +5 -6
  85. data/spec/functional/resource/registry_spec.rb +81 -81
  86. data/spec/functional/win32/registry_spec.rb +8 -8
  87. data/spec/integration/compliance/compliance_spec.rb +60 -0
  88. data/spec/spec_helper.rb +3 -0
  89. data/spec/support/platform_helpers.rb +4 -0
  90. data/spec/support/ruby_installer.rb +51 -0
  91. data/spec/unit/compliance/input_spec.rb +104 -0
  92. data/spec/unit/compliance/profile_spec.rb +120 -0
  93. data/spec/unit/compliance/waiver_spec.rb +104 -0
  94. data/spec/unit/data_collector_spec.rb +24 -1
  95. data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
  96. data/spec/unit/http/basic_client_spec.rb +30 -0
  97. data/spec/unit/http_spec.rb +8 -2
  98. data/spec/unit/mixin/default_paths_spec.rb +1 -1
  99. data/spec/unit/mixin/securable_spec.rb +3 -3
  100. data/spec/unit/provider/cron_spec.rb +45 -0
  101. data/spec/unit/provider/link_spec.rb +13 -7
  102. data/spec/unit/provider/package/rubygems_spec.rb +5 -5
  103. data/spec/unit/provider/package/windows_spec.rb +1 -1
  104. data/spec/unit/provider/registry_key_spec.rb +4 -4
  105. data/spec/unit/provider/remote_file/http_spec.rb +10 -0
  106. data/spec/unit/provider/service/windows_spec.rb +5 -5
  107. data/spec/unit/provider/subversion_spec.rb +4 -4
  108. data/spec/unit/provider/template_spec.rb +2 -2
  109. data/spec/unit/provider/windows_env_spec.rb +1 -1
  110. data/spec/unit/provider/zypper_repository_spec.rb +1 -1
  111. data/spec/unit/resource/archive_file_spec.rb +414 -3
  112. data/spec/unit/resource/chef_client_scheduled_task_spec.rb +69 -0
  113. data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
  114. data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
  115. data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
  116. data/spec/unit/resource/file/verification/json_spec.rb +72 -0
  117. data/spec/unit/resource/file/verification/yaml_spec.rb +67 -0
  118. data/spec/unit/resource/inspec_input_spec.rb +300 -0
  119. data/spec/unit/resource/inspec_waiver_spec.rb +312 -0
  120. data/spec/unit/resource/kernel_module_spec.rb +2 -1
  121. data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
  122. data/spec/unit/resource/mount_spec.rb +10 -0
  123. data/spec/unit/resource/powershell_package_source_spec.rb +63 -62
  124. data/spec/unit/resource/registry_key_spec.rb +10 -10
  125. data/spec/unit/resource/user_ulimit_spec.rb +14 -1
  126. data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
  127. data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
  128. data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
  129. data/spec/unit/resource/windows_task_spec.rb +3 -3
  130. data/spec/unit/resource_reporter_spec.rb +2 -2
  131. data/spec/unit/resource_spec.rb +5 -0
  132. data/spec/unit/secret_fetcher/akeyless_vault_spec.rb +37 -0
  133. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
  134. data/spec/unit/secret_fetcher/hashi_vault_spec.rb +80 -0
  135. data/spec/unit/util/backup_spec.rb +1 -1
  136. data/spec/unit/win32/registry_spec.rb +3 -3
  137. data/tasks/rspec.rb +2 -1
  138. metadata +75 -6
@@ -88,7 +88,7 @@ class Chef
88
88
  # @return [String]
89
89
  def registry_path
90
90
  { machine: "HKLM", user: "HKCU" }[new_resource.root] + \
91
- '\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'
91
+ "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"
92
92
  end
93
93
  end
94
94
  end
@@ -38,7 +38,7 @@ class Chef
38
38
 
39
39
  property :full_users, Array,
40
40
  description: "Determines which users should have full access to the share.",
41
- default: ['BUILTIN\\administrators']
41
+ default: ["BUILTIN\\administrators"]
42
42
 
43
43
  property :change_users, Array,
44
44
  description: "Determines which users should have change access to the share.",
@@ -50,7 +50,7 @@ class Chef
50
50
 
51
51
  property :root, String,
52
52
  description: "The root from which to create the DFS tree. Defaults to C:\\DFSRoots.",
53
- default: 'C:\\DFSRoots'
53
+ default: "C:\\DFSRoots"
54
54
 
55
55
  action :create, description: "Creates the dfs namespace on the server." do
56
56
  directory file_path do
@@ -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
@@ -145,7 +145,7 @@ class Chef
145
145
  action :set, description: "Set Windows Update settings." do
146
146
  actual_day = convert_day(new_resource.scheduled_install_day)
147
147
 
148
- registry_key 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate' do
148
+ registry_key "HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate" do
149
149
  recursive true
150
150
  values [{
151
151
  name: "DisableOSUpgrade",
@@ -180,7 +180,7 @@ class Chef
180
180
  action :create
181
181
  end
182
182
 
183
- registry_key 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' do
183
+ registry_key "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer" do
184
184
  recursive true
185
185
  values [{
186
186
  name: "NoWindowsUpdate",
@@ -190,7 +190,7 @@ class Chef
190
190
  action :create
191
191
  end
192
192
 
193
- registry_key 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU' do
193
+ registry_key "HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU" do
194
194
  recursive true
195
195
  values [{
196
196
  name: "AUOptions",
@@ -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))
data/lib/chef/resource.rb CHANGED
@@ -1508,7 +1508,7 @@ class Chef
1508
1508
  # @return Chef::CookbookVersion The cookbook in which this Resource was defined.
1509
1509
  #
1510
1510
  def cookbook_version
1511
- if cookbook_name
1511
+ if cookbook_name && cookbook_name != "@recipe_files"
1512
1512
  run_context.cookbook_collection[cookbook_name]
1513
1513
  end
1514
1514
  end
@@ -41,7 +41,7 @@ class Chef
41
41
  as_hash["result"] = action_record.action.to_s
42
42
  if new_resource.cookbook_name
43
43
  as_hash["cookbook_name"] = new_resource.cookbook_name
44
- as_hash["cookbook_version"] = new_resource.cookbook_version.version
44
+ as_hash["cookbook_version"] = new_resource.cookbook_version&.version
45
45
  end
46
46
 
47
47
  as_hash
@@ -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)
@@ -0,0 +1,57 @@
1
+ #
2
+ # Author:: Marc Paradise (<marc@chef.io>)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "base"
20
+ require_relative "hashi_vault"
21
+
22
+ class Chef
23
+ class SecretFetcher
24
+ # == Chef::SecretFetcher::AKeylessVault
25
+ # A fetcher that fetches a secret from AKeyless Vault. Initial implementation is
26
+ # based on HashiVault , because AKeyless provides a compatibility layer that makes this possible.
27
+ # Future revisions will use native akeyless authentication.
28
+ #
29
+ # Required config:
30
+ # :access_id - the access id of the API key
31
+ # :access_key - the access key of the API key
32
+ #
33
+ #
34
+ # @example
35
+ #
36
+ # fetcher = SecretFetcher.for_service(:akeyless_vault, { access_id: "my-access-id", access_key: "my-access-key" }, run_context )
37
+ # fetcher.fetch("/secret/data/secretkey1")
38
+ #
39
+ AKEYLESS_VAULT_PROXY_ADDR = "https://hvp.akeyless.io".freeze
40
+ class AKeylessVault < HashiVault
41
+ def validate!
42
+ if config[:access_key].nil?
43
+ raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the secret access key in the configuration as :secret_access_key")
44
+ end
45
+ if config[:access_id].nil?
46
+ raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the access key id in the configuration as :access_key_id")
47
+ end
48
+
49
+ config[:vault_addr] ||= AKEYLESS_VAULT_PROXY_ADDR
50
+ config[:auth_method] = :token
51
+ config[:token] = "#{config[:access_id]}..#{config[:access_key]}"
52
+ super
53
+ end
54
+ end
55
+ end
56
+ end
57
+
@@ -52,7 +52,7 @@ class Chef
52
52
  end
53
53
 
54
54
  # @param identifier [String] the secret_id
55
- # @param version [String] the secret version. Not usd at this time
55
+ # @param version [String] the secret version.
56
56
  # @return Aws::SecretsManager::Types::GetSecretValueResponse
57
57
  def do_fetch(identifier, version)
58
58
  client = Aws::SecretsManager::Client.new(config)
@@ -1,8 +1,10 @@
1
1
  require_relative "base"
2
+ require_relative "../exceptions"
3
+ require "uri" unless defined?(URI)
2
4
 
3
5
  class Chef
4
6
  class SecretFetcher
5
- # == Chef::SecretFetcher::AWSSecretsManager
7
+ # == Chef::SecretFetcher::AzureKeyVault
6
8
  # A fetcher that fetches a secret from Azure Key Vault. Supports fetching with version.
7
9
  #
8
10
  # In this initial iteration this authenticates via token obtained from the OAuth2 /token
@@ -14,13 +16,19 @@ class Chef
14
16
  #
15
17
  # @example
16
18
  #
17
- # fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context )
19
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context)
18
20
  # fetcher.fetch("secretkey1", "v1")
19
21
  #
20
22
  # @example
21
23
  #
22
- # fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context )
24
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context)
23
25
  # fetcher.fetch("my_vault/secretkey1", "v1")
26
+ #
27
+ # @example
28
+ #
29
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, { client_id: "540d76b6-7f76-456c-b68b-ccae4dc9d99d" }, run_context)
30
+ # fetcher.fetch("my_vault/secretkey1", "v1")
31
+ #
24
32
  class AzureKeyVault < Base
25
33
 
26
34
  def do_fetch(name, version)
@@ -48,6 +56,12 @@ class Chef
48
56
  end
49
57
  end
50
58
 
59
+ def validate!
60
+ raise Chef::Exceptions::Secret::ConfigurationInvalid, "You may only specify one (these are mutually exclusive): :object_id, :client_id, or :mi_res_id" if [object_id, client_id, mi_res_id].select { |x| !x.nil? }.length > 1
61
+ end
62
+
63
+ private
64
+
51
65
  # Determine the vault name and secret name from the provided name.
52
66
  # If it is not in the provided name in the form "vault_name/secret_name"
53
67
  # it will determine the vault name from `config[:vault]`.
@@ -63,16 +77,56 @@ class Chef
63
77
  end
64
78
  end
65
79
 
80
+ def api_version
81
+ "2018-02-01"
82
+ end
83
+
84
+ def resource
85
+ "https://vault.azure.net"
86
+ end
87
+
88
+ def object_id
89
+ config[:object_id]
90
+ end
91
+
92
+ def client_id
93
+ config[:client_id]
94
+ end
95
+
96
+ def mi_res_id
97
+ config[:mi_res_id]
98
+ end
99
+
100
+ def token_query
101
+ @token_query ||= begin
102
+ p = {}
103
+ p["api-version"] = api_version
104
+ p["resource"] = resource
105
+ p["object_id"] = object_id if object_id
106
+ p["client_id"] = client_id if client_id
107
+ p["mi_res_id"] = mi_res_id if mi_res_id
108
+ URI.encode_www_form(p)
109
+ end
110
+ end
111
+
66
112
  def fetch_token
67
- token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net")
113
+ token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token")
114
+ token_uri.query = token_query
68
115
  http = Net::HTTP.new(token_uri.host, token_uri.port)
69
116
  response = http.get(token_uri, { "Metadata" => "true" })
70
- body = JSON.parse(response.body)
71
- body["access_token"]
117
+
118
+ case response
119
+ when Net::HTTPSuccess
120
+ body = JSON.parse(response.body)
121
+ body["access_token"]
122
+ when Net::HTTPBadRequest
123
+ body = JSON.parse(response.body)
124
+ raise Chef::Exceptions::Secret::Azure::IdentityNotFound if body["error_description"] =~ /identity not found/i
125
+ else
126
+ body = JSON.parse(response.body)
127
+ body["access_token"]
128
+ end
72
129
  end
73
130
  end
74
131
  end
75
132
  end
76
-
77
-
78
-
@@ -56,7 +56,7 @@ class Chef
56
56
  # @raise [Chef::Exceptions::Secret::ConfigurationInvalid] if it is not.
57
57
  def validate!; end
58
58
 
59
- # Called to fetch the secret identified by 'identifer'. Implementations
59
+ # Called to fetch the secret identified by 'identifier'. Implementations
60
60
  # should expect that `validate!` has been invoked before `do_fetch`.
61
61
  #
62
62
  # @param identifier [Object] Unique identifier of the secret to be retrieved.