chef 16.3.45-universal-mingw32 → 16.4.35-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/chef-universal-mingw32.gemspec +0 -1
  3. data/lib/chef/action_collection.rb +4 -0
  4. data/lib/chef/api_client/registration.rb +2 -2
  5. data/lib/chef/application.rb +1 -1
  6. data/lib/chef/application/apply.rb +5 -5
  7. data/lib/chef/application/windows_service.rb +27 -27
  8. data/lib/chef/chef_class.rb +0 -1
  9. data/lib/chef/chef_fs/chef_fs_data_store.rb +54 -54
  10. data/lib/chef/chef_fs/file_system/chef_server/acl_entry.rb +10 -10
  11. data/lib/chef/chef_fs/file_system/chef_server/organization_invites_entry.rb +8 -8
  12. data/lib/chef/chef_fs/file_system/chef_server/organization_members_entry.rb +8 -8
  13. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_dir.rb +2 -2
  14. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb +1 -1
  15. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +18 -18
  16. data/lib/chef/chef_fs/file_system/repository/directory.rb +1 -1
  17. data/lib/chef/chef_fs/file_system/repository/file_system_entry.rb +1 -1
  18. data/lib/chef/client.rb +11 -11
  19. data/lib/chef/data_collector/run_end_message.rb +11 -1
  20. data/lib/chef/dsl/platform_introspection.rb +8 -8
  21. data/lib/chef/encrypted_data_bag_item/decryptor.rb +1 -1
  22. data/lib/chef/environment.rb +2 -2
  23. data/lib/chef/exceptions.rb +1 -1
  24. data/lib/chef/file_content_management/tempfile.rb +9 -9
  25. data/lib/chef/http.rb +2 -1
  26. data/lib/chef/json_compat.rb +1 -1
  27. data/lib/chef/knife/bootstrap.rb +2 -2
  28. data/lib/chef/knife/cookbook_download.rb +1 -1
  29. data/lib/chef/knife/cookbook_metadata.rb +1 -1
  30. data/lib/chef/knife/cookbook_upload.rb +23 -23
  31. data/lib/chef/knife/core/generic_presenter.rb +1 -1
  32. data/lib/chef/knife/core/hashed_command_loader.rb +2 -2
  33. data/lib/chef/knife/core/windows_bootstrap_context.rb +32 -24
  34. data/lib/chef/knife/delete.rb +15 -15
  35. data/lib/chef/knife/exec.rb +2 -2
  36. data/lib/chef/knife/ssh.rb +6 -6
  37. data/lib/chef/knife/xargs.rb +19 -19
  38. data/lib/chef/knife/yaml_convert.rb +1 -1
  39. data/lib/chef/mixin/checksum.rb +0 -1
  40. data/lib/chef/mixin/deep_merge.rb +35 -6
  41. data/lib/chef/mixin/openssl_helper.rb +3 -1
  42. data/lib/chef/mixin/shell_out.rb +1 -1
  43. data/lib/chef/mixin/which.rb +1 -1
  44. data/lib/chef/monkey_patches/webrick-utils.rb +10 -10
  45. data/lib/chef/node/attribute.rb +2 -4
  46. data/lib/chef/platform/service_helpers.rb +1 -1
  47. data/lib/chef/property.rb +1 -1
  48. data/lib/chef/provider/cron/unix.rb +0 -2
  49. data/lib/chef/provider/git.rb +5 -5
  50. data/lib/chef/provider/group.rb +0 -2
  51. data/lib/chef/provider/group/suse.rb +5 -5
  52. data/lib/chef/provider/ifconfig.rb +1 -4
  53. data/lib/chef/provider/mount.rb +0 -2
  54. data/lib/chef/provider/package.rb +0 -2
  55. data/lib/chef/provider/package/rubygems.rb +1 -1
  56. data/lib/chef/provider/package/snap.rb +1 -1
  57. data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +9 -9
  58. data/lib/chef/provider/powershell_script.rb +21 -5
  59. data/lib/chef/provider/route.rb +1 -1
  60. data/lib/chef/provider/service/arch.rb +1 -1
  61. data/lib/chef/provider/service/debian.rb +1 -1
  62. data/lib/chef/provider/service/gentoo.rb +2 -2
  63. data/lib/chef/provider/service/macosx.rb +2 -2
  64. data/lib/chef/provider/service/openbsd.rb +1 -4
  65. data/lib/chef/provider/service/redhat.rb +2 -2
  66. data/lib/chef/provider/service/upstart.rb +1 -1
  67. data/lib/chef/provider/service/windows.rb +10 -10
  68. data/lib/chef/provider/systemd_unit.rb +0 -2
  69. data/lib/chef/provider/template/content.rb +1 -0
  70. data/lib/chef/provider/user/dscl.rb +2 -2
  71. data/lib/chef/provider/user/mac.rb +9 -9
  72. data/lib/chef/provider/windows_task.rb +0 -3
  73. data/lib/chef/provider/zypper_repository.rb +0 -1
  74. data/lib/chef/providers.rb +0 -1
  75. data/lib/chef/recipe.rb +1 -1
  76. data/lib/chef/resource.rb +6 -10
  77. data/lib/chef/resource/apt_repository.rb +1 -10
  78. data/lib/chef/resource/chef_client_systemd_timer.rb +2 -2
  79. data/lib/chef/resource/chef_vault_secret.rb +13 -13
  80. data/lib/chef/resource/execute.rb +2 -3
  81. data/lib/chef/resource/homebrew_update.rb +2 -2
  82. data/lib/chef/resource/openssl_dhparam.rb +2 -0
  83. data/lib/chef/resource/openssl_ec_private_key.rb +2 -0
  84. data/lib/chef/resource/openssl_ec_public_key.rb +2 -0
  85. data/lib/chef/resource/openssl_rsa_private_key.rb +2 -0
  86. data/lib/chef/resource/openssl_rsa_public_key.rb +2 -0
  87. data/lib/chef/resource/openssl_x509_certificate.rb +24 -21
  88. data/lib/chef/resource/openssl_x509_crl.rb +2 -0
  89. data/lib/chef/resource/openssl_x509_request.rb +23 -20
  90. data/lib/chef/resource/osx_profile.rb +227 -5
  91. data/lib/chef/resource/powershell_package_source.rb +1 -1
  92. data/lib/chef/resource/powershell_script.rb +24 -30
  93. data/lib/chef/resource/sudo.rb +1 -1
  94. data/lib/chef/resource/sysctl.rb +5 -5
  95. data/lib/chef/resource/windows_ad_join.rb +2 -0
  96. data/lib/chef/resource/windows_audit_policy.rb +3 -0
  97. data/lib/chef/resource/windows_auto_run.rb +2 -0
  98. data/lib/chef/resource/windows_certificate.rb +2 -0
  99. data/lib/chef/resource/windows_dfs_folder.rb +2 -0
  100. data/lib/chef/resource/windows_dfs_namespace.rb +2 -0
  101. data/lib/chef/resource/windows_dfs_server.rb +2 -0
  102. data/lib/chef/resource/windows_dns_record.rb +10 -7
  103. data/lib/chef/resource/windows_dns_zone.rb +12 -7
  104. data/lib/chef/resource/windows_feature.rb +2 -0
  105. data/lib/chef/resource/windows_feature_dism.rb +10 -0
  106. data/lib/chef/resource/windows_feature_powershell.rb +14 -2
  107. data/lib/chef/resource/windows_firewall_profile.rb +4 -2
  108. data/lib/chef/resource/windows_firewall_rule.rb +5 -3
  109. data/lib/chef/resource/windows_font.rb +3 -1
  110. data/lib/chef/resource/windows_pagefile.rb +4 -0
  111. data/lib/chef/resource/windows_printer.rb +17 -18
  112. data/lib/chef/resource/windows_printer_port.rb +14 -13
  113. data/lib/chef/resource/windows_security_policy.rb +2 -0
  114. data/lib/chef/resource/windows_share.rb +5 -3
  115. data/lib/chef/resource/windows_shortcut.rb +2 -0
  116. data/lib/chef/resource/windows_uac.rb +2 -0
  117. data/lib/chef/resource/windows_user_privilege.rb +2 -0
  118. data/lib/chef/resource/windows_workgroup.rb +2 -3
  119. data/lib/chef/resource_collection/stepable_iterator.rb +1 -2
  120. data/lib/chef/role.rb +2 -2
  121. data/lib/chef/run_context/cookbook_compiler.rb +20 -20
  122. data/lib/chef/run_status.rb +2 -6
  123. data/lib/chef/shell.rb +1 -1
  124. data/lib/chef/util/backup.rb +1 -1
  125. data/lib/chef/util/diff.rb +11 -11
  126. data/lib/chef/util/powershell/cmdlet.rb +1 -1
  127. data/lib/chef/version.rb +1 -1
  128. data/lib/chef/win32/file.rb +2 -2
  129. data/lib/chef/win32/file/version_info.rb +5 -5
  130. data/spec/data/ssl/chef-rspec.cert +15 -15
  131. data/spec/functional/resource/aixinit_service_spec.rb +7 -7
  132. data/spec/functional/resource/bff_spec.rb +2 -2
  133. data/spec/functional/resource/cookbook_file_spec.rb +1 -1
  134. data/spec/functional/resource/dsc_resource_spec.rb +1 -1
  135. data/spec/functional/resource/dsc_script_spec.rb +0 -1
  136. data/spec/functional/resource/group_spec.rb +6 -6
  137. data/spec/functional/resource/insserv_spec.rb +4 -4
  138. data/spec/functional/resource/link_spec.rb +20 -20
  139. data/spec/functional/resource/powershell_script_spec.rb +4 -4
  140. data/spec/functional/resource/rpm_spec.rb +2 -2
  141. data/spec/functional/resource/windows_certificate_spec.rb +3 -3
  142. data/spec/functional/resource/windows_font_spec.rb +49 -0
  143. data/spec/functional/resource/windows_security_policy_spec.rb +0 -3
  144. data/spec/functional/run_lock_spec.rb +24 -24
  145. data/spec/functional/win32/registry_spec.rb +8 -8
  146. data/spec/functional/win32/service_manager_spec.rb +1 -1
  147. data/spec/integration/knife/common_options_spec.rb +12 -12
  148. data/spec/integration/knife/config_get_profile_spec.rb +69 -68
  149. data/spec/integration/knife/config_get_spec.rb +126 -125
  150. data/spec/integration/knife/config_list_profiles_spec.rb +181 -180
  151. data/spec/integration/knife/config_use_profile_spec.rb +110 -109
  152. data/spec/integration/knife/diff_spec.rb +3 -1
  153. data/spec/integration/knife/download_spec.rb +3 -1
  154. data/spec/integration/knife/serve_spec.rb +5 -5
  155. data/spec/integration/knife/upload_spec.rb +3 -1
  156. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +1 -1
  157. data/spec/spec_helper.rb +6 -6
  158. data/spec/support/platform_helpers.rb +9 -9
  159. data/spec/support/platforms/win32/spec_service.rb +1 -1
  160. data/spec/support/shared/functional/directory_resource.rb +1 -1
  161. data/spec/support/shared/functional/execute_resource.rb +1 -1
  162. data/spec/support/shared/functional/file_resource.rb +20 -20
  163. data/spec/support/shared/functional/win32_service.rb +1 -1
  164. data/spec/support/shared/functional/windows_script.rb +3 -3
  165. data/spec/support/shared/integration/integration_helper.rb +22 -52
  166. data/spec/support/shared/unit/script_resource.rb +6 -20
  167. data/spec/support/shared/unit/windows_script_resource.rb +15 -28
  168. data/spec/unit/data_collector_spec.rb +22 -0
  169. data/spec/unit/environment_spec.rb +7 -7
  170. data/spec/unit/knife/bootstrap_spec.rb +14 -14
  171. data/spec/unit/knife/cookbook_download_spec.rb +4 -4
  172. data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +1 -1
  173. data/spec/unit/knife/core/hashed_command_loader_spec.rb +3 -3
  174. data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +21 -12
  175. data/spec/unit/knife/supermarket_share_spec.rb +1 -1
  176. data/spec/unit/mixin/template_spec.rb +30 -30
  177. data/spec/unit/mixin/windows_architecture_helper_spec.rb +4 -4
  178. data/spec/unit/node/immutable_collections_spec.rb +6 -2
  179. data/spec/unit/node_spec.rb +5 -5
  180. data/spec/unit/provider/powershell_script_spec.rb +11 -4
  181. data/spec/unit/provider/remote_directory_spec.rb +9 -9
  182. data/spec/unit/provider/service/arch_service_spec.rb +3 -2
  183. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  184. data/spec/unit/provider/service/gentoo_service_spec.rb +7 -7
  185. data/spec/unit/provider/service/macosx_spec.rb +3 -3
  186. data/spec/unit/provider/service/redhat_spec.rb +2 -2
  187. data/spec/unit/provider/service/upstart_service_spec.rb +3 -3
  188. data/spec/unit/provider_resolver_spec.rb +6 -6
  189. data/spec/unit/resource/batch_spec.rb +6 -6
  190. data/spec/unit/resource/execute_spec.rb +113 -118
  191. data/spec/unit/resource/osx_profile_spec.rb +233 -0
  192. data/spec/unit/resource/powershell_script_spec.rb +11 -29
  193. data/spec/unit/resource/script_spec.rb +6 -1
  194. data/spec/unit/resource/windows_feature_powershell_spec.rb +30 -4
  195. data/spec/unit/role_spec.rb +11 -11
  196. data/tasks/rspec.rb +1 -1
  197. metadata +7 -22
  198. data/lib/chef/provider/osx_profile.rb +0 -255
  199. data/spec/unit/provider/osx_profile_spec.rb +0 -255
