chef 12.4.3-universal-mingw32 → 12.5.1-universal-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +21 -25
  3. data/Gemfile +46 -0
  4. data/README.md +4 -4
  5. data/Rakefile +4 -110
  6. data/bin/chef-service-manager +3 -1
  7. data/distro/common/html/knife_cookbook_site.html +18 -18
  8. data/distro/common/man/man1/knife-cookbook-site.1 +11 -11
  9. data/lib/chef.rb +1 -1
  10. data/lib/chef/application.rb +1 -1
  11. data/lib/chef/application/apply.rb +19 -1
  12. data/lib/chef/application/client.rb +11 -5
  13. data/lib/chef/application/knife.rb +2 -2
  14. data/lib/chef/application/solo.rb +1 -1
  15. data/lib/chef/application/windows_service_manager.rb +19 -12
  16. data/lib/chef/chef_class.rb +46 -0
  17. data/lib/chef/chef_fs/config.rb +22 -24
  18. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +3 -1
  19. data/lib/chef/chef_fs/file_pattern.rb +4 -15
  20. data/lib/chef/chef_fs/file_system/acl_dir.rb +3 -4
  21. data/lib/chef/chef_fs/file_system/acls_dir.rb +5 -1
  22. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +0 -5
  23. data/lib/chef/chef_fs/file_system/base_fs_object.rb +5 -2
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +2 -9
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +2 -9
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +10 -17
  27. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -12
  28. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +15 -11
  29. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +8 -2
  30. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +4 -4
  31. data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +1 -1
  32. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -11
  33. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +3 -5
  34. data/lib/chef/chef_fs/file_system/environments_dir.rb +1 -1
  35. data/lib/chef/chef_fs/file_system/file_system_entry.rb +7 -4
  36. data/lib/chef/chef_fs/file_system/memory_dir.rb +2 -3
  37. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +15 -0
  38. data/lib/chef/chef_fs/file_system/nodes_dir.rb +1 -1
  39. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +2 -2
  40. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +4 -9
  41. data/lib/chef/chef_fs/knife.rb +35 -7
  42. data/lib/chef/chef_fs/path_utils.rb +65 -34
  43. data/lib/chef/client.rb +2 -3
  44. data/lib/chef/config.rb +34 -2
  45. data/lib/chef/{mixin/wstring.rb → constants.rb} +9 -13
  46. data/lib/chef/cookbook/metadata.rb +25 -3
  47. data/lib/chef/cookbook/synchronizer.rb +1 -1
  48. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  49. data/lib/chef/cookbook_version.rb +3 -3
  50. data/lib/chef/delayed_evaluator.rb +21 -0
  51. data/lib/chef/deprecation/mixin/template.rb +1 -2
  52. data/lib/chef/deprecation/provider/cookbook_file.rb +1 -1
  53. data/lib/chef/deprecation/provider/file.rb +1 -1
  54. data/lib/chef/deprecation/provider/remote_directory.rb +52 -0
  55. data/lib/chef/deprecation/provider/remote_file.rb +1 -2
  56. data/lib/chef/deprecation/provider/template.rb +1 -1
  57. data/lib/chef/deprecation/warnings.rb +3 -4
  58. data/lib/chef/dsl/reboot_pending.rb +3 -2
  59. data/lib/chef/dsl/recipe.rb +26 -7
  60. data/lib/chef/dsl/resources.rb +2 -2
  61. data/lib/chef/event_dispatch/base.rb +51 -22
  62. data/lib/chef/event_dispatch/dispatcher.rb +21 -6
  63. data/lib/chef/event_dispatch/dsl.rb +64 -0
  64. data/lib/chef/exceptions.rb +28 -1
  65. data/lib/chef/file_content_management/tempfile.rb +1 -1
  66. data/lib/chef/formatters/base.rb +3 -0
  67. data/lib/chef/formatters/doc.rb +56 -6
  68. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +36 -0
  69. data/lib/chef/formatters/minimal.rb +2 -2
  70. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +3 -1
  71. data/lib/chef/http/http_request.rb +1 -1
  72. data/lib/chef/knife.rb +35 -55
  73. data/lib/chef/knife/bootstrap.rb +41 -0
  74. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +1 -0
  75. data/lib/chef/knife/bootstrap/client_builder.rb +16 -0
  76. data/lib/chef/knife/bootstrap/templates/README.md +3 -4
  77. data/lib/chef/knife/bootstrap/templates/chef-full.erb +1 -1
  78. data/lib/chef/knife/cookbook_create.rb +1 -1
  79. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  80. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  81. data/lib/chef/knife/cookbook_site_share.rb +6 -6
  82. data/lib/chef/knife/cookbook_site_unshare.rb +2 -2
  83. data/lib/chef/knife/core/bootstrap_context.rb +12 -4
  84. data/lib/chef/knife/core/custom_manifest_loader.rb +69 -0
  85. data/lib/chef/knife/core/gem_glob_loader.rb +138 -0
  86. data/lib/chef/knife/core/hashed_command_loader.rb +80 -0
  87. data/lib/chef/knife/core/node_presenter.rb +24 -1
  88. data/lib/chef/knife/core/object_loader.rb +1 -0
  89. data/lib/chef/knife/core/subcommand_loader.rb +131 -146
  90. data/lib/chef/knife/node_run_list_remove.rb +12 -1
  91. data/lib/chef/knife/null.rb +10 -0
  92. data/lib/chef/knife/rehash.rb +62 -0
  93. data/lib/chef/knife/search.rb +3 -3
  94. data/lib/chef/knife/ssh.rb +52 -30
  95. data/lib/chef/knife/ssl_check.rb +3 -2
  96. data/lib/chef/knife/user_edit.rb +1 -2
  97. data/lib/chef/local_mode.rb +5 -0
  98. data/lib/chef/log.rb +5 -1
  99. data/lib/chef/mixin/deprecation.rb +8 -8
  100. data/lib/chef/mixin/params_validate.rb +362 -135
  101. data/lib/chef/mixin/template.rb +48 -0
  102. data/lib/chef/mixin/which.rb +1 -1
  103. data/lib/chef/mixin/wide_string.rb +72 -0
  104. data/lib/chef/mixin/windows_architecture_helper.rb +15 -39
  105. data/lib/chef/mixin/windows_env_helper.rb +4 -1
  106. data/lib/chef/monkey_patches/webrick-utils.rb +51 -0
  107. data/lib/chef/monkey_patches/win32/registry.rb +72 -0
  108. data/lib/chef/node.rb +116 -3
  109. data/lib/chef/node_map.rb +2 -2
  110. data/lib/chef/platform/handler_map.rb +0 -5
  111. data/lib/chef/platform/provider_mapping.rb +5 -6
  112. data/lib/chef/platform/query_helpers.rb +46 -4
  113. data/lib/chef/platform/rebooter.rb +1 -1
  114. data/lib/chef/platform/service_helpers.rb +30 -32
  115. data/lib/chef/policy_builder.rb +1 -8
  116. data/lib/chef/policy_builder/dynamic.rb +186 -0
  117. data/lib/chef/policy_builder/expand_node_object.rb +30 -15
  118. data/lib/chef/policy_builder/policyfile.rb +155 -18
  119. data/lib/chef/property.rb +568 -0
  120. data/lib/chef/provider.rb +222 -13
  121. data/lib/chef/provider/batch.rb +8 -0
  122. data/lib/chef/provider/deploy.rb +5 -7
  123. data/lib/chef/provider/directory.rb +14 -2
  124. data/lib/chef/provider/dsc_resource.rb +5 -9
  125. data/lib/chef/provider/group/pw.rb +1 -1
  126. data/lib/chef/provider/ifconfig.rb +2 -2
  127. data/lib/chef/provider/lwrp_base.rb +1 -75
  128. data/lib/chef/provider/mount.rb +7 -3
  129. data/lib/chef/provider/package.rb +1 -1
  130. data/lib/chef/provider/package/dpkg.rb +5 -11
  131. data/lib/chef/provider/package/rpm.rb +2 -2
  132. data/lib/chef/provider/package/rubygems.rb +1 -1
  133. data/lib/chef/provider/package/windows/msi.rb +2 -2
  134. data/lib/chef/provider/package/yum.rb +17 -5
  135. data/lib/chef/provider/powershell_script.rb +59 -23
  136. data/lib/chef/provider/registry_key.rb +5 -5
  137. data/lib/chef/provider/remote_directory.rb +190 -102
  138. data/lib/chef/provider/service.rb +12 -2
  139. data/lib/chef/provider/service/aix.rb +1 -1
  140. data/lib/chef/provider/service/debian.rb +3 -5
  141. data/lib/chef/provider/service/freebsd.rb +1 -1
  142. data/lib/chef/provider/service/gentoo.rb +3 -3
  143. data/lib/chef/provider/service/init.rb +3 -3
  144. data/lib/chef/provider/service/insserv.rb +2 -4
  145. data/lib/chef/provider/service/invokercd.rb +2 -4
  146. data/lib/chef/provider/service/macosx.rb +5 -1
  147. data/lib/chef/provider/service/openbsd.rb +2 -1
  148. data/lib/chef/provider/service/redhat.rb +52 -16
  149. data/lib/chef/provider/service/simple.rb +2 -2
  150. data/lib/chef/provider/service/systemd.rb +3 -5
  151. data/lib/chef/provider/service/upstart.rb +4 -6
  152. data/lib/chef/provider/subversion.rb +13 -7
  153. data/lib/chef/provider/template/content.rb +16 -6
  154. data/lib/chef/provider/user/solaris.rb +32 -4
  155. data/lib/chef/provider/windows_script.rb +3 -5
  156. data/lib/chef/provider_resolver.rb +2 -2
  157. data/lib/chef/recipe.rb +1 -8
  158. data/lib/chef/resource.rb +563 -90
  159. data/lib/chef/resource/action_class.rb +83 -0
  160. data/lib/chef/resource/chef_gem.rb +3 -3
  161. data/lib/chef/resource/deploy.rb +8 -2
  162. data/lib/chef/resource/dsc_script.rb +2 -0
  163. data/lib/chef/resource/file/verification.rb +7 -1
  164. data/lib/chef/resource/lwrp_base.rb +1 -7
  165. data/lib/chef/resource/registry_key.rb +1 -1
  166. data/lib/chef/resource/service.rb +10 -2
  167. data/lib/chef/resource/subversion.rb +5 -0
  168. data/lib/chef/resource/windows_script.rb +6 -2
  169. data/lib/chef/resource/yum_package.rb +10 -1
  170. data/lib/chef/resource_resolver.rb +3 -3
  171. data/lib/chef/run_context.rb +402 -83
  172. data/lib/chef/run_list/versioned_recipe_list.rb +15 -0
  173. data/lib/chef/run_lock.rb +30 -21
  174. data/lib/chef/util/powershell/ps_credential.rb +4 -0
  175. data/lib/chef/util/windows.rb +0 -32
  176. data/lib/chef/util/windows/net_group.rb +85 -106
  177. data/lib/chef/util/windows/net_use.rb +35 -71
  178. data/lib/chef/util/windows/net_user.rb +0 -1
  179. data/lib/chef/util/windows/volume.rb +19 -19
  180. data/lib/chef/version.rb +3 -3
  181. data/lib/chef/win32/api.rb +1 -0
  182. data/lib/chef/win32/api/file.rb +20 -0
  183. data/lib/chef/win32/api/net.rb +163 -43
  184. data/lib/chef/win32/api/registry.rb +51 -0
  185. data/lib/chef/win32/api/system.rb +23 -0
  186. data/lib/chef/win32/api/unicode.rb +0 -43
  187. data/lib/chef/win32/crypto.rb +2 -1
  188. data/lib/chef/win32/file.rb +28 -3
  189. data/lib/chef/win32/mutex.rb +1 -2
  190. data/lib/chef/win32/net.rb +162 -8
  191. data/lib/chef/win32/process.rb +13 -0
  192. data/lib/chef/win32/registry.rb +35 -30
  193. data/lib/chef/win32/security.rb +1 -1
  194. data/lib/chef/win32/security/token.rb +1 -1
  195. data/lib/chef/win32/system.rb +62 -0
  196. data/lib/chef/win32/unicode.rb +7 -2
  197. data/lib/chef/win32/version.rb +0 -4
  198. data/lib/chef/workstation_config_loader.rb +3 -158
  199. data/spec/data/cookbooks/openldap/templates/default/helpers.erb +14 -0
  200. data/spec/data/cookbooks/openldap/templates/default/nested_openldap_partials.erb +1 -0
  201. data/spec/data/cookbooks/openldap/templates/default/nested_partial.erb +1 -0
  202. data/spec/data/dsc_lcm.pfx +0 -0
  203. data/spec/data/run_context/cookbooks/include/recipes/default.rb +24 -0
  204. data/spec/data/run_context/cookbooks/include/recipes/includee.rb +3 -0
  205. data/spec/functional/dsl/reboot_pending_spec.rb +33 -43
  206. data/spec/functional/knife/cookbook_delete_spec.rb +17 -7
  207. data/spec/functional/knife/ssh_spec.rb +16 -0
  208. data/spec/functional/rebooter_spec.rb +1 -1
  209. data/spec/functional/resource/deploy_revision_spec.rb +1 -1
  210. data/spec/functional/resource/dsc_resource_spec.rb +2 -0
  211. data/spec/functional/resource/dsc_script_spec.rb +91 -2
  212. data/spec/functional/resource/group_spec.rb +67 -44
  213. data/spec/functional/resource/{powershell_spec.rb → powershell_script_spec.rb} +107 -18
  214. data/spec/functional/resource/windows_service_spec.rb +1 -1
  215. data/spec/functional/run_lock_spec.rb +368 -189
  216. data/spec/functional/win32/{registry_helper_spec.rb → registry_spec.rb} +16 -23
  217. data/spec/functional/win32/service_manager_spec.rb +2 -2
  218. data/spec/integration/client/client_spec.rb +51 -0
  219. data/spec/integration/knife/chef_repo_path_spec.rb +13 -11
  220. data/spec/integration/knife/download_spec.rb +4 -0
  221. data/spec/integration/knife/list_spec.rb +8 -0
  222. data/spec/integration/knife/upload_spec.rb +1 -1
  223. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -16
  224. data/spec/integration/recipes/remote_directory.rb +74 -0
  225. data/spec/integration/recipes/resource_action_spec.rb +363 -0
  226. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +423 -0
  227. data/spec/integration/recipes/resource_load_spec.rb +206 -0
  228. data/spec/spec_helper.rb +9 -0
  229. data/spec/support/platform_helpers.rb +13 -0
  230. data/spec/support/shared/context/win32.rb +34 -0
  231. data/spec/support/shared/functional/win32_service.rb +2 -1
  232. data/spec/support/shared/functional/windows_script.rb +63 -26
  233. data/spec/support/shared/unit/mock_shellout.rb +46 -0
  234. data/spec/support/shared/unit/provider/file.rb +10 -4
  235. data/spec/unit/application/client_spec.rb +16 -3
  236. data/spec/unit/application/knife_spec.rb +2 -2
  237. data/spec/unit/application/solo_spec.rb +4 -3
  238. data/spec/unit/chef_class_spec.rb +23 -4
  239. data/spec/unit/chef_fs/path_util_spec.rb +108 -0
  240. data/spec/unit/client_spec.rb +6 -1
  241. data/spec/unit/config_spec.rb +31 -0
  242. data/spec/unit/cookbook/metadata_spec.rb +23 -3
  243. data/spec/unit/cookbook/syntax_check_spec.rb +3 -0
  244. data/spec/unit/deprecation_spec.rb +3 -6
  245. data/spec/unit/dsl/reboot_pending_spec.rb +12 -6
  246. data/spec/unit/event_dispatch/dispatcher_spec.rb +65 -3
  247. data/spec/unit/event_dispatch/dsl_spec.rb +83 -0
  248. data/spec/unit/formatters/doc_spec.rb +32 -0
  249. data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +26 -0
  250. data/spec/unit/json_compat_spec.rb +4 -3
  251. data/spec/unit/knife/bootstrap/client_builder_spec.rb +27 -0
  252. data/spec/unit/knife/bootstrap_spec.rb +55 -3
  253. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  254. data/spec/unit/knife/core/bootstrap_context_spec.rb +21 -4
  255. data/spec/unit/knife/core/custom_manifest_loader_spec.rb +41 -0
  256. data/spec/unit/knife/core/gem_glob_loader_spec.rb +210 -0
  257. data/spec/unit/knife/core/hashed_command_loader_spec.rb +93 -0
  258. data/spec/unit/knife/core/subcommand_loader_spec.rb +16 -192
  259. data/spec/unit/knife/node_run_list_remove_spec.rb +17 -0
  260. data/spec/unit/knife/ssl_check_spec.rb +4 -0
  261. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +10 -10
  262. data/spec/unit/mixin/params_validate_spec.rb +4 -2
  263. data/spec/unit/mixin/template_spec.rb +5 -1
  264. data/spec/unit/mixin/windows_architecture_helper_spec.rb +13 -8
  265. data/spec/unit/node_spec.rb +220 -0
  266. data/spec/unit/platform/query_helpers_spec.rb +146 -3
  267. data/spec/unit/policy_builder/dynamic_spec.rb +275 -0
  268. data/spec/unit/policy_builder/expand_node_object_spec.rb +37 -38
  269. data/spec/unit/policy_builder/policyfile_spec.rb +260 -46
  270. data/spec/unit/property/state_spec.rb +506 -0
  271. data/spec/unit/property/validation_spec.rb +663 -0
  272. data/spec/unit/property_spec.rb +1094 -0
  273. data/spec/unit/provider/deploy_spec.rb +5 -5
  274. data/spec/unit/provider/directory_spec.rb +35 -0
  275. data/spec/unit/provider/dsc_resource_spec.rb +3 -10
  276. data/spec/unit/provider/ifconfig_spec.rb +22 -2
  277. data/spec/unit/provider/mount/aix_spec.rb +2 -1
  278. data/spec/unit/provider/mount/mount_spec.rb +6 -0
  279. data/spec/unit/provider/mount/windows_spec.rb +14 -0
  280. data/spec/unit/provider/mount_spec.rb +12 -1
  281. data/spec/unit/provider/package/dpkg_spec.rb +8 -1
  282. data/spec/unit/provider/package/rpm_spec.rb +18 -1
  283. data/spec/unit/provider/package/rubygems_spec.rb +18 -0
  284. data/spec/unit/provider/package/yum_spec.rb +97 -24
  285. data/spec/unit/provider/powershell_script_spec.rb +106 -0
  286. data/spec/unit/provider/registry_key_spec.rb +12 -0
  287. data/spec/unit/provider/remote_directory_spec.rb +1 -2
  288. data/spec/unit/provider/service/aix_service_spec.rb +3 -3
  289. data/spec/unit/provider/service/gentoo_service_spec.rb +4 -4
  290. data/spec/unit/provider/service/macosx_spec.rb +4 -4
  291. data/spec/unit/provider/service/openbsd_service_spec.rb +10 -8
  292. data/spec/unit/provider/service/redhat_spec.rb +88 -8
  293. data/spec/unit/provider/service/upstart_service_spec.rb +11 -7
  294. data/spec/unit/provider/service/windows_spec.rb +211 -200
  295. data/spec/unit/provider/subversion_spec.rb +50 -31
  296. data/spec/unit/provider/template/content_spec.rb +93 -2
  297. data/spec/unit/provider/user/solaris_spec.rb +66 -9
  298. data/spec/unit/provider_resolver_spec.rb +707 -650
  299. data/spec/unit/provider_spec.rb +1 -3
  300. data/spec/unit/recipe_spec.rb +0 -4
  301. data/spec/unit/resource/deploy_spec.rb +7 -1
  302. data/spec/unit/resource/dsc_script_spec.rb +4 -0
  303. data/spec/unit/resource/file/verification_spec.rb +33 -5
  304. data/spec/unit/resource/{powershell_spec.rb → powershell_script_spec.rb} +17 -13
  305. data/spec/unit/resource/service_spec.rb +4 -4
  306. data/spec/unit/resource/subversion_spec.rb +4 -0
  307. data/spec/unit/resource/yum_package_spec.rb +10 -1
  308. data/spec/unit/resource_spec.rb +2 -2
  309. data/spec/unit/run_context/child_run_context_spec.rb +133 -0
  310. data/spec/unit/run_context_spec.rb +7 -0
  311. data/spec/unit/run_list/versioned_recipe_list_spec.rb +5 -0
  312. data/spec/unit/win32/registry_spec.rb +394 -0
  313. data/tasks/external_tests.rb +47 -23
  314. data/tasks/maintainers.rb +155 -14
  315. metadata +64 -53
  316. data/lib/chef/knife/bootstrap/templates/archlinux-gems.erb +0 -76
  317. data/lib/chef/knife/bootstrap/templates/chef-aix.erb +0 -72
  318. data/spec/unit/provider/powershell_spec.rb +0 -80
  319. data/spec/unit/registry_helper_spec.rb +0 -376
  320. data/spec/unit/workstation_config_loader_spec.rb +0 -283
