chef-dk 3.0.36 → 3.1.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 (377) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +124 -126
  3. data/Gemfile.lock +815 -812
  4. data/LICENSE +201 -201
  5. data/README.md +333 -333
  6. data/Rakefile +74 -74
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
  8. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +287 -287
  9. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
  10. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
  11. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
  12. data/acceptance/Gemfile +21 -21
  13. data/acceptance/Gemfile.lock +334 -334
  14. data/acceptance/README.md +132 -132
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
  17. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
  18. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
  19. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
  20. data/acceptance/trivial/.kitchen.yml +7 -7
  21. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
  22. data/bin/chef +25 -25
  23. data/chef-dk.gemspec +60 -60
  24. data/lib/chef-dk.rb +19 -19
  25. data/lib/chef-dk/authenticated_http.rb +22 -22
  26. data/lib/chef-dk/builtin_commands.rb +59 -59
  27. data/lib/chef-dk/chef_runner.rb +114 -114
  28. data/lib/chef-dk/chef_server_api_multi.rb +73 -73
  29. data/lib/chef-dk/cli.rb +201 -201
  30. data/lib/chef-dk/command/base.rb +79 -79
  31. data/lib/chef-dk/command/clean_policy_cookbooks.rb +114 -114
  32. data/lib/chef-dk/command/clean_policy_revisions.rb +111 -111
  33. data/lib/chef-dk/command/delete_policy.rb +120 -120
  34. data/lib/chef-dk/command/delete_policy_group.rb +120 -120
  35. data/lib/chef-dk/command/diff.rb +315 -315
  36. data/lib/chef-dk/command/env.rb +89 -89
  37. data/lib/chef-dk/command/exec.rb +44 -44
  38. data/lib/chef-dk/command/export.rb +155 -155
  39. data/lib/chef-dk/command/gem.rb +47 -47
  40. data/lib/chef-dk/command/generate.rb +125 -125
  41. data/lib/chef-dk/command/generator_commands.rb +83 -83
  42. data/lib/chef-dk/command/generator_commands/app.rb +106 -106
  43. data/lib/chef-dk/command/generator_commands/attribute.rb +36 -36
  44. data/lib/chef-dk/command/generator_commands/base.rb +157 -157
  45. data/lib/chef-dk/command/generator_commands/build_cookbook.rb +125 -125
  46. data/lib/chef-dk/command/generator_commands/chef_exts/generator_desc_resource.rb +85 -85
  47. data/lib/chef-dk/command/generator_commands/chef_exts/quieter_doc_formatter.rb +38 -38
  48. data/lib/chef-dk/command/generator_commands/chef_exts/recipe_dsl_ext.rb +39 -39
  49. data/lib/chef-dk/command/generator_commands/cookbook.rb +241 -241
  50. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  51. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  52. data/lib/chef-dk/command/generator_commands/generator_generator.rb +174 -174
  53. data/lib/chef-dk/command/generator_commands/helpers.rb +36 -36
  54. data/lib/chef-dk/command/generator_commands/policyfile.rb +124 -124
  55. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  56. data/lib/chef-dk/command/generator_commands/repo.rb +123 -123
  57. data/lib/chef-dk/command/generator_commands/resource.rb +36 -36
  58. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  59. data/lib/chef-dk/command/install.rb +120 -120
  60. data/lib/chef-dk/command/provision.rb +436 -436
  61. data/lib/chef-dk/command/push.rb +117 -117
  62. data/lib/chef-dk/command/push_archive.rb +125 -125
  63. data/lib/chef-dk/command/shell_init.rb +179 -179
  64. data/lib/chef-dk/command/show_policy.rb +163 -163
  65. data/lib/chef-dk/command/undelete.rb +154 -154
  66. data/lib/chef-dk/command/update.rb +133 -133
  67. data/lib/chef-dk/command/verify.rb +629 -629
  68. data/lib/chef-dk/commands_map.rb +113 -113
  69. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  70. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  71. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  72. data/lib/chef-dk/component_test.rb +227 -227
  73. data/lib/chef-dk/configurable.rb +88 -88
  74. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  75. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  76. data/lib/chef-dk/cookbook_profiler/git.rb +152 -152
  77. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  78. data/lib/chef-dk/cookbook_profiler/null_scm.rb +31 -31
  79. data/lib/chef-dk/exceptions.rb +151 -151
  80. data/lib/chef-dk/generator.rb +165 -165
  81. data/lib/chef-dk/helpers.rb +176 -176
  82. data/lib/chef-dk/pager.rb +104 -104
  83. data/lib/chef-dk/policyfile/artifactory_cookbook_source.rb +102 -102
  84. data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -110
  85. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  86. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +99 -99
  87. data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +167 -167
  88. data/lib/chef-dk/policyfile/community_cookbook_source.rb +95 -95
  89. data/lib/chef-dk/policyfile/comparison_base.rb +123 -123
  90. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  91. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  92. data/lib/chef-dk/policyfile/cookbook_sources.rb +23 -23
  93. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +89 -89
  94. data/lib/chef-dk/policyfile/differ.rb +263 -263
  95. data/lib/chef-dk/policyfile/dsl.rb +288 -288
  96. data/lib/chef-dk/policyfile/git_lock_fetcher.rb +265 -265
  97. data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -156
  98. data/lib/chef-dk/policyfile/lister.rb +229 -229
  99. data/lib/chef-dk/policyfile/local_lock_fetcher.rb +129 -129
  100. data/lib/chef-dk/policyfile/lock_applier.rb +80 -80
  101. data/lib/chef-dk/policyfile/null_cookbook_source.rb +49 -49
  102. data/lib/chef-dk/policyfile/policyfile_location_specification.rb +125 -125
  103. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  104. data/lib/chef-dk/policyfile/reports/install.rb +69 -69
  105. data/lib/chef-dk/policyfile/reports/table_printer.rb +57 -57
  106. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  107. data/lib/chef-dk/policyfile/solution_dependencies.rb +311 -311
  108. data/lib/chef-dk/policyfile/source_uri.rb +57 -57
  109. data/lib/chef-dk/policyfile/storage_config.rb +112 -112
  110. data/lib/chef-dk/policyfile/undo_record.rb +139 -139
  111. data/lib/chef-dk/policyfile/undo_stack.rb +128 -128
  112. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  113. data/lib/chef-dk/policyfile_compiler.rb +528 -528
  114. data/lib/chef-dk/policyfile_lock.rb +581 -581
  115. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  116. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +123 -123
  117. data/lib/chef-dk/policyfile_services/export_repo.rb +419 -419
  118. data/lib/chef-dk/policyfile_services/install.rb +162 -162
  119. data/lib/chef-dk/policyfile_services/push.rb +112 -112
  120. data/lib/chef-dk/policyfile_services/push_archive.rb +164 -164
  121. data/lib/chef-dk/policyfile_services/rm_policy.rb +141 -141
  122. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +85 -85
  123. data/lib/chef-dk/policyfile_services/show_policy.rb +234 -234
  124. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  125. data/lib/chef-dk/policyfile_services/update_attributes.rb +110 -110
  126. data/lib/chef-dk/service_exception_inspectors.rb +24 -24
  127. data/lib/chef-dk/service_exception_inspectors/base.rb +39 -39
  128. data/lib/chef-dk/service_exception_inspectors/http.rb +119 -119
  129. data/lib/chef-dk/service_exceptions.rb +142 -142
  130. data/lib/chef-dk/shell_out.rb +36 -36
  131. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +4 -4
  132. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/.kitchen.yml +21 -21
  133. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/README.md +146 -146
  134. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +9 -9
  135. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +104 -104
  136. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  137. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +66 -66
  138. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-config.json +17 -17
  139. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-project.toml +36 -36
  140. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +22 -22
  141. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +24 -24
  142. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  143. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +8 -8
  144. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +7 -7
  145. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +9 -9
  146. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -56
  147. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  148. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  149. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  150. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  151. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  152. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  153. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  154. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +3 -3
  155. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +3 -3
  156. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  157. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +89 -89
  158. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +13 -13
  159. data/lib/chef-dk/skeletons/code_generator/recipes/build_cookbook.rb +177 -177
  160. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +158 -158
  161. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +25 -25
  162. data/lib/chef-dk/skeletons/code_generator/recipes/helpers.rb +21 -21
  163. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +9 -9
  164. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +52 -52
  165. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +68 -68
  166. data/lib/chef-dk/skeletons/code_generator/recipes/resource.rb +13 -13
  167. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  168. data/lib/chef-dk/skeletons/code_generator/templates/default/CHANGELOG.md.erb +11 -11
  169. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  170. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -201
  171. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  172. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  173. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  174. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  175. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  176. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -7
  177. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -10
  178. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +8 -8
  179. data/lib/chef-dk/skeletons/code_generator/templates/default/helpers.rb.erb +39 -39
  180. data/lib/chef-dk/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +18 -18
  181. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +26 -26
  182. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +33 -33
  183. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +20 -20
  184. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  185. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +35 -35
  186. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -128
  187. data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +1 -1
  188. data/lib/chef-dk/ui.rb +57 -57
  189. data/lib/chef-dk/version.rb +20 -20
  190. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  191. data/omnibus_overrides.rb +25 -25
  192. data/spec/shared/a_file_generator.rb +125 -125
  193. data/spec/shared/a_generated_file.rb +12 -12
  194. data/spec/shared/command_with_ui_object.rb +11 -11
  195. data/spec/shared/custom_generator_cookbook.rb +136 -136
  196. data/spec/shared/fixture_cookbook_checksums.rb +46 -46
  197. data/spec/shared/setup_git_committer_config.rb +54 -54
  198. data/spec/shared/setup_git_cookbooks.rb +53 -53
  199. data/spec/spec_helper.rb +51 -51
  200. data/spec/test_helpers.rb +84 -84
  201. data/spec/unit/chef_runner_spec.rb +139 -139
  202. data/spec/unit/chef_server_api_multi_spec.rb +120 -120
  203. data/spec/unit/cli_spec.rb +377 -377
  204. data/spec/unit/command/base_spec.rb +172 -172
  205. data/spec/unit/command/clean_policy_cookbooks_spec.rb +180 -180
  206. data/spec/unit/command/clean_policy_revisions_spec.rb +180 -180
  207. data/spec/unit/command/delete_policy_group_spec.rb +206 -206
  208. data/spec/unit/command/delete_policy_spec.rb +206 -206
  209. data/spec/unit/command/diff_spec.rb +311 -311
  210. data/spec/unit/command/env_spec.rb +52 -52
  211. data/spec/unit/command/exec_spec.rb +178 -178
  212. data/spec/unit/command/export_spec.rb +199 -199
  213. data/spec/unit/command/generate_spec.rb +142 -142
  214. data/spec/unit/command/generator_commands/app_spec.rb +166 -166
  215. data/spec/unit/command/generator_commands/attribute_spec.rb +31 -31
  216. data/spec/unit/command/generator_commands/base_spec.rb +181 -181
  217. data/spec/unit/command/generator_commands/build_cookbook_spec.rb +377 -377
  218. data/spec/unit/command/generator_commands/chef_exts/generator_desc_resource_spec.rb +97 -97
  219. data/spec/unit/command/generator_commands/chef_exts/recipe_dsl_ext_spec.rb +111 -111
  220. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +31 -31
  221. data/spec/unit/command/generator_commands/cookbook_spec.rb +765 -765
  222. data/spec/unit/command/generator_commands/generator_generator_spec.rb +227 -227
  223. data/spec/unit/command/generator_commands/helpers_spec.rb +31 -31
  224. data/spec/unit/command/generator_commands/policyfile_spec.rb +223 -223
  225. data/spec/unit/command/generator_commands/recipe_spec.rb +37 -37
  226. data/spec/unit/command/generator_commands/repo_spec.rb +374 -374
  227. data/spec/unit/command/generator_commands/resource_spec.rb +31 -31
  228. data/spec/unit/command/generator_commands/template_spec.rb +31 -31
  229. data/spec/unit/command/install_spec.rb +179 -179
  230. data/spec/unit/command/provision_spec.rb +589 -589
  231. data/spec/unit/command/push_archive_spec.rb +153 -153
  232. data/spec/unit/command/push_spec.rb +198 -198
  233. data/spec/unit/command/shell_init_spec.rb +339 -339
  234. data/spec/unit/command/show_policy_spec.rb +234 -234
  235. data/spec/unit/command/undelete_spec.rb +244 -244
  236. data/spec/unit/command/update_spec.rb +283 -283
  237. data/spec/unit/command/verify_spec.rb +341 -341
  238. data/spec/unit/commands_map_spec.rb +57 -57
  239. data/spec/unit/component_test_spec.rb +128 -128
  240. data/spec/unit/configurable_spec.rb +68 -68
  241. data/spec/unit/cookbook_metadata_spec.rb +96 -96
  242. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  243. data/spec/unit/cookbook_profiler/identifiers_spec.rb +81 -81
  244. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  245. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  246. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  247. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  248. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  249. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  250. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  251. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  252. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  253. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  254. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  255. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  256. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  257. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  258. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  259. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  260. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  261. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  262. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  263. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  264. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  265. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  266. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  267. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  268. data/spec/unit/fixtures/cookbooks_api/chef_server_universe.json +56 -56
  269. data/spec/unit/fixtures/cookbooks_api/pruned_chef_server_universe.json +30 -30
  270. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  271. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  272. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  273. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +33 -33
  274. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  275. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  276. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  277. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  278. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  279. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  280. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  281. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  282. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  283. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  284. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  285. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  286. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  287. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  288. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  289. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  290. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  291. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  292. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  293. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  294. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  295. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  296. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  297. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  298. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  299. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  300. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  301. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  302. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  303. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  304. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  305. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  306. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  307. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  308. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  309. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  310. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  311. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  312. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  313. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  314. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  315. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  316. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  317. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  318. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  319. data/spec/unit/generator_spec.rb +119 -119
  320. data/spec/unit/pager_spec.rb +117 -117
  321. data/spec/unit/policyfile/artifactory_cookbook_source_spec.rb +59 -59
  322. data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -80
  323. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  324. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +55 -55
  325. data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -161
  326. data/spec/unit/policyfile/community_cookbook_source_spec.rb +83 -83
  327. data/spec/unit/policyfile/comparison_base_spec.rb +340 -340
  328. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +347 -347
  329. data/spec/unit/policyfile/cookbook_locks_spec.rb +527 -527
  330. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +129 -129
  331. data/spec/unit/policyfile/differ_spec.rb +686 -686
  332. data/spec/unit/policyfile/git_lock_fetcher_spec.rb +155 -155
  333. data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -242
  334. data/spec/unit/policyfile/lister_spec.rb +268 -268
  335. data/spec/unit/policyfile/local_lock_fetcher_spec.rb +173 -173
  336. data/spec/unit/policyfile/lock_applier_spec.rb +100 -100
  337. data/spec/unit/policyfile/null_cookbook_source_spec.rb +34 -34
  338. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  339. data/spec/unit/policyfile/reports/install_spec.rb +114 -114
  340. data/spec/unit/policyfile/reports/upload_spec.rb +94 -94
  341. data/spec/unit/policyfile/solution_dependencies_spec.rb +170 -170
  342. data/spec/unit/policyfile/source_uri_spec.rb +36 -36
  343. data/spec/unit/policyfile/storage_config_spec.rb +180 -180
  344. data/spec/unit/policyfile/undo_record_spec.rb +258 -258
  345. data/spec/unit/policyfile/undo_stack_spec.rb +265 -265
  346. data/spec/unit/policyfile/uploader_spec.rb +409 -409
  347. data/spec/unit/policyfile_demands_spec.rb +1197 -1197
  348. data/spec/unit/policyfile_evaluation_spec.rb +628 -628
  349. data/spec/unit/policyfile_includes_dsl_spec.rb +159 -159
  350. data/spec/unit/policyfile_includes_spec.rb +720 -720
  351. data/spec/unit/policyfile_install_with_includes_spec.rb +232 -232
  352. data/spec/unit/policyfile_lock_build_spec.rb +1065 -1065
  353. data/spec/unit/policyfile_lock_install_spec.rb +137 -137
  354. data/spec/unit/policyfile_lock_serialization_spec.rb +424 -424
  355. data/spec/unit/policyfile_lock_validation_spec.rb +608 -608
  356. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  357. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +272 -272
  358. data/spec/unit/policyfile_services/export_repo_spec.rb +473 -473
  359. data/spec/unit/policyfile_services/install_spec.rb +209 -209
  360. data/spec/unit/policyfile_services/push_archive_spec.rb +359 -359
  361. data/spec/unit/policyfile_services/push_spec.rb +249 -249
  362. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +237 -237
  363. data/spec/unit/policyfile_services/rm_policy_spec.rb +263 -263
  364. data/spec/unit/policyfile_services/show_policy_spec.rb +887 -887
  365. data/spec/unit/policyfile_services/undelete_spec.rb +302 -302
  366. data/spec/unit/policyfile_services/update_attributes_spec.rb +229 -229
  367. data/spec/unit/policyfile_services/update_spec.rb +140 -140
  368. data/spec/unit/service_exception_inspectors/base_spec.rb +41 -41
  369. data/spec/unit/service_exception_inspectors/http_spec.rb +138 -138
  370. data/spec/unit/shell_out_spec.rb +34 -34
  371. data/tasks/announce.rb +57 -57
  372. data/tasks/bin/bundle-platform.bat +2 -2
  373. data/tasks/dependencies.rb +89 -89
  374. data/tasks/templates/prerelease.md.erb +35 -35
  375. data/tasks/templates/release.md.erb +34 -34
  376. data/warning.txt +9 -9
  377. metadata +2 -2
