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
@@ -87,7 +87,7 @@ iface <%= new_resource.device %> <%= new_resource.family %> static
87
87
  directory INTERFACES_DOT_D_DIR
88
88
 
89
89
  # roll our own file_edit resource, this will not get reported until we have a file_edit resource
90
- interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(/\./, '\.') # escape dots for the regexp
90
+ interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(/\./, "\\.") # escape dots for the regexp
91
91
  regexp = %r{^\s*source\s+#{interfaces_dot_d_for_regexp}/\*\s*$}
92
92
 
93
93
  return if ::File.exist?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE))
@@ -43,8 +43,8 @@ class Chef
43
43
  )
44
44
  else
45
45
  current_resource.link_type(:hard)
46
- if ::File.exists?(current_resource.target_file)
47
- if ::File.exists?(new_resource.to) &&
46
+ if ::File.exist?(current_resource.target_file)
47
+ if ::File.exist?(new_resource.to) &&
48
48
  file_class.stat(current_resource.target_file).ino ==
49
49
  file_class.stat(new_resource.to).ino
50
50
  current_resource.to(canonicalize(new_resource.to))
@@ -19,7 +19,7 @@
19
19
 
20
20
  require_relative "../config"
21
21
  require_relative "../log"
22
- require_relative "../resource/file"
22
+ require_relative "../resource/registry_key"
23
23
  require_relative "../mixin/checksum"
24
24
  require_relative "../provider"
25
25
  require "etc" unless defined?(Etc)
@@ -50,7 +50,8 @@ class Chef
50
50
  current_resource.architecture(new_resource.architecture)
51
51
  current_resource.recursive(new_resource.recursive)
52
52
  if registry.key_exists?(new_resource.key)
53
- current_resource.values(registry.get_values(new_resource.key))
53
+ current_registry_values = registry.get_values(new_resource.key) || []
54
+ current_resource.values(current_registry_values)
54
55
  end
55
56
  values_to_hash(current_resource.unscrubbed_values)
56
57
  current_resource
@@ -137,7 +137,7 @@ class Chef
137
137
  if new_resource.ssl_verify_mode
138
138
  opts[:ssl_verify_mode] = new_resource.ssl_verify_mode
139
139
  end
140
- opts
140
+ opts.merge(new_resource.http_options)
141
141
  end
142
142
 
143
143
  end
@@ -58,7 +58,7 @@ class Chef
58
58
  action :checkout, description: "Clone or check out the source. When a checkout is available, this provider does nothing." do
59
59
  if target_dir_non_existent_or_empty?
60
60
  converge_by("perform checkout of #{new_resource.repository} into #{new_resource.destination}") do
61
- shell_out!(checkout_command, run_options)
61
+ shell_out!(checkout_command, **run_options)
62
62
  end
63
63
  else
64
64
  logger.debug "#{new_resource} checkout destination #{new_resource.destination} already exists or is a non-empty directory - nothing to do"
@@ -75,7 +75,7 @@ class Chef
75
75
 
76
76
  action :force_export, description: "Export the source, excluding or removing any version control artifacts and force an export of the source that is overwriting the existing copy (if it exists)." do
77
77
  converge_by("export #{new_resource.repository} into #{new_resource.destination}") do
78
- shell_out!(export_command, run_options)
78
+ shell_out!(export_command, **run_options)
79
79
  end
80
80
  end
81
81
 
@@ -86,7 +86,7 @@ class Chef
86
86
  logger.trace "#{new_resource} current revision: #{current_rev} target revision: #{revision_int}"
87
87
  unless current_revision_matches_target_revision?
88
88
  converge_by("sync #{new_resource.destination} from #{new_resource.repository}") do
89
- shell_out!(sync_command, run_options)
89
+ shell_out!(sync_command, **run_options)
90
90
  logger.info "#{new_resource} updated to revision: #{revision_int}"
91
91
  end
92
92
  end
@@ -125,7 +125,7 @@ class Chef
125
125
  new_resource.revision
126
126
  else
127
127
  command = scm(:info, new_resource.repository, new_resource.svn_info_args, authentication, "-r#{new_resource.revision}")
128
- svn_info = shell_out!(command, run_options(cwd: cwd, returns: [0, 1])).stdout
128
+ svn_info = shell_out!(command, **run_options(cwd: cwd, returns: [0, 1])).stdout
129
129
 