@@ -23,6 +23,8 @@ class Chef
23
23
  require_relative "../mixin/openssl_helper"
24
24
  include Chef::Mixin::OpenSSLHelper
25
25
 
26
+ unified_mode true
27
+
26
28
  provides(:openssl_dhparam) { true }
27
29
 
28
30
  description "Use the **openssl_dhparam** resource to generate dhparam.pem files. If a valid dhparam.pem file is found at the specified location, no new file will be created. If a file is found at the specified location but it is not a valid dhparam file, it will be overwritten."
@@ -24,6 +24,8 @@ class Chef
24
24
  require_relative "../mixin/openssl_helper"
25
25
  include Chef::Mixin::OpenSSLHelper
26
26
 
27
+ unified_mode true
28
+
27
29
  provides :openssl_ec_private_key
28
30
 
29
31
  description "Use the **openssl_ec_private_key** resource to generate an elliptic curve (EC) private key file. If a valid EC key file can be opened at the specified location, no new file will be created. If the EC key file cannot be opened, either because it does not exist or because the password to the EC key file does not match the password in the recipe, then it will be overwritten."
@@ -24,6 +24,8 @@ class Chef
24
24
  require_relative "../mixin/openssl_helper"
25
25
  include Chef::Mixin::OpenSSLHelper