@@ -38,14 +38,14 @@ describe Chef::Knife::Core::BootstrapContext do
38
38
  expect{described_class.new(config, run_list, chef_config)}.not_to raise_error
39
39
  end
40
40
 
41
- it "runs chef with the first-boot.json in the _default environment" do
42
- expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json -E _default"
41
+ it "runs chef with the first-boot.json with no environment specified" do
42
+ expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json"
43
43
  end
44
44
 
45
45
  describe "when in verbosity mode" do
46
46
  let(:config) { {:verbosity => 2} }
47
47
  it "adds '-l debug' when verbosity is >= 2" do
48
- expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json -l debug -E _default"
48
+ expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json -l debug"
49
49
  end
50
50
  end
51
51
 
@@ -70,7 +70,7 @@ EXPECTED
70
70
  describe "alternate chef-client path" do
71
71
  let(:chef_config){ {:chef_client_path => '/usr/local/bin/chef-client'} }
72
72
  it "runs chef-client from another path when specified" do
73
- expect(bootstrap_context.start_chef).to eq "/usr/local/bin/chef-client -j /etc/chef/first-boot.json -E _default"
73
+ expect(bootstrap_context.start_chef).to eq "/usr/local/bin/chef-client -j /etc/chef/first-boot.json"
74
74
  end
