chef-dk 0.14.25 → 0.15.9

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 (328) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -12
  3. data/Gemfile.lock +56 -82
  4. data/LICENSE +201 -201
  5. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
  6. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +288 -288
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
  8. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
  9. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
  10. data/acceptance/Gemfile.lock +18 -21
  11. data/acceptance/README.md +132 -132
  12. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
  13. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
  14. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
  17. data/acceptance/trivial/.kitchen.yml +7 -7
  18. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
  19. data/bin/chef +25 -25
  20. data/chef-dk.gemspec +1 -0
  21. data/lib/chef-dk.rb +19 -19
  22. data/lib/chef-dk/authenticated_http.rb +40 -40
  23. data/lib/chef-dk/chef_runner.rb +1 -1
  24. data/lib/chef-dk/cli.rb +2 -2
  25. data/lib/chef-dk/command/base.rb +79 -79
  26. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
  27. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
  28. data/lib/chef-dk/command/delete_policy.rb +122 -122
  29. data/lib/chef-dk/command/delete_policy_group.rb +122 -122
  30. data/lib/chef-dk/command/diff.rb +316 -316
  31. data/lib/chef-dk/command/env.rb +90 -90
  32. data/lib/chef-dk/command/exec.rb +45 -45
  33. data/lib/chef-dk/command/export.rb +2 -2
  34. data/lib/chef-dk/command/gem.rb +47 -47
  35. data/lib/chef-dk/command/generate.rb +2 -0
  36. data/lib/chef-dk/command/generator_commands/app.rb +107 -107
  37. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
  38. data/lib/chef-dk/command/generator_commands/base.rb +148 -148
  39. data/lib/chef-dk/command/generator_commands/build_cookbook.rb +110 -0
  40. data/lib/chef-dk/command/generator_commands/cookbook.rb +21 -0
  41. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  42. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  43. data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -177
  44. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
  45. data/lib/chef-dk/command/generator_commands/policyfile.rb +127 -127
  46. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  47. data/lib/chef-dk/command/generator_commands/repo.rb +125 -125
  48. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  49. data/lib/chef-dk/command/install.rb +121 -121
  50. data/lib/chef-dk/command/provision.rb +438 -438
  51. data/lib/chef-dk/command/push.rb +118 -118
  52. data/lib/chef-dk/command/push_archive.rb +126 -126
  53. data/lib/chef-dk/command/shell_init.rb +180 -180
  54. data/lib/chef-dk/command/show_policy.rb +165 -165
  55. data/lib/chef-dk/command/undelete.rb +155 -155
  56. data/lib/chef-dk/command/update.rb +148 -148
  57. data/lib/chef-dk/command/verify.rb +9 -11
  58. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  59. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  60. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  61. data/lib/chef-dk/configurable.rb +69 -69
  62. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  63. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  64. data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
  65. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  66. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
  67. data/lib/chef-dk/exceptions.rb +129 -129
  68. data/lib/chef-dk/helpers.rb +24 -17
  69. data/lib/chef-dk/pager.rb +106 -106
  70. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  71. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
  72. data/lib/chef-dk/policyfile/community_cookbook_source.rb +97 -97
  73. data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
  74. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  75. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  76. data/lib/chef-dk/policyfile/cookbook_sources.rb +22 -22
  77. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +90 -90
  78. data/lib/chef-dk/policyfile/differ.rb +266 -266
  79. data/lib/chef-dk/policyfile/dsl.rb +261 -261
  80. data/lib/chef-dk/policyfile/lister.rb +232 -232
  81. data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
  82. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  83. data/lib/chef-dk/policyfile/reports/install.rb +70 -70
  84. data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
  85. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  86. data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
  87. data/lib/chef-dk/policyfile/storage_config.rb +100 -100
  88. data/lib/chef-dk/policyfile/undo_record.rb +142 -142
  89. data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
  90. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  91. data/lib/chef-dk/policyfile_compiler.rb +419 -419
  92. data/lib/chef-dk/policyfile_lock.rb +552 -552
  93. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  94. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
  95. data/lib/chef-dk/policyfile_services/export_repo.rb +421 -421
  96. data/lib/chef-dk/policyfile_services/install.rb +126 -126
  97. data/lib/chef-dk/policyfile_services/push_archive.rb +204 -204
  98. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
  99. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
  100. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
  101. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  102. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
  103. data/lib/chef-dk/service_exception_inspectors.rb +25 -25
  104. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
  105. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
  106. data/lib/chef-dk/service_exceptions.rb +143 -143
  107. data/lib/chef-dk/shell_out.rb +36 -36
  108. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
  109. data/lib/chef-dk/skeletons/code_generator/files/default/build-cookbook/.kitchen.yml +21 -0
  110. data/lib/chef-dk/skeletons/code_generator/files/default/build-cookbook/README.md +146 -0
  111. data/lib/chef-dk/skeletons/code_generator/files/default/build-cookbook/test-fixture-recipe.rb +7 -0
  112. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +102 -102
  113. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  114. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
  115. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-config.json +10 -0
  116. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
  117. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
  118. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  119. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
  120. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
  121. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
  122. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +58 -58
  123. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  124. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  125. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  126. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  127. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  128. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  129. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  130. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -8
  131. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
  132. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -2
  133. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  134. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
  135. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
  136. data/lib/chef-dk/skeletons/code_generator/recipes/build_cookbook.rb +88 -0
  137. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +6 -0
  138. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -24
  139. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -23
  140. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -8
  141. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +27 -27
  142. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +67 -67
  143. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  144. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  145. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  146. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  147. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  148. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  149. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  150. data/lib/chef-dk/skeletons/code_generator/templates/default/build-cookbook/Berksfile.erb +20 -0
  151. data/lib/chef-dk/skeletons/code_generator/templates/default/build-cookbook/metadata.rb.erb +9 -0
  152. data/lib/chef-dk/skeletons/code_generator/templates/default/build-cookbook/recipe.rb.erb +8 -0
  153. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +3 -2
  154. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +3 -2
  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 +1 -1
  162. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  163. data/omnibus_overrides.rb +2 -1
  164. data/spec/shared/a_file_generator.rb +125 -125
  165. data/spec/shared/a_generated_file.rb +12 -12
  166. data/spec/shared/command_with_ui_object.rb +11 -11
  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 -51
  170. data/spec/test_helpers.rb +84 -84
  171. data/spec/unit/chef_runner_spec.rb +1 -1
  172. data/spec/unit/cli_spec.rb +23 -6
  173. data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -181
  174. data/spec/unit/command/clean_policy_revisions_spec.rb +181 -181
  175. data/spec/unit/command/delete_policy_group_spec.rb +207 -207
  176. data/spec/unit/command/delete_policy_spec.rb +207 -207
  177. data/spec/unit/command/diff_spec.rb +312 -312
  178. data/spec/unit/command/env_spec.rb +52 -52
  179. data/spec/unit/command/exec_spec.rb +179 -179
  180. data/spec/unit/command/export_spec.rb +200 -200
  181. data/spec/unit/command/generate_spec.rb +142 -142
  182. data/spec/unit/command/generator_commands/app_spec.rb +169 -169
  183. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -32
  184. data/spec/unit/command/generator_commands/base_spec.rb +136 -136
  185. data/spec/unit/command/generator_commands/build_cookbook_spec.rb +309 -0
  186. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
  187. data/spec/unit/command/generator_commands/cookbook_spec.rb +98 -4
  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/template_spec.rb +32 -32
  193. data/spec/unit/command/install_spec.rb +179 -179
  194. data/spec/unit/command/provision_spec.rb +592 -592
  195. data/spec/unit/command/push_archive_spec.rb +153 -153
  196. data/spec/unit/command/push_spec.rb +199 -199
  197. data/spec/unit/command/shell_init_spec.rb +329 -329
  198. data/spec/unit/command/show_policy_spec.rb +235 -235
  199. data/spec/unit/command/undelete_spec.rb +246 -246
  200. data/spec/unit/command/update_spec.rb +275 -275
  201. data/spec/unit/command/verify_spec.rb +1 -3
  202. data/spec/unit/commands_map_spec.rb +57 -57
  203. data/spec/unit/configurable_spec.rb +41 -41
  204. data/spec/unit/cookbook_metadata_spec.rb +98 -98
  205. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  206. data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
  207. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  208. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  209. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  210. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  211. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  212. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  213. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  214. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  215. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  216. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  217. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  218. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  219. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  220. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  221. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  222. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  223. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  224. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  225. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  226. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  227. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  228. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  229. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  230. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  231. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  232. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  233. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  234. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
  235. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  236. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  237. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  238. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  239. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  240. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  241. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  242. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  243. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  244. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  245. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  246. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  247. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  248. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  249. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  250. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  251. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  252. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  253. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  254. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  255. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  256. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  257. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  258. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  259. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  260. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  261. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  262. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  263. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  264. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  265. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  266. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  267. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  268. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  269. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  270. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  271. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  272. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  273. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  274. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  275. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  276. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  277. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  278. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  279. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  280. data/spec/unit/gemfile_util_spec.rb +41 -0
  281. data/spec/unit/helpers_spec.rb +19 -0
  282. data/spec/unit/pager_spec.rb +119 -119
  283. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  284. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
  285. data/spec/unit/policyfile/community_cookbook_source_spec.rb +84 -84
  286. data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
  287. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +277 -277
  288. data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
  289. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +130 -130
  290. data/spec/unit/policyfile/differ_spec.rb +687 -687
  291. data/spec/unit/policyfile/lister_spec.rb +272 -272
  292. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
  293. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  294. data/spec/unit/policyfile/reports/install_spec.rb +115 -115
  295. data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
  296. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
  297. data/spec/unit/policyfile/storage_config_spec.rb +172 -172
  298. data/spec/unit/policyfile/undo_record_spec.rb +260 -260
  299. data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
  300. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  301. data/spec/unit/policyfile_demands_spec.rb +1203 -1203
  302. data/spec/unit/policyfile_evaluation_spec.rb +642 -642
  303. data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
  304. data/spec/unit/policyfile_lock_install_spec.rb +138 -138
  305. data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
  306. data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
  307. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  308. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
  309. data/spec/unit/policyfile_services/export_repo_spec.rb +481 -481
  310. data/spec/unit/policyfile_services/install_spec.rb +211 -211
  311. data/spec/unit/policyfile_services/push_archive_spec.rb +378 -378
  312. data/spec/unit/policyfile_services/push_spec.rb +233 -233
  313. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
  314. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
  315. data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
  316. data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
  317. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
  318. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
  319. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
  320. data/spec/unit/shell_out_spec.rb +34 -34
  321. data/tasks/bin/bundle-platform +6 -2
  322. data/tasks/bin/bundle-platform.bat +0 -0
  323. data/tasks/bin/create-override-gemfile +0 -0
  324. data/tasks/bundle_util.rb +18 -2
  325. data/tasks/gemfile_util.rb +53 -8
  326. data/version_policy.rb +9 -1
  327. data/warning.txt +9 -9
  328. metadata +30 -3