26
26
 
27
+ unified_mode true
28
+
27
29
  provides :openssl_ec_public_key
28
30
 
29
31
  description "Use the **openssl_ec_public_key** resource to generate elliptic curve (EC) public key files from a given EC private key."
@@ -23,6 +23,8 @@ class Chef
23
23
  require_relative "../mixin/openssl_helper"
24
24
  include Chef::Mixin::OpenSSLHelper
25
25
 
26
+ unified_mode true
27
+
26
28
  provides(:openssl_rsa_private_key) { true }
27
29
  provides(:openssl_rsa_key) { true } # legacy cookbook resource name
28
30
 
@@ -23,6 +23,8 @@ class Chef
23
23
  require_relative "../mixin/openssl_helper"
24
24
  include Chef::Mixin::OpenSSLHelper
25
25
 
26
+ unified_mode true
27
+
26
28
  provides(:openssl_rsa_public_key) { true }
27
29
 
28
30
  examples <<~DOC
@@ -24,6 +24,8 @@ class Chef
24
24
  require_relative "../mixin/openssl_helper"
25
25
  include Chef::Mixin::OpenSSLHelper
26
26
 
27
+ unified_mode true
28
+
27
29
  provides :openssl_x509_certificate
28
30
  provides(:openssl_x509) { true } # legacy cookbook name.