130
130
  extract_revision_info(svn_info)
131
131
  end
@@ -137,7 +137,7 @@ class Chef
137
137
  return nil unless ::File.exist?(::File.join(new_resource.destination, ".svn"))
138
138
 
139
139
  command = scm(:info)
140
- svn_info = shell_out!(command, run_options(cwd: cwd, returns: [0, 1])).stdout
140
+ svn_info = shell_out!(command, **run_options(cwd: cwd, returns: [0, 1])).stdout
141
141
 
142
142
  extract_revision_info(svn_info)
143
143
  end
@@ -39,7 +39,7 @@ class Chef
39
39
  super
40
40
 
41
41
  requirements.assert(:create, :create_if_missing) do |a|
42
- a.assertion { ::File.exists?(content.template_location) }
42
+ a.assertion { ::File.exist?(content.template_location) }
43
43
  a.failure_message "Template source #{content.template_location} could not be found."
44
44
  a.whyrun "Template source #{content.template_location} does not exist. Assuming it would have been created."
45
45
  a.block_action!
@@ -81,6 +81,11 @@ class Chef
81
81
  description: "Should the resource overwrite the destination file contents if they already exist? If set to `:auto` the date stamp of files within the archive will be compared to those on disk and disk contents will be overwritten if they differ. This may cause unintended consequences if disk date stamps are changed between runs, which will result in the files being overwritten during each client run. Make sure to properly test any change to this property.",
82
82
  default: false
83
83
 
84
+ property :strip_components, Integer,
85
+ description: "Remove the specified number of leading path elements. Pathnames with fewer elements will be silently skipped. This behaves similarly to tar's --strip-components command line argument.",
86
+ introduced: "17.5",
87
+ default: 0
88
+
84
89
  # backwards compatibility for the legacy cookbook names
85
90
  alias_method :extract_options, :options
86
91
  alias_method :extract_to, :destination
@@ -117,7 +122,7 @@ class Chef
117
122
 
118
123
  if new_resource.owner || new_resource.group
119
124
  converge_by("set owner of files extracted in #{new_resource.destination} to #{new_resource.owner}:#{new_resource.group}") do
120
- archive = Archive::Reader.open_filename(new_resource.path)
125
+ archive = Archive::Reader.open_filename(new_resource.path, nil, strip_components: new_resource.strip_components)
121
126
  archive.each_entry do |e|
122
127
  FileUtils.chown(new_resource.owner, new_resource.group, "#{new_resource.destination}/#{e.pathname}")
123
128
  end
@@ -160,18 +165,16 @@ class Chef
160
165
  # @return [Boolean]
161
166
  def archive_differs_from_disk?(src, dest)
162
167
  modified = false
163
- Dir.chdir(dest) do
164
- archive = Archive::Reader.open_filename(src)
165
- Chef::Log.trace("Beginning the comparison of file mtime between contents of #{src} and #{dest}")
166
- archive.each_entry do |e|
167
- pathname = ::File.expand_path(e.pathname)
168
- if ::File.exist?(pathname)
169
- Chef::Log.trace("#{pathname} mtime is #{::File.mtime(pathname)} and archive is #{e.mtime}")
170
- modified = true unless ::File.mtime(pathname) == e.mtime
171
- else
172
- Chef::Log.trace("#{pathname} doesn't exist on disk, but exists in the archive")
173
- modified = true
174
- end
168
+ archive = Archive::Reader.open_filename(src, nil, strip_components: new_resource.strip_components)
169
+ Chef::Log.trace("Beginning the comparison of file mtime between contents of #{src} and #{dest}")
170
+ archive.each_entry do |e|
171
+ pathname = ::File.expand_path(e.pathname, dest)
172
+ if ::File.exist?(pathname)
173
+ Chef::Log.trace("#{pathname} mtime is #{::File.mtime(pathname)} and archive is #{e.mtime}")
174
+ modified = true unless ::File.mtime(pathname) == e.mtime
175
+ else
176
+ Chef::Log.trace("#{pathname} doesn't exist on disk, but exists in the archive")
177
+ modified = true
175
178
  end
176
179
  end
177
180
  modified
@@ -189,7 +192,7 @@ class Chef
189
192
  flags = [options].flatten.map { |option| extract_option_map[option] }.compact.reduce(:|)
