chef 10.34.6 → 11.0.0.beta.0

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 (506) hide show
  1. data/CONTRIBUTING.md +155 -0
  2. data/README.md +89 -0
  3. data/Rakefile +4 -12
  4. data/bin/chef-apply +25 -0
  5. data/bin/chef-shell +34 -0
  6. data/bin/shef +6 -5
  7. data/distro/common/html/chef-client.8.html +4 -4
  8. data/distro/common/html/chef-expander.8.html +4 -4
  9. data/distro/common/html/chef-expanderctl.8.html +4 -4
  10. data/distro/common/html/chef-server-webui.8.html +4 -4
  11. data/distro/common/html/chef-server.8.html +4 -4
  12. data/distro/common/html/{shef.1.html → chef-shell.1.html} +49 -46
  13. data/distro/common/html/chef-solo.8.html +18 -12
  14. data/distro/common/html/chef-solr.8.html +4 -4
  15. data/distro/common/html/knife-bootstrap.1.html +4 -4
  16. data/distro/common/html/knife-client.1.html +4 -4
  17. data/distro/common/html/knife-configure.1.html +4 -4
  18. data/distro/common/html/knife-cookbook-site.1.html +4 -4
  19. data/distro/common/html/knife-cookbook.1.html +10 -7
  20. data/distro/common/html/knife-data-bag.1.html +10 -7
  21. data/distro/common/html/knife-environment.1.html +8 -6
  22. data/distro/common/html/knife-exec.1.html +9 -9
  23. data/distro/common/html/knife-index.1.html +4 -4
  24. data/distro/common/html/knife-node.1.html +4 -4
  25. data/distro/common/html/knife-role.1.html +4 -4
  26. data/distro/common/html/knife-search.1.html +4 -4
  27. data/distro/common/html/knife-ssh.1.html +4 -4
  28. data/distro/common/html/knife-status.1.html +4 -4
  29. data/distro/common/html/knife-tag.1.html +4 -4
  30. data/distro/common/html/knife.1.html +8 -13
  31. data/distro/common/man/man1/{shef.1 → chef-shell.1} +21 -57
  32. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  33. data/distro/common/man/man1/knife-client.1 +1 -1
  34. data/distro/common/man/man1/knife-configure.1 +1 -1
  35. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  36. data/distro/common/man/man1/knife-cookbook.1 +15 -2
  37. data/distro/common/man/man1/knife-data-bag.1 +15 -2
  38. data/distro/common/man/man1/knife-environment.1 +12 -2
  39. data/distro/common/man/man1/knife-exec.1 +4 -7
  40. data/distro/common/man/man1/knife-index.1 +1 -1
  41. data/distro/common/man/man1/knife-node.1 +1 -1
  42. data/distro/common/man/man1/knife-role.1 +1 -1
  43. data/distro/common/man/man1/knife-search.1 +1 -1
  44. data/distro/common/man/man1/knife-ssh.1 +1 -1
  45. data/distro/common/man/man1/knife-status.1 +1 -1
  46. data/distro/common/man/man1/knife-tag.1 +1 -1
  47. data/distro/common/man/man1/knife.1 +3 -6
  48. data/distro/common/man/man8/chef-client.8 +1 -1
  49. data/distro/common/man/man8/chef-expander.8 +1 -1
  50. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  51. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  52. data/distro/common/man/man8/chef-server.8 +1 -1
  53. data/distro/common/man/man8/chef-solo.8 +36 -4
  54. data/distro/common/man/man8/chef-solr.8 +1 -1
  55. data/distro/common/markdown/man1/{shef.mkd → chef-shell.mkd} +49 -43
  56. data/distro/common/markdown/man1/knife-exec.mkd +11 -6
  57. data/distro/common/markdown/man1/knife.mkd +4 -9
  58. data/distro/debian/etc/default/chef-client +0 -1
  59. data/distro/debian/etc/init.d/chef-client +2 -2
  60. data/lib/chef.rb +2 -5
  61. data/lib/chef/api_client.rb +20 -130
  62. data/lib/chef/api_client/registration.rb +126 -0
  63. data/lib/chef/application.rb +71 -14
  64. data/lib/chef/application/apply.rb +160 -0
  65. data/lib/chef/application/client.rb +25 -18
  66. data/lib/chef/application/knife.rb +0 -2
  67. data/lib/chef/application/solo.rb +23 -8
  68. data/lib/chef/application/windows_service.rb +5 -2
  69. data/lib/chef/applications.rb +1 -0
  70. data/lib/chef/chef_fs.rb +11 -0
  71. data/lib/chef/chef_fs/command_line.rb +232 -0
  72. data/lib/chef/chef_fs/file_pattern.rb +312 -0
  73. data/lib/chef/chef_fs/file_system.rb +358 -0
  74. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +47 -0
  75. data/lib/chef/chef_fs/file_system/base_fs_object.rb +121 -0
  76. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +109 -0
  77. data/{spec/unit/monkey_patches/uri_spec.rb → lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb} +12 -15
  78. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +84 -0
  79. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +188 -0
  80. data/lib/chef/chef_fs/file_system/cookbook_file.rb +78 -0
  81. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +54 -0
  82. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +68 -0
  83. data/lib/chef/chef_fs/file_system/data_bag_dir.rb +78 -0
  84. data/lib/chef/chef_fs/file_system/data_bag_item.rb +59 -0
  85. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +66 -0
  86. data/lib/chef/chef_fs/file_system/file_system_entry.rb +90 -0
  87. data/lib/chef/{index_queue.rb → chef_fs/file_system/file_system_error.rb} +14 -12
  88. data/lib/chef/{resource/whyrun_safe_ruby_block.rb → chef_fs/file_system/file_system_root_dir.rb} +10 -10
  89. data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +31 -0
  90. data/lib/chef/chef_fs/file_system/nodes_dir.rb +47 -0
  91. data/lib/chef/{provider/whyrun_safe_ruby_block.rb → chef_fs/file_system/nonexistent_fs_object.rb} +19 -9
  92. data/lib/chef/chef_fs/file_system/not_found_error.rb +31 -0
  93. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +84 -0
  94. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +123 -0
  95. data/lib/chef/chef_fs/knife.rb +77 -0
  96. data/lib/chef/chef_fs/path_utils.rb +64 -0
  97. data/lib/chef/client.rb +44 -21
  98. data/lib/chef/config.rb +52 -43
  99. data/lib/chef/cookbook/synchronizer.rb +6 -8
  100. data/lib/chef/cookbook/syntax_check.rb +61 -14
  101. data/lib/chef/cookbook_loader.rb +39 -26
  102. data/lib/chef/cookbook_uploader.rb +17 -19
  103. data/lib/chef/cookbook_version.rb +3 -302
  104. data/lib/chef/daemon.rb +3 -18
  105. data/lib/chef/data_bag.rb +4 -97
  106. data/lib/chef/data_bag_item.rb +2 -65
  107. data/lib/chef/digester.rb +73 -0
  108. data/lib/chef/dsl.rb +6 -0
  109. data/lib/chef/dsl/data_query.rb +66 -0
  110. data/lib/chef/dsl/include_attribute.rb +60 -0
  111. data/lib/chef/dsl/include_recipe.rb +42 -0
  112. data/lib/chef/dsl/platform_introspection.rb +213 -0
  113. data/lib/chef/dsl/recipe.rb +84 -0
  114. data/lib/chef/dsl/registry_helper.rb +59 -0
  115. data/lib/chef/encrypted_data_bag_item.rb +74 -19
  116. data/lib/chef/environment.rb +9 -180
  117. data/lib/chef/exceptions.rb +87 -14
  118. data/lib/chef/formatters/base.rb +4 -1
  119. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +0 -4
  120. data/lib/chef/json_compat.rb +1 -97
  121. data/lib/chef/knife.rb +90 -41
  122. data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
  123. data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
  124. data/lib/chef/knife/bootstrap/chef-full.erb +3 -3
  125. data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
  126. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  127. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
  128. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
  129. data/lib/chef/knife/configure.rb +1 -2
  130. data/lib/chef/knife/cookbook_metadata.rb +1 -0
  131. data/lib/chef/knife/cookbook_test.rb +3 -2
  132. data/lib/chef/knife/cookbook_upload.rb +12 -7
  133. data/lib/chef/knife/core/bootstrap_context.rb +1 -1
  134. data/lib/chef/knife/core/generic_presenter.rb +26 -13
  135. data/lib/chef/knife/core/node_editor.rb +36 -16
  136. data/lib/chef/knife/core/node_presenter.rb +1 -1
  137. data/lib/chef/knife/core/text_formatter.rb +23 -37
  138. data/lib/chef/knife/core/ui.rb +15 -9
  139. data/lib/chef/knife/delete.rb +39 -0
  140. data/lib/chef/knife/diff.rb +46 -0
  141. data/lib/chef/knife/download.rb +50 -0
  142. data/lib/chef/knife/environment_show.rb +7 -0
  143. data/lib/chef/knife/exec.rb +5 -5
  144. data/lib/chef/knife/help_topics.rb +1 -1
  145. data/lib/chef/knife/index_rebuild.rb +91 -7
  146. data/lib/chef/knife/list.rb +109 -0
  147. data/lib/chef/knife/raw.rb +108 -0
  148. data/lib/chef/knife/search.rb +40 -22
  149. data/lib/chef/knife/show.rb +32 -0
  150. data/lib/chef/knife/ssh.rb +6 -2
  151. data/lib/chef/knife/upload.rb +50 -0
  152. data/lib/chef/mixin/checksum.rb +3 -3
  153. data/lib/chef/mixin/deep_merge.rb +55 -197
  154. data/lib/chef/mixin/language.rb +9 -222
  155. data/lib/chef/mixin/language_include_attribute.rb +6 -38
  156. data/lib/chef/mixin/language_include_recipe.rb +3 -35
  157. data/lib/chef/mixin/params_validate.rb +6 -19
  158. data/lib/chef/mixin/recipe_definition_dsl_core.rb +8 -61
  159. data/lib/chef/mixin/securable.rb +32 -7
  160. data/lib/chef/mixin/template.rb +40 -0
  161. data/lib/chef/mixins.rb +0 -4
  162. data/lib/chef/monkey_patches/net_http.rb +0 -34
  163. data/lib/chef/node.rb +133 -309
  164. data/lib/chef/node/attribute.rb +333 -473
  165. data/lib/chef/node/attribute_collections.rb +199 -0
  166. data/lib/chef/node/immutable_collections.rb +186 -0
  167. data/lib/chef/platform.rb +7 -22
  168. data/lib/chef/provider.rb +2 -49
  169. data/lib/chef/provider/breakpoint.rb +6 -6
  170. data/lib/chef/provider/cookbook_file.rb +5 -33
  171. data/lib/chef/provider/deploy.rb +2 -1
  172. data/lib/chef/provider/directory.rb +14 -17
  173. data/lib/chef/provider/file.rb +19 -52
  174. data/lib/chef/provider/group.rb +31 -51
  175. data/lib/chef/provider/group/dscl.rb +13 -53
  176. data/lib/chef/provider/group/gpasswd.rb +19 -14
  177. data/lib/chef/provider/group/groupadd.rb +1 -41
  178. data/lib/chef/provider/group/groupmod.rb +36 -46
  179. data/lib/chef/provider/group/pw.rb +16 -59
  180. data/lib/chef/provider/group/suse.rb +13 -16
  181. data/lib/chef/provider/group/usermod.rb +18 -40
  182. data/lib/chef/provider/group/windows.rb +6 -13
  183. data/lib/chef/provider/http_request.rb +25 -42
  184. data/lib/chef/provider/link.rb +2 -0
  185. data/lib/chef/provider/lwrp_base.rb +150 -0
  186. data/lib/chef/provider/package/portage.rb +4 -9
  187. data/lib/chef/provider/package/rpm.rb +2 -2
  188. data/lib/chef/provider/package/rubygems.rb +9 -41
  189. data/lib/chef/provider/package/yum.rb +12 -19
  190. data/lib/chef/provider/registry_key.rb +156 -0
  191. data/lib/chef/provider/remote_directory.rb +2 -0
  192. data/lib/chef/provider/remote_file.rb +21 -12
  193. data/lib/chef/provider/ruby_block.rb +5 -2
  194. data/lib/chef/provider/service.rb +15 -0
  195. data/lib/chef/provider/service/init.rb +9 -7
  196. data/lib/chef/provider/service/macosx.rb +15 -73
  197. data/lib/chef/provider/service/simple.rb +1 -1
  198. data/lib/chef/provider/service/solaris.rb +3 -3
  199. data/lib/chef/provider/template.rb +22 -25
  200. data/lib/chef/provider/template_finder.rb +61 -0
  201. data/lib/chef/provider/user.rb +0 -1
  202. data/lib/chef/provider/user/dscl.rb +175 -568
  203. data/lib/chef/provider/user/useradd.rb +30 -47
  204. data/lib/chef/providers.rb +3 -2
  205. data/lib/chef/recipe.rb +14 -8
  206. data/lib/chef/resource.rb +13 -154
  207. data/lib/chef/resource/group.rb +1 -11
  208. data/lib/chef/resource/http_request.rb +2 -1
  209. data/lib/chef/resource/lwrp_base.rb +127 -0
  210. data/lib/chef/resource/mount.rb +10 -11
  211. data/lib/chef/resource/registry_key.rb +86 -0
  212. data/lib/chef/resource/remote_directory.rb +6 -5
  213. data/lib/chef/resource/remote_file.rb +22 -31
  214. data/lib/chef/resource/ruby_block.rb +2 -2
  215. data/lib/chef/resource/service.rb +14 -0
  216. data/lib/chef/resource/user.rb +0 -18
  217. data/lib/chef/resource_collection.rb +25 -21
  218. data/lib/chef/resources.rb +2 -1
  219. data/lib/chef/rest.rb +50 -131
  220. data/lib/chef/rest/auth_credentials.rb +4 -20
  221. data/lib/chef/rest/rest_request.rb +2 -7
  222. data/lib/chef/role.rb +1 -97
  223. data/lib/chef/run_context.rb +108 -130
  224. data/lib/chef/run_context/cookbook_compiler.rb +280 -0
  225. data/lib/chef/run_list.rb +0 -2
  226. data/lib/chef/run_list/run_list_expansion.rb +0 -15
  227. data/lib/chef/run_lock.rb +90 -0
  228. data/lib/chef/runner.rb +28 -5
  229. data/lib/chef/sandbox.rb +15 -148
  230. data/lib/chef/scan_access_control.rb +2 -4
  231. data/lib/chef/shef/ext.rb +3 -575
  232. data/lib/chef/{shef.rb → shell.rb} +35 -40
  233. data/lib/chef/shell/ext.rb +593 -0
  234. data/lib/chef/{shef → shell}/model_wrapper.rb +3 -3
  235. data/lib/chef/{shef/shef_rest.rb → shell/shell_rest.rb} +4 -4
  236. data/lib/chef/{shef/shef_session.rb → shell/shell_session.rb} +17 -15
  237. data/lib/chef/shell_out.rb +7 -0
  238. data/lib/chef/util/windows/net_group.rb +1 -5
  239. data/lib/chef/version.rb +3 -3
  240. data/lib/chef/win32/api/process.rb +0 -1
  241. data/lib/chef/win32/handle.rb +1 -8
  242. data/lib/chef/win32/registry.rb +371 -0
  243. data/spec/data/big_json.json +1 -2
  244. data/spec/data/big_json_plus_one.json +1 -2
  245. data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
  246. data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
  247. data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
  248. data/spec/data/nodes/default.rb +3 -3
  249. data/spec/data/nodes/test.example.com.rb +3 -3
  250. data/spec/data/nodes/test.rb +3 -3
  251. data/spec/data/partial_one.erb +1 -0
  252. data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
  253. data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
  254. data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
  255. data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
  256. data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
  257. data/spec/data/{knife-home/.chef/plugins/knife/example_home_subcommand.rb → run_context/cookbooks/circular-dep1/recipes/default.rb} +0 -0
  258. data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
  259. data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
  260. data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
  261. data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
  262. data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
  263. data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
  264. data/spec/data/{lwrp_const_scoping/resources/conflict.rb → run_context/cookbooks/circular-dep2/recipes/default.rb} +0 -0
  265. data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
  266. data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
  267. data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
  268. data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
  269. data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
  270. data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
  271. data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
  272. data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
  273. data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
  274. data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
  275. data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
  276. data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
  277. data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
  278. data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
  279. data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
  280. data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
  281. data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
  282. data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
  283. data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
  284. data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
  285. data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
  286. data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
  287. data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
  288. data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
  289. data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
  290. data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
  291. data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
  292. data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
  293. data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
  294. data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
  295. data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
  296. data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
  297. data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
  298. data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
  299. data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
  300. data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
  301. data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
  302. data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
  303. data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
  304. data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
  305. data/spec/data/shef-config.rb +7 -0
  306. data/spec/functional/dsl/registry_helper_spec.rb +63 -0
  307. data/spec/functional/knife/cookbook_delete_spec.rb +1 -1
  308. data/spec/functional/knife/exec_spec.rb +2 -2
  309. data/spec/functional/knife/ssh_spec.rb +5 -1
  310. data/spec/functional/resource/cookbook_file_spec.rb +7 -19
  311. data/spec/functional/resource/directory_spec.rb +4 -0
  312. data/spec/functional/resource/file_spec.rb +56 -22
  313. data/spec/functional/resource/link_spec.rb +2 -0
  314. data/spec/functional/resource/registry_spec.rb +576 -0
  315. data/spec/functional/resource/remote_directory_spec.rb +142 -36
  316. data/spec/functional/resource/remote_file_spec.rb +18 -0
  317. data/spec/functional/resource/template_spec.rb +23 -2
  318. data/spec/functional/run_lock_spec.rb +106 -0
  319. data/spec/functional/shell_spec.rb +100 -0
  320. data/spec/functional/win32/registry_helper_spec.rb +632 -0
  321. data/spec/spec_helper.rb +5 -29
  322. data/spec/stress/win32/security_spec.rb +1 -1
  323. data/spec/support/chef_helpers.rb +0 -2
  324. data/spec/support/platform_helpers.rb +8 -15
  325. data/spec/support/shared/functional/directory_resource.rb +84 -22
  326. data/spec/support/shared/functional/file_resource.rb +169 -71
  327. data/spec/support/shared/functional/securable_resource.rb +143 -119
  328. data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
  329. data/spec/support/shared/unit/file_system_support.rb +110 -0
  330. data/spec/support/shared/unit/platform_introspector.rb +162 -0
  331. data/spec/unit/api_client/registration_spec.rb +175 -0
  332. data/spec/unit/api_client_spec.rb +78 -156
  333. data/spec/unit/application/apply.rb +84 -0
  334. data/spec/unit/application/client_spec.rb +1 -37
  335. data/spec/unit/application/knife_spec.rb +5 -0
  336. data/spec/unit/application_spec.rb +57 -2
  337. data/spec/unit/checksum/storage/filesystem_spec.rb +1 -1
  338. data/spec/unit/chef_fs/diff_spec.rb +328 -0
  339. data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
  340. data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
  341. data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
  342. data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
  343. data/spec/unit/chef_fs/file_system_spec.rb +136 -0
  344. data/spec/unit/client_spec.rb +124 -33
  345. data/spec/unit/config_spec.rb +46 -13
  346. data/spec/unit/cookbook/synchronizer_spec.rb +1 -49
  347. data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
  348. data/spec/unit/cookbook_loader_spec.rb +153 -91
  349. data/spec/unit/cookbook_manifest_spec.rb +81 -81
  350. data/spec/unit/cookbook_spec.rb +3 -20
  351. data/spec/unit/cookbook_version_spec.rb +23 -122
  352. data/spec/unit/daemon_spec.rb +3 -24
  353. data/spec/unit/data_bag_spec.rb +6 -4
  354. data/spec/unit/digester_spec.rb +50 -0
  355. data/spec/unit/dsl/data_query_spec.rb +66 -0
  356. data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
  357. data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
  358. data/spec/unit/encrypted_data_bag_item_spec.rb +50 -105
  359. data/spec/unit/environment_spec.rb +0 -130
  360. data/spec/unit/exceptions_spec.rb +2 -3
  361. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -3
  362. data/spec/unit/json_compat_spec.rb +15 -7
  363. data/spec/unit/knife/bootstrap_spec.rb +2 -0
  364. data/spec/unit/knife/configure_spec.rb +20 -14
  365. data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
  366. data/spec/unit/knife/cookbook_test_spec.rb +1 -0
  367. data/spec/unit/knife/cookbook_upload_spec.rb +43 -8
  368. data/spec/unit/knife/core/bootstrap_context_spec.rb +1 -1
  369. data/spec/unit/knife/core/ui_spec.rb +156 -125
  370. data/spec/unit/knife/data_bag_create_spec.rb +9 -0
  371. data/spec/unit/knife/data_bag_edit_spec.rb +1 -4
  372. data/spec/unit/knife/data_bag_from_file_spec.rb +4 -6
  373. data/spec/unit/knife/data_bag_show_spec.rb +11 -4
  374. data/spec/unit/knife/index_rebuild_spec.rb +96 -33
  375. data/spec/unit/knife/knife_help.rb +7 -7
  376. data/spec/unit/knife/node_edit_spec.rb +6 -33
  377. data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
  378. data/spec/unit/knife/ssh_spec.rb +12 -15
  379. data/spec/unit/knife/status_spec.rb +2 -2
  380. data/spec/unit/knife_spec.rb +53 -0
  381. data/spec/unit/lwrp_spec.rb +59 -42
  382. data/spec/unit/mixin/checksum_spec.rb +2 -2
  383. data/spec/unit/mixin/deep_merge_spec.rb +101 -799
  384. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
  385. data/spec/unit/mixin/params_validate_spec.rb +4 -37
  386. data/spec/unit/mixin/securable_spec.rb +5 -3
  387. data/spec/unit/mixin/template_spec.rb +119 -0
  388. data/spec/unit/node/attribute_spec.rb +195 -173
  389. data/spec/unit/node/immutable_collections_spec.rb +139 -0
  390. data/spec/unit/node_spec.rb +366 -370
  391. data/spec/unit/platform_spec.rb +9 -10
  392. data/spec/unit/provider/breakpoint_spec.rb +8 -8
  393. data/spec/unit/provider/cookbook_file_spec.rb +4 -8
  394. data/spec/unit/provider/directory_spec.rb +96 -64
  395. data/spec/unit/provider/env_spec.rb +2 -2
  396. data/spec/unit/provider/file_spec.rb +48 -39
  397. data/spec/unit/provider/group/dscl_spec.rb +0 -36
  398. data/spec/unit/provider/group/gpasswd_spec.rb +9 -16
  399. data/spec/unit/provider/group/groupadd_spec.rb +4 -3
  400. data/spec/unit/provider/group/groupmod_spec.rb +1 -0
  401. data/spec/unit/provider/group/pw_spec.rb +15 -12
  402. data/spec/unit/provider/group/usermod_spec.rb +6 -21
  403. data/spec/unit/provider/group/windows_spec.rb +8 -0
  404. data/spec/unit/provider/group_spec.rb +6 -28
  405. data/spec/unit/provider/http_request_spec.rb +28 -69
  406. data/spec/unit/provider/ifconfig_spec.rb +2 -2
  407. data/spec/unit/provider/ohai_spec.rb +4 -4
  408. data/spec/unit/provider/package/apt_spec.rb +0 -1
  409. data/spec/unit/provider/package/ips_spec.rb +0 -1
  410. data/spec/unit/provider/package/portage_spec.rb +0 -44
  411. data/spec/unit/provider/package/rpm_spec.rb +0 -12
  412. data/spec/unit/provider/package/rubygems_spec.rb +1 -44
  413. data/spec/unit/provider/package/yum_spec.rb +39 -36
  414. data/spec/unit/provider/package_spec.rb +7 -5
  415. data/spec/unit/provider/registry_key_spec.rb +269 -0
  416. data/spec/unit/provider/remote_directory_spec.rb +7 -3
  417. data/spec/unit/provider/remote_file_spec.rb +36 -0
  418. data/spec/unit/provider/route_spec.rb +4 -3
  419. data/spec/unit/provider/ruby_block_spec.rb +8 -0
  420. data/spec/unit/provider/service/arch_service_spec.rb +5 -5
  421. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  422. data/spec/unit/provider/service/freebsd_service_spec.rb +5 -5
  423. data/spec/unit/provider/service/init_service_spec.rb +27 -4
  424. data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
  425. data/spec/unit/provider/service/invokercd_service_spec.rb +4 -4
  426. data/spec/unit/provider/service/macosx_spec.rb +11 -66
  427. data/spec/unit/provider/service/redhat_spec.rb +1 -1
  428. data/spec/unit/provider/service/simple_service_spec.rb +3 -3
  429. data/spec/unit/provider/service/upstart_service_spec.rb +9 -9
  430. data/spec/unit/provider/subversion_spec.rb +1 -1
  431. data/spec/unit/provider/template_spec.rb +35 -11
  432. data/spec/unit/provider/user/dscl_spec.rb +285 -681
  433. data/spec/unit/provider/user/useradd_spec.rb +1 -22
  434. data/spec/unit/provider/user_spec.rb +1 -1
  435. data/spec/unit/recipe_spec.rb +10 -8
  436. data/spec/unit/registry_helper_spec.rb +374 -0
  437. data/spec/unit/resource/mount_spec.rb +0 -11
  438. data/spec/unit/resource/registry_key_spec.rb +171 -0
  439. data/spec/unit/resource/remote_file_spec.rb +21 -23
  440. data/spec/unit/resource/ruby_block_spec.rb +7 -3
  441. data/spec/unit/resource/service_spec.rb +11 -0
  442. data/spec/unit/resource_spec.rb +4 -19
  443. data/spec/unit/rest/auth_credentials_spec.rb +2 -19
  444. data/spec/unit/rest_spec.rb +130 -284
  445. data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
  446. data/spec/unit/run_context_spec.rb +18 -4
  447. data/spec/unit/run_list_spec.rb +0 -209
  448. data/spec/unit/run_lock_spec.rb +37 -0
  449. data/spec/unit/runner_spec.rb +101 -2
  450. data/spec/unit/scan_access_control_spec.rb +4 -4
  451. data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
  452. data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
  453. data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +14 -69
  454. data/spec/unit/shell_out_spec.rb +18 -0
  455. data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
  456. metadata +275 -234
  457. checksums.yaml +0 -15
  458. data/README.rdoc +0 -177
  459. data/distro/common/html/knife-recipe.1.html +0 -92
  460. data/lib/chef/certificate.rb +0 -161
  461. data/lib/chef/checksum.rb +0 -167
  462. data/lib/chef/checksum_cache.rb +0 -190
  463. data/lib/chef/cookbook_version_selector.rb +0 -168
  464. data/lib/chef/couchdb.rb +0 -246
  465. data/lib/chef/index_queue/amqp_client.rb +0 -116
  466. data/lib/chef/index_queue/consumer.rb +0 -76
  467. data/lib/chef/index_queue/indexable.rb +0 -109
  468. data/lib/chef/knife/bootstrap/ubuntu12.10-gems.erb +0 -60
  469. data/lib/chef/monkey_patches/moneta.rb +0 -50
  470. data/lib/chef/monkey_patches/uri.rb +0 -70
  471. data/lib/chef/openid_registration.rb +0 -187
  472. data/lib/chef/provider/user/solaris.rb +0 -90
  473. data/lib/chef/solr_query.rb +0 -187
  474. data/lib/chef/solr_query/lucene.treetop +0 -150
  475. data/lib/chef/solr_query/lucene_nodes.rb +0 -285
  476. data/lib/chef/solr_query/query_transform.rb +0 -65
  477. data/lib/chef/solr_query/solr_http_request.rb +0 -132
  478. data/lib/chef/webui_user.rb +0 -231
  479. data/spec/data/cookbooks/openldap/files/default/.dotfile +0 -1
  480. data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +0 -1
  481. data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +0 -1
  482. data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +0 -1
  483. data/spec/data/mac_users/10.7-8.plist.xml +0 -559
  484. data/spec/data/mac_users/10.7-8.shadow.xml +0 -11
  485. data/spec/data/mac_users/10.7.plist.xml +0 -559
  486. data/spec/data/mac_users/10.7.shadow.xml +0 -11
  487. data/spec/data/mac_users/10.8.plist.xml +0 -559
  488. data/spec/data/mac_users/10.8.shadow.xml +0 -21
  489. data/spec/data/mac_users/10.9.plist.xml +0 -560
  490. data/spec/data/mac_users/10.9.shadow.xml +0 -21
  491. data/spec/functional/resource/base.rb +0 -40
  492. data/spec/functional/resource/group_spec.rb +0 -343
  493. data/spec/functional/resource/user/dscl_spec.rb +0 -199
  494. data/spec/unit/certificate_spec.rb +0 -76
  495. data/spec/unit/checksum_cache_spec.rb +0 -209
  496. data/spec/unit/checksum_spec.rb +0 -94
  497. data/spec/unit/couchdb_spec.rb +0 -274
  498. data/spec/unit/index_queue_spec.rb +0 -391
  499. data/spec/unit/mixin/language_spec.rb +0 -305
  500. data/spec/unit/openid_registration_spec.rb +0 -153
  501. data/spec/unit/provider/user/solaris_spec.rb +0 -414
  502. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +0 -47
  503. data/spec/unit/solr_query/query_transform_spec.rb +0 -454
  504. data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
  505. data/spec/unit/solr_query_spec.rb +0 -203
  506. data/spec/unit/webui_user_spec.rb +0 -238