75
75
  end
76
76
 
@@ -97,6 +97,13 @@ EXPECTED
97
97
  end
98
98
  end
99
99
 
100
+ describe "when tags are given" do
101
+ let(:config) { {:tags => [ "unicorn" ] } }
102
+ it "adds the attributes to first_boot" do
103
+ expect(Chef::JSONCompat.to_json(bootstrap_context.first_boot)).to eq(Chef::JSONCompat.to_json({:run_list => run_list, :tags => ["unicorn"]}))
104
+ end
105
+ end
106
+
100
107
  describe "when JSON attributes are given" do
101
108
  let(:config) { {:first_boot_attributes => {:baz => :quux}} }
102
109
  it "adds the attributes to first_boot" do
@@ -110,6 +117,16 @@ EXPECTED
110
117
  end
111
118
  end
112
119
 
120
+ describe "when policy_name and policy_group are present in config" do
121
+
122
+ let(:config) { { policy_name: "my_app_server", policy_group: "staging" } }
123
+
124
+ it "includes them in the first_boot data and excludes run_list" do
125
+ expect(Chef::JSONCompat.to_json(bootstrap_context.first_boot)).to eq(Chef::JSONCompat.to_json(config))
126
+ end
127
+
128
+ end
129
+
113
130
  describe "when an encrypted_data_bag_secret is provided" do