29
31
 
@@ -161,7 +163,7 @@ class Chef
161
163
  content cert.to_pem
162
164
  end
163
165
 
164
- if !new_resource.renew_before_expiry.nil? && cert_need_renewall?(new_resource.path, new_resource.renew_before_expiry)
166
+ if !new_resource.renew_before_expiry.nil? && cert_need_renewal?(new_resource.path, new_resource.renew_before_expiry)
165
167
  file new_resource.path do
166
168
  action :create
167
169
  owner new_resource.owner unless new_resource.owner.nil?
@@ -173,7 +175,7 @@ class Chef
173
175
  end
174
176
 
175
177
  if new_resource.csr_file.nil?
176
- file new_resource.key_file do
178
+ file key_file do
177
179
  action :create_if_missing
178
180
  owner new_resource.owner unless new_resource.owner.nil?
179
181
  group new_resource.group unless new_resource.group.nil?
@@ -185,24 +187,25 @@ class Chef
185
187
  end
186
188
 
187
189
  action_class do
188
- def generate_key_file
189
- unless new_resource.key_file
190
- path, file = ::File.split(new_resource.path)
191
- filename = ::File.basename(file, ::File.extname(file))
192
- new_resource.key_file path + "/" + filename + ".key"
193
- end
194
- new_resource.key_file
190
+ def key_file
191
+ @key_file ||=
192
+ if new_resource.key_file
193
+ new_resource.key_file
194
+ else
195
+ path, file = ::File.split(new_resource.path)
196
+ filename = ::File.basename(file, ::File.extname(file))
197
+ path + "/" + filename + ".key"
198
+ end
195
199
  end