@@ -0,0 +1,110 @@
1
+ #
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2012 Opscode, 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 'chef/chef_fs/file_system'
20
+ require 'chef/chef_fs/file_system/base_fs_dir'
21
+ require 'chef/chef_fs/file_system/base_fs_object'
22
+
23
+ module FileSystemSupport
24
+ class MemoryFile < Chef::ChefFS::FileSystem::BaseFSObject
25
+ def initialize(name, parent, value)
26
+ super(name, parent)
27
+ @value = value
28
+ end
29
+ def read
30
+ return @value
31
+ end
32
+ end
33
+
34
+ class MemoryDir < Chef::ChefFS::FileSystem::BaseFSDir
35
+ def initialize(name, parent)
36
+ super(name, parent)
37
+ @children = []
38
+ end
39
+ attr_reader :children
40
+ def child(name)
41
+ @children.select { |child| child.name == name }.first || Chef::ChefFS::FileSystem::NonexistentFSObject.new(name, self)
42
+ end
43
+ def add_child(child)
44
+ @children.push(child)
45
+ end
46
+ def can_have_child?(name, is_dir)
47
+ root.cannot_be_in_regex ? (name !~ root.cannot_be_in_regex) : true
48
+ end
49
+ end
50
+
51
+ class MemoryRoot < MemoryDir
52
+ def initialize(pretty_name, cannot_be_in_regex = nil)
53
+ super('', nil)
54
+ @pretty_name = pretty_name
55
+ @cannot_be_in_regex = cannot_be_in_regex
56
+ end
57
+
58
+ attr_reader :cannot_be_in_regex
59
+
60
+ def path_for_printing
61
+ @pretty_name
62
+ end
63
+ end
64
+
65
+ def memory_fs(pretty_name, value, cannot_be_in_regex = nil)
66
+ if !value.is_a?(Hash)
67
+ raise "memory_fs() must take a Hash"
68
+ end
69
+ dir = MemoryRoot.new(pretty_name, cannot_be_in_regex)
70
+ value.each do |key, child|
71
+ dir.add_child(memory_fs_value(child, key.to_s, dir))
72
+ end
73
+ dir
74
+ end
75
+
76
+ def memory_fs_value(value, name = '', parent = nil)
77
+ if value.is_a?(Hash)
78
+ dir = MemoryDir.new(name, parent)
79
+ value.each do |key, child|
80
+ dir.add_child(memory_fs_value(child, key.to_s, dir))
81
+ end
82
+ dir
83
+ else
84
+ MemoryFile.new(name, parent, value || "#{name}\n")
85
+ end
86
+ end
87
+
88
+ def pattern(p)
89
+ Chef::ChefFS::FilePattern.new(p)
90
+ end
91
+
92
+ def return_paths(*expected)
93
+ ReturnPaths.new(expected)
94
+ end
95
+
96
+ def no_blocking_calls_allowed
97
+ [ MemoryFile, MemoryDir ].each do |c|
98
+ [ :children, :exists?, :read ].each do |m|
99
+ c.any_instance.stub(m).and_raise("#{m.to_s} should not be called")
100
+ end
101
+ end
102
+ end
103
+
104
+ def list_should_yield_paths(fs, pattern_str, *expected_paths)
105
+ result_paths = []
106
+ Chef::ChefFS::FileSystem.list(fs, pattern(pattern_str)) { |result| result_paths << result.path }
107
+ result_paths.should =~ expected_paths
108
+ end
109
+ end
110
+
@@ -0,0 +1,162 @@
1
+ #
2
+ # Author:: Seth Falcon (<seth@opscode.com>)
3
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010, 2012 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+
21
+ shared_examples_for "a platform introspector" do
22
+ before(:each) do
23
+ @platform_hash = {}
24
+ %w{openbsd freebsd}.each do |x|
25
+ @platform_hash[x] = {
26
+ "default" => x,
27
+ "1.2.3" => "#{x}-1.2.3"
28
+ }
29
+ end
30
+ @platform_hash["debian"] = {["5", "6"] => "debian-5/6", "default" => "debian"}
31
+ @platform_hash["default"] = "default"
32
+
33
+ @platform_family_hash = {
34
+ "debian" => "debian value",
35
+ [:rhel, :fedora] => "redhatty value",
36
+ "suse" => "suse value",
37
+ :default => "default value"
38
+ }
39
+ end
40
+
41
+ it "returns a default value when there is no known platform" do
42
+ node = Hash.new
43
+ platform_introspector.value_for_platform(@platform_hash).should == "default"
44
+ end
45
+
46
+ it "returns a default value when there is no known platform family" do
47
+ platform_introspector.value_for_platform_family(@platform_family_hash).should == "default value"
48
+ end
49
+
50
+ it "returns a default value when the current platform doesn't match" do
51
+ node.automatic_attrs[:platform] = "not-a-known-platform"
52
+ platform_introspector.value_for_platform(@platform_hash).should == "default"
53
+ end
54
+
55
+ it "returns a default value when current platform_family doesn't match" do
56
+ node.automatic_attrs[:platform_family] = "ultra-derived-linux"
57
+ platform_introspector.value_for_platform_family(@platform_family_hash).should == "default value"
58
+ end
59
+
60
+ it "returns a value based on the current platform" do
61
+ node.automatic_attrs[:platform] = "openbsd"
62
+ platform_introspector.value_for_platform(@platform_hash).should == "openbsd"
63
+ end
64
+
65
+ it "returns a value based on the current platform family" do
66
+ node.automatic_attrs[:platform_family] = "debian"
67
+ platform_introspector.value_for_platform_family(@platform_family_hash).should == "debian value"
68
+ end
69
+
70
+ it "returns a version-specific value based on the current platform" do
71
+ node.automatic_attrs[:platform] = "openbsd"
72
+ node.automatic_attrs[:platform_version] = "1.2.3"
73
+ platform_introspector.value_for_platform(@platform_hash).should == "openbsd-1.2.3"
74
+ end
75
+
76
+ it "returns a value based on the current platform if version not found" do
77
+ node.automatic_attrs[:platform] = "openbsd"
78
+ node.automatic_attrs[:platform_version] = "0.0.0"
79
+ platform_introspector.value_for_platform(@platform_hash).should == "openbsd"
80
+ end
81
+
82
+ describe "when platform versions is an array" do
83
+ it "returns a version-specific value based on the current platform" do
84
+ node.automatic_attrs[:platform] = "debian"
85
+ node.automatic_attrs[:platform_version] = "6"
86
+ platform_introspector.value_for_platform(@platform_hash).should == "debian-5/6"
87
+ end
88
+
89
+ it "returns a value based on the current platform if version not found" do
90
+ node.automatic_attrs[:platform] = "debian"
91
+ node.automatic_attrs[:platform_version] = "0.0.0"
92
+ platform_introspector.value_for_platform(@platform_hash).should == "debian"
93
+ end
94
+ end
95
+
96
+ describe "when checking platform?" do
97
+
98
+ it "returns true if the node is a provided platform and platforms are provided as symbols" do
99
+ node.automatic_attrs[:platform] = 'ubuntu'
100
+ platform_introspector.platform?([:redhat, :ubuntu]).should == true
101
+ end
102
+
103
+ it "returns true if the node is a provided platform and platforms are provided as strings" do
104
+ node.automatic_attrs[:platform] = 'ubuntu'
105
+ platform_introspector.platform?(["redhat", "ubuntu"]).should == true
106
+ end
107
+
108
+ it "returns false if the node is not of the provided platforms" do
109
+ node.automatic_attrs[:platform] = 'ubuntu'
110
+ platform_introspector.platform?(:splatlinux).should == false
111
+ end
112
+ end
113
+
114
+ describe "when checking platform_family?" do
115
+
116
+ it "returns true if the node is in a provided platform family and families are provided as symbols" do
117
+ node.automatic_attrs[:platform_family] = 'debian'
118
+ platform_introspector.platform_family?([:rhel, :debian]).should == true
119
+ end
120
+
121
+ it "returns true if the node is a provided platform and platforms are provided as strings" do
122
+ node.automatic_attrs[:platform_family] = 'rhel'
123
+ platform_introspector.platform_family?(["rhel", "debian"]).should == true
124
+ end
125
+
126
+ it "returns false if the node is not of the provided platforms" do
127
+ node.automatic_attrs[:platform_family] = 'suse'
128
+ platform_introspector.platform_family?(:splatlinux).should == false
129
+ end
130
+
131
+ it "returns false if the node is not of the provided platforms and platform_family is not set" do
132
+ platform_introspector.platform_family?(:splatlinux).should == false
133
+ end
134
+
135
+ end
136
+ # NOTE: this is a regression test for bug CHEF-1514
137
+ describe "when the value is an array" do
138
+ before do
139
+ @platform_hash = {
140
+ "debian" => { "4.0" => [ :restart, :reload ], "default" => [ :restart, :reload, :status ] },
141
+ "ubuntu" => { "default" => [ :restart, :reload, :status ] },
142
+ "centos" => { "default" => [ :restart, :reload, :status ] },
143
+ "redhat" => { "default" => [ :restart, :reload, :status ] },
144
+ "fedora" => { "default" => [ :restart, :reload, :status ] },
145
+ "default" => { "default" => [:restart, :reload ] }}
146
+ end
147
+
148
+ it "returns the correct default for a given platform" do
149
+ node.automatic_attrs[:platform] = "debian"
150
+ node.automatic_attrs[:platform_version] = '9000'
151
+ platform_introspector.value_for_platform(@platform_hash).should == [ :restart, :reload, :status ]
152
+ end
153
+
154
+ it "returns the correct platform+version specific value " do
155
+ node.automatic_attrs[:platform] = "debian"
156
+ node.automatic_attrs[:platform_version] = '4.0'
157
+ platform_introspector.value_for_platform(@platform_hash).should == [:restart, :reload]
158
+ end
159
+ end
160
+
161
+ end
162
+
@@ -0,0 +1,175 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Copyright:: Copyright (c) 2012 Opscode, 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 'spec_helper'
20
+ require 'tempfile'
21
+
22
+ require 'chef/api_client/registration'
23
+
24
+ describe Chef::ApiClient::Registration do
25
+ let(:key_location) do
26
+ path = nil
27
+ Tempfile.open("client-registration-key") {|f| path = f.path }
28
+ File.unlink(path)
29
+ path
30
+ end
31
+
32
+ let(:registration) { Chef::ApiClient::Registration.new("silent-bob", key_location) }
33
+
34
+ let :private_key_data do
35
+ File.open(Chef::Config[:validation_key], "r") {|f| f.read.chomp }
36
+ end
37
+
38
+ before do
39
+ Chef::Config[:validation_client_name] = "test-validator"
40
+ Chef::Config[:validation_key] = File.expand_path('ssl/private_key.pem', CHEF_SPEC_DATA)
41
+ end
42
+
43
+ after do
44
+ File.unlink(key_location) if File.exist?(key_location)
45
+ Chef::Config[:validation_client_name] = nil
46
+ Chef::Config[:validation_key] = nil
47
+ end
48
+
49
+ it "has an HTTP client configured with validator credentials" do
50
+ registration.http_api.should be_a_kind_of(Chef::REST)
51
+ registration.http_api.client_name.should == "test-validator"
52
+ registration.http_api.signing_key.should == private_key_data
53
+ end
54
+
55
+ describe "when creating/updating the client on the server" do
56
+ let(:http_mock) { mock("Chef::REST mock") }
57
+
58
+ before do
59
+ registration.stub!(:http_api).and_return(http_mock)
60
+ end
61
+
62
+ it "creates a new ApiClient on the server using the validator identity" do
63
+ response = {"uri" => "https://chef.local/clients/silent-bob",
64
+ "private_key" => "--begin rsa key etc--"}
65
+ http_mock.should_receive(:post).
66
+ with("clients", :name => 'silent-bob', :admin => false).
67
+ and_return(response)
68
+ registration.create_or_update.should == response
69
+ registration.private_key.should == "--begin rsa key etc--"
70
+ end
71
+
72
+ context "and the client already exists on a Chef 10 server" do
73
+ it "requests a new key from the server and saves it" do
74
+ response = {"name" => "silent-bob", "private_key" => "--begin rsa key etc--" }
75
+
76
+ response_409 = Net::HTTPConflict.new("1.1", "409", "Conflict")
77
+ exception_409 = Net::HTTPServerException.new("409 conflict", response_409)
78
+
79
+ http_mock.should_receive(:post).and_raise(exception_409)
80
+ http_mock.should_receive(:put).
81
+ with("clients/silent-bob", :name => 'silent-bob', :admin => false, :private_key => true).
82
+ and_return(response)
83
+ registration.create_or_update.should == response
84
+ registration.private_key.should == "--begin rsa key etc--"
85
+ end
86
+ end
87
+
88
+ context "and the client already exists on a Chef 11 server" do
89
+ it "requests a new key from the server and saves it" do
90
+ response = Chef::ApiClient.new
91
+ response.name("silent-bob")
92
+ response.private_key("--begin rsa key etc--")
93
+
94
+ response_409 = Net::HTTPConflict.new("1.1", "409", "Conflict")
95
+ exception_409 = Net::HTTPServerException.new("409 conflict", response_409)
96
+
97
+ http_mock.should_receive(:post).and_raise(exception_409)
98
+ http_mock.should_receive(:put).
99
+ with("clients/silent-bob", :name => 'silent-bob', :admin => false, :private_key => true).
100
+ and_return(response)
101
+ registration.create_or_update.should == response
102
+ registration.private_key.should == "--begin rsa key etc--"
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "when writing the private key to disk" do
108
+ before do
109
+ registration.stub!(:private_key).and_return('--begin rsa key etc--')
110
+ end
111
+
112
+ # Permission read via File.stat is busted on windows, though creating the
113
+ # file with 0600 has the desired effect of giving access rights to the
114
+ # owner only. A platform-specific functional test would be helpful.
115
+ it "creates the file with 0600 permissions", :unix_only do
116
+ File.should_not exist(key_location)
117
+ registration.write_key
118
+ File.should exist(key_location)
119
+ stat = File.stat(key_location)
120
+ (stat.mode & 07777).should == 0600
121
+ end
122
+
123
+ it "writes the private key content to the file" do
124
+ registration.write_key
125
+ IO.read(key_location).should == "--begin rsa key etc--"
126
+ end
127
+ end
128
+
129
+ describe "when registering a client" do
130
+
131
+ let(:http_mock) { mock("Chef::REST mock") }
132
+
133
+ before do
134
+ registration.stub!(:http_api).and_return(http_mock)
135
+ end
136
+
137
+ it "creates the client on the server and writes the key" do
138
+ response = {"uri" => "http://chef.local/clients/silent-bob",
139
+ "private_key" => "--begin rsa key etc--" }
140
+ http_mock.should_receive(:post).ordered.and_return(response)
141
+ registration.run
142
+ IO.read(key_location).should == "--begin rsa key etc--"
143
+ end
144
+
145
+ it "retries up to 5 times" do
146
+ response_500 = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
147
+ exception_500 = Net::HTTPFatalError.new("500 Internal Server Error", response_500)
148
+
149
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 1
150
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 2
151
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 3
152
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 4
153
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 5
154
+
155
+ response = {"uri" => "http://chef.local/clients/silent-bob",
156
+ "private_key" => "--begin rsa key etc--" }
157
+ http_mock.should_receive(:post).ordered.and_return(response)
158
+ registration.run
159
+ IO.read(key_location).should == "--begin rsa key etc--"
160
+ end
161
+
162
+ it "gives up retrying after the max attempts" do
163
+ response_500 = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
164
+ exception_500 = Net::HTTPFatalError.new("500 Internal Server Error", response_500)
165
+
166
+ http_mock.should_receive(:post).exactly(6).times.and_raise(exception_500)
167
+
168
+ lambda {registration.run}.should raise_error(Net::HTTPFatalError)
169
+ end
170
+
171
+ end
172
+
173
+ end
174
+
175
+
@@ -6,9 +6,9 @@
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,128 +26,85 @@ describe Chef::ApiClient do
26
26
  @client = Chef::ApiClient.new
