chef-dk 0.11.2 → 0.12.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 (325) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +186 -190
  3. data/Gemfile +30 -26
  4. data/LICENSE +201 -201
  5. data/README.md +307 -307
  6. data/Rakefile +29 -27
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -0
  8. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +284 -0
  9. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -0
  10. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -0
  11. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -0
  12. data/acceptance/Gemfile +11 -0
  13. data/acceptance/README.md +132 -0
  14. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -0
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -0
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -0
  17. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -0
  18. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -0
  19. data/acceptance/trivial/.kitchen.yml +7 -0
  20. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -0
  21. data/bin/chef +25 -25
  22. data/chef-dk.gemspec +64 -64
  23. data/lib/chef-dk.rb +19 -19
  24. data/lib/chef-dk/authenticated_http.rb +40 -40
  25. data/lib/chef-dk/builtin_commands.rb +60 -60
  26. data/lib/chef-dk/chef_runner.rb +107 -107
  27. data/lib/chef-dk/cli.rb +200 -200
  28. data/lib/chef-dk/command/base.rb +79 -79
  29. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
  30. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
  31. data/lib/chef-dk/command/delete_policy.rb +122 -122
  32. data/lib/chef-dk/command/delete_policy_group.rb +122 -122
  33. data/lib/chef-dk/command/diff.rb +316 -316
  34. data/lib/chef-dk/command/env.rb +90 -90
  35. data/lib/chef-dk/command/exec.rb +45 -45
  36. data/lib/chef-dk/command/export.rb +157 -157
  37. data/lib/chef-dk/command/gem.rb +47 -47
  38. data/lib/chef-dk/command/generate.rb +120 -120
  39. data/lib/chef-dk/command/generator_commands.rb +80 -80
  40. data/lib/chef-dk/command/generator_commands/app.rb +107 -107
  41. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
  42. data/lib/chef-dk/command/generator_commands/base.rb +148 -148
  43. data/lib/chef-dk/command/generator_commands/cookbook.rb +153 -153
  44. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  45. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  46. data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -177
  47. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
  48. data/lib/chef-dk/command/generator_commands/policyfile.rb +127 -127
  49. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  50. data/lib/chef-dk/command/generator_commands/repo.rb +125 -125
  51. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  52. data/lib/chef-dk/command/install.rb +121 -121
  53. data/lib/chef-dk/command/provision.rb +438 -438
  54. data/lib/chef-dk/command/push.rb +118 -118
  55. data/lib/chef-dk/command/push_archive.rb +126 -126
  56. data/lib/chef-dk/command/shell_init.rb +180 -180
  57. data/lib/chef-dk/command/show_policy.rb +165 -165
  58. data/lib/chef-dk/command/undelete.rb +155 -155
  59. data/lib/chef-dk/command/update.rb +148 -148
  60. data/lib/chef-dk/command/verify.rb +534 -534
  61. data/lib/chef-dk/commands_map.rb +115 -115
  62. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  63. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  64. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  65. data/lib/chef-dk/component_test.rb +194 -173
  66. data/lib/chef-dk/configurable.rb +69 -69
  67. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  68. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  69. data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
  70. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  71. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
  72. data/lib/chef-dk/exceptions.rb +129 -129
  73. data/lib/chef-dk/generator.rb +163 -163
  74. data/lib/chef-dk/helpers.rb +159 -159
  75. data/lib/chef-dk/pager.rb +106 -106
  76. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  77. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
  78. data/lib/chef-dk/policyfile/community_cookbook_source.rb +97 -97
  79. data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
  80. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  81. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  82. data/lib/chef-dk/policyfile/cookbook_sources.rb +22 -22
  83. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +90 -90
  84. data/lib/chef-dk/policyfile/differ.rb +266 -266
  85. data/lib/chef-dk/policyfile/dsl.rb +261 -261
  86. data/lib/chef-dk/policyfile/lister.rb +232 -232
  87. data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
  88. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  89. data/lib/chef-dk/policyfile/reports/install.rb +70 -70
  90. data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
  91. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  92. data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
  93. data/lib/chef-dk/policyfile/storage_config.rb +100 -100
  94. data/lib/chef-dk/policyfile/undo_record.rb +142 -142
  95. data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
  96. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  97. data/lib/chef-dk/policyfile_compiler.rb +419 -419
  98. data/lib/chef-dk/policyfile_lock.rb +552 -552
  99. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  100. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
  101. data/lib/chef-dk/policyfile_services/export_repo.rb +421 -414
  102. data/lib/chef-dk/policyfile_services/install.rb +126 -126
  103. data/lib/chef-dk/policyfile_services/push.rb +114 -114
  104. data/lib/chef-dk/policyfile_services/push_archive.rb +204 -204
  105. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
  106. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
  107. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
  108. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  109. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
  110. data/lib/chef-dk/service_exception_inspectors.rb +25 -25
  111. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
  112. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
  113. data/lib/chef-dk/service_exceptions.rb +143 -143
  114. data/lib/chef-dk/shell_out.rb +36 -36
  115. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
  116. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +102 -102
  117. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  118. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
  119. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
  120. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
  121. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  122. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
  123. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
  124. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
  125. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +58 -58
  126. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  127. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  128. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  129. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  130. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  131. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  132. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  133. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -8
  134. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
  135. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -2
  136. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  137. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
  138. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
  139. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +117 -117
  140. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -24
  141. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -23
  142. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -8
  143. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +27 -27
  144. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +67 -67
  145. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  146. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  147. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -201
  148. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  149. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  150. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  151. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  152. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  153. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +21 -21
  154. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +32 -32
  155. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +7 -7
  156. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  157. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +20 -20
  158. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -11
  159. data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +9 -9
  160. data/lib/chef-dk/ui.rb +58 -58
  161. data/lib/chef-dk/version.rb +20 -20
  162. data/lib/kitchen/provisioner/policyfile_zero.rb +194 -194
  163. data/spec/shared/a_file_generator.rb +125 -125
  164. data/spec/shared/a_generated_file.rb +12 -12
  165. data/spec/shared/command_with_ui_object.rb +11 -11
  166. data/spec/shared/custom_generator_cookbook.rb +130 -130
  167. data/spec/shared/fixture_cookbook_checksums.rb +47 -47
  168. data/spec/shared/setup_git_cookbooks.rb +53 -53
  169. data/spec/spec_helper.rb +51 -50
  170. data/spec/test_helpers.rb +84 -84
  171. data/spec/unit/chef_runner_spec.rb +139 -139
  172. data/spec/unit/cli_spec.rb +357 -357
  173. data/spec/unit/command/base_spec.rb +169 -169
  174. data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -181
  175. data/spec/unit/command/clean_policy_revisions_spec.rb +181 -181
  176. data/spec/unit/command/delete_policy_group_spec.rb +207 -207
  177. data/spec/unit/command/delete_policy_spec.rb +207 -207
  178. data/spec/unit/command/diff_spec.rb +312 -312
  179. data/spec/unit/command/env_spec.rb +52 -52
  180. data/spec/unit/command/exec_spec.rb +179 -179
  181. data/spec/unit/command/export_spec.rb +200 -200
  182. data/spec/unit/command/generate_spec.rb +142 -142
  183. data/spec/unit/command/generator_commands/app_spec.rb +169 -169
  184. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -32
  185. data/spec/unit/command/generator_commands/base_spec.rb +136 -136
  186. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
  187. data/spec/unit/command/generator_commands/cookbook_spec.rb +450 -450
  188. data/spec/unit/command/generator_commands/generator_generator_spec.rb +229 -229
  189. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -32
  190. data/spec/unit/command/generator_commands/policyfile_spec.rb +225 -225
  191. data/spec/unit/command/generator_commands/recipe_spec.rb +34 -34
  192. data/spec/unit/command/generator_commands/repo_spec.rb +367 -367
  193. data/spec/unit/command/generator_commands/template_spec.rb +32 -32
  194. data/spec/unit/command/install_spec.rb +179 -179
  195. data/spec/unit/command/provision_spec.rb +592 -592
  196. data/spec/unit/command/push_archive_spec.rb +153 -153
  197. data/spec/unit/command/push_spec.rb +199 -199
  198. data/spec/unit/command/shell_init_spec.rb +329 -329
  199. data/spec/unit/command/show_policy_spec.rb +235 -235
  200. data/spec/unit/command/undelete_spec.rb +246 -246
  201. data/spec/unit/command/update_spec.rb +275 -275
  202. data/spec/unit/command/verify_spec.rb +325 -325
  203. data/spec/unit/commands_map_spec.rb +57 -57
  204. data/spec/unit/component_test_spec.rb +126 -126
  205. data/spec/unit/configurable_spec.rb +41 -41
  206. data/spec/unit/cookbook_metadata_spec.rb +98 -98
  207. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  208. data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
  209. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  210. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  211. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  212. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  213. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  214. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  215. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  216. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  217. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  218. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  219. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  220. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  221. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  222. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  223. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  224. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  225. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  226. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  227. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  228. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  229. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  230. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  231. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  232. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  233. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  234. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  235. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  236. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
  237. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  238. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  239. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  240. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  241. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  242. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  243. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  244. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  245. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  246. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  247. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  248. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  249. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  250. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  251. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  252. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  253. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  254. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  255. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  256. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  257. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  258. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  259. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  260. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  261. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  262. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  263. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  264. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  265. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  266. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  267. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  268. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  269. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  270. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  271. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  272. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  273. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  274. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  275. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/extra/extra_file.txt +0 -0
  276. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  277. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  278. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  279. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  280. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  281. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  282. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  283. data/spec/unit/generator_spec.rb +120 -120
  284. data/spec/unit/helpers_spec.rb +92 -92
  285. data/spec/unit/pager_spec.rb +119 -119
  286. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  287. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
  288. data/spec/unit/policyfile/community_cookbook_source_spec.rb +84 -84
  289. data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
  290. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +277 -277
  291. data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
  292. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +130 -130
  293. data/spec/unit/policyfile/differ_spec.rb +687 -687
  294. data/spec/unit/policyfile/lister_spec.rb +272 -272
  295. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
  296. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  297. data/spec/unit/policyfile/reports/install_spec.rb +115 -115
  298. data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
  299. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
  300. data/spec/unit/policyfile/storage_config_spec.rb +172 -172
  301. data/spec/unit/policyfile/undo_record_spec.rb +260 -260
  302. data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
  303. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  304. data/spec/unit/policyfile_demands_spec.rb +1203 -1203
  305. data/spec/unit/policyfile_evaluation_spec.rb +642 -642
  306. data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
  307. data/spec/unit/policyfile_lock_install_spec.rb +138 -138
  308. data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
  309. data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
  310. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  311. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
  312. data/spec/unit/policyfile_services/export_repo_spec.rb +481 -481
  313. data/spec/unit/policyfile_services/install_spec.rb +211 -211
  314. data/spec/unit/policyfile_services/push_archive_spec.rb +378 -378
  315. data/spec/unit/policyfile_services/push_spec.rb +233 -233
  316. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
  317. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
  318. data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
  319. data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
  320. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
  321. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
  322. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
  323. data/spec/unit/shell_out_spec.rb +34 -34
  324. data/warning.txt +9 -9
  325. metadata +24 -19