196
200
 
197
201
  def key
198
- @key ||= if priv_key_file_valid?(generate_key_file, new_resource.key_pass)
199
- OpenSSL::PKey.read ::File.read(generate_key_file), new_resource.key_pass
202
+ @key ||= if priv_key_file_valid?(key_file, new_resource.key_pass)
203
+ OpenSSL::PKey.read ::File.read(key_file), new_resource.key_pass
200
204
  elsif new_resource.key_type == "rsa"
201
205
  gen_rsa_priv_key(new_resource.key_length)
202
206
  else
203
207
  gen_ec_priv_key(new_resource.key_curve)
204
208
  end
205
- @key
206
209
  end
207
210
 
208
211
  def request
@@ -214,15 +217,15 @@ class Chef
214
217
  end
215
218
 
216
219
  def subject
217
- subject = OpenSSL::X509::Name.new
218
- subject.add_entry("C", new_resource.country) unless new_resource.country.nil?
219
- subject.add_entry("ST", new_resource.state) unless new_resource.state.nil?
220
- subject.add_entry("L", new_resource.city) unless new_resource.city.nil?
221
- subject.add_entry("O", new_resource.org) unless new_resource.org.nil?
222
- subject.add_entry("OU", new_resource.org_unit) unless new_resource.org_unit.nil?
223
- subject.add_entry("CN", new_resource.common_name)
224
- subject.add_entry("emailAddress", new_resource.email) unless new_resource.email.nil?
225
- subject
220
+ OpenSSL::X509::Name.new.tap do |csr_subject|
221
+ csr_subject.add_entry("C", new_resource.country) unless new_resource.country.nil?
222
+ csr_subject.add_entry("ST", new_resource.state) unless new_resource.state.nil?
223
+ csr_subject.add_entry("L", new_resource.city) unless new_resource.city.nil?
224
+ csr_subject.add_entry("O", new_resource.org) unless new_resource.org.nil?
225
+ csr_subject.add_entry("OU", new_resource.org_unit) unless new_resource.org_unit.nil?
226
+ csr_subject.add_entry("CN", new_resource.common_name)
227
+ csr_subject.add_entry("emailAddress", new_resource.email) unless new_resource.email.nil?
228
+ end
226
229
  end
227
230
 
228
231
  def ca_private_key
@@ -24,6 +24,8 @@ class Chef
24
24
  require_relative "../mixin/openssl_helper"
25
25
  include Chef::Mixin::OpenSSLHelper
26
26
 
27
+ unified_mode true
28
+
27
29
  provides :openssl_x509_crl
28
30
 
29
31
  description "Use the **openssl_x509_crl** resource to generate PEM-formatted x509 certificate revocation list (CRL) files."
@@ -24,6 +24,8 @@ class Chef
24
24
  require_relative "../mixin/openssl_helper"
25
25
  include Chef::Mixin::OpenSSLHelper
26
26
 
27
+ unified_mode true
28
+
27
29
  provides :openssl_x509_request
28
30
 
29
31
  description "Use the **openssl_x509_request** resource to generate PEM-formatted x509 certificates requests. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate."