27
27
  end
28
28
 
29
- describe "initialize" do
30
- it "should be a Chef::ApiClient" do
31
- @client.should be_a_kind_of(Chef::ApiClient)
32
- end
29
+ it "has a name attribute" do
30
+ @client.name("ops_master")
31
+ @client.name.should == "ops_master"
33
32
  end
34
33
 
35
- describe "name" do
36
- it "should let you set the name to a string" do
37
- @client.name("ops_master").should == "ops_master"
38
- end
39
-
40
- it "should return the current name" do
41
- @client.name "ops_master"
42
- @client.name.should == "ops_master"
43
- end
44
-
45
- it "should not accept spaces" do
46
- lambda { @client.name "ops master" }.should raise_error(ArgumentError)
47
- end
48
-
49
- it "should throw an ArgumentError if you feed it anything but a string" do
50
- lambda { @client.name Hash.new }.should raise_error(ArgumentError)
51
- end
34
+ it "does not allow spaces in the name" do
35
+ lambda { @client.name "ops master" }.should raise_error(ArgumentError)
52
36
  end
53
37
 
54
- describe "admin" do
55
- it "should let you set the admin bit" do
56
- @client.admin(true).should == true
57
- end
38
+ it "only allows string values for the name" do
39
+ lambda { @client.name Hash.new }.should raise_error(ArgumentError)
40
+ end
58
41
 