@@ -1,128 +1,128 @@
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 "fileutils"
19
-
20
- require "ffi_yajl"
21
-
22
- require "chef-dk/helpers"
23
- require "chef-dk/policyfile/undo_record"
24
-
25
- module ChefDK
26
- module Policyfile
27
-
28
- class UndoStack
29
-
30
- MAX_SIZE = 10
31
-
32
- include Helpers
33
-
34
- def undo_dir
35
- File.join(Helpers.chefdk_home, "undo")
36
- end
37
-
38
- def size
39
- undo_record_files.size
40
- end
41
-
42
- def empty?
43
- size == 0
44
- end
45
-
46
- def has_id?(id)
47
- File.exist?(undo_file_for(id))
48
- end
49
-
50
- def each_with_id
51
- undo_record_files.each do |filename|
52
- yield File.basename(filename), load_undo_record(filename)
53
- end
54
- end
55
-
56
- def undo_records
57
- undo_record_files.map { |f| load_undo_record(f) }
58
- end
59
-
60
- def push(undo_record)
61
- ensure_undo_dir_exists
62
-
63
- record_id = Time.new.utc.strftime("%Y%m%d%H%M%S")
64
- path = File.join(undo_dir, record_id)
65
-
66
- with_file(path) do |f|
67
- f.print(FFI_Yajl::Encoder.encode(undo_record.for_serialization, pretty: true))
68
- end
69
-
70
- records_to_delete = undo_record_files.size - MAX_SIZE
71
- if records_to_delete > 0
72
- undo_record_files.take(records_to_delete).each do |file|
73
- File.unlink(file)
74
- end
75
- end
76
-
77
- self
78
- end
79
-
80
- def pop
81
- file_to_pop = undo_record_files.last
82
- if file_to_pop.nil?
83
- raise CantUndo, "No undo records exist in #{undo_dir}"
84
- end
85
-
86
- record = load_undo_record(file_to_pop)
87
- # if this hits an exception, we skip unlink
88
- yield record if block_given?
89
- File.unlink(file_to_pop)
90
- record
91
- end
92
-
93
- def delete(id)
94
- undo_file = undo_file_for(id)
95
- unless File.exist?(undo_file)
96
- raise UndoRecordNotFound, "No undo record for id '#{id}' exists at #{undo_file}"
97
- end
98
-
99
- record = load_undo_record(undo_file)
100
- yield record if block_given?
101
- File.unlink(undo_file)
102
- record
103
- end
104
-
105
- private
106
-
107
- def undo_file_for(id)
108
- File.join(undo_dir, id)
109
- end
110
-
111
- def load_undo_record(file)
112
- data = FFI_Yajl::Parser.parse(IO.read(file))
113
- UndoRecord.new.load(data)
114
- end
115
-
116
- def undo_record_files
117
- Dir[File.join(undo_dir, "*")].sort
118
- end
119
-
120
- def ensure_undo_dir_exists
121
- return false if File.directory?(undo_dir)
122
-
123
- FileUtils.mkdir_p(undo_dir)
124
- end
125
- end
126
-
127
- end
128
- 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 "fileutils"
19
+
20
+ require "ffi_yajl"
21
+
22
+ require "chef-dk/helpers"
23
+ require "chef-dk/policyfile/undo_record"
24
+
25
+ module ChefDK
26
+ module Policyfile
27
+
28
+ class UndoStack
29
+
30
+ MAX_SIZE = 10
31
+
32
+ include Helpers
33
+
34
+ def undo_dir
35
+ File.join(Helpers.chefdk_home, "undo")
36
+ end
37
+
38
+ def size
39
+ undo_record_files.size
40
+ end
41
+
42
+ def empty?
43
+ size == 0
44
+ end
45
+
46
+ def has_id?(id)
47
+ File.exist?(undo_file_for(id))
48
+ end
49
+
50
+ def each_with_id
51
+ undo_record_files.each do |filename|
52
+ yield File.basename(filename), load_undo_record(filename)
53
+ end
54
+ end
55
+
56
+ def undo_records
57
+ undo_record_files.map { |f| load_undo_record(f) }
58
+ end
59
+
60
+ def push(undo_record)
61
+ ensure_undo_dir_exists
62
+
63
+ record_id = Time.new.utc.strftime("%Y%m%d%H%M%S")
64
+ path = File.join(undo_dir, record_id)
65
+
66
+ with_file(path) do |f|
67
+ f.print(FFI_Yajl::Encoder.encode(undo_record.for_serialization, pretty: true))
68
+ end
69
+
70
+ records_to_delete = undo_record_files.size - MAX_SIZE
71
+ if records_to_delete > 0
72
+ undo_record_files.take(records_to_delete).each do |file|
73
+ File.unlink(file)
74
+ end
75
+ end
76
+
77
+ self
78
+ end
79
+
80
+ def pop
81
+ file_to_pop = undo_record_files.last
82
+ if file_to_pop.nil?
83
+ raise CantUndo, "No undo records exist in #{undo_dir}"
84
+ end
85
+
86
+ record = load_undo_record(file_to_pop)
87
+ # if this hits an exception, we skip unlink
88
+ yield record if block_given?
89
+ File.unlink(file_to_pop)
90
+ record
91
+ end
92
+
93
+ def delete(id)
94
+ undo_file = undo_file_for(id)
95
+ unless File.exist?(undo_file)
96
+ raise UndoRecordNotFound, "No undo record for id '#{id}' exists at #{undo_file}"
97
+ end
98
+
99
+ record = load_undo_record(undo_file)
100
+ yield record if block_given?
101
+ File.unlink(undo_file)
102
+ record
103
+ end
104
+
105
+ private
106
+
107
+ def undo_file_for(id)
108
+ File.join(undo_dir, id)
109
+ end
110
+
111
+ def load_undo_record(file)
112
+ data = FFI_Yajl::Parser.parse(IO.read(file))
113
+ UndoRecord.new.load(data)
114
+ end
115
+
116
+ def undo_record_files
117
+ Dir[File.join(undo_dir, "*")].sort
118
+ end
119
+
120
+ def ensure_undo_dir_exists
121
+ return false if File.directory?(undo_dir)
122
+
123
+ FileUtils.mkdir_p(undo_dir)
124
+ end
125
+ end
126
+
127
+ end
128
+ end
@@ -1,213 +1,213 @@
1
- #
2
- # Copyright:: Copyright (c) 2014-2018 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 "chef/cookbook_uploader"
19
- require "chef-dk/policyfile/read_cookbook_for_compat_mode_upload"
20
-
21
- require "chef-dk/ui"
22
- require "chef-dk/policyfile/reports/upload"
23
-
24
- module ChefDK
25
- module Policyfile
26
- class Uploader
27
-
28
- LockedCookbookForUpload = Struct.new(:cookbook, :lock)
29
-
30
- COMPAT_MODE_DATA_BAG_NAME = "policyfiles".freeze
31
-
32
- attr_reader :policyfile_lock
33
- attr_reader :policy_group
34
- attr_reader :http_client
35
- attr_reader :ui
36
-
37
- def initialize(policyfile_lock, policy_group, ui: nil, http_client: nil, policy_document_native_api: false)
38
- @policyfile_lock = policyfile_lock
39
- @policy_group = policy_group
40
- @http_client = http_client
41
- @ui = ui || UI.null
42
- @policy_document_native_api = policy_document_native_api
43
-
44
- @cookbook_versions_for_policy = nil
45
- end
46
-
47
- def policy_name
48
- policyfile_lock.name
49
- end
50
-
51
- def upload
52
- ui.msg("Uploading policy to policy group #{policy_group}")
53
-
54
- if !using_policy_document_native_api?
55
- ui.msg(<<-DRAGONS)
56
- WARN: Uploading policy to policy group #{policy_group} in compatibility mode.
57
- Cookbooks will be uploaded with very large version numbers, which may be picked
58
- up by existing nodes.
59
- DRAGONS
60
- end
61
-
62
- upload_cookbooks
63
- upload_policy
64
- end
65
-
66
- def upload_policy
67
- if using_policy_document_native_api?
68
- upload_policy_native
69
- else
70
- data_bag_create
71
- data_bag_item_create
72
- end
73
- end
74
-
75
- def upload_policy_native
76
- http_client.put("/policy_groups/#{policy_group}/policies/#{policy_name}", policyfile_lock.to_lock)
77
- end
78
-
79
- def data_bag_create
80
- http_client.post("data", { "name" => COMPAT_MODE_DATA_BAG_NAME })
81
- rescue Net::HTTPServerException => e
82
- raise e unless e.response.code == "409"
83
- end
84
-
85
- def data_bag_item_create
86
- policy_id = "#{policy_name}-#{policy_group}"
87
- lock_data = policyfile_lock.to_lock.dup
88
-
89
- lock_data["id"] = policy_id
90
-
91
- data_item = {
92
- "id" => policy_id,
93
- "name" => "data_bag_item_#{COMPAT_MODE_DATA_BAG_NAME}_#{policy_id}",
94
- "data_bag" => COMPAT_MODE_DATA_BAG_NAME,
95
- "raw_data" => lock_data,
96
- # we'd prefer to leave this out, but the "compatibility mode"
97
- # implementation in chef-client relies on magical class inflation
98
- "json_class" => "Chef::DataBagItem",
99
- }
100
-
101
- upload_lockfile_as_data_bag_item(policy_id, data_item)
102
- ui.msg("Policy uploaded as data bag item #{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}")
103
- true
104
- end
105
-
106
- def uploader
107
- # TODO: uploader runs cookbook validation; we want to do this at a different time.
108
- @uploader ||= Chef::CookbookUploader.new(cookbook_versions_to_upload, rest: http_client, policy_mode: using_policy_document_native_api?)
109
- end
110
-
111
- def cookbook_versions_to_upload
112
- cookbook_versions_for_policy.inject([]) do |versions_to_upload, cookbook_with_lock|
113
- cb = cookbook_with_lock.cookbook
114
- # When we abandon custom identifier support in favor of the one true
115
- # hash, identifier generation code can be moved into chef proper and
116
- # this can be removed.
117
- cb.identifier = cookbook_with_lock.lock.identifier
118
-
119
- versions_to_upload << cb unless remote_already_has_cookbook?(cb)
120
- versions_to_upload
121
- end
122
- end
123
-
124
- def remote_already_has_cookbook?(cookbook)
125
- return false unless existing_cookbook_on_remote.key?(cookbook.name.to_s)
126
-
127
- if using_policy_document_native_api?
128
- native_mode_cookbook_exists_on_remote?(cookbook)
129
- else
130
- compat_mode_cookbook_exists_on_remote?(cookbook)
131
- end
132
- end
133
-
134
- def native_mode_cookbook_exists_on_remote?(cookbook)
135
- existing_cookbook_on_remote[cookbook.name.to_s]["versions"].any? do |cookbook_info|
136
- cookbook_info["identifier"] == cookbook.identifier
137
- end
138
- end
139
-
140
- def compat_mode_cookbook_exists_on_remote?(cookbook)
141
- existing_cookbook_on_remote[cookbook.name.to_s]["versions"].any? do |cookbook_info|
142
- cookbook_info["version"] == cookbook.version
143
- end
144
- end
145
-
146
- def existing_cookbook_on_remote
147
- @existing_cookbook_on_remote ||= http_client.get(list_cookbooks_url)
148
- end
149
-
150
- # An Array of Chef::CookbookVersion objects representing the full set that
151
- # the policyfile lock requires.
152
- def cookbook_versions_for_policy
153
- return @cookbook_versions_for_policy if @cookbook_versions_for_policy
154
- policyfile_lock.validate_cookbooks!
155
- @cookbook_versions_for_policy =
156
- if using_policy_document_native_api?
157
- load_cookbooks_in_native_mode
158
- else
159
- load_cookbooks_in_compat_mode
160
- end
161
- end
162
-
163
- def load_cookbooks_in_native_mode
164
- policyfile_lock.cookbook_locks.map do |name, lock|
165
- cb = CookbookLoaderWithChefignore.load(name, lock.cookbook_path)
166
- LockedCookbookForUpload.new(cb, lock)
167
- end
168
- end
169
-
170
- def load_cookbooks_in_compat_mode
171
- policyfile_lock.cookbook_locks.map do |name, lock|
172
- cb = ReadCookbookForCompatModeUpload.load(name, lock.dotted_decimal_identifier, lock.cookbook_path)
173
- LockedCookbookForUpload.new(cb, lock)
174
- end
175
- end
176
-
177
- def using_policy_document_native_api?
178
- @policy_document_native_api
179
- end
180
-
181
- private
182
-
183
- def list_cookbooks_url
184
- if using_policy_document_native_api?
185
- "cookbook_artifacts?num_versions=all"
186
- else
187
- "cookbooks?num_versions=all"
188
- end
189
- end
190
-
191
- def upload_cookbooks
192
- ui.msg("WARN: Uploading cookbooks using semver compat mode") unless using_policy_document_native_api?
193
-
194
- uploader.upload_cookbooks unless cookbook_versions_to_upload.empty?
195
-
196
- reused_cbs, uploaded_cbs = cookbook_versions_for_policy.partition do |cb_with_lock|
197
- remote_already_has_cookbook?(cb_with_lock.cookbook)
198
- end
199
-
200
- Reports::Upload.new(reused_cbs: reused_cbs, uploaded_cbs: uploaded_cbs, ui: ui).show
201
-
202
- true
203
- end
204
-
205
- def upload_lockfile_as_data_bag_item(policy_id, data_item)
206
- http_client.put("data/#{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}", data_item)
207
- rescue Net::HTTPServerException => e
208
- raise e unless e.response.code == "404"
209
- http_client.post("data/#{COMPAT_MODE_DATA_BAG_NAME}", data_item)
210
- end
211
- end
212
- end
213
- end
1
+ #
2
+ # Copyright:: Copyright (c) 2014-2018 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 "chef/cookbook_uploader"
19
+ require "chef-dk/policyfile/read_cookbook_for_compat_mode_upload"
20
+
21
+ require "chef-dk/ui"
22
+ require "chef-dk/policyfile/reports/upload"
23
+
24
+ module ChefDK
25
+ module Policyfile
26
+ class Uploader
27
+
28
+ LockedCookbookForUpload = Struct.new(:cookbook, :lock)
29
+
30
+ COMPAT_MODE_DATA_BAG_NAME = "policyfiles".freeze
31
+
32
+ attr_reader :policyfile_lock
33
+ attr_reader :policy_group
34
+ attr_reader :http_client
35
+ attr_reader :ui
36
+
37
+ def initialize(policyfile_lock, policy_group, ui: nil, http_client: nil, policy_document_native_api: false)
38
+ @policyfile_lock = policyfile_lock
39
+ @policy_group = policy_group
40
+ @http_client = http_client
41
+ @ui = ui || UI.null
42
+ @policy_document_native_api = policy_document_native_api
43
+
44
+ @cookbook_versions_for_policy = nil
45
+ end
46
+
47
+ def policy_name
48
+ policyfile_lock.name
49
+ end
50
+
51
+ def upload
52
+ ui.msg("Uploading policy to policy group #{policy_group}")
53
+
54
+ if !using_policy_document_native_api?
55
+ ui.msg(<<-DRAGONS)
56
+ WARN: Uploading policy to policy group #{policy_group} in compatibility mode.
57
+ Cookbooks will be uploaded with very large version numbers, which may be picked
58
+ up by existing nodes.
59
+ DRAGONS
60
+ end
61
+
62
+ upload_cookbooks
63
+ upload_policy
64
+ end
65
+
66
+ def upload_policy
67
+ if using_policy_document_native_api?
68
+ upload_policy_native
69
+ else
70
+ data_bag_create
71
+ data_bag_item_create
72
+ end
73
+ end
74
+
75
+ def upload_policy_native
76
+ http_client.put("/policy_groups/#{policy_group}/policies/#{policy_name}", policyfile_lock.to_lock)
77
+ end
78
+
79
+ def data_bag_create
80
+ http_client.post("data", { "name" => COMPAT_MODE_DATA_BAG_NAME })
81
+ rescue Net::HTTPServerException => e
82
+ raise e unless e.response.code == "409"
83
+ end
84
+
85
+ def data_bag_item_create
86
+ policy_id = "#{policy_name}-#{policy_group}"
87
+ lock_data = policyfile_lock.to_lock.dup
88
+
89
+ lock_data["id"] = policy_id
90
+
91
+ data_item = {
92
+ "id" => policy_id,
93
+ "name" => "data_bag_item_#{COMPAT_MODE_DATA_BAG_NAME}_#{policy_id}",
94
+ "data_bag" => COMPAT_MODE_DATA_BAG_NAME,
95
+ "raw_data" => lock_data,
96
+ # we'd prefer to leave this out, but the "compatibility mode"
97
+ # implementation in chef-client relies on magical class inflation
98
+ "json_class" => "Chef::DataBagItem",
99
+ }
100
+
101
+ upload_lockfile_as_data_bag_item(policy_id, data_item)
102
+ ui.msg("Policy uploaded as data bag item #{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}")
103
+ true
104
+ end
105
+
106
+ def uploader
107
+ # TODO: uploader runs cookbook validation; we want to do this at a different time.
108
+ @uploader ||= Chef::CookbookUploader.new(cookbook_versions_to_upload, rest: http_client, policy_mode: using_policy_document_native_api?)
109
+ end
110
+
111
+ def cookbook_versions_to_upload
112
+ cookbook_versions_for_policy.inject([]) do |versions_to_upload, cookbook_with_lock|
113
+ cb = cookbook_with_lock.cookbook
114
+ # When we abandon custom identifier support in favor of the one true
115
+ # hash, identifier generation code can be moved into chef proper and
116
+ # this can be removed.
117
+ cb.identifier = cookbook_with_lock.lock.identifier
118
+
119
+ versions_to_upload << cb unless remote_already_has_cookbook?(cb)
120
+ versions_to_upload
121
+ end
122
+ end
123
+
124
+ def remote_already_has_cookbook?(cookbook)
125
+ return false unless existing_cookbook_on_remote.key?(cookbook.name.to_s)
126
+
127
+ if using_policy_document_native_api?
128
+ native_mode_cookbook_exists_on_remote?(cookbook)
129
+ else
130
+ compat_mode_cookbook_exists_on_remote?(cookbook)
131
+ end
132
+ end
133
+
134
+ def native_mode_cookbook_exists_on_remote?(cookbook)
135
+ existing_cookbook_on_remote[cookbook.name.to_s]["versions"].any? do |cookbook_info|
136
+ cookbook_info["identifier"] == cookbook.identifier
137
+ end
138
+ end
139
+
140
+ def compat_mode_cookbook_exists_on_remote?(cookbook)
141
+ existing_cookbook_on_remote[cookbook.name.to_s]["versions"].any? do |cookbook_info|
142
+ cookbook_info["version"] == cookbook.version
143
+ end
144
+ end
145
+
146
+ def existing_cookbook_on_remote
147
+ @existing_cookbook_on_remote ||= http_client.get(list_cookbooks_url)
148
+ end
149
+
150
+ # An Array of Chef::CookbookVersion objects representing the full set that
151
+ # the policyfile lock requires.
152
+ def cookbook_versions_for_policy
153
+ return @cookbook_versions_for_policy if @cookbook_versions_for_policy
154
+ policyfile_lock.validate_cookbooks!
155
+ @cookbook_versions_for_policy =
156
+ if using_policy_document_native_api?
157
+ load_cookbooks_in_native_mode
158
+ else
159
+ load_cookbooks_in_compat_mode
160
+ end
161
+ end
162
+
163
+ def load_cookbooks_in_native_mode
164
+ policyfile_lock.cookbook_locks.map do |name, lock|
165
+ cb = CookbookLoaderWithChefignore.load(name, lock.cookbook_path)
166
+ LockedCookbookForUpload.new(cb, lock)
167
+ end
168
+ end
169
+
170
+ def load_cookbooks_in_compat_mode
171
+ policyfile_lock.cookbook_locks.map do |name, lock|
172
+ cb = ReadCookbookForCompatModeUpload.load(name, lock.dotted_decimal_identifier, lock.cookbook_path)
173
+ LockedCookbookForUpload.new(cb, lock)
174
+ end
175
+ end
176
+
177
+ def using_policy_document_native_api?
178
+ @policy_document_native_api
179
+ end
180
+
181
+ private
182
+
183
+ def list_cookbooks_url
184
+ if using_policy_document_native_api?
185
+ "cookbook_artifacts?num_versions=all"
186
+ else
187
+ "cookbooks?num_versions=all"
188
+ end
189
+ end
190
+
191
+ def upload_cookbooks
192
+ ui.msg("WARN: Uploading cookbooks using semver compat mode") unless using_policy_document_native_api?
193
+
194
+ uploader.upload_cookbooks unless cookbook_versions_to_upload.empty?
195
+
196
+ reused_cbs, uploaded_cbs = cookbook_versions_for_policy.partition do |cb_with_lock|
197
+ remote_already_has_cookbook?(cb_with_lock.cookbook)
198
+ end
199
+
200
+ Reports::Upload.new(reused_cbs: reused_cbs, uploaded_cbs: uploaded_cbs, ui: ui).show
201
+
202
+ true
203
+ end
204
+
205
+ def upload_lockfile_as_data_bag_item(policy_id, data_item)
206
+ http_client.put("data/#{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}", data_item)
207
+ rescue Net::HTTPServerException => e
208
+ raise e unless e.response.code == "404"
209
+ http_client.post("data/#{COMPAT_MODE_DATA_BAG_NAME}", data_item)
210
+ end
211
+ end
212
+ end
213
+ end