@@ -1,126 +1,126 @@
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 'ffi_yajl'
19
-
20
- require 'chef-dk/helpers'
21
- require 'chef-dk/service_exceptions'
22
- require 'chef-dk/policyfile_compiler'
23
- require 'chef-dk/policyfile/storage_config'
24
- require 'chef-dk/policyfile_lock'
25
-
26
- module ChefDK
27
- module PolicyfileServices
28
-
29
- class Install
30
-
31
- include Policyfile::StorageConfigDelegation
32
- include ChefDK::Helpers
33
-
34
- attr_reader :ui
35
- attr_reader :storage_config
36
- attr_reader :overwrite
37
-
38
- def initialize(policyfile: nil, ui: nil, root_dir: nil, overwrite: false)
39
- @ui = ui
40
- @overwrite = overwrite
41
-
42
- policyfile_rel_path = policyfile || "Policyfile.rb"
43
- policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
44
- @storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
45
-
46
- @policyfile_content = nil
47
- @policyfile_compiler = nil
48
- end
49
-
50
- def run
51
- unless File.exist?(policyfile_expanded_path)
52
- # TODO: suggest next step. Add a generator/init command? Specify path to Policyfile.rb?
53
- # See card CC-232
54
- raise PolicyfileNotFound, "Policyfile not found at path #{policyfile_expanded_path}"
55
- end
56
-
57
- if installing_from_lock?
58
- install_from_lock
59
- else
60
- generate_lock_and_install
61
- end
62
- end
63
-
64
- def policyfile_content
65
- @policyfile_content ||= IO.read(policyfile_expanded_path)
66
- end
67
-
68
- def policyfile_compiler
69
- @policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content, policyfile_expanded_path, ui: ui)
70
- end
71
-
72
- def expanded_run_list
73
- policyfile_compiler.expanded_run_list.to_s
74
- end
75
-
76
- def policyfile_lock_content
77
- @policyfile_lock_content ||= IO.read(policyfile_lock_expanded_path) if File.exist?(policyfile_lock_expanded_path)
78
- end
79
-
80
- def policyfile_lock
81
- return nil if policyfile_lock_content.nil?
82
- @policyfile_lock ||= begin
83
- lock_data = FFI_Yajl::Parser.new.parse(policyfile_lock_content)
84
- PolicyfileLock.new(storage_config, ui: ui).build_from_lock_data(lock_data)
85
- end
86
- end
87
-
88
- def generate_lock_and_install
89
- policyfile_compiler.error!
90
-
91
- ui.msg "Building policy #{policyfile_compiler.name}"
92
- ui.msg "Expanded run list: " + expanded_run_list + "\n"
93
-
94
- ui.msg "Caching Cookbooks..."
95
-
96
- policyfile_compiler.install
97
-
98
- lock_data = policyfile_compiler.lock.to_lock
99
-
100
- with_file(policyfile_lock_expanded_path) do |f|
101
- f.print(FFI_Yajl::Encoder.encode(lock_data, pretty: true ))
102
- end
103
-
104
- ui.msg ""
105
-
106
- ui.msg "Lockfile written to #{policyfile_lock_expanded_path}"
107
- ui.msg "Policy revision id: #{policyfile_lock.revision_id}"
108
- rescue => error
109
- raise PolicyfileInstallError.new("Failed to generate Policyfile.lock", error)
110
- end
111
-
112
- def install_from_lock
113
- ui.msg "Installing cookbooks from lock"
114
-
115
- policyfile_lock.install_cookbooks
116
- rescue => error
117
- raise PolicyfileInstallError.new("Failed to install cookbooks from lockfile", error)
118
- end
119
-
120
- def installing_from_lock?
121
- !@overwrite && File.exist?(policyfile_lock_expanded_path)
122
- end
123
-
124
- end
125
- end
126
- end
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 'ffi_yajl'
19
+
20
+ require 'chef-dk/helpers'
21
+ require 'chef-dk/service_exceptions'
22
+ require 'chef-dk/policyfile_compiler'
23
+ require 'chef-dk/policyfile/storage_config'
24
+ require 'chef-dk/policyfile_lock'
25
+
26
+ module ChefDK
27
+ module PolicyfileServices
28
+
29
+ class Install
30
+
31
+ include Policyfile::StorageConfigDelegation
32
+ include ChefDK::Helpers
33
+
34
+ attr_reader :ui
35
+ attr_reader :storage_config
36
+ attr_reader :overwrite
37
+
38
+ def initialize(policyfile: nil, ui: nil, root_dir: nil, overwrite: false)
39
+ @ui = ui
40
+ @overwrite = overwrite
41
+
42
+ policyfile_rel_path = policyfile || "Policyfile.rb"
43
+ policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
44
+ @storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
45
+
46
+ @policyfile_content = nil
47
+ @policyfile_compiler = nil
48
+ end
49
+
50
+ def run
51
+ unless File.exist?(policyfile_expanded_path)
52
+ # TODO: suggest next step. Add a generator/init command? Specify path to Policyfile.rb?
53
+ # See card CC-232
54
+ raise PolicyfileNotFound, "Policyfile not found at path #{policyfile_expanded_path}"
55
+ end
56
+
57
+ if installing_from_lock?
58
+ install_from_lock
59
+ else
60
+ generate_lock_and_install
61
+ end
62
+ end
63
+
64
+ def policyfile_content
65
+ @policyfile_content ||= IO.read(policyfile_expanded_path)
66
+ end
67
+
68
+ def policyfile_compiler
69
+ @policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content, policyfile_expanded_path, ui: ui)
70
+ end
71
+
72
+ def expanded_run_list
73
+ policyfile_compiler.expanded_run_list.to_s
74
+ end
75
+
76
+ def policyfile_lock_content
77
+ @policyfile_lock_content ||= IO.read(policyfile_lock_expanded_path) if File.exist?(policyfile_lock_expanded_path)
78
+ end
79
+
80
+ def policyfile_lock
81
+ return nil if policyfile_lock_content.nil?
82
+ @policyfile_lock ||= begin
83
+ lock_data = FFI_Yajl::Parser.new.parse(policyfile_lock_content)
84
+ PolicyfileLock.new(storage_config, ui: ui).build_from_lock_data(lock_data)
85
+ end
86
+ end
87
+
88
+ def generate_lock_and_install
89
+ policyfile_compiler.error!
90
+
91
+ ui.msg "Building policy #{policyfile_compiler.name}"
92
+ ui.msg "Expanded run list: " + expanded_run_list + "\n"
93
+
94
+ ui.msg "Caching Cookbooks..."
95
+
96
+ policyfile_compiler.install
97
+
98
+ lock_data = policyfile_compiler.lock.to_lock
99
+
100
+ with_file(policyfile_lock_expanded_path) do |f|
101
+ f.print(FFI_Yajl::Encoder.encode(lock_data, pretty: true ))
102
+ end
103
+
104
+ ui.msg ""
105
+
106
+ ui.msg "Lockfile written to #{policyfile_lock_expanded_path}"
107
+ ui.msg "Policy revision id: #{policyfile_lock.revision_id}"
108
+ rescue => error
109
+ raise PolicyfileInstallError.new("Failed to generate Policyfile.lock", error)
110
+ end
111
+
112
+ def install_from_lock
113
+ ui.msg "Installing cookbooks from lock"
114
+
115
+ policyfile_lock.install_cookbooks
116
+ rescue => error
117
+ raise PolicyfileInstallError.new("Failed to install cookbooks from lockfile", error)
118
+ end
119
+
120
+ def installing_from_lock?
121
+ !@overwrite && File.exist?(policyfile_lock_expanded_path)
122
+ end
123
+
124
+ end
125
+ end
126
+ end
@@ -1,204 +1,204 @@
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 'zlib'
19
- require 'archive/tar/minitar'
20
-
21
- require 'chef-dk/service_exceptions'
22
- require 'chef-dk/policyfile_lock'
23
- require 'chef-dk/authenticated_http'
24
- require 'chef-dk/policyfile/uploader'
25
-
26
- module ChefDK
27
- module PolicyfileServices
28
- class PushArchive
29
-
30
- USTAR_INDICATOR = "ustar\0".force_encoding(Encoding::ASCII_8BIT).freeze
31
-
32
- attr_reader :archive_file
33
- attr_reader :policy_group
34
- attr_reader :root_dir
35
- attr_reader :ui
36
- attr_reader :config
37
-
38
- attr_reader :policyfile_lock
39
-
40
-
41
- def initialize(archive_file: nil, policy_group: nil, root_dir: nil, ui: nil, config: nil)
42
- @archive_file = archive_file
43
- @policy_group = policy_group
44
- @root_dir = root_dir || Dir.pwd
45
- @ui = ui
46
- @config = config
47
-
48
- @policyfile_lock = nil
49
- end
50
-
51
- def archive_file_path
52
- File.expand_path(archive_file, root_dir)
53
- end
54
-
55
- def run
56
- unless File.exist?(archive_file_path)
57
- raise InvalidPolicyArchive, "Archive file #{archive_file_path} not found"
58
- end
59
- stage_unpacked_archive do |staging_dir|
60
- read_policyfile_lock(staging_dir)
61
-
62
- uploader.upload
63
- end
64
-
65
- rescue => e
66
- raise PolicyfilePushArchiveError.new("Failed to publish archived policy", e)
67
- end
68
-
69
- # @api private
70
- def uploader
71
- ChefDK::Policyfile::Uploader.new(policyfile_lock, policy_group,
72
- ui: ui,
73
- http_client: http_client,
74
- policy_document_native_api: config.policy_document_native_api)
75
- end
76
-
77
- # @api private
78
- def http_client
79
- @http_client ||= ChefDK::AuthenticatedHTTP.new(config.chef_server_url,
80
- signing_key_filename: config.client_key,
81
- client_name: config.node_name)
82
- end
83
-
84
- private
85
-
86
- def read_policyfile_lock(staging_dir)
87
- policyfile_lock_path = File.join(staging_dir, "Policyfile.lock.json")
88
-
89
- if looks_like_old_format_archive?(staging_dir)
90
- raise InvalidPolicyArchive, <<-MESSAGE
91
- This archive is in an unsupported format.
92
-
93
- This archive was created with an older version of ChefDK. This version of
94
- ChefDK does not support archives in the older format. Re-create the archive
95
- with a newer version of ChefDK or downgrade ChefDK.
96
- MESSAGE
97
- end
98
-
99
- unless File.exist?(policyfile_lock_path)
100
- raise InvalidPolicyArchive, "Archive does not contain a Policyfile.lock.json"
101
- end
102
-
103
- unless File.directory?(File.join(staging_dir, "cookbook_artifacts"))
104
- raise InvalidPolicyArchive, "Archive does not contain a cookbook_artifacts directory"
105
- end
106
-
107
-
108
- policy_data = load_policy_data(policyfile_lock_path)
109
- storage_config = Policyfile::StorageConfig.new.use_policyfile_lock(policyfile_lock_path)
110
- @policyfile_lock = ChefDK::PolicyfileLock.new(storage_config).build_from_archive(policy_data)
111
-
112
- missing_cookbooks = policyfile_lock.cookbook_locks.select do |name, lock|
113
- !lock.installed?
114
- end
115
-
116
- unless missing_cookbooks.empty?
117
- message = "Archive does not have all cookbooks required by the Policyfile.lock. " +
118
- "Missing cookbooks: '#{missing_cookbooks.keys.join('", "')}'."
119
- raise InvalidPolicyArchive, message
120
- end
121
-
122
- end
123
-
124
- def load_policy_data(policyfile_lock_path)
125
- FFI_Yajl::Parser.parse(IO.read(policyfile_lock_path))
126
- end
127
-
128
- def stage_unpacked_archive
129
- p = Process.pid
130
- t = Time.new.utc.strftime("%Y%m%d%H%M%S")
131
- Dir.mktmpdir("chefdk-push-archive-#{p}-#{t}") do |staging_dir|
132
- unpack_to(staging_dir)
133
- yield staging_dir
134
- end
135
-
136
- end
137
-
138
- def unpack_to(staging_dir)
139
- Zlib::GzipReader.open(archive_file_path) do |gz_file|
140
- untar_to(gz_file, staging_dir)
141
- end
142
-
143
- # untar_to can raise InvalidPolicyArchive, let it through
144
- rescue InvalidPolicyArchive
145
- raise
146
- rescue => e
147
- raise InvalidPolicyArchive, "Archive file #{archive_file_path} could not be unpacked. #{e}"
148
- end
149
-
150
- def untar_to(tar_file, staging_dir)
151
- # Minitar doesn't do much input checking, so if you feed it a
152
- # garbage-enough file it will just do weird things and blow up. For
153
- # example, if tar_file is just a bunch of nul characters, then tar will
154
- # try to open a file named '.'; if you give it some random string that
155
- # fits in the size of the filename header, it will create that file.
156
- #
157
- # Tar archives that we create via `chef export -a` and probably
158
- # everything else we might encounter should be in ustar format. For
159
- # such a tar file, bytes 257-263 should be "ustar\0", so we use this as
160
- # a sanity check.
161
- # https://en.wikipedia.org/wiki/Tar_(computing)
162
-
163
- first_tar_header = tar_file.read(512)
164
- ustar_indicator = first_tar_header[257, 6]
165
-
166
- unless ustar_indicator == USTAR_INDICATOR
167
- raise InvalidPolicyArchive, "Archive file #{archive_file_path} could not be unpacked. Tar archive looks corrupt."
168
- end
169
-
170
- # "undo" read of the first 512 bytes
171
- tar_file.rewind
172
-
173
- Archive::Tar::Minitar::Input.open(tar_file) do |stream|
174
- stream.each do |entry|
175
- stream.extract_entry(staging_dir, entry)
176
- end
177
- end
178
- end
179
-
180
- def looks_like_old_format_archive?(staging_dir)
181
- cookbooks_dir = File.join(staging_dir, "cookbooks")
182
- data_bags_dir = File.join(staging_dir, "data_bags")
183
-
184
- cookbook_artifacts_dir = File.join(staging_dir, "cookbook_artifacts")
185
- policies_dir = File.join(staging_dir, "policies")
186
- policy_groups_dir = File.join(staging_dir, "policy_groups")
187
-
188
- # Old archives just had these two dirs
189
- have_old_dirs = File.exist?(cookbooks_dir) && File.exist?(data_bags_dir)
190
-
191
- # New archives created by `chef export` will have all of these; it's
192
- # also possible we'll encounter an "artisanal" archive, which might
193
- # only be missing one of these by accident. In that case we want to
194
- # trigger a different error than we're detecting here.
195
- have_any_new_dirs = File.exist?(cookbook_artifacts_dir) ||
196
- File.exist?(policies_dir) ||
197
- File.exist?(policy_groups_dir)
198
-
199
- have_old_dirs && !have_any_new_dirs
200
- end
201
-
202
- end
203
- end
204
- end
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 'zlib'
19
+ require 'archive/tar/minitar'
20
+
21
+ require 'chef-dk/service_exceptions'
22
+ require 'chef-dk/policyfile_lock'
23
+ require 'chef-dk/authenticated_http'
24
+ require 'chef-dk/policyfile/uploader'
25
+
26
+ module ChefDK
27
+ module PolicyfileServices
28
+ class PushArchive
29
+
30
+ USTAR_INDICATOR = "ustar\0".force_encoding(Encoding::ASCII_8BIT).freeze
31
+
32
+ attr_reader :archive_file
33
+ attr_reader :policy_group
34
+ attr_reader :root_dir
35
+ attr_reader :ui
36
+ attr_reader :config
37
+
38
+ attr_reader :policyfile_lock
39
+
40
+
41
+ def initialize(archive_file: nil, policy_group: nil, root_dir: nil, ui: nil, config: nil)
42
+ @archive_file = archive_file
43
+ @policy_group = policy_group
44
+ @root_dir = root_dir || Dir.pwd
45
+ @ui = ui
46
+ @config = config
47
+
48
+ @policyfile_lock = nil
49
+ end
50
+
51
+ def archive_file_path
52
+ File.expand_path(archive_file, root_dir)
53
+ end
54
+
55
+ def run
56
+ unless File.exist?(archive_file_path)
57
+ raise InvalidPolicyArchive, "Archive file #{archive_file_path} not found"
58
+ end
59
+ stage_unpacked_archive do |staging_dir|
60
+ read_policyfile_lock(staging_dir)
61
+
62
+ uploader.upload
63
+ end
64
+
65
+ rescue => e
66
+ raise PolicyfilePushArchiveError.new("Failed to publish archived policy", e)
67
+ end
68
+
69
+ # @api private
70
+ def uploader
71
+ ChefDK::Policyfile::Uploader.new(policyfile_lock, policy_group,
72
+ ui: ui,
73
+ http_client: http_client,
74
+ policy_document_native_api: config.policy_document_native_api)
75
+ end
76
+
77
+ # @api private
78
+ def http_client
79
+ @http_client ||= ChefDK::AuthenticatedHTTP.new(config.chef_server_url,
80
+ signing_key_filename: config.client_key,
81
+ client_name: config.node_name)
82
+ end
83
+
84
+ private
85
+
86
+ def read_policyfile_lock(staging_dir)
87
+ policyfile_lock_path = File.join(staging_dir, "Policyfile.lock.json")
88
+
89
+ if looks_like_old_format_archive?(staging_dir)
90
+ raise InvalidPolicyArchive, <<-MESSAGE
91
+ This archive is in an unsupported format.
92
+
93
+ This archive was created with an older version of ChefDK. This version of
94
+ ChefDK does not support archives in the older format. Re-create the archive
95
+ with a newer version of ChefDK or downgrade ChefDK.
96
+ MESSAGE
97
+ end
98
+
99
+ unless File.exist?(policyfile_lock_path)
100
+ raise InvalidPolicyArchive, "Archive does not contain a Policyfile.lock.json"
101
+ end
102
+
103
+ unless File.directory?(File.join(staging_dir, "cookbook_artifacts"))
104
+ raise InvalidPolicyArchive, "Archive does not contain a cookbook_artifacts directory"
105
+ end
106
+
107
+
108
+ policy_data = load_policy_data(policyfile_lock_path)
109
+ storage_config = Policyfile::StorageConfig.new.use_policyfile_lock(policyfile_lock_path)
110
+ @policyfile_lock = ChefDK::PolicyfileLock.new(storage_config).build_from_archive(policy_data)
111
+
112
+ missing_cookbooks = policyfile_lock.cookbook_locks.select do |name, lock|
113
+ !lock.installed?
114
+ end
115
+
116
+ unless missing_cookbooks.empty?
117
+ message = "Archive does not have all cookbooks required by the Policyfile.lock. " +
118
+ "Missing cookbooks: '#{missing_cookbooks.keys.join('", "')}'."
119
+ raise InvalidPolicyArchive, message
120
+ end
121
+
122
+ end
123
+
124
+ def load_policy_data(policyfile_lock_path)
125
+ FFI_Yajl::Parser.parse(IO.read(policyfile_lock_path))
126
+ end
127
+
128
+ def stage_unpacked_archive
129
+ p = Process.pid
130
+ t = Time.new.utc.strftime("%Y%m%d%H%M%S")
131
+ Dir.mktmpdir("chefdk-push-archive-#{p}-#{t}") do |staging_dir|
132
+ unpack_to(staging_dir)
133
+ yield staging_dir
134
+ end
135
+
136
+ end
137
+
138
+ def unpack_to(staging_dir)
139
+ Zlib::GzipReader.open(archive_file_path) do |gz_file|
140
+ untar_to(gz_file, staging_dir)
141
+ end
142
+
143
+ # untar_to can raise InvalidPolicyArchive, let it through
144
+ rescue InvalidPolicyArchive
145
+ raise
146
+ rescue => e
147
+ raise InvalidPolicyArchive, "Archive file #{archive_file_path} could not be unpacked. #{e}"
148
+ end
149
+
150
+ def untar_to(tar_file, staging_dir)
151
+ # Minitar doesn't do much input checking, so if you feed it a
152
+ # garbage-enough file it will just do weird things and blow up. For
153
+ # example, if tar_file is just a bunch of nul characters, then tar will
154
+ # try to open a file named '.'; if you give it some random string that
155
+ # fits in the size of the filename header, it will create that file.
156
+ #
157
+ # Tar archives that we create via `chef export -a` and probably
158
+ # everything else we might encounter should be in ustar format. For
159
+ # such a tar file, bytes 257-263 should be "ustar\0", so we use this as
160
+ # a sanity check.
161
+ # https://en.wikipedia.org/wiki/Tar_(computing)
162
+
163
+ first_tar_header = tar_file.read(512)
164
+ ustar_indicator = first_tar_header[257, 6]
165
+
166
+ unless ustar_indicator == USTAR_INDICATOR
167
+ raise InvalidPolicyArchive, "Archive file #{archive_file_path} could not be unpacked. Tar archive looks corrupt."
168
+ end
169
+
170
+ # "undo" read of the first 512 bytes
171
+ tar_file.rewind
172
+
173
+ Archive::Tar::Minitar::Input.open(tar_file) do |stream|
174
+ stream.each do |entry|
175
+ stream.extract_entry(staging_dir, entry)
176
+ end
177
+ end
178
+ end
179
+
180
+ def looks_like_old_format_archive?(staging_dir)
181
+ cookbooks_dir = File.join(staging_dir, "cookbooks")
182
+ data_bags_dir = File.join(staging_dir, "data_bags")
183
+
184
+ cookbook_artifacts_dir = File.join(staging_dir, "cookbook_artifacts")
185
+ policies_dir = File.join(staging_dir, "policies")
186
+ policy_groups_dir = File.join(staging_dir, "policy_groups")
187
+
188
+ # Old archives just had these two dirs
189
+ have_old_dirs = File.exist?(cookbooks_dir) && File.exist?(data_bags_dir)
190
+
191
+ # New archives created by `chef export` will have all of these; it's
192
+ # also possible we'll encounter an "artisanal" archive, which might
193
+ # only be missing one of these by accident. In that case we want to
194
+ # trigger a different error than we're detecting here.
195
+ have_any_new_dirs = File.exist?(cookbook_artifacts_dir) ||
196
+ File.exist?(policies_dir) ||
197
+ File.exist?(policy_groups_dir)
198
+
199
+ have_old_dirs && !have_any_new_dirs
200
+ end
201
+
202
+ end
203
+ end
204
+ end