59
- it "should return the current admin value" do
60
- @client.admin true
61
- @client.admin.should == true
62
- end
42
+ it "has an admin flag attribute" do
43
+ @client.admin(true)
44
+ @client.admin.should be_true
45
+ end
63
46
 
64
- it "should default to false" do
65
- @client.admin.should == false
66
- end
47
+ it "defaults to non-admin" do
48
+ @client.admin.should be_false
49
+ end
67
50
 
68
- it "should throw an ArgumentError if you feed it anything but true or false" do
69
- lambda { @client.name Hash.new }.should raise_error(ArgumentError)
70
- end
51
+ it "allows only boolean values for the admin flag" do
52
+ lambda { @client.admin(false) }.should_not raise_error
53
+ lambda { @client.admin(Hash.new) }.should raise_error(ArgumentError)
71
54
  end
72
55
 
73
- describe "public_key" do
74
- it "should let you set the public key" do
75
- @client.public_key("super public").should == "super public"
76
- end
77
56
 
78
- it "should return the current public key" do
79
- @client.public_key("super public")
80
- @client.public_key.should == "super public"
81
- end
57
+ it "has a public key attribute" do
58
+ @client.public_key("super public")
59
+ @client.public_key.should == "super public"
60
+ end
82
61
 
83
- it "should throw an ArgumentError if you feed it something lame" do
84
- lambda { @client.public_key Hash.new }.should raise_error(ArgumentError)
85
- end
62
+ it "accepts only String values for the public key" do
63
+ lambda { @client.public_key "" }.should_not raise_error
64
+ lambda { @client.public_key Hash.new }.should raise_error(ArgumentError)
86
65
  end