114
131
  let(:secret) { "supersekret" }
115
132
  it "reads the encrypted_data_bag_secret" do
@@ -0,0 +1,41 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+
20
+ describe Chef::Knife::SubcommandLoader::CustomManifestLoader do
21
+ let(:ec2_server_create_plugin) { "/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_server_create.rb" }
22
+ let(:manifest_content) do
23
+ { "plugins" => {
24
+ "knife-ec2" => {
25
+ "paths" => [
26
+ ec2_server_create_plugin
27
+ ]
28
+ }
29
+ }
30
+ }
31
+ end
32
+ let(:loader) do
33
+ Chef::Knife::SubcommandLoader::CustomManifestLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands'),
34
+ manifest_content)
35
+ end
36
+
37
+ it "uses paths from the manifest instead of searching gems" do
38
+ expect(Gem::Specification).not_to receive(:latest_specs).and_call_original
39
+ expect(loader.subcommand_files).to include(ec2_server_create_plugin)
40
+ end
41
+ end
@@ -0,0 +1,210 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+
20
+ describe Chef::Knife::SubcommandLoader::GemGlobLoader do
21
+ let(:loader) { Chef::Knife::SubcommandLoader::GemGlobLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands')) }
22
+ let(:home) { File.join(CHEF_SPEC_DATA, 'knife-home') }
23
+ let(:plugin_dir) { File.join(home, '.chef', 'plugins', 'knife') }
24
+
25
+ before do
26
+ allow(ChefConfig).to receive(:windows?) { false }
27
+ Chef::Util::PathHelper.class_variable_set(:@@home_dir, home)
28
+ end
29
+
30
+ after do
31
+ Chef::Util::PathHelper.class_variable_set(:@@home_dir, nil)
32
+ end
33
+
34
+ it "builds a list of the core subcommand file require paths" do
35
+ expect(loader.subcommand_files).not_to be_empty
36
+ loader.subcommand_files.each do |require_path|
37
+ expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
38
+ end
39
+ end
40
+
41
+ it "finds files installed via rubygems" do
42
+ expect(loader.find_subcommands_via_rubygems).to include('chef/knife/node_create')
43
+ loader.find_subcommands_via_rubygems.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
44
+ end
45
+
46
+ it "finds files from latest version of installed gems" do
47
+ gems = [ double('knife-ec2-0.5.12') ]
48
+ gem_files = [
49
+ '/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_base.rb',
50
+ '/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_otherstuff.rb'
51
+ ]
52
+ expect($LOAD_PATH).to receive(:map).and_return([])
53
+ if Gem::Specification.respond_to? :latest_specs
54
+ expect(Gem::Specification).to receive(:latest_specs).with(true).and_return(gems)
55
+ expect(gems[0]).to receive(:matches_for_glob).with(/chef\/knife\/\*\.rb\{(.*),\.rb,(.*)\}/).and_return(gem_files)
56
+ else
57
+ expect(Gem.source_index).to receive(:latest_specs).with(true).and_return(gems)
58
+ expect(gems[0]).to receive(:require_paths).twice.and_return(['lib'])
59
+ expect(gems[0]).to receive(:full_gem_path).and_return('/usr/lib/ruby/gems/knife-ec2-0.5.12')
60
+ expect(Dir).to receive(:[]).with('/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/*.rb').and_return(gem_files)
61
+ end
62
+ expect(loader).to receive(:find_subcommands_via_dirglob).and_return({})
63
+ expect(loader.subcommand_files.select { |file| file =~ /knife-ec2/ }.sort).to eq(gem_files)
64
+ end
65
+
66
+ it "finds files using a dirglob when rubygems is not available" do
67
+ expect(loader.find_subcommands_via_dirglob).to include('chef/knife/node_create')
68
+ loader.find_subcommands_via_dirglob.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
69
+ end
70
+
71
+ it "finds user-specific subcommands in the user's ~/.chef directory" do
72
+ expected_command = File.join(home, '.chef', 'plugins', 'knife', 'example_home_subcommand.rb')
73
+ expect(loader.site_subcommands).to include(expected_command)
74
+ end
75
+
76
+ it "finds repo specific subcommands by searching for a .chef directory" do
77
+ expected_command = File.join(CHEF_SPEC_DATA, 'knife-site-subcommands', 'plugins', 'knife', 'example_subcommand.rb')
78
+ expect(loader.site_subcommands).to include(expected_command)
79
+ end
80
+
81
+ # https://github.com/opscode/chef-dk/issues/227
82
+ #
83
+ # `knife` in ChefDK isn't from a gem install, it's directly run from a clone
84
+ # of the source, but there can be one or more versions of chef also installed
85
+ # as a gem. If the gem install contains a command that doesn't exist in the
86
+ # source tree of the "primary" chef install, it can be loaded and cause an
87
+ # error. We also want to ensure that we only load builtin commands from the
88
+ # "primary" chef install.
89
+ context "when a different version of chef is also installed as a gem" do
90
+
91
+ let(:all_found_commands) do
92
+ [
93
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
94
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
95
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
96
+
97
+ # We use the fake version 1.0.0 because that version doesn't exist,
98
+ # which ensures it won't ever equal "chef-#{Chef::VERSION}"
99
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/bootstrap.rb",
100
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_bulk_delete.rb",
101
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_create.rb",
102
+
103
+ # Test that we don't accept a version number that is different only in
104
+ # trailing characters, e.g. we are running Chef 12.0.0 but there is a
105
+ # Chef 12.0.0.rc.0 gem also:
106
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.rc.0/lib/chef/knife/thing.rb",
107
+
108
+ # Test that we ignore the platform suffix when checking for different
109
+ # gem versions.
110
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-x86-mingw32/lib/chef/knife/valid.rb",
111
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-i386-mingw64/lib/chef/knife/valid-too.rb",
112
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-mswin32/lib/chef/knife/also-valid.rb",
113
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-universal-mingw32/lib/chef/knife/universal-is-valid.rb",
114
+ # ...but don't ignore the .rc / .dev parts in the case when we have
115
+ # platform suffixes
116
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.rc.0-x86-mingw32/lib/chef/knife/invalid.rb",
117
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.dev-mswin32/lib/chef/knife/invalid-too.rb",
118
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.dev.0-x86-mingw64/lib/chef/knife/still-invalid.rb",
119
+
120
+ # This command is "extra" compared to what's in the embedded/apps/chef install:
121
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/data_bag_secret_options.rb",
122
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
123
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
124
+
125
+ # These are fake commands that have names designed to test that the
126
+ # regex is strict enough
127
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
128
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
129
+
130
+ # In a real scenario, we'd use rubygems APIs to only select the most
131
+ # recent gem, but for this test we want to check that we're doing the
132
+ # right thing both when the plugin version matches and does not match
133
+ # the current chef version. Looking at
134
+ # `SubcommandLoader::MATCHES_THIS_CHEF_GEM` and
135
+ # `SubcommandLoader::MATCHES_CHEF_GEM` should make it clear why we want
136
+ # to test these two cases.
137
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
138
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
139
+ ]
140
+ end
141
+
142
+ let(:expected_valid_commands) do
143
+ [
144
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
145
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
146
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
147
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-x86-mingw32/lib/chef/knife/valid.rb",
148
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-i386-mingw64/lib/chef/knife/valid-too.rb",
149
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-mswin32/lib/chef/knife/also-valid.rb",
150
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-universal-mingw32/lib/chef/knife/universal-is-valid.rb",
151
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
152
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
153
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
154
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
155
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
156
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
157
+ ]
158
+ end
159
+
160
+ before do
161
+ expect(loader).to receive(:find_files_latest_gems).with("chef/knife/*.rb").and_return(all_found_commands)
162
+ expect(loader).to receive(:find_subcommands_via_dirglob).and_return({})
163
+ end
164
+
165
+ it "ignores commands from the non-matching gem install" do
166
+ expect(loader.find_subcommands_via_rubygems.values).to eq(expected_valid_commands)
167
+ end
168
+
169
+ end
170
+
171
+ describe "finding 3rd party plugins" do
172
+ let(:env_home) { "/home/alice" }
173
+ let(:manifest_path) { env_home + "/.chef/plugin_manifest.json" }
174
+
175
+ before do
176
+ env_dup = ENV.to_hash
177
+ allow(ENV).to receive(:[]) { |key| env_dup[key] }
178
+ allow(ENV).to receive(:[]).with("HOME").and_return(env_home)
179
+ end
180
+
181
+
182
+ it "searches rubygems for plugins" do
183
+ if Gem::Specification.respond_to?(:latest_specs)
184
+ expect(Gem::Specification).to receive(:latest_specs).and_call_original
185
+ else
186
+ expect(Gem.source_index).to receive(:latest_specs).and_call_original
187
+ end
188
+ loader.subcommand_files.each do |require_path|
189
+ expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
190
+ end
191
+ end
192
+
193
+ context "and HOME environment variable is not set" do
194
+ before do
195
+ allow(ENV).to receive(:[]).with("HOME").and_return(nil)
196
+ end
197
+
198
+ it "searches rubygems for plugins" do
199
+ if Gem::Specification.respond_to?(:latest_specs)
200
+ expect(Gem::Specification).to receive(:latest_specs).and_call_original
201
+ else
202
+ expect(Gem.source_index).to receive(:latest_specs).and_call_original
203
+ end
204
+ loader.subcommand_files.each do |require_path|
205
+ expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,93 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+
20
+ describe Chef::Knife::SubcommandLoader::HashedCommandLoader do
21
+ before do
22
+ allow(ChefConfig).to receive(:windows?) { false }
23
+ end
24
+
25
+ let(:plugin_manifest) {
26
+ {
27
+ "_autogenerated_command_paths" => {
28
+ "plugins_paths" => {
29
+ "cool_a" => ["/file/for/plugin/a"],
30
+ "cooler_b" => ["/file/for/plugin/b"]
31
+ },
32
+ "plugins_by_category" => {
33
+ "cool" => [
34
+ "cool_a"
35
+ ],
36
+ "cooler" => [
37
+ "cooler_b"
38
+ ]
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ let(:loader) { Chef::Knife::SubcommandLoader::HashedCommandLoader.new(
45
+ File.join(CHEF_SPEC_DATA, 'knife-site-subcommands'),
46
+ plugin_manifest)}
47
+
48
+ describe "#list_commands" do
49
+ it "lists all commands by category when no argument is given" do
50
+ expect(loader.list_commands).to eq({"cool" => ["cool_a"], "cooler" => ["cooler_b"]})
51
+ end
52
+
53
+ it "lists only commands in the given category when a category is given" do
54
+ expect(loader.list_commands("cool")).to eq({"cool" => ["cool_a"]})
55
+ end
56
+ end
57
+
58
+ describe "#subcommand_files" do
59
+ it "lists all the files" do
60
+ expect(loader.subcommand_files).to eq(["/file/for/plugin/a", "/file/for/plugin/b"])
61
+ end
62
+ end
63
+
64
+ describe "#load_commands" do
65
+ before do
66
+ allow(Kernel).to receive(:load).and_return(true)
67
+ end
68
+
69
+ it "returns false for non-existant commands" do
70
+ expect(loader.load_command(["nothere"])).to eq(false)
71
+ end
72
+
73
+ it "loads the correct file and returns true if the command exists" do
74
+ allow(File).to receive(:exists?).and_return(true)
75
+ expect(Kernel).to receive(:load).with("/file/for/plugin/a").and_return(true)
76
+ expect(loader.load_command(["cool_a"])).to eq(true)
77
+ end
78
+ end
79
+
80
+ describe "#subcommand_for_args" do
81
+ it "returns the subcommands for an exact match" do
82
+ expect(loader.subcommand_for_args(["cooler_b"])).to eq("cooler_b")
83
+ end
84
+
85
+ it "finds the right subcommand even when _'s are elided" do
86
+ expect(loader.subcommand_for_args(["cooler", "b"])).to eq("cooler_b")
87
+ end
88
+
89
+ it "returns nil if the the subcommand isn't in our manifest" do
90
+ expect(loader.subcommand_for_args(["cooler c"])).to eq(nil)
91
+ end
92
+ end
93
+ end
@@ -1,6 +1,5 @@
1
1
  #
2
- # Author:: Daniel DeLeo (<dan@opscode.com>)
3
- # Copyright:: Copyright (c) 2011 Opscode, Inc.
2
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc
4
3
  # License:: Apache License, Version 2.0
5
4
  #
6
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,209 +31,34 @@ describe Chef::Knife::SubcommandLoader do
32
31
  Chef::Util::PathHelper.class_variable_set(:@@home_dir, nil)
33
32
  end
34
33
 
35
- it "builds a list of the core subcommand file require paths" do
36
- expect(loader.subcommand_files).not_to be_empty
37
- loader.subcommand_files.each do |require_path|
38
- expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
39
- end
40
- end
41
-
42
- it "finds files installed via rubygems" do
43
- expect(loader.find_subcommands_via_rubygems).to include('chef/knife/node_create')
44
- loader.find_subcommands_via_rubygems.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
45
- end
46
-
47
- it "finds files from latest version of installed gems" do
48
- gems = [ double('knife-ec2-0.5.12') ]
49
- gem_files = [
50
- '/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_base.rb',
51
- '/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_otherstuff.rb'
52
- ]
53
- expect($LOAD_PATH).to receive(:map).and_return([])
54
- if Gem::Specification.respond_to? :latest_specs
55
- expect(Gem::Specification).to receive(:latest_specs).with(true).and_return(gems)
56
- expect(gems[0]).to receive(:matches_for_glob).with(/chef\/knife\/\*\.rb\{(.*),\.rb,(.*)\}/).and_return(gem_files)
57
- else
58
- expect(Gem.source_index).to receive(:latest_specs).with(true).and_return(gems)
59
- expect(gems[0]).to receive(:require_paths).twice.and_return(['lib'])
60
- expect(gems[0]).to receive(:full_gem_path).and_return('/usr/lib/ruby/gems/knife-ec2-0.5.12')
61
- expect(Dir).to receive(:[]).with('/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/*.rb').and_return(gem_files)
62
- end
63
- expect(loader).to receive(:find_subcommands_via_dirglob).and_return({})
64
- expect(loader.find_subcommands_via_rubygems.values.select { |file| file =~ /knife-ec2/ }.sort).to eq(gem_files)
65
- end
66
-
67
- it "finds files using a dirglob when rubygems is not available" do
68
- expect(loader.find_subcommands_via_dirglob).to include('chef/knife/node_create')
69
- loader.find_subcommands_via_dirglob.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
70
- end
71
-
72
- it "finds user-specific subcommands in the user's ~/.chef directory" do
73
- expected_command = File.join(home, '.chef', 'plugins', 'knife', 'example_home_subcommand.rb')
74
- expect(loader.site_subcommands).to include(expected_command)
75
- end
76
-
77
- it "finds repo specific subcommands by searching for a .chef directory" do
78
- expected_command = File.join(CHEF_SPEC_DATA, 'knife-site-subcommands', 'plugins', 'knife', 'example_subcommand.rb')
79
- expect(loader.site_subcommands).to include(expected_command)
80
- end
81
-
82
- # https://github.com/opscode/chef-dk/issues/227
83
- #
84
- # `knife` in ChefDK isn't from a gem install, it's directly run from a clone
85
- # of the source, but there can be one or more versions of chef also installed
86
- # as a gem. If the gem install contains a command that doesn't exist in the
87
- # source tree of the "primary" chef install, it can be loaded and cause an
88
- # error. We also want to ensure that we only load builtin commands from the
89
- # "primary" chef install.
90
- context "when a different version of chef is also installed as a gem" do
91
-
92
- let(:all_found_commands) do
93
- [
94
- "/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
95
- "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
96
- "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
97
-
98
- # We use the fake version 1.0.0 because that version doesn't exist,
99
- # which ensures it won't ever equal "chef-#{Chef::VERSION}"
100
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/bootstrap.rb",
101
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_bulk_delete.rb",
102
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_create.rb",
103
-
104
- # Test that we don't accept a version number that is different only in
105
- # trailing characters, e.g. we are running Chef 12.0.0 but there is a
106
- # Chef 12.0.0.rc.0 gem also:
107
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.rc.0/lib/chef/knife/thing.rb",
108
-
109
- # Test that we ignore the platform suffix when checking for different
110
- # gem versions.
111
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-x86-mingw32/lib/chef/knife/valid.rb",
112
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-i386-mingw64/lib/chef/knife/valid-too.rb",
113
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-mswin32/lib/chef/knife/also-valid.rb",
114
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-universal-mingw32/lib/chef/knife/universal-is-valid.rb",
115
- # ...but don't ignore the .rc / .dev parts in the case when we have
116
- # platform suffixes
117
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.rc.0-x86-mingw32/lib/chef/knife/invalid.rb",
118
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.dev-mswin32/lib/chef/knife/invalid-too.rb",
119
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.dev.0-x86-mingw64/lib/chef/knife/still-invalid.rb",
120
-
121
- # This command is "extra" compared to what's in the embedded/apps/chef install:
122
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/data_bag_secret_options.rb",
123
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
124
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
125
-
126
- # These are fake commands that have names designed to test that the
127
- # regex is strict enough
128
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
129
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
34
+ let(:config_dir) { File.join(CHEF_SPEC_DATA, 'knife-site-subcommands') }
130
35
 
131
- # In a real scenario, we'd use rubygems APIs to only select the most
132
- # recent gem, but for this test we want to check that we're doing the
133
- # right thing both when the plugin version matches and does not match
134
- # the current chef version. Looking at
135
- # `SubcommandLoader::MATCHES_THIS_CHEF_GEM` and
136
- # `SubcommandLoader::MATCHES_CHEF_GEM` should make it clear why we want
137
- # to test these two cases.
138
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
139
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
140
- ]
141
- end
142
-
143
- let(:expected_valid_commands) do
144
- [
145
- "/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
146
- "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
147
- "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
148
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-x86-mingw32/lib/chef/knife/valid.rb",
149
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-i386-mingw64/lib/chef/knife/valid-too.rb",
150
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-mswin32/lib/chef/knife/also-valid.rb",
151
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}-universal-mingw32/lib/chef/knife/universal-is-valid.rb",
152
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
153
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
154
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
155
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
156
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
157
- "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
158
- ]
159
- end
160
-
161
- before do
162
- expect(loader).to receive(:find_files_latest_gems).with("chef/knife/*.rb").and_return(all_found_commands)
163
- expect(loader).to receive(:find_subcommands_via_dirglob).and_return({})
164
- end
165
-
166
- it "ignores commands from the non-matching gem install" do
167
- expect(loader.find_subcommands_via_rubygems.values).to eq(expected_valid_commands)
168
- end
169
-
170
- end
171
-
172
- describe "finding 3rd party plugins" do
173
- let(:home) { "/home/alice" }
174
- let(:manifest_path) { home + "/.chef/plugin_manifest.json" }
175
-
176
- context "when there is not a ~/.chef/plugin_manifest.json file" do
36
+ describe "#for_config" do
37
+ context "when ~/.chef/plugin_manifest.json exists" do
177
38
  before do
178
- allow(File).to receive(:exist?).with(manifest_path).and_return(false)
39
+ allow(File).to receive(:exist?).with(File.join(home, '.chef', 'plugin_manifest.json')).and_return(true)
179
40
  end
180
41
 
181
- it "searches rubygems for plugins" do
182
- if Gem::Specification.respond_to?(:latest_specs)
183
- expect(Gem::Specification).to receive(:latest_specs).and_call_original
184
- else
185
- expect(Gem.source_index).to receive(:latest_specs).and_call_original
186
- end
187
- loader.subcommand_files.each do |require_path|
188
- expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
189
- end
42
+ it "creates a HashedCommandLoader with the manifest has _autogenerated_command_paths" do
43
+ allow(File).to receive(:read).with(File.join(home, '.chef', 'plugin_manifest.json')).and_return("{ \"_autogenerated_command_paths\": {}}")
44
+ expect(Chef::Knife::SubcommandLoader.for_config(config_dir)).to be_a Chef::Knife::SubcommandLoader::HashedCommandLoader
190
45
  end
191
46
 
192
- context "and HOME environment variable is not set" do
193
- before do
194
- allow(Chef::Util::PathHelper).to receive(:home).and_return(nil)
195
- end
196
-
197
- it "searches rubygems for plugins" do
198
- if Gem::Specification.respond_to?(:latest_specs)
199
- expect(Gem::Specification).to receive(:latest_specs).and_call_original
200
- else
201
- expect(Gem.source_index).to receive(:latest_specs).and_call_original
202
- end
203
- loader.subcommand_files.each do |require_path|
204
- expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
205
- end
206
- end
47
+ it "creates a CustomManifestLoader with then manifest has a key other than _autogenerated_command_paths" do
48
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
49
+ allow(File).to receive(:read).with(File.join(home, '.chef', 'plugin_manifest.json')).and_return("{ \"plugins\": {}}")
50
+ expect(Chef::Knife::SubcommandLoader.for_config(config_dir)).to be_a Chef::Knife::SubcommandLoader::CustomManifestLoader
207
51
  end
208
-
209
52
  end
210
53
 
211
- context "when there is a ~/.chef/plugin_manifest.json file" do
212
- let(:ec2_server_create_plugin) { "/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_server_create.rb" }
213
-
214
- let(:manifest_content) do
215
- { "plugins" => {
216
- "knife-ec2" => {
217
- "paths" => [
218
- ec2_server_create_plugin
219
- ]
220
- }
221
- }
222
- }
223
- end
224
-
225
- let(:manifest_json) { Chef::JSONCompat.to_json(manifest_content) }
226
-
54
+ context "when ~/.chef/plugin_manifest.json does not exist" do
227
55
  before do
228
- allow(File).to receive(:exist?).with(manifest_path).and_return(true)
229
- allow(File).to receive(:read).with(manifest_path).and_return(manifest_json)
56
+ allow(File).to receive(:exist?).with(File.join(home, '.chef', 'plugin_manifest.json')).and_return(false)
230
57
  end
231
58
 
232
- it "uses paths from the manifest instead of searching gems" do
233
- expect(Gem::Specification).not_to receive(:latest_specs).and_call_original
234
- expect(loader.subcommand_files).to include(ec2_server_create_plugin)
59
+ it "creates a GemGlobLoader" do
60
+ expect(Chef::Knife::SubcommandLoader.for_config(config_dir)).to be_a Chef::Knife::SubcommandLoader::GemGlobLoader
235
61
  end
236
-
237
62
  end
238
63
  end
239
-
240
64
  end