@@ -1,211 +1,211 @@
1
- #
2
- # Copyright:: Copyright (c) 2014 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
- require 'chef-dk/policyfile_services/install'
20
-
21
- describe ChefDK::PolicyfileServices::Install do
22
-
23
- include ChefDK::Helpers
24
-
25
- let(:working_dir) do
26
- path = File.join(tempdir, "policyfile_services_test_working_dir")
27
- Dir.mkdir(path)
28
- path
29
- end
30
-
31
- let(:policyfile_rb_explicit_name) { nil }
32
-
33
- let(:policyfile_rb_name) { policyfile_rb_explicit_name || "Policyfile.rb" }
34
-
35
- let(:policyfile_lock_name) { "Policyfile.lock.json" }
36
-
37
- let(:policyfile_rb_path) { File.join(working_dir, policyfile_rb_name) }
38
-
39
- let(:policyfile_lock_path) { File.join(working_dir, policyfile_lock_name) }
40
-
41
- let(:local_cookbooks_root) do
42
- File.join(fixtures_path, "local_path_cookbooks")
43
- end
44
-
45
- let(:policyfile_content) do
46
- <<-E
47
- name 'install-example'
48
-
49
- run_list 'local-cookbook'
50
-
51
- cookbook 'local-cookbook', path: '#{local_cookbooks_root}/local-cookbook'
52
- E
53
- end
54
-
55
- let(:overwrite) { false }
56
-
57
- let(:ui) { TestHelpers::TestUI.new }
58
-
59
- let(:install_service) { described_class.new(policyfile: policyfile_rb_name, ui: ui, root_dir: working_dir, overwrite: overwrite) }
60
-
61
- let(:storage_config) do
62
- ChefDK::Policyfile::StorageConfig.new( cache_path: nil, relative_paths_root: local_cookbooks_root )
63
- end
64
-
65
- def result_policyfile_lock
66
- expect(File).to exist(policyfile_lock_path)
67
- content = IO.read(policyfile_lock_path)
68
- lock_data = FFI_Yajl::Parser.parse(content)
69
- ChefDK::PolicyfileLock.new(storage_config).build_from_lock_data(lock_data)
70
- end
71
-
72
- context "when no Policyfile is present or specified" do
73
-
74
- it "errors out" do
75
- expect { install_service.run }.to raise_error(ChefDK::PolicyfileNotFound, "Policyfile not found at path #{policyfile_rb_path}")
76
- end
77
-
78
- end
79
-
80
- context "when a Policyfile exists" do
81
-
82
- before do
83
- with_file(policyfile_rb_path) { |f| f.print(policyfile_content) }
84
- end
85
-
86
- it "infers that the Policyfile.rb is located at $CWD/Policyfile.rb" do
87
- expect(install_service.policyfile_expanded_path).to eq(policyfile_rb_path)
88
- end
89
-
90
- it "reads the policyfile from disk" do
91
- expect(install_service.policyfile_content).to eq(policyfile_content)
92
- end
93
-
94
- context "and the policyfile has an error" do
95
-
96
- let(:policyfile_content) { 'raise "borkbork"' }
97
-
98
- it "errors out and creates no lockfile" do
99
- expect { install_service.run }.to raise_error(ChefDK::PolicyfileInstallError)
100
- expect(File).to_not exist(policyfile_lock_path)
101
- end
102
-
103
- end
104
-
105
- context "and no lockfile exists" do
106
-
107
- it "solves the Policyfile demands, installs cookbooks, emits a lockfile" do
108
- install_service.run
109
- generated_lock = result_policyfile_lock
110
- expect(generated_lock.name).to eq('install-example')
111
- expect(generated_lock.cookbook_locks).to have_key("local-cookbook")
112
- end
113
-
114
- it "prints the policy name" do
115
- install_service.run
116
- expect(ui.output).to include("Building policy install-example")
117
- end
118
-
119
- it "prints the expanded run list" do
120
- install_service.run
121
- expect(ui.output).to include("Expanded run list: recipe[local-cookbook]")
122
- end
123
-
124
- it "prints the lockfile path" do
125
- install_service.run
126
- expect(ui.output).to include("Lockfile written to #{working_dir}/Policyfile.lock.json")
127
- end
128
-
129
- it "prints the lockfile's revision id" do
130
- install_service.run
131
- expect(ui.output).to include("Policy revision id: 60e5ad638dce219d8f87d589463ec4a9884007ba5e2adbb4c0a7021d67204f1a")
132
- end
133
-
134
- end
135
-
136
- context "and a lockfile exists and `overwrite` is specified" do
137
-
138
- let(:overwrite) { true }
139
-
140
- before do
141
- File.binwrite(policyfile_lock_path, "This is the old lockfile content")
142
- end
143
-
144
- it "solves the Policyfile demands, installs cookbooks, emits a lockfile" do
145
- install_service.run
146
- generated_lock = result_policyfile_lock
147
- expect(generated_lock.name).to eq('install-example')
148
- expect(generated_lock.cookbook_locks).to have_key("local-cookbook")
149
- end
150
-
151
- end
152
-
153
- context "and a lockfile exists" do
154
-
155
- before do
156
- install_service.dup.run
157
- end
158
-
159
- it "reads the policyfile lock from disk" do
160
- lock = install_service.policyfile_lock
161
- expect(lock).to be_an_instance_of(ChefDK::PolicyfileLock)
162
- expect(lock.name).to eq('install-example')
163
- expect(lock.cookbook_locks).to have_key("local-cookbook")
164
- end
165
-
166
- it "ensures that cookbooks are installed" do
167
- expect(install_service.policyfile_lock).to receive(:install_cookbooks).and_call_original
168
- install_service.run
169
- end
170
-
171
- describe "when an error occurs during the install" do
172
-
173
- before do
174
- expect(install_service.policyfile_lock).to receive(:install_cookbooks).and_raise("some error")
175
- end
176
-
177
- it "raises a PolicyfileInstallError" do
178
- expect { install_service.run }.to raise_error(ChefDK::PolicyfileInstallError)
179
- end
180
-
181
-
182
- end
183
-
184
- context "and the Policyfile has updated dependendencies" do
185
-
186
- # For very first iteration, we won't tackle this case if it's hard
187
- it "Conservatively updates deps, recomputes lock, and installs"
188
-
189
- end
190
-
191
- end
192
-
193
- context "and an explicit Policyfile name is given" do
194
-
195
- let(:policyfile_rb_explicit_name) { "MyPolicy.rb" }
196
-
197
- let(:policyfile_lock_name) { "MyPolicy.lock.json" }
198
-
199
- it "infers that the Policyfile.rb is located at $CWD/$POLICYFILE_NAME" do
200
- expect(install_service.policyfile_expanded_path).to eq(policyfile_rb_path)
201
- end
202
-
203
- it "reads the policyfile from disk" do
204
- expect(install_service.policyfile_content).to eq(policyfile_content)
205
- end
206
-
207
- end
208
- end
209
-
210
- end
211
-
1
+ #
2
+ # Copyright:: Copyright (c) 2014 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
+ require 'chef-dk/policyfile_services/install'
20
+
21
+ describe ChefDK::PolicyfileServices::Install do
22
+
23
+ include ChefDK::Helpers
24
+
25
+ let(:working_dir) do
26
+ path = File.join(tempdir, "policyfile_services_test_working_dir")
27
+ Dir.mkdir(path)
28
+ path
29
+ end
30
+
31
+ let(:policyfile_rb_explicit_name) { nil }
32
+
33
+ let(:policyfile_rb_name) { policyfile_rb_explicit_name || "Policyfile.rb" }
34
+
35
+ let(:policyfile_lock_name) { "Policyfile.lock.json" }
36
+
37
+ let(:policyfile_rb_path) { File.join(working_dir, policyfile_rb_name) }
38
+
39
+ let(:policyfile_lock_path) { File.join(working_dir, policyfile_lock_name) }
40
+
41
+ let(:local_cookbooks_root) do
42
+ File.join(fixtures_path, "local_path_cookbooks")
43
+ end
44
+
45
+ let(:policyfile_content) do
46
+ <<-E
47
+ name 'install-example'
48
+
49
+ run_list 'local-cookbook'
50
+
51
+ cookbook 'local-cookbook', path: '#{local_cookbooks_root}/local-cookbook'
52
+ E
53
+ end
54
+
55
+ let(:overwrite) { false }
56
+
57
+ let(:ui) { TestHelpers::TestUI.new }
58
+
59
+ let(:install_service) { described_class.new(policyfile: policyfile_rb_name, ui: ui, root_dir: working_dir, overwrite: overwrite) }
60
+
61
+ let(:storage_config) do
62
+ ChefDK::Policyfile::StorageConfig.new( cache_path: nil, relative_paths_root: local_cookbooks_root )
63
+ end
64
+
65
+ def result_policyfile_lock
66
+ expect(File).to exist(policyfile_lock_path)
67
+ content = IO.read(policyfile_lock_path)
68
+ lock_data = FFI_Yajl::Parser.parse(content)
69
+ ChefDK::PolicyfileLock.new(storage_config).build_from_lock_data(lock_data)
70
+ end
71
+
72
+ context "when no Policyfile is present or specified" do
73
+
74
+ it "errors out" do
75
+ expect { install_service.run }.to raise_error(ChefDK::PolicyfileNotFound, "Policyfile not found at path #{policyfile_rb_path}")
76
+ end
77
+
78
+ end
79
+
80
+ context "when a Policyfile exists" do
81
+
82
+ before do
83
+ with_file(policyfile_rb_path) { |f| f.print(policyfile_content) }
84
+ end
85
+
86
+ it "infers that the Policyfile.rb is located at $CWD/Policyfile.rb" do
87
+ expect(install_service.policyfile_expanded_path).to eq(policyfile_rb_path)
88
+ end
89
+
90
+ it "reads the policyfile from disk" do
91
+ expect(install_service.policyfile_content).to eq(policyfile_content)
92
+ end
93
+
94
+ context "and the policyfile has an error" do
95
+
96
+ let(:policyfile_content) { 'raise "borkbork"' }
97
+
98
+ it "errors out and creates no lockfile" do
99
+ expect { install_service.run }.to raise_error(ChefDK::PolicyfileInstallError)
100
+ expect(File).to_not exist(policyfile_lock_path)
101
+ end
102
+
103
+ end
104
+
105
+ context "and no lockfile exists" do
106
+
107
+ it "solves the Policyfile demands, installs cookbooks, emits a lockfile" do
108
+ install_service.run
109
+ generated_lock = result_policyfile_lock
110
+ expect(generated_lock.name).to eq('install-example')
111
+ expect(generated_lock.cookbook_locks).to have_key("local-cookbook")
112
+ end
113
+
114
+ it "prints the policy name" do
115
+ install_service.run
116
+ expect(ui.output).to include("Building policy install-example")
117
+ end
118
+
119
+ it "prints the expanded run list" do
120
+ install_service.run
121
+ expect(ui.output).to include("Expanded run list: recipe[local-cookbook]")
122
+ end
123
+
124
+ it "prints the lockfile path" do
125
+ install_service.run
126
+ expect(ui.output).to include("Lockfile written to #{working_dir}/Policyfile.lock.json")
127
+ end
128
+
129
+ it "prints the lockfile's revision id" do
130
+ install_service.run
131
+ expect(ui.output).to include("Policy revision id: 60e5ad638dce219d8f87d589463ec4a9884007ba5e2adbb4c0a7021d67204f1a")
132
+ end
133
+
134
+ end
135
+
136
+ context "and a lockfile exists and `overwrite` is specified" do
137
+
138
+ let(:overwrite) { true }
139
+
140
+ before do
141
+ File.binwrite(policyfile_lock_path, "This is the old lockfile content")
142
+ end
143
+
144
+ it "solves the Policyfile demands, installs cookbooks, emits a lockfile" do
145
+ install_service.run
146
+ generated_lock = result_policyfile_lock
147
+ expect(generated_lock.name).to eq('install-example')
148
+ expect(generated_lock.cookbook_locks).to have_key("local-cookbook")
149
+ end
150
+
151
+ end
152
+
153
+ context "and a lockfile exists" do
154
+
155
+ before do
156
+ install_service.dup.run
157
+ end
158
+
159
+ it "reads the policyfile lock from disk" do
160
+ lock = install_service.policyfile_lock
161
+ expect(lock).to be_an_instance_of(ChefDK::PolicyfileLock)
162
+ expect(lock.name).to eq('install-example')
163
+ expect(lock.cookbook_locks).to have_key("local-cookbook")
164
+ end
165
+
166
+ it "ensures that cookbooks are installed" do
167
+ expect(install_service.policyfile_lock).to receive(:install_cookbooks).and_call_original
168
+ install_service.run
169
+ end
170
+
171
+ describe "when an error occurs during the install" do
172
+
173
+ before do
174
+ expect(install_service.policyfile_lock).to receive(:install_cookbooks).and_raise("some error")
175
+ end
176
+
177
+ it "raises a PolicyfileInstallError" do
178
+ expect { install_service.run }.to raise_error(ChefDK::PolicyfileInstallError)
179
+ end
180
+
181
+
182
+ end
183
+
184
+ context "and the Policyfile has updated dependendencies" do
185
+
186
+ # For very first iteration, we won't tackle this case if it's hard
187
+ it "Conservatively updates deps, recomputes lock, and installs"
188
+
189
+ end
190
+
191
+ end
192
+
193
+ context "and an explicit Policyfile name is given" do
194
+
195
+ let(:policyfile_rb_explicit_name) { "MyPolicy.rb" }
196
+
197
+ let(:policyfile_lock_name) { "MyPolicy.lock.json" }
198
+
199
+ it "infers that the Policyfile.rb is located at $CWD/$POLICYFILE_NAME" do
200
+ expect(install_service.policyfile_expanded_path).to eq(policyfile_rb_path)
201
+ end
202
+
203
+ it "reads the policyfile from disk" do
204
+ expect(install_service.policyfile_content).to eq(policyfile_content)
205
+ end
206
+
207
+ end
208
+ end
209
+
210
+ end
211
+
@@ -1,378 +1,378 @@
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
- require 'chef-dk/policyfile_services/push_archive'
20
-
21
- describe ChefDK::PolicyfileServices::PushArchive do
22
-
23
- FileToTar = Struct.new(:name, :content)
24
-
25
- def create_archive
26
- Zlib::GzipWriter.open(archive_file_path) do |gz_file|
27
- Archive::Tar::Minitar::Writer.open(gz_file) do |tar|
28
-
29
-
30
- archive_dirs.each do |dir|
31
- tar.mkdir(dir, mode: 0755)
32
- end
33
-
34
- archive_files.each do |file|
35
- name = file.name
36
- content = file.content
37
- size = content.bytesize
38
- tar.add_file_simple(name, mode: 0644, size: size) { |f| f.write(content) }
39
- end
40
-
41
- end
42
- end
43
- end
44
-
45
- let(:valid_lockfile) do
46
- <<-E
47
- {
48
- "name": "install-example",
49
- "run_list": [
50
- "recipe[local-cookbook::default]"
51
- ],
52
- "cookbook_locks": {
53
- "local-cookbook": {
54
- "version": "2.3.4",
55
- "identifier": "fab501cfaf747901bd82c1bc706beae7dc3a350c",
56
- "dotted_decimal_identifier": "70567763561641081.489844270461035.258281553147148",
57
- "source": "project-cookbooks/local-cookbook",
58
- "cache_key": null,
59
- "scm_info": null,
60
- "source_options": {
61
- "path": "project-cookbooks/local-cookbook"
62
- }
63
- }
64
- },
65
- "default_attributes": {},
66
- "override_attributes": {},
67
- "solution_dependencies": {
68
- "Policyfile": [
69
- [
70
- "local-cookbook",
71
- ">= 0.0.0"
72
- ]
73
- ],
74
- "dependencies": {
75
- "local-cookbook (2.3.4)": [
76
-
77
- ]
78
- }
79
- }
80
- }
81
- E
82
- end
83
-
84
- let(:archive_files) { [] }
85
-
86
- let(:archive_dirs) { [] }
87
-
88
- let(:working_dir) do
89
- path = File.join(tempdir, "policyfile_services_test_working_dir")
90
- Dir.mkdir(path)
91
- path
92
- end
93
-
94
- let(:archive_file_name) { "example-policy-abc123.tgz" }
95
-
96
- let(:archive_file_path) { File.join(working_dir, archive_file_name) }
97
-
98
- let(:policy_group) { "dev-cluster-1" }
99
-
100
- let(:config) do
101
- double("Chef::Config",
102
- chef_server_url: "https://localhost:10443",
103
- client_key: "/path/to/client/key.pem",
104
- node_name: "deuce",
105
- policy_document_native_api: true)
106
- end
107
-
108
- let(:ui) { TestHelpers::TestUI.new }
109
-
110
- subject(:push_archive_service) do
111
- described_class.new(archive_file: archive_file_name,
112
- policy_group: policy_group,
113
- root_dir: working_dir,
114
- ui: ui,
115
- config: config)
116
- end
117
-
118
- it "has an archive file" do
119
- expect(push_archive_service.archive_file).to eq(archive_file_name)
120
- expect(push_archive_service.archive_file_path).to eq(archive_file_path)
121
- end
122
-
123
- it "configures an HTTP client" do
124
- expect(ChefDK::AuthenticatedHTTP).to receive(:new).with("https://localhost:10443",
125
- signing_key_filename: "/path/to/client/key.pem",
126
- client_name: "deuce")
127
- push_archive_service.http_client
128
- end
129
-
130
- context "with an invalid archive" do
131
-
132
- let(:exception) do
133
- begin
134
- push_archive_service.run
135
- rescue ChefDK::PolicyfilePushArchiveError => e
136
- e
137
- else
138
- nil
139
- end
140
- end
141
-
142
- let(:exception_cause) { exception.cause }
143
-
144
- context "when the archive is malformed/corrupted/etc" do
145
-
146
- context "when the archive file doesn't exist" do
147
-
148
- it "errors out" do
149
- expect(exception).to_not be_nil
150
- expect(exception.message).to eq("Failed to publish archived policy")
151
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
152
- expect(exception_cause.message).to eq("Archive file #{archive_file_path} not found")
153
- end
154
- end
155
-
156
- context "when the archive is not a gzip file" do
157
-
158
- before do
159
- FileUtils.touch(archive_file_path)
160
- end
161
-
162
- it "errors out" do
163
- expect(exception).to_not be_nil
164
- expect(exception.message).to eq("Failed to publish archived policy")
165
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
166
- expect(exception_cause.message).to eq("Archive file #{archive_file_path} could not be unpacked. not in gzip format")
167
- end
168
-
169
- end
170
-
171
- context "when the archive is a gzip file of a garbage file" do
172
-
173
- before do
174
- Zlib::GzipWriter.open(archive_file_path) do |gz_file|
175
- gz_file << "lol this isn't a tar file"
176
- end
177
- end
178
-
179
- it "errors out" do
180
- expect(exception).to_not be_nil
181
- expect(exception.message).to eq("Failed to publish archived policy")
182
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
183
- expect(exception_cause.message).to eq("Archive file #{archive_file_path} could not be unpacked. Tar archive looks corrupt.")
184
- end
185
- end
186
-
187
-
188
- context "when the archive is a gzip file of a very malformed tar archive" do
189
-
190
- before do
191
- Zlib::GzipWriter.open(archive_file_path) do |gz_file|
192
- gz_file << "\0\0\0\0\0"
193
- end
194
- end
195
-
196
- it "errors out" do
197
- expect(exception).to_not be_nil
198
- expect(exception.message).to eq("Failed to publish archived policy")
199
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
200
- expect(exception_cause.message).to eq("Archive file #{archive_file_path} could not be unpacked. Tar archive looks corrupt.")
201
- end
202
- end
203
- end
204
-
205
- context "when the archive is well-formed but has invalid content" do
206
-
207
- before do
208
- create_archive
209
- end
210
-
211
- context "when the archive is missing Policyfile.lock.json" do
212
-
213
- let(:archive_files) { [ FileToTar.new("empty.txt", "") ] }
214
-
215
- it "errors out" do
216
- expect(exception).to_not be_nil
217
- expect(exception.message).to eq("Failed to publish archived policy")
218
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
219
- expect(exception_cause.message).to eq("Archive does not contain a Policyfile.lock.json")
220
- end
221
-
222
- end
223
-
224
- context "when the archive has no cookbook_artifacts/ directory" do
225
-
226
- let(:archive_files) { [ FileToTar.new("Policyfile.lock.json", "") ] }
227
-
228
- it "errors out" do
229
- expect(exception).to_not be_nil
230
- expect(exception.message).to eq("Failed to publish archived policy")
231
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
232
- expect(exception_cause.message).to eq("Archive does not contain a cookbook_artifacts directory")
233
- end
234
-
235
- end
236
-
237
- context "when the archive has the correct files but the lockfile is invalid" do
238
-
239
- let(:archive_dirs) { ["cookbook_artifacts"] }
240
-
241
- let(:archive_files) { [ FileToTar.new("Policyfile.lock.json", lockfile_content) ] }
242
-
243
- context "when the lockfile has invalid JSON" do
244
-
245
- let(:lockfile_content) { ":::" }
246
-
247
- it "errors out" do
248
- expect(exception).to_not be_nil
249
- expect(exception.message).to eq("Failed to publish archived policy")
250
- expect(exception_cause).to be_a(FFI_Yajl::ParseError)
251
- end
252
-
253
- end
254
-
255
- context "when the lockfile is semantically invalid" do
256
-
257
- let(:lockfile_content) { '{ }' }
258
-
259
- it "errors out" do
260
- expect(exception).to_not be_nil
261
- expect(exception.message).to eq("Failed to publish archived policy")
262
- expect(exception_cause).to be_a(ChefDK::InvalidLockfile)
263
- end
264
-
265
- end
266
-
267
-
268
- context "when the archive does not have all the necessary cookbooks" do
269
-
270
- let(:lockfile_content) { valid_lockfile }
271
-
272
- it "errors out" do
273
- expect(exception).to_not be_nil
274
- expect(exception.message).to eq("Failed to publish archived policy")
275
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
276
-
277
- msg = "Archive does not have all cookbooks required by the Policyfile.lock. Missing cookbooks: 'local-cookbook'."
278
- expect(exception_cause.message).to eq(msg)
279
- end
280
-
281
- end
282
-
283
- # `chef export` previously generated Chef repos designed for
284
- # compatibility mode Policyfile usage. We don't intend to be backwards
285
- # compatible, but we want to kindly explain what's going on.
286
- context "when the archive is in the old format" do
287
-
288
- let(:lockfile_content) { valid_lockfile }
289
-
290
- let(:archive_dirs) { %w{ cookbooks data_bags } }
291
-
292
- let(:archive_files) do
293
- [
294
- FileToTar.new("Policyfile.lock.json", lockfile_content),
295
- FileToTar.new("client.rb", "#content"),
296
- ]
297
- end
298
-
299
- it "errors out, explaining the compatibility issue" do
300
- expect(exception).to_not be_nil
301
- expect(exception.message).to eq("Failed to publish archived policy")
302
- expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
303
-
304
- msg = <<-MESSAGE
305
- This archive is in an unsupported format.
306
-
307
- This archive was created with an older version of ChefDK. This version of
308
- ChefDK does not support archives in the older format. Re-create the archive
309
- with a newer version of ChefDK or downgrade ChefDK.
310
- MESSAGE
311
- expect(exception_cause.message).to eq(msg)
312
- end
313
-
314
- end
315
- end
316
- end
317
-
318
- end
319
-
320
- context "with a valid archive" do
321
-
322
- let(:lockfile_content) { valid_lockfile }
323
-
324
- let(:cookbook_name) { "local-cookbook" }
325
-
326
- let(:identifier) { "fab501cfaf747901bd82c1bc706beae7dc3a350c" }
327
-
328
- let(:cookbook_artifact_dir) { File.join("cookbook_artifacts", "#{cookbook_name}-#{identifier}") }
329
-
330
- let(:recipes_dir) { File.join(cookbook_artifact_dir, "recipes") }
331
-
332
- let(:archive_dirs) { ["cookbook_artifacts", cookbook_artifact_dir, recipes_dir] }
333
-
334
- let(:archive_files) do
335
- [
336
- FileToTar.new("Policyfile.lock.json", lockfile_content),
337
- FileToTar.new(File.join(cookbook_artifact_dir, "metadata.rb"), "name 'local-cookbook'"),
338
- FileToTar.new(File.join(recipes_dir, "default.rb"), "puts 'hello'")
339
- ]
340
- end
341
-
342
- let(:http_client) { instance_double(ChefDK::AuthenticatedHTTP) }
343
-
344
- let(:uploader) { instance_double(ChefDK::Policyfile::Uploader) }
345
-
346
- before do
347
- expect(push_archive_service).to receive(:http_client).and_return(http_client)
348
-
349
- expect(ChefDK::Policyfile::Uploader).to receive(:new).
350
- # TODO: need more verification that the policyfile.lock is right (?)
351
- with(an_instance_of(ChefDK::PolicyfileLock), policy_group, http_client: http_client, ui: ui, policy_document_native_api: true).
352
- and_return(uploader)
353
-
354
- create_archive
355
- end
356
-
357
- describe "when the upload is successful" do
358
-
359
- it "uploads the cookbooks and lockfile" do
360
- expect(uploader).to receive(:upload)
361
- push_archive_service.run
362
- end
363
-
364
- end
365
-
366
- describe "when the upload fails" do
367
-
368
- it "raises a nested error" do
369
- expect(uploader).to receive(:upload).and_raise("an error")
370
- expect { push_archive_service.run }.to raise_error(ChefDK::PolicyfilePushArchiveError)
371
- end
372
-
373
- end
374
-
375
- end
376
-
377
- end
378
-
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
+ require 'chef-dk/policyfile_services/push_archive'
20
+
21
+ describe ChefDK::PolicyfileServices::PushArchive do
22
+
23
+ FileToTar = Struct.new(:name, :content)
24
+
25
+ def create_archive
26
+ Zlib::GzipWriter.open(archive_file_path) do |gz_file|
27
+ Archive::Tar::Minitar::Writer.open(gz_file) do |tar|
28
+
29
+
30
+ archive_dirs.each do |dir|
31
+ tar.mkdir(dir, mode: 0755)
32
+ end
33
+
34
+ archive_files.each do |file|
35
+ name = file.name
36
+ content = file.content
37
+ size = content.bytesize
38
+ tar.add_file_simple(name, mode: 0644, size: size) { |f| f.write(content) }
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+
45
+ let(:valid_lockfile) do
46
+ <<-E
47
+ {
48
+ "name": "install-example",
49
+ "run_list": [
50
+ "recipe[local-cookbook::default]"
51
+ ],
52
+ "cookbook_locks": {
53
+ "local-cookbook": {
54
+ "version": "2.3.4",
55
+ "identifier": "fab501cfaf747901bd82c1bc706beae7dc3a350c",
56
+ "dotted_decimal_identifier": "70567763561641081.489844270461035.258281553147148",
57
+ "source": "project-cookbooks/local-cookbook",
58
+ "cache_key": null,
59
+ "scm_info": null,
60
+ "source_options": {
61
+ "path": "project-cookbooks/local-cookbook"
62
+ }
63
+ }
64
+ },
65
+ "default_attributes": {},
66
+ "override_attributes": {},
67
+ "solution_dependencies": {
68
+ "Policyfile": [
69
+ [
70
+ "local-cookbook",
71
+ ">= 0.0.0"
72
+ ]
73
+ ],
74
+ "dependencies": {
75
+ "local-cookbook (2.3.4)": [
76
+
77
+ ]
78
+ }
79
+ }
80
+ }
81
+ E
82
+ end
83
+
84
+ let(:archive_files) { [] }
85
+
86
+ let(:archive_dirs) { [] }
87
+
88
+ let(:working_dir) do
89
+ path = File.join(tempdir, "policyfile_services_test_working_dir")
90
+ Dir.mkdir(path)
91
+ path
92
+ end
93
+
94
+ let(:archive_file_name) { "example-policy-abc123.tgz" }
95
+
96
+ let(:archive_file_path) { File.join(working_dir, archive_file_name) }
97
+
98
+ let(:policy_group) { "dev-cluster-1" }
99
+
100
+ let(:config) do
101
+ double("Chef::Config",
102
+ chef_server_url: "https://localhost:10443",
103
+ client_key: "/path/to/client/key.pem",
104
+ node_name: "deuce",
105
+ policy_document_native_api: true)
106
+ end
107
+
108
+ let(:ui) { TestHelpers::TestUI.new }
109
+
110
+ subject(:push_archive_service) do
111
+ described_class.new(archive_file: archive_file_name,
112
+ policy_group: policy_group,
113
+ root_dir: working_dir,
114
+ ui: ui,
115
+ config: config)
116
+ end
117
+
118
+ it "has an archive file" do
119
+ expect(push_archive_service.archive_file).to eq(archive_file_name)
120
+ expect(push_archive_service.archive_file_path).to eq(archive_file_path)
121
+ end
122
+
123
+ it "configures an HTTP client" do
124
+ expect(ChefDK::AuthenticatedHTTP).to receive(:new).with("https://localhost:10443",
125
+ signing_key_filename: "/path/to/client/key.pem",
126
+ client_name: "deuce")
127
+ push_archive_service.http_client
128
+ end
129
+
130
+ context "with an invalid archive" do
131
+
132
+ let(:exception) do
133
+ begin
134
+ push_archive_service.run
135
+ rescue ChefDK::PolicyfilePushArchiveError => e
136
+ e
137
+ else
138
+ nil
139
+ end
140
+ end
141
+
142
+ let(:exception_cause) { exception.cause }
143
+
144
+ context "when the archive is malformed/corrupted/etc" do
145
+
146
+ context "when the archive file doesn't exist" do
147
+
148
+ it "errors out" do
149
+ expect(exception).to_not be_nil
150
+ expect(exception.message).to eq("Failed to publish archived policy")
151
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
152
+ expect(exception_cause.message).to eq("Archive file #{archive_file_path} not found")
153
+ end
154
+ end
155
+
156
+ context "when the archive is not a gzip file" do
157
+
158
+ before do
159
+ FileUtils.touch(archive_file_path)
160
+ end
161
+
162
+ it "errors out" do
163
+ expect(exception).to_not be_nil
164
+ expect(exception.message).to eq("Failed to publish archived policy")
165
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
166
+ expect(exception_cause.message).to eq("Archive file #{archive_file_path} could not be unpacked. not in gzip format")
167
+ end
168
+
169
+ end
170
+
171
+ context "when the archive is a gzip file of a garbage file" do
172
+
173
+ before do
174
+ Zlib::GzipWriter.open(archive_file_path) do |gz_file|
175
+ gz_file << "lol this isn't a tar file"
176
+ end
177
+ end
178
+
179
+ it "errors out" do
180
+ expect(exception).to_not be_nil
181
+ expect(exception.message).to eq("Failed to publish archived policy")
182
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
183
+ expect(exception_cause.message).to eq("Archive file #{archive_file_path} could not be unpacked. Tar archive looks corrupt.")
184
+ end
185
+ end
186
+
187
+
188
+ context "when the archive is a gzip file of a very malformed tar archive" do
189
+
190
+ before do
191
+ Zlib::GzipWriter.open(archive_file_path) do |gz_file|
192
+ gz_file << "\0\0\0\0\0"
193
+ end
194
+ end
195
+
196
+ it "errors out" do
197
+ expect(exception).to_not be_nil
198
+ expect(exception.message).to eq("Failed to publish archived policy")
199
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
200
+ expect(exception_cause.message).to eq("Archive file #{archive_file_path} could not be unpacked. Tar archive looks corrupt.")
201
+ end
202
+ end
203
+ end
204
+
205
+ context "when the archive is well-formed but has invalid content" do
206
+
207
+ before do
208
+ create_archive
209
+ end
210
+
211
+ context "when the archive is missing Policyfile.lock.json" do
212
+
213
+ let(:archive_files) { [ FileToTar.new("empty.txt", "") ] }
214
+
215
+ it "errors out" do
216
+ expect(exception).to_not be_nil
217
+ expect(exception.message).to eq("Failed to publish archived policy")
218
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
219
+ expect(exception_cause.message).to eq("Archive does not contain a Policyfile.lock.json")
220
+ end
221
+
222
+ end
223
+
224
+ context "when the archive has no cookbook_artifacts/ directory" do
225
+
226
+ let(:archive_files) { [ FileToTar.new("Policyfile.lock.json", "") ] }
227
+
228
+ it "errors out" do
229
+ expect(exception).to_not be_nil
230
+ expect(exception.message).to eq("Failed to publish archived policy")
231
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
232
+ expect(exception_cause.message).to eq("Archive does not contain a cookbook_artifacts directory")
233
+ end
234
+
235
+ end
236
+
237
+ context "when the archive has the correct files but the lockfile is invalid" do
238
+
239
+ let(:archive_dirs) { ["cookbook_artifacts"] }
240
+
241
+ let(:archive_files) { [ FileToTar.new("Policyfile.lock.json", lockfile_content) ] }
242
+
243
+ context "when the lockfile has invalid JSON" do
244
+
245
+ let(:lockfile_content) { ":::" }
246
+
247
+ it "errors out" do
248
+ expect(exception).to_not be_nil
249
+ expect(exception.message).to eq("Failed to publish archived policy")
250
+ expect(exception_cause).to be_a(FFI_Yajl::ParseError)
251
+ end
252
+
253
+ end
254
+
255
+ context "when the lockfile is semantically invalid" do
256
+
257
+ let(:lockfile_content) { '{ }' }
258
+
259
+ it "errors out" do
260
+ expect(exception).to_not be_nil
261
+ expect(exception.message).to eq("Failed to publish archived policy")
262
+ expect(exception_cause).to be_a(ChefDK::InvalidLockfile)
263
+ end
264
+
265
+ end
266
+
267
+
268
+ context "when the archive does not have all the necessary cookbooks" do
269
+
270
+ let(:lockfile_content) { valid_lockfile }
271
+
272
+ it "errors out" do
273
+ expect(exception).to_not be_nil
274
+ expect(exception.message).to eq("Failed to publish archived policy")
275
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
276
+
277
+ msg = "Archive does not have all cookbooks required by the Policyfile.lock. Missing cookbooks: 'local-cookbook'."
278
+ expect(exception_cause.message).to eq(msg)
279
+ end
280
+
281
+ end
282
+
283
+ # `chef export` previously generated Chef repos designed for
284
+ # compatibility mode Policyfile usage. We don't intend to be backwards
285
+ # compatible, but we want to kindly explain what's going on.
286
+ context "when the archive is in the old format" do
287
+
288
+ let(:lockfile_content) { valid_lockfile }
289
+
290
+ let(:archive_dirs) { %w{ cookbooks data_bags } }
291
+
292
+ let(:archive_files) do
293
+ [
294
+ FileToTar.new("Policyfile.lock.json", lockfile_content),
295
+ FileToTar.new("client.rb", "#content"),
296
+ ]
297
+ end
298
+
299
+ it "errors out, explaining the compatibility issue" do
300
+ expect(exception).to_not be_nil
301
+ expect(exception.message).to eq("Failed to publish archived policy")
302
+ expect(exception_cause).to be_a(ChefDK::InvalidPolicyArchive)
303
+
304
+ msg = <<-MESSAGE
305
+ This archive is in an unsupported format.
306
+
307
+ This archive was created with an older version of ChefDK. This version of
308
+ ChefDK does not support archives in the older format. Re-create the archive
309
+ with a newer version of ChefDK or downgrade ChefDK.
310
+ MESSAGE
311
+ expect(exception_cause.message).to eq(msg)
312
+ end
313
+
314
+ end
315
+ end
316
+ end
317
+
318
+ end
319
+
320
+ context "with a valid archive" do
321
+
322
+ let(:lockfile_content) { valid_lockfile }
323
+
324
+ let(:cookbook_name) { "local-cookbook" }
325
+
326
+ let(:identifier) { "fab501cfaf747901bd82c1bc706beae7dc3a350c" }
327
+
328
+ let(:cookbook_artifact_dir) { File.join("cookbook_artifacts", "#{cookbook_name}-#{identifier}") }
329
+
330
+ let(:recipes_dir) { File.join(cookbook_artifact_dir, "recipes") }
331
+
332
+ let(:archive_dirs) { ["cookbook_artifacts", cookbook_artifact_dir, recipes_dir] }
333
+
334
+ let(:archive_files) do
335
+ [
336
+ FileToTar.new("Policyfile.lock.json", lockfile_content),
337
+ FileToTar.new(File.join(cookbook_artifact_dir, "metadata.rb"), "name 'local-cookbook'"),
338
+ FileToTar.new(File.join(recipes_dir, "default.rb"), "puts 'hello'")
339
+ ]
340
+ end
341
+
342
+ let(:http_client) { instance_double(ChefDK::AuthenticatedHTTP) }
343
+
344
+ let(:uploader) { instance_double(ChefDK::Policyfile::Uploader) }
345
+
346
+ before do
347
+ expect(push_archive_service).to receive(:http_client).and_return(http_client)
348
+
349
+ expect(ChefDK::Policyfile::Uploader).to receive(:new).
350
+ # TODO: need more verification that the policyfile.lock is right (?)
351
+ with(an_instance_of(ChefDK::PolicyfileLock), policy_group, http_client: http_client, ui: ui, policy_document_native_api: true).
352
+ and_return(uploader)
353
+
354
+ create_archive
355
+ end
356
+
357
+ describe "when the upload is successful" do
358
+
359
+ it "uploads the cookbooks and lockfile" do
360
+ expect(uploader).to receive(:upload)
361
+ push_archive_service.run
362
+ end
363
+
364
+ end
365
+
366
+ describe "when the upload fails" do
367
+
368
+ it "raises a nested error" do
369
+ expect(uploader).to receive(:upload).and_raise("an error")
370
+ expect { push_archive_service.run }.to raise_error(ChefDK::PolicyfilePushArchiveError)
371
+ end
372
+
373
+ end
374
+
375
+ end
376
+
377
+ end
378
+