87
66
 
88
- describe "private_key" do
89
- it "should let you set the private key" do
90
- @client.private_key("super private").should == "super private"
91
- end
92
67
 
93
- it "should return the private key" do
94
- @client.private_key("super private")
95
- @client.private_key.should == "super private"
96
- end
68
+ it "has a private key attribute" do
69
+ @client.private_key("super private")
70
+ @client.private_key.should == "super private"
71
+ end
97
72
 
98
- it "should throw an ArgumentError if you feed it something lame" do
99
- lambda { @client.private_key Hash.new }.should raise_error(ArgumentError)
100
- end
73
+ it "accepts only String values for the private key" do
74
+ lambda { @client.private_key "" }.should_not raise_error
75
+ lambda { @client.private_key Hash.new }.should raise_error(ArgumentError)
101
76
  end
102
77
 
103
- describe "create_keys" do
78
+ describe "when serializing to JSON" do
104
79
  before(:each) do
105
- Chef::Certificate.stub!(:gen_keypair).and_return(["cert", "key"])
106
- end
107
-
108
- it "should create a certificate based on the client name" do
109
- Chef::Certificate.should_receive(:gen_keypair).with(@client.name)
110
- @client.create_keys
111
- end
112
-
113
- it "should set the private key" do
114
- @client.create_keys
115
- @client.private_key.should == "key"
80
+ @client.name("black")
81
+ @client.public_key("crowes")
82
+ @json = @client.to_json
116
83
  end