@@ -132,7 +134,7 @@ class Chef
132
134
  action :create
133
135
  end
134
136
 
135
- file new_resource.key_file do
137
+ file key_file do
136
138
  owner new_resource.owner unless new_resource.owner.nil?
137
139
  group new_resource.group unless new_resource.group.nil?
138
140
  mode new_resource.mode unless new_resource.mode.nil?
@@ -145,36 +147,37 @@ class Chef
145
147
  end
146
148
 
147
149
  action_class do
148
- def generate_key_file
149
- unless new_resource.key_file
150
- path, file = ::File.split(new_resource.path)
151
- filename = ::File.basename(file, ::File.extname(file))
152
- new_resource.key_file path + "/" + filename + ".key"
153
- end
154
- new_resource.key_file
150
+ def key_file
151
+ @key_file ||=
152
+ if new_resource.key_file
153
+ new_resource.key_file
154
+ else
155
+ path, file = ::File.split(new_resource.path)
156
+ filename = ::File.basename(file, ::File.extname(file))
157
+ path + "/" + filename + ".key"
158
+ end
155
159
  end
156
160
 
157
161
  def key
158
- @key ||= if priv_key_file_valid?(generate_key_file, new_resource.key_pass)
159
- OpenSSL::PKey.read ::File.read(generate_key_file), new_resource.key_pass
162
+ @key ||= if priv_key_file_valid?(key_file, new_resource.key_pass)
163
+ OpenSSL::PKey.read ::File.read(key_file), new_resource.key_pass
160
164
  elsif new_resource.key_type == "rsa"
161
165
  gen_rsa_priv_key(new_resource.key_length)
162
166
  else
163
167
  gen_ec_priv_key(new_resource.key_curve)
164
168
  end
165
- @key
166
169
  end
167
170
 
168
171
  def subject
169
- csr_subject = OpenSSL::X509::Name.new
170
- csr_subject.add_entry("C", new_resource.country) unless new_resource.country.nil?
171
- csr_subject.add_entry("ST", new_resource.state) unless new_resource.state.nil?
172
- csr_subject.add_entry("L", new_resource.city) unless new_resource.city.nil?
173
- csr_subject.add_entry("O", new_resource.org) unless new_resource.org.nil?
174
- csr_subject.add_entry("OU", new_resource.org_unit) unless new_resource.org_unit.nil?
175
- csr_subject.add_entry("CN", new_resource.common_name)
176
- csr_subject.add_entry("emailAddress", new_resource.email) unless new_resource.email.nil?
177
- csr_subject
172
+ OpenSSL::X509::Name.new.tap do |csr_subject|
173
+ csr_subject.add_entry("C", new_resource.country) unless new_resource.country.nil?
174
+ csr_subject.add_entry("ST", new_resource.state) unless new_resource.state.nil?
175
+ csr_subject.add_entry("L", new_resource.city) unless new_resource.city.nil?
176
+ csr_subject.add_entry("O", new_resource.org) unless new_resource.org.nil?
177
+ csr_subject.add_entry("OU", new_resource.org_unit) unless new_resource.org_unit.nil?
178
+ csr_subject.add_entry("CN", new_resource.common_name)
179
+ csr_subject.add_entry("emailAddress", new_resource.email) unless new_resource.email.nil?
180
+ end
178
181
  end
179
182
 
180
183
  def csr
@@ -17,6 +17,10 @@
17
17
  #
18
18
 
19
19
  require_relative "../resource"
20
+ require_relative "../log"
21
+ require_relative "../resource/file"
22
+ require "uuidtools"
23
+ require "plist"
20
24
 
21
25
  class Chef
22
26
  class Resource
@@ -29,9 +33,6 @@ class Chef
29
33
  description "Use the **osx_profile** resource to manage configuration profiles (.mobileconfig files) on the macOS platform. The osx_profile resource installs profiles by using the uuidgen library to generate a unique ProfileUUID, and then using the profiles command to install the profile on the system."
30
34
  introduced "12.7"
31
35
 
32
- default_action :install
33
- allowed_actions :install, :remove
34
-
35
36
  property :profile_name, String,
36
37
  description: "Use to specify the name of the profile, if different from the name of the resource block.",
37
38
  name_property: true