190
193
 
191
194
  Dir.chdir(dest) do
192
- archive = Archive::Reader.open_filename(src)
195
+ archive = Archive::Reader.open_filename(src, nil, strip_components: new_resource.strip_components)
193
196
 
194
197
  archive.each_entry do |e|
195
198
  archive.extract(e, flags.to_i)
@@ -58,6 +58,14 @@ class Chef
58
58
  daemon_options ['-n audit_only']
59
59
  end
60
60
  ```
61
+
62
+ **Run #{ChefUtils::Dist::Infra::PRODUCT} with a persistent delay on every run calculated once, similar to how chef_client_cron resource works**:
63
+
64
+ ```ruby
65
+ chef_client_scheduled_task 'Run chef-client with persistent splay' do
66
+ use_consistent_splay true
67
+ end
68
+ ```
61
69
  DOC
62
70
 
63
71
  resource_name :chef_client_scheduled_task
@@ -104,6 +112,11 @@ class Chef
104
112
  description: "A random number of seconds between 0 and X to add to interval so that all #{ChefUtils::Dist::Infra::CLIENT} commands don't execute at the same time.",
105
113
  default: 300
106
114
 
115
+ property :use_consistent_splay, [true, false],
116
+ description: "Always use the same random splay amount for each node to ensure consistent frequencies between #{ChefUtils::Dist::Infra::CLIENT} execution.",
117
+ introduced: "17.5",
118
+ default: false
119
+
107
120
  property :run_on_battery, [true, false],
108
121
  description: "Run the #{ChefUtils::Dist::Infra::PRODUCT} task when the system is on batteries.",
109
122
  default: true
@@ -129,6 +142,11 @@ class Chef
129
142
  description: "An array of options to pass to the #{ChefUtils::Dist::Infra::CLIENT} command.",
130
143
  default: []
131
144
 
145
+ property :priority, Integer,
146
+ description: "Use to set Priority Levels range from 0 to 10.",
147
+ introduced: "17.5",
148
+ default: 7, callbacks: { "should be in range of 0 to 10" => proc { |v| v >= 0 && v <= 10 } }
149
+
132
150
  action :add, description: "Add a Windows Scheduled Task that runs #{ChefUtils::Dist::Infra::PRODUCT}." do
133
151
  # TODO: Replace this with a :create_if_missing action on directory when that exists
134
152
  unless Dir.exist?(new_resource.log_directory)
@@ -151,8 +169,9 @@ class Chef
151
169
  frequency_modifier new_resource.frequency_modifier if frequency_supports_frequency_modifier?
152
170
  start_time new_resource.start_time
153
171
  start_day new_resource.start_date unless new_resource.start_date.nil?
154
- random_delay new_resource.splay if frequency_supports_random_delay?
172
+ random_delay new_resource.splay if frequency_supports_random_delay? && !new_resource.use_consistent_splay
155
173
  disallow_start_if_on_batteries new_resource.splay unless new_resource.run_on_battery
174
+ priority new_resource.priority
156
175
  action %i{create enable}
157
176
  end
158
177
  end
@@ -173,7 +192,31 @@ class Chef
173
192
  # Fetch path of cmd.exe through environment variable comspec
174
193
  cmd_path = ENV["COMSPEC"]
175
194
 
176
- "#{cmd_path} /c \"#{client_cmd}\""
195
+ "#{cmd_path} /c \"#{consistent_splay_command}#{client_cmd}\""
196
+ end
197
+
198
+ #
199
+ # Generate a uniformly distributed unique number to sleep from 0 to the splay time
200
+ #
201
+ # @param [Integer] splay The number of seconds to splay
202
+ #
203
+ # @return [Integer]
204
+ #
205
+ def splay_sleep_time(splay)
206
+ seed = node["shard_seed"] || Digest::MD5.hexdigest(node.name).to_s.hex
207
+ random = Random.new(seed.to_i)
208
+ random.rand(splay)
209
+ end
210
+
211
+ #
212
+ # The consistent splay sleep time when use_consistent_splay is true.
213
+ #
214
+ # @return [NilClass,String] The prepended sleep command to run prior to executing the full command.
215
+ #
216
+ def consistent_splay_command
217
+ return unless new_resource.use_consistent_splay
218
+
219
+ "C:/windows/system32/windowspowershell/v1.0/powershell.exe Start-Sleep -s #{splay_sleep_time(new_resource.splay)} && "
177
220
  end
178
221
 
179
222
  #
@@ -21,25 +21,25 @@ class Chef
21
21
 
22
22
  provides :chocolatey_config
23
23
 
24
- description "Use the **chocolatey_config** resource to add or remove Chocolatey configuration keys."
24
+ description "Use the **chocolatey_config** resource to add or remove Chocolatey configuration keys. Note: The Chocolatey package manager is not installed on Windows by default. You will need to install it prior to using this resource by adding the [Chocolatey cookbook](https://supermarket.chef.io/cookbooks/chocolatey/) to your node's run list."
25
25
  introduced "14.3"
26
26
  examples <<~DOC
27
- **Set the Chocolatey cacheLocation config**:
27
+ **Set the Chocolatey cacheLocation config**:
28
28
 
29
- ```ruby
30
- chocolatey_config 'Set cacheLocation config' do
31
- config_key 'cacheLocation'
32
- value 'C:\temp\choco'
33
- end
34
- ```
29
+ ```ruby
30
+ chocolatey_config 'Set cacheLocation config' do
31
+ config_key 'cacheLocation'
32
+ value 'C:\\temp\\choco'
33
+ end
34
+ ```
35
35
 
36
- **Unset a Chocolatey config**:
36
+ **Unset a Chocolatey config**:
37
37
 
38
- ```ruby
39
- chocolatey_config 'BogusConfig' do
40
- action :unset
41
- end
42
- ```
38
+ ```ruby
39
+ chocolatey_config 'BogusConfig' do
40
+ action :unset
41
+ end
42
+ ```
43
43
  DOC
44
44
 
45
45
  property :config_key, String, name_property: true,
@@ -20,7 +20,7 @@ class Chef
20
20
  unified_mode true
21
21
  provides :chocolatey_feature
22
22
 
23
- description "Use the **chocolatey_feature** resource to enable and disable Chocolatey features."
23
+ description "Use the **chocolatey_feature** resource to enable and disable Chocolatey features. Note: The Chocolatey package manager is not installed on Windows by default. You will need to install it prior to using this resource by adding the [Chocolatey cookbook](https://supermarket.chef.io/cookbooks/chocolatey/) to your node's run list."
24
24
  introduced "15.1"
25
25
  examples <<~DOC
26
26
  **Enable the checksumFiles Chocolatey feature**
@@ -20,7 +20,7 @@ class Chef
20
20
  unified_mode true
21
21
  provides :chocolatey_source
22
22
 
23
- description "Use the **chocolatey_source** resource to add, remove, enable, or disable Chocolatey sources."
23
+ description "Use the **chocolatey_source** resource to add, remove, enable, or disable Chocolatey sources. Note: The Chocolatey package manager is not installed on Windows by default. You will need to install it prior to using this resource by adding the [Chocolatey cookbook](https://supermarket.chef.io/cookbooks/chocolatey/) to your node's run list."
24
24
  introduced "14.3"
25
25
  examples <<~DOC
26
26
  **Add a Chocolatey source**
@@ -63,6 +63,22 @@ class Chef
63
63
 
64
64
  property :disabled, [TrueClass, FalseClass], default: false, desired_state: false, skip_docs: true
65
65
 
66
+ property :username, String,
67
+ description: "The username to use when authenticating against the source",
68
+ introduced: "17.7"
69
+
70
+ property :password, String, sensitive: true, desired_state: false,
71
+ description: "The password to use when authenticating against the source",
72
+ introduced: "17.7"
73
+
74
+ property :cert, String,
75
+ description: "The certificate to use when authenticating against the source",
76
+ introduced: "17.7"
77
+
78
+ property :cert_password, String, sensitive: true, desired_state: false,
79
+ description: "The password for the certificate to use when authenticating against the source",
80
+ introduced: "17.7"
81
+
66
82
  load_current_value do
67
83
  element = fetch_source_element(source_name)
68
84
  current_value_does_not_exist! if element.nil?
@@ -74,6 +90,8 @@ class Chef
74
90
  allow_self_service element["selfService"] == "true"
75
91
  priority element["priority"].to_i
76
92
  disabled element["disabled"] == "true"
93
+ username element["user"]
94
+ cert element["certificate"]
77
95
  end
78
96
 
79
97
  # @param [String] id the source name
@@ -129,10 +147,14 @@ class Chef
129
147
  def choco_cmd(action)
130
148
  cmd = "#{ENV["ALLUSERSPROFILE"]}\\chocolatey\\bin\\choco source #{action} -n \"#{new_resource.source_name}\""
131
149
  if action == "add"
132
- cmd << " -s #{new_resource.source} --priority=#{new_resource.priority}"
150
+ cmd << " --source=\"#{new_resource.source}\" --priority=#{new_resource.priority}"
133
151
  cmd << " --bypassproxy" if new_resource.bypass_proxy
134
152
  cmd << " --allowselfservice" if new_resource.allow_self_service
135
153
  cmd << " --adminonly" if new_resource.admin_only
154
+ cmd << " --user=\"#{new_resource.username}\"" if new_resource.username
155
+ cmd << " --password=\"#{new_resource.password}\"" if new_resource.password
156
+ cmd << " --cert=\"#{new_resource.cert}\"" if new_resource.cert
157
+ cmd << " --certpassword=\"#{new_resource.cert_password}\"" if new_resource.cert_password
136
158
  end
137
159
  cmd
138
160
  end
@@ -46,7 +46,7 @@ class Chef
46
46
  description: "The path to the directory. Using a fully qualified path is recommended, but is not always required."
47
47
 
48
48
  property :recursive, [ TrueClass, FalseClass ],
49
- description: "Create or delete parent directories recursively. For the owner, group, and mode properties, the value of this property applies only to the leaf directory.",
49
+ description: "Create parent directories recursively, or delete directory and all children recursively. For the owner, group, and mode properties, the value of this property applies only to the leaf directory.",
50
50
  default: false
51
51
  end
52
52
  end
@@ -0,0 +1,50 @@
1
+ #
2
+ # Author:: Antony Thomas (<antonydeepak@gmail.com>)
3
+ # Copyright:: Copyright (c) Facebook, Inc. and its affiliates.
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
+ class Chef
20
+ class Resource
21
+ class File
22
+ class Verification
23
+
24
+ #
25
+ # Extends File verification to provide Json verification
26
+ #
27
+ # Example:
28
+ # file 'foo.json' do
29
+ # content '{"foo": "bar"}'
30
+ # verify :json
31
+ # end
32
+ #
33
+ #
34
+
35
+ class Json < Chef::Resource::File::Verification
36
+
37
+ provides :json
38
+
39
+ def verify(path, opts = {})
40
+ Chef::JSONCompat.parse(IO.read(path))
41
+ true
42
+ rescue Chef::Exceptions::JSON::ParseError => e
43
+ Chef::Log.error("Json syntax verify failed with : #{e.message}")
44
+ false
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,52 @@
1
+ #
2
+ # Author:: Antony Thomas (<antonydeepak@gmail.com>)
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 "psych" unless defined?(Psych)
20
+
21
+ class Chef
22
+ class Resource
23
+ class File
24
+ class Verification
25
+
26
+ #
27
+ # Extends File verification to provide a Yaml verification
28
+ #
29
+ # Example:
30
+ # file 'foo.yaml' do
31
+ # content "--- foo: 'foo-"
32
+ # verify :yaml
33
+ # end
34
+ #
35
+ #
36
+
37
+ class Yaml < Chef::Resource::File::Verification
38
+
39
+ provides :yaml
40
+
41
+ def verify(path, opts = {})
42
+ Psych.parse_file(path)
43
+ true
44
+ rescue Psych::SyntaxError => e
45
+ Chef::Log.error("Yaml syntax verify failed with : #{e.message}")
46
+ false
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -95,10 +95,10 @@ class Chef
95
95
  path habfile
96
96
  destination "#{Chef::Config[:file_cache_path]}/habitat"
97
97
  action :extract
98
- not_if { ::Dir.exist?('c:\habitat') }
98
+ not_if { ::Dir.exist?("c:\\habitat") }
99
99
  end
100
100
 
101
- directory 'c:\habitat' do
101
+ directory "c:\\habitat" do
102
102
  notifies :run, "powershell_script[installing from archive]", :immediately
103
103
  end
104
104
 
@@ -110,7 +110,7 @@ class Chef
110
110
  end
111
111
 
112
112
  # TODO: This won't self heal if missing until the next upgrade
113
- windows_path 'C:\habitat' do
113
+ windows_path "C:\\habitat" do
114
114
  action :add
115
115
  end
116
116
  else
@@ -0,0 +1,127 @@
1
+ #
2
+ # Copyright:: Copyright (c) Chef Software Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require_relative "../resource"
18
+
19
+ class Chef
20
+ class Resource
21
+ class InspecInput < Chef::Resource
22
+ provides :inspec_input
23
+ unified_mode true
24
+
25
+ description "Use the **inspec_input** resource to add an input to the Compliance Phase."
26
+ introduced "17.5"
27
+ examples <<~DOC
28
+
29
+ **Activate the default input in the openssh cookbook's compliance segment**:
30
+
31
+ ```ruby
32
+ inspec_input 'openssh' do
33
+ action :add
34
+ end
35
+ ```
36
+
37
+ **Activate all inputs in the openssh cookbook's compliance segment**:
38
+
39
+ ```ruby
40
+ inspec_input 'openssh::.*' do
41
+ action :add
42
+ end
43
+ ```
44
+
45
+ **Add an InSpec input to the Compliance Phase from a hash**:
46
+
47
+ ```ruby
48
+ inspec_input { ssh_custom_path: '/whatever2' }
49
+ ```
50
+
51
+ **Add an InSpec input to the Compliance Phase using the 'name' property to identify the input**:
52
+
53
+ ```ruby
54
+ inspec_input "setting my input" do
55
+ source( { ssh_custom_path: '/whatever2' })
56
+ end
57
+ ```
58
+
59
+ **Add an InSpec input to the Compliance Phase using a TOML, JSON, or YAML file**:
60
+
61
+ ```ruby
62
+ inspec_input "/path/to/my/input.yml"
63
+ ```
64
+
65
+ **Add an InSpec input to the Compliance Phase using a TOML, JSON, or YAML file, using the 'name' property**:
66
+
67
+ ```ruby
68
+ inspec_input "setting my input" do
69
+ source "/path/to/my/input.yml"
70
+ end
71
+ ```
72
+
73
+ Note that the **inspec_input** resource does not update and will not fire notifications (similar to the log resource). This is done to preserve the ability to use
74
+ the resource while not causing the updated resource count to be larger than zero. Since the resource does not update the state of the managed node, this behavior
75
+ is still consistent with the configuration management model. Instead, you should use events to observe configuration changes for the compliance phase. It is
76
+ possible to use the `notify_group` resource to chain notifications of the two resources, but notifications are the wrong model to use, and you should use pure ruby
77
+ conditionals instead. Compliance configuration should be independent of other resources and should only be conditional based on state/attributes, not other resources.
78
+ DOC
79
+
80
+ property :name, [ Hash, String ]
81
+
82
+ property :input, [ Hash, String ],
83
+ name_property: true
84
+
85
+ property :source, [ Hash, String ],
86
+ name_property: true
87
+
88
+ action :add, description: "Add an input to the compliance phase" do
89
+ if run_context.input_collection.valid?(new_resource.input)
90
+ include_input(new_resource.input)
91
+ else
92
+ include_input(input_hash)
93
+ end
94
+ end
95
+
96
+ action_class do
97
+ # If the source is nil and the input / name_property contains a file separator and is a string of a
98
+ # file that exists, then use that as the file (similar to the package provider automatic source property). Otherwise
99
+ # just return the source.
100
+ #
101
+ # @api private
102
+ def source
103
+ @source ||= build_source
104
+ end
105
+
106
+ def build_source
107
+ return new_resource.source unless new_resource.source.nil?
108
+ return nil unless new_resource.input.count(::File::SEPARATOR) > 0 || (::File::ALT_SEPARATOR && new_resource.input.count(::File::ALT_SEPARATOR) > 0 )
109
+ return nil unless ::File.exist?(new_resource.input)
110
+
111
+ new_resource.input
112
+ end
113
+
114
+ def input_hash
115
+ case source
116
+ when Hash
117
+ source
118
+ when String
119
+ parse_file(source)
120
+ when nil
121
+ raise Chef::Exceptions::ValidationFailed, "Could not find the input #{new_resource.input} in any cookbook segment."
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end