117
84
 
118
- it "should set the public key" do
119
- @client.create_keys
120
- @client.public_key.should == "cert"
85
+ it "serializes as a JSON object" do
86
+ @json.should match(/^\{.+\}$/)
121
87
  end
122
- end
123
88
 
124
- describe "serialize" do
125
- before(:each) do
126
- @client.name("black")
127
- @client.public_key("crowes")
128
- @client.private_key("monkeypants")
129
- @serial = @client.to_json
89
+ it "includes the name value" do
90
+ @json.should include(%q{"name":"black"})
130
91
  end
131
92
 
132
- it "should serialize to a json hash" do
133
- @client.to_json.should match(/^\{.+\}$/)
93
+ it "includes the public key value" do
94
+ @json.should include(%{"public_key":"crowes"})
134
95
  end
135
96
 
136
- %w{
137
- name
138
- public_key
139
- }.each do |t|
140
- it "should include '#{t}'" do
141
- @serial.should =~ /"#{t}":"#{@client.send(t.to_sym)}"/
142
- end
97
+ it "includes the 'admin' flag" do
98
+ @json.should include(%q{"admin":false})
143
99
  end
144
100
 
145
- it "should include 'admin'" do
146
- @serial.should =~ /"admin":false/
101
+ it "includes the private key when present" do
102
+ @client.private_key("monkeypants")
103
+ @client.to_json.should include(%q{"private_key":"monkeypants"})
147
104
  end