@@ -42,8 +43,229 @@ class Chef
42
43
  property :identifier, String,
43
44
  description: "Use to specify the identifier for the profile, such as com.company.screensaver."
44
45
 
45
- property :path, String,
46
- description: "The path to write the profile to disk before loading it."
46
+ # this is not a property it is necessary for the tempfile this resource uses to work (FIXME: this is terrible)
47
+ #
48
+ # @api private
49
+ #
50
+ def path(path = nil)
51
+ @path ||= path
52
+ @path
53
+ end
54
+
55
+ action_class do
56
+ def load_current_resource
57
+ @current_resource = Chef::Resource::OsxProfile.new(new_resource.name)
58
+ current_resource.profile_name(new_resource.profile_name)
59
+
60
+ if new_profile_hash
61
+ new_profile_hash["PayloadUUID"] = config_uuid(new_profile_hash)
62
+ end
63
+
64
+ current_resource.profile(current_profile)
65
+ end
66
+
67
+ def current_profile
68
+ all_profiles = get_installed_profiles
69
+
70
+ if all_profiles && all_profiles.key?("_computerlevel")
71
+ return all_profiles["_computerlevel"].find do |item|
72
+ item["ProfileIdentifier"] == new_profile_identifier
73
+ end
74
+ end
75
+ nil
76
+ end
77
+
78
+ def invalid_profile_name?(name_or_identifier)
79
+ name_or_identifier.end_with?(".mobileconfig") || !/^\w+(?:(\.| )\w+)+$/.match(name_or_identifier)
80
+ end
81
+
82
+ def check_resource_semantics!
83
+ if mac? && node["platform_version"] =~ "> 10.15"
84
+ raise "The osx_profile resource is not available on macOS Bug Sur or above due to the removal of apple support for CLI installation of profiles"
85
+ end
86
+
87
+ if action == :remove
88
+ if new_profile_identifier
89
+ if invalid_profile_name?(new_profile_identifier)
90
+ raise "when removing using the identifier property, it must match the profile identifier"
91
+ end
92
+ else
93
+ if invalid_profile_name?(new_resource.profile_name)
94
+ raise "When removing by resource name, it must match the profile identifier"
95
+ end
96
+ end
97
+ end
98
+
99
+ if action == :install
100
+ if new_profile_hash.is_a?(Hash) && !new_profile_hash.include?("PayloadIdentifier")
101
+ raise "The specified profile does not seem to be valid"
102
+ end
103
+ if new_profile_hash.is_a?(String) && !new_profile_hash.end_with?(".mobileconfig")
104
+ raise "#{new_profile_hash}' is not a valid profile"
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ action :install do
111
+ unless profile_installed?
112
+ converge_by("install profile #{new_profile_identifier}") do
113
+ profile_path = write_profile_to_disk
114
+ install_profile(profile_path)
115
+ get_installed_profiles(true)
116
+ end
117
+ end
118
+ end
119
+
120
+ action :remove do
121
+ # Clean up profile after removing it
122
+ if profile_installed?
123
+ converge_by("remove profile #{new_profile_identifier}") do
124
+ remove_profile
125
+ get_installed_profiles(true)
126
+ end
127
+ end
128
+ end
129
+
130
+ action_class do
131
+ private
132
+
133
+ def profile
134
+ @profile ||= new_resource.profile || new_resource.profile_name
135
+ end
136
+
137
+ def new_profile_hash
138
+ @new_profile_hash ||= get_profile_hash(profile)
139
+ end
140
+
141
+ def new_profile_identifier
142
+ @new_profile_identifier ||= if new_profile_hash
143
+ new_profile_hash["PayloadIdentifier"]
144
+ else
145
+ new_resource.identifier || new_resource.profile_name
146
+ end
147
+ end
148
+
149
+ def load_profile_hash(new_profile)
150
+ # file must exist in cookbook
151
+ return nil unless new_profile.end_with?(".mobileconfig")
152
+
153
+ unless cookbook_file_available?(new_profile)
154
+ raise Chef::Exceptions::FileNotFound, "#{self}: '#{new_profile}' not found in cookbook"
155
+ end
156
+
157
+ cookbook_profile = cache_cookbook_profile(new_profile)
158
+ ::Plist.parse_xml(cookbook_profile)
159
+ end
160
+
161
+ def cookbook_file_available?(cookbook_file)
162
+ run_context.has_cookbook_file_in_cookbook?(
163
+ new_resource.cookbook_name, cookbook_file
164
+ )
165
+ end
166
+
167
+ def get_cache_dir
168
+ Chef::FileCache.create_cache_path(
169
+ "profiles/#{new_resource.cookbook_name}"
170
+ )
171
+ end
172
+
173
+ def cache_cookbook_profile(cookbook_file)
174
+ Chef::FileCache.create_cache_path(
175
+ ::File.join(
176
+ "profiles",
177
+ new_resource.cookbook_name,
178
+ ::File.dirname(cookbook_file)
179
+ )
180
+ )
181
+
182
+ path = ::File.join( get_cache_dir, "#{cookbook_file}.remote")
183
+
184
+ cookbook_file path do
185
+ cookbook_name = new_resource.cookbook_name
186
+ source(cookbook_file)
187
+ backup(false)
188
+ run_action(:create)
189
+ end
190
+
191
+ path
192
+ end
193
+
194
+ def get_profile_hash(new_profile)
195
+ if new_profile.is_a?(Hash)
196
+ new_profile
197
+ elsif new_profile.is_a?(String)
198
+ load_profile_hash(new_profile)
199
+ end
200
+ end
201
+
202
+ def config_uuid(profile)
203
+ # Make a UUID of the profile contents and return as string
204
+ UUIDTools::UUID.sha1_create(
205
+ UUIDTools::UUID_DNS_NAMESPACE,
206
+ profile.to_s
207
+ ).to_s
208
+ end
209
+
210
+ def write_profile_to_disk
211
+ # FIXME: this is kind of terrible, the resource needs a tempfile to use and
212
+ # wants it created similarly to the file providers (with all the magic necessary
213
+ # for determining if it should go in the cwd or into a tmpdir), but it abuses
214
+ # the Chef::FileContentManagement::Tempfile API to do that, which requires setting
215
+ # a `path` method on the resource because of tight-coupling to the file provider
216
+ # pattern. We don't just want to use a file here because the point is to get
217
+ # at the tempfile pattern from the file provider, but to feed that into a shell
218
+ # command rather than deploying the file to somewhere on disk. There's some
219
+ # better API that needs extracting here.
220
+ new_resource.path(Chef::FileCache.create_cache_path("profiles"))
221
+ tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile
222
+ tempfile.write(new_profile_hash.to_plist)
223
+ tempfile.close
224
+ tempfile.path
225
+ end
226
+
227
+ def install_profile(profile_path)
228
+ cmd = [ "/usr/bin/profiles", "-I", "-F", profile_path ]
229
+ logger.trace("cmd: #{cmd.join(" ")}")
230
+ shell_out!(*cmd)
231
+ end
232
+
233
+ def remove_profile
234
+ cmd = [ "/usr/bin/profiles", "-R", "-p", new_profile_identifier ]
235
+ logger.trace("cmd: #{cmd.join(" ")}")
236
+ shell_out!(*cmd)
237
+ end
238
+
239
+ #
240
+ # FIXME FIXME FIXME
241
+ # The node object should not be used for caching state like this and this is not a public API and may break.
242
+ # FIXME FIXME FIXME
243
+ #
244
+
245
+ def get_installed_profiles(update = nil)
246
+ if update
247
+ node.run_state[:config_profiles] = query_installed_profiles
248
+ else
249
+ node.run_state[:config_profiles] ||= query_installed_profiles
250
+ end
251
+ logger.trace("Saved profiles to run_state")
252
+ end
253
+
254
+ def query_installed_profiles
255
+ Tempfile.open("allprofiles.plist") do |tempfile|
256
+ shell_out!( "/usr/bin/profiles", "-P", "-o", tempfile.path )
257
+ ::Plist.parse_xml(tempfile)
258
+ end
259
+ end
260
+
261
+ def profile_installed?
262
+ # Profile Identifier and UUID must match a currently installed profile
263
+ return false if current_resource.profile.nil? || current_resource.profile.empty?
264
+ return true if action == :remove
265
+
266
+ current_resource.profile["ProfileUUID"] == new_profile_hash["PayloadUUID"]
267
+ end
268
+ end
47
269
  end
48
270
  end
49
271
  end