148
105
 
149
- it "should not include the private key" do
150
- @serial.should_not =~ /"private_key":/
106
+ it "does not include the private key if not present" do
107
+ @json.should_not include("private_key")
151
108
  end
152
109
  end
153
110
 
@@ -185,6 +142,29 @@ describe Chef::ApiClient do
185
142
 
186
143
  end
187
144
 
145
+ describe "with correctly configured API credentials" do
146
+ before do
147
+ Chef::Config[:node_name] = "silent-bob"
148
+ Chef::Config[:client_key] = File.expand_path('ssl/private_key.pem', CHEF_SPEC_DATA)
149
+ end
150
+
151
+ after do
152
+ Chef::Config[:node_name] = nil
153
+ Chef::Config[:client_key] = nil
154
+ end
155
+
156
+ let :private_key_data do
157
+ File.open(Chef::Config[:client_key], "r") {|f| f.read.chomp }
158
+ end
159
+
160
+ it "has an HTTP client configured with default credentials" do
161
+ @client.http_api.should be_a_kind_of(Chef::REST)
162
+ @client.http_api.client_name.should == "silent-bob"
163
+ @client.http_api.signing_key.to_s.should == private_key_data
164
+ end
165
+ end
166
+
167
+
188
168
  describe "when requesting a new key" do
189
169
  before do
190
170
  @http_client = mock("Chef::REST mock")
@@ -196,7 +176,7 @@ describe Chef::ApiClient do
196
176
  @a_404_response = Net::HTTPNotFound.new("404 not found and such", nil, nil)
197
177
  @a_404_exception = Net::HTTPServerException.new("404 not found exception", @a_404_response)
198
178
 
199
- @http_client.should_receive(:get_rest).with("clients/lost-my-key").and_raise(@a_404_exception)
179
+ @http_client.should_receive(:get).with("clients/lost-my-key").and_raise(@a_404_exception)
200
180
  end
201
181
 
202
182
  it "raises a 404 error" do
@@ -208,7 +188,7 @@ describe Chef::ApiClient do
208
188
  before do
209
189
  @api_client_without_key = Chef::ApiClient.new
210
190
  @api_client_without_key.name("lost-my-key")
211
- @http_client.should_receive(:get_rest).with("clients/lost-my-key").and_return(@api_client_without_key)
191
+ @http_client.should_receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key)
212
192
  end
213
193
 
214
194
 
@@ -217,7 +197,7 @@ describe Chef::ApiClient do
217
197
  @api_client_with_key = Chef::ApiClient.new
218
198
  @api_client_with_key.name("lost-my-key")
219
199
  @api_client_with_key.private_key("the new private key")
220
- @http_client.should_receive(:put_rest).
200
+ @http_client.should_receive(:put).
221
201
  with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :private_key => true).
222
202
  and_return(@api_client_with_key)
223
203
  end
@@ -235,7 +215,7 @@ describe Chef::ApiClient do
235
215
  context "and the client exists on a Chef 10-like server" do
236
216
  before do
237
217
  @api_client_with_key = {"name" => "lost-my-key", "private_key" => "the new private key"}
238
- @http_client.should_receive(:put_rest).
218
+ @http_client.should_receive(:put).
239
219
  with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :private_key => true).
240
220
  and_return(@api_client_with_key)
241
221
  end
@@ -251,64 +231,6 @@ describe Chef::ApiClient do
251
231
  end
252
232
 
253
233
  end
254
-
255
- context "and client side key generation is enabled" do
256
-
257
- let(:response) { {"uri"=> "https://example.com/clients/selfgenkeytest-1395958070", "public_key" => "rsa-key-data"} }
258
- let(:pkey_in) { IO.read(File.join(CHEF_SPEC_DATA, "ssl/private_key.pem")) }
259
-
260
- let(:generated_key) { OpenSSL::PKey::RSA.new(pkey_in) }
261
- let(:generated_public_key) { generated_key.public_key }
262
-
263
- before do
264
- @client.name("deadsexy")
265
- OpenSSL::PKey::RSA.stub(:generate).and_return(generated_key)
266
- Chef::Config.stub(:local_key_generation).and_return true
267
- end
268
-
269
- context "and the client doesn't exist" do
270
- let(:response) { {"uri"=> "https://example.com/clients/selfgenkeytest-1395958070", "public_key" => "rsa-key-data"} }
271
- let(:pkey_in) { IO.read(File.join(CHEF_SPEC_DATA, "ssl/private_key.pem")) }
272
-
273
- let(:generated_key) { OpenSSL::PKey::RSA.new(pkey_in) }
274
- let(:generated_public_key) { generated_key.public_key }
275
-
276
- before do
277
- @http_client.should_receive(:post_rest).
278
- with("clients", :name => "deadsexy", :admin => false, :public_key => generated_public_key.to_pem).
279
- and_return(response)
280
- end
281
-
282
- it "creates the client with self generated key" do
283
- @client.save(true, true)
284
- @client.private_key.should == generated_key.to_pem
285
- end
286
-
287
- end
288
-
289
- context "and the client already exists" do
290
- before do
291
- http_conflict_response = Net::HTTPConflict.new("409 blah blah", "409", "409")
292
- http_conflict_error = Net::HTTPServerException.new("409 conflict", http_conflict_response)
293
-
294
- @http_client.should_receive(:post_rest).
295
- with("clients", :name => "deadsexy", :admin => false, :public_key => generated_public_key.to_pem).
296
- and_raise(http_conflict_error)
297
-
298
- @http_client.should_receive(:put_rest).
299
- with("clients/deadsexy", :name => "deadsexy", :admin => false, :public_key => generated_public_key.to_pem).
300
- and_return(response)
301
- end
302
-
303
- it "creates the client with self generated key" do
304
- @client.save(true, true)
305
- @client.private_key.should == generated_key.to_pem
306
- end
307
-
308
- end
309
-
310
- end
311
-
312
234
  end
313
235
  end
314
236