chef-cli 1.0.3

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 (372) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +32 -0
  3. data/LICENSE +201 -0
  4. data/Rakefile +70 -0
  5. data/bin/chef +25 -0
  6. data/chef-cli.gemspec +53 -0
  7. data/lib/chef-cli.rb +19 -0
  8. data/lib/chef-cli/authenticated_http.rb +22 -0
  9. data/lib/chef-cli/builtin_commands.rb +62 -0
  10. data/lib/chef-cli/chef_runner.rb +114 -0
  11. data/lib/chef-cli/chef_server_api_multi.rb +73 -0
  12. data/lib/chef-cli/cli.rb +206 -0
  13. data/lib/chef-cli/command/base.rb +89 -0
  14. data/lib/chef-cli/command/clean_policy_cookbooks.rb +115 -0
  15. data/lib/chef-cli/command/clean_policy_revisions.rb +112 -0
  16. data/lib/chef-cli/command/delete_policy.rb +121 -0
  17. data/lib/chef-cli/command/delete_policy_group.rb +121 -0
  18. data/lib/chef-cli/command/describe_cookbook.rb +98 -0
  19. data/lib/chef-cli/command/diff.rb +316 -0
  20. data/lib/chef-cli/command/env.rb +99 -0
  21. data/lib/chef-cli/command/exec.rb +45 -0
  22. data/lib/chef-cli/command/export.rb +156 -0
  23. data/lib/chef-cli/command/gem.rb +48 -0
  24. data/lib/chef-cli/command/generate.rb +123 -0
  25. data/lib/chef-cli/command/generator_commands.rb +83 -0
  26. data/lib/chef-cli/command/generator_commands/attribute.rb +37 -0
  27. data/lib/chef-cli/command/generator_commands/base.rb +157 -0
  28. data/lib/chef-cli/command/generator_commands/build_cookbook.rb +126 -0
  29. data/lib/chef-cli/command/generator_commands/chef_exts/generator_desc_resource.rb +40 -0
  30. data/lib/chef-cli/command/generator_commands/chef_exts/quieter_doc_formatter.rb +38 -0
  31. data/lib/chef-cli/command/generator_commands/chef_exts/recipe_dsl_ext.rb +39 -0
  32. data/lib/chef-cli/command/generator_commands/cookbook.rb +251 -0
  33. data/lib/chef-cli/command/generator_commands/cookbook_code_file.rb +100 -0
  34. data/lib/chef-cli/command/generator_commands/cookbook_file.rb +46 -0
  35. data/lib/chef-cli/command/generator_commands/generator_generator.rb +175 -0
  36. data/lib/chef-cli/command/generator_commands/helpers.rb +37 -0
  37. data/lib/chef-cli/command/generator_commands/policyfile.rb +125 -0
  38. data/lib/chef-cli/command/generator_commands/recipe.rb +37 -0
  39. data/lib/chef-cli/command/generator_commands/repo.rb +140 -0
  40. data/lib/chef-cli/command/generator_commands/resource.rb +37 -0
  41. data/lib/chef-cli/command/generator_commands/template.rb +47 -0
  42. data/lib/chef-cli/command/install.rb +121 -0
  43. data/lib/chef-cli/command/provision.rb +38 -0
  44. data/lib/chef-cli/command/push.rb +118 -0
  45. data/lib/chef-cli/command/push_archive.rb +126 -0
  46. data/lib/chef-cli/command/shell_init.rb +185 -0
  47. data/lib/chef-cli/command/show_policy.rb +164 -0
  48. data/lib/chef-cli/command/undelete.rb +155 -0
  49. data/lib/chef-cli/command/update.rb +140 -0
  50. data/lib/chef-cli/command/verify.rb +548 -0
  51. data/lib/chef-cli/commands_map.rb +113 -0
  52. data/lib/chef-cli/completions/bash.sh.erb +5 -0
  53. data/lib/chef-cli/completions/chef.fish.erb +10 -0
  54. data/lib/chef-cli/completions/zsh.zsh.erb +21 -0
  55. data/lib/chef-cli/component_test.rb +226 -0
  56. data/lib/chef-cli/configurable.rb +88 -0
  57. data/lib/chef-cli/cookbook_metadata.rb +45 -0
  58. data/lib/chef-cli/cookbook_omnifetch.rb +32 -0
  59. data/lib/chef-cli/cookbook_profiler/git.rb +152 -0
  60. data/lib/chef-cli/cookbook_profiler/identifiers.rb +72 -0
  61. data/lib/chef-cli/cookbook_profiler/null_scm.rb +31 -0
  62. data/lib/chef-cli/dist.rb +31 -0
  63. data/lib/chef-cli/exceptions.rb +153 -0
  64. data/lib/chef-cli/generator.rb +165 -0
  65. data/lib/chef-cli/helpers.rb +170 -0
  66. data/lib/chef-cli/pager.rb +104 -0
  67. data/lib/chef-cli/policyfile/artifactory_cookbook_source.rb +102 -0
  68. data/lib/chef-cli/policyfile/attribute_merge_checker.rb +110 -0
  69. data/lib/chef-cli/policyfile/chef_repo_cookbook_source.rb +138 -0
  70. data/lib/chef-cli/policyfile/chef_server_cookbook_source.rb +99 -0
  71. data/lib/chef-cli/policyfile/chef_server_lock_fetcher.rb +167 -0
  72. data/lib/chef-cli/policyfile/community_cookbook_source.rb +95 -0
  73. data/lib/chef-cli/policyfile/comparison_base.rb +123 -0
  74. data/lib/chef-cli/policyfile/cookbook_location_specification.rb +154 -0
  75. data/lib/chef-cli/policyfile/cookbook_locks.rb +466 -0
  76. data/lib/chef-cli/policyfile/cookbook_sources.rb +23 -0
  77. data/lib/chef-cli/policyfile/delivery_supermarket_source.rb +89 -0
  78. data/lib/chef-cli/policyfile/differ.rb +263 -0
  79. data/lib/chef-cli/policyfile/dsl.rb +288 -0
  80. data/lib/chef-cli/policyfile/git_lock_fetcher.rb +265 -0
  81. data/lib/chef-cli/policyfile/included_policies_cookbook_source.rb +156 -0
  82. data/lib/chef-cli/policyfile/lister.rb +229 -0
  83. data/lib/chef-cli/policyfile/local_lock_fetcher.rb +132 -0
  84. data/lib/chef-cli/policyfile/lock_applier.rb +80 -0
  85. data/lib/chef-cli/policyfile/lock_fetcher_mixin.rb +37 -0
  86. data/lib/chef-cli/policyfile/null_cookbook_source.rb +49 -0
  87. data/lib/chef-cli/policyfile/policyfile_location_specification.rb +128 -0
  88. data/lib/chef-cli/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -0
  89. data/lib/chef-cli/policyfile/remote_lock_fetcher.rb +108 -0
  90. data/lib/chef-cli/policyfile/reports/install.rb +69 -0
  91. data/lib/chef-cli/policyfile/reports/table_printer.rb +57 -0
  92. data/lib/chef-cli/policyfile/reports/upload.rb +70 -0
  93. data/lib/chef-cli/policyfile/solution_dependencies.rb +311 -0
  94. data/lib/chef-cli/policyfile/source_uri.rb +57 -0
  95. data/lib/chef-cli/policyfile/storage_config.rb +112 -0
  96. data/lib/chef-cli/policyfile/undo_record.rb +139 -0
  97. data/lib/chef-cli/policyfile/undo_stack.rb +128 -0
  98. data/lib/chef-cli/policyfile/uploader.rb +222 -0
  99. data/lib/chef-cli/policyfile_compiler.rb +528 -0
  100. data/lib/chef-cli/policyfile_lock.rb +581 -0
  101. data/lib/chef-cli/policyfile_services/clean_policies.rb +95 -0
  102. data/lib/chef-cli/policyfile_services/clean_policy_cookbooks.rb +123 -0
  103. data/lib/chef-cli/policyfile_services/export_repo.rb +419 -0
  104. data/lib/chef-cli/policyfile_services/install.rb +167 -0
  105. data/lib/chef-cli/policyfile_services/push.rb +112 -0
  106. data/lib/chef-cli/policyfile_services/push_archive.rb +164 -0
  107. data/lib/chef-cli/policyfile_services/rm_policy.rb +141 -0
  108. data/lib/chef-cli/policyfile_services/rm_policy_group.rb +85 -0
  109. data/lib/chef-cli/policyfile_services/show_policy.rb +234 -0
  110. data/lib/chef-cli/policyfile_services/undelete.rb +108 -0
  111. data/lib/chef-cli/policyfile_services/update_attributes.rb +110 -0
  112. data/lib/chef-cli/service_exception_inspectors.rb +24 -0
  113. data/lib/chef-cli/service_exception_inspectors/base.rb +39 -0
  114. data/lib/chef-cli/service_exception_inspectors/http.rb +119 -0
  115. data/lib/chef-cli/service_exceptions.rb +142 -0
  116. data/lib/chef-cli/shell_out.rb +36 -0
  117. data/lib/chef-cli/skeletons/code_generator/files/default/Berksfile +3 -0
  118. data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/README.md +146 -0
  119. data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/kitchen.yml +21 -0
  120. data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +8 -0
  121. data/lib/chef-cli/skeletons/code_generator/files/default/chefignore +110 -0
  122. data/lib/chef-cli/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -0
  123. data/lib/chef-cli/skeletons/code_generator/files/default/cookbook_readmes/README.md +66 -0
  124. data/lib/chef-cli/skeletons/code_generator/files/default/delivery-config.json +17 -0
  125. data/lib/chef-cli/skeletons/code_generator/files/default/delivery-project.toml +34 -0
  126. data/lib/chef-cli/skeletons/code_generator/files/default/gitignore +22 -0
  127. data/lib/chef-cli/skeletons/code_generator/files/default/repo/README.md +20 -0
  128. data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -0
  129. data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -0
  130. data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +6 -0
  131. data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -0
  132. data/lib/chef-cli/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -0
  133. data/lib/chef-cli/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +4 -0
  134. data/lib/chef-cli/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -0
  135. data/lib/chef-cli/skeletons/code_generator/files/default/repo/environments/README.md +9 -0
  136. data/lib/chef-cli/skeletons/code_generator/files/default/repo/environments/example.json +13 -0
  137. data/lib/chef-cli/skeletons/code_generator/files/default/repo/policyfiles/README.md +24 -0
  138. data/lib/chef-cli/skeletons/code_generator/files/default/repo/roles/README.md +9 -0
  139. data/lib/chef-cli/skeletons/code_generator/files/default/repo/roles/example.json +13 -0
  140. data/lib/chef-cli/skeletons/code_generator/files/default/spec_helper.rb +2 -0
  141. data/lib/chef-cli/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -0
  142. data/lib/chef-cli/skeletons/code_generator/metadata.rb +8 -0
  143. data/lib/chef-cli/skeletons/code_generator/recipes/attribute.rb +11 -0
  144. data/lib/chef-cli/skeletons/code_generator/recipes/build_cookbook.rb +175 -0
  145. data/lib/chef-cli/skeletons/code_generator/recipes/cookbook.rb +167 -0
  146. data/lib/chef-cli/skeletons/code_generator/recipes/cookbook_file.rb +23 -0
  147. data/lib/chef-cli/skeletons/code_generator/recipes/helpers.rb +19 -0
  148. data/lib/chef-cli/skeletons/code_generator/recipes/policyfile.rb +7 -0
  149. data/lib/chef-cli/skeletons/code_generator/recipes/recipe.rb +50 -0
  150. data/lib/chef-cli/skeletons/code_generator/recipes/repo.rb +71 -0
  151. data/lib/chef-cli/skeletons/code_generator/recipes/resource.rb +12 -0
  152. data/lib/chef-cli/skeletons/code_generator/recipes/template.rb +31 -0
  153. data/lib/chef-cli/skeletons/code_generator/templates/default/CHANGELOG.md.erb +11 -0
  154. data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
  155. data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -0
  156. data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
  157. data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
  158. data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
  159. data/lib/chef-cli/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -0
  160. data/lib/chef-cli/skeletons/code_generator/templates/default/README.md.erb +4 -0
  161. data/lib/chef-cli/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
  162. data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -0
  163. data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -0
  164. data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +9 -0
  165. data/lib/chef-cli/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
  166. data/lib/chef-cli/skeletons/code_generator/templates/default/helpers.rb.erb +39 -0
  167. data/lib/chef-cli/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +16 -0
  168. data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen.yml.erb +38 -0
  169. data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen_dokken.yml.erb +36 -0
  170. data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +32 -0
  171. data/lib/chef-cli/skeletons/code_generator/templates/default/metadata.rb.erb +20 -0
  172. data/lib/chef-cli/skeletons/code_generator/templates/default/recipe.rb.erb +5 -0
  173. data/lib/chef-cli/skeletons/code_generator/templates/default/recipe_spec.rb.erb +29 -0
  174. data/lib/chef-cli/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -0
  175. data/lib/chef-cli/skeletons/code_generator/templates/default/resource.rb.erb +1 -0
  176. data/lib/chef-cli/skeletons/code_generator/templates/default/template.erb +0 -0
  177. data/lib/chef-cli/ui.rb +57 -0
  178. data/lib/chef-cli/version.rb +20 -0
  179. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -0
  180. data/spec/shared/a_file_generator.rb +125 -0
  181. data/spec/shared/a_generated_file.rb +12 -0
  182. data/spec/shared/command_with_ui_object.rb +11 -0
  183. data/spec/shared/custom_generator_cookbook.rb +136 -0
  184. data/spec/shared/fixture_cookbook_checksums.rb +46 -0
  185. data/spec/shared/setup_git_committer_config.rb +54 -0
  186. data/spec/shared/setup_git_cookbooks.rb +53 -0
  187. data/spec/spec_helper.rb +51 -0
  188. data/spec/test_helpers.rb +84 -0
  189. data/spec/unit/chef_runner_spec.rb +139 -0
  190. data/spec/unit/chef_server_api_multi_spec.rb +120 -0
  191. data/spec/unit/cli_spec.rb +375 -0
  192. data/spec/unit/command/base_spec.rb +195 -0
  193. data/spec/unit/command/clean_policy_cookbooks_spec.rb +180 -0
  194. data/spec/unit/command/clean_policy_revisions_spec.rb +180 -0
  195. data/spec/unit/command/delete_policy_group_spec.rb +206 -0
  196. data/spec/unit/command/delete_policy_spec.rb +206 -0
  197. data/spec/unit/command/diff_spec.rb +311 -0
  198. data/spec/unit/command/env_spec.rb +86 -0
  199. data/spec/unit/command/exec_spec.rb +178 -0
  200. data/spec/unit/command/export_spec.rb +199 -0
  201. data/spec/unit/command/generate_spec.rb +142 -0
  202. data/spec/unit/command/generator_commands/attribute_spec.rb +31 -0
  203. data/spec/unit/command/generator_commands/base_spec.rb +180 -0
  204. data/spec/unit/command/generator_commands/build_cookbook_spec.rb +377 -0
  205. data/spec/unit/command/generator_commands/chef_exts/generator_desc_resource_spec.rb +77 -0
  206. data/spec/unit/command/generator_commands/chef_exts/recipe_dsl_ext_spec.rb +111 -0
  207. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +31 -0
  208. data/spec/unit/command/generator_commands/cookbook_spec.rb +769 -0
  209. data/spec/unit/command/generator_commands/generator_generator_spec.rb +227 -0
  210. data/spec/unit/command/generator_commands/helpers_spec.rb +31 -0
  211. data/spec/unit/command/generator_commands/policyfile_spec.rb +223 -0
  212. data/spec/unit/command/generator_commands/recipe_spec.rb +37 -0
  213. data/spec/unit/command/generator_commands/repo_spec.rb +374 -0
  214. data/spec/unit/command/generator_commands/resource_spec.rb +31 -0
  215. data/spec/unit/command/generator_commands/template_spec.rb +31 -0
  216. data/spec/unit/command/install_spec.rb +179 -0
  217. data/spec/unit/command/push_archive_spec.rb +153 -0
  218. data/spec/unit/command/push_spec.rb +198 -0
  219. data/spec/unit/command/shell_init_spec.rb +339 -0
  220. data/spec/unit/command/show_policy_spec.rb +234 -0
  221. data/spec/unit/command/undelete_spec.rb +244 -0
  222. data/spec/unit/command/update_spec.rb +283 -0
  223. data/spec/unit/command/verify_spec.rb +341 -0
  224. data/spec/unit/commands_map_spec.rb +57 -0
  225. data/spec/unit/component_test_spec.rb +128 -0
  226. data/spec/unit/configurable_spec.rb +68 -0
  227. data/spec/unit/cookbook_metadata_spec.rb +96 -0
  228. data/spec/unit/cookbook_profiler/git_spec.rb +176 -0
  229. data/spec/unit/cookbook_profiler/identifiers_spec.rb +81 -0
  230. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -0
  231. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -0
  232. data/spec/unit/fixtures/command/cli_test_command.rb +26 -0
  233. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -0
  234. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -0
  235. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -0
  236. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  237. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -0
  238. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  239. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -0
  240. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  241. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  242. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -0
  243. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -0
  244. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -0
  245. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -0
  246. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -0
  247. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -0
  248. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -0
  249. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -0
  250. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -0
  251. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/kitchen.yml +16 -0
  252. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -0
  253. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -0
  254. data/spec/unit/fixtures/cookbooks_api/chef_server_universe.json +56 -0
  255. data/spec/unit/fixtures/cookbooks_api/pruned_chef_server_universe.json +30 -0
  256. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1322 -0
  257. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -0
  258. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -0
  259. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +33 -0
  260. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -0
  261. data/spec/unit/fixtures/dev_cookbooks/bar-cookbook.gitbundle +0 -0
  262. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/bin/.keep +0 -0
  263. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/.keep +0 -0
  264. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/bin/.keep +0 -0
  265. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/bin/.keep +0 -0
  266. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/berkshelf/.keep +0 -0
  267. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/test-kitchen/.keep +0 -0
  268. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/bin/.keep +0 -0
  269. data/spec/unit/fixtures/eg_omnibus_dir/valid/bin/.keep +0 -0
  270. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -0
  271. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -0
  272. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef-dk/.keep +0 -0
  273. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -0
  274. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -0
  275. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/bin/.keep +0 -0
  276. data/spec/unit/fixtures/example_app/Policyfile.rb +0 -0
  277. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -0
  278. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -0
  279. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -0
  280. data/spec/unit/fixtures/example_cookbook/README.md +4 -0
  281. data/spec/unit/fixtures/example_cookbook/chefignore +96 -0
  282. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -0
  283. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -0
  284. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -0
  285. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -0
  286. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -0
  287. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -0
  288. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -0
  289. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -0
  290. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -0
  291. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -0
  292. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -0
  293. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -0
  294. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -0
  295. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -0
  296. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -0
  297. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -0
  298. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -0
  299. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -0
  300. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -0
  301. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -0
  302. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -0
  303. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -0
  304. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -0
  305. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -0
  306. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -0
  307. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -0
  308. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -0
  309. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -0
  310. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/extra/extra_file.txt +0 -0
  311. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -0
  312. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -0
  313. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -0
  314. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  315. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  316. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  317. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  318. data/spec/unit/generator_spec.rb +119 -0
  319. data/spec/unit/pager_spec.rb +117 -0
  320. data/spec/unit/policyfile/artifactory_cookbook_source_spec.rb +59 -0
  321. data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -0
  322. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -0
  323. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +55 -0
  324. data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -0
  325. data/spec/unit/policyfile/community_cookbook_source_spec.rb +83 -0
  326. data/spec/unit/policyfile/comparison_base_spec.rb +340 -0
  327. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +347 -0
  328. data/spec/unit/policyfile/cookbook_locks_spec.rb +527 -0
  329. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +129 -0
  330. data/spec/unit/policyfile/differ_spec.rb +686 -0
  331. data/spec/unit/policyfile/git_lock_fetcher_spec.rb +155 -0
  332. data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -0
  333. data/spec/unit/policyfile/lister_spec.rb +268 -0
  334. data/spec/unit/policyfile/local_lock_fetcher_spec.rb +199 -0
  335. data/spec/unit/policyfile/lock_applier_spec.rb +100 -0
  336. data/spec/unit/policyfile/lock_fetcher_mixin_spec.rb +60 -0
  337. data/spec/unit/policyfile/null_cookbook_source_spec.rb +34 -0
  338. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -0
  339. data/spec/unit/policyfile/remote_lock_fetcher_spec.rb +129 -0
  340. data/spec/unit/policyfile/reports/install_spec.rb +114 -0
  341. data/spec/unit/policyfile/reports/upload_spec.rb +94 -0
  342. data/spec/unit/policyfile/solution_dependencies_spec.rb +170 -0
  343. data/spec/unit/policyfile/source_uri_spec.rb +36 -0
  344. data/spec/unit/policyfile/storage_config_spec.rb +180 -0
  345. data/spec/unit/policyfile/undo_record_spec.rb +258 -0
  346. data/spec/unit/policyfile/undo_stack_spec.rb +265 -0
  347. data/spec/unit/policyfile/uploader_spec.rb +410 -0
  348. data/spec/unit/policyfile_demands_spec.rb +1197 -0
  349. data/spec/unit/policyfile_evaluation_spec.rb +628 -0
  350. data/spec/unit/policyfile_includes_dsl_spec.rb +220 -0
  351. data/spec/unit/policyfile_includes_spec.rb +720 -0
  352. data/spec/unit/policyfile_install_with_includes_spec.rb +232 -0
  353. data/spec/unit/policyfile_lock_build_spec.rb +1065 -0
  354. data/spec/unit/policyfile_lock_install_spec.rb +137 -0
  355. data/spec/unit/policyfile_lock_serialization_spec.rb +424 -0
  356. data/spec/unit/policyfile_lock_validation_spec.rb +608 -0
  357. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -0
  358. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +272 -0
  359. data/spec/unit/policyfile_services/export_repo_spec.rb +473 -0
  360. data/spec/unit/policyfile_services/install_spec.rb +209 -0
  361. data/spec/unit/policyfile_services/push_archive_spec.rb +359 -0
  362. data/spec/unit/policyfile_services/push_spec.rb +249 -0
  363. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +237 -0
  364. data/spec/unit/policyfile_services/rm_policy_spec.rb +263 -0
  365. data/spec/unit/policyfile_services/show_policy_spec.rb +887 -0
  366. data/spec/unit/policyfile_services/undelete_spec.rb +302 -0
  367. data/spec/unit/policyfile_services/update_attributes_spec.rb +229 -0
  368. data/spec/unit/policyfile_services/update_spec.rb +162 -0
  369. data/spec/unit/service_exception_inspectors/base_spec.rb +41 -0
  370. data/spec/unit/service_exception_inspectors/http_spec.rb +138 -0
  371. data/spec/unit/shell_out_spec.rb +34 -0
  372. metadata +796 -0
@@ -0,0 +1,167 @@
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 "ffi_yajl" unless defined?(FFI_Yajl)
19
+
20
+ require_relative "../helpers"
21
+ require_relative "../service_exceptions"
22
+ require_relative "../policyfile_compiler"
23
+ require_relative "../policyfile/storage_config"
24
+ require_relative "../policyfile_lock"
25
+ require_relative "../policyfile/lock_applier"
26
+
27
+ module ChefCLI
28
+ module PolicyfileServices
29
+
30
+ class Install
31
+
32
+ include Policyfile::StorageConfigDelegation
33
+ include ChefCLI::Helpers
34
+
35
+ attr_reader :ui
36
+ attr_reader :storage_config
37
+ attr_reader :overwrite
38
+ attr_reader :chef_config
39
+
40
+ def initialize(policyfile: nil, ui: nil, root_dir: nil, overwrite: false, config: nil)
41
+ @ui = ui
42
+ @overwrite = overwrite
43
+ @chef_config = config
44
+
45
+ policyfile_rel_path = policyfile || "Policyfile.rb"
46
+ policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
47
+ @storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
48
+
49
+ @policyfile_content = nil
50
+ @policyfile_compiler = nil
51
+ end
52
+
53
+ def run(cookbooks_to_update = [], exclude_deps = false)
54
+ unless File.exist?(policyfile_expanded_path)
55
+ # TODO: suggest next step. Add a generator/init command? Specify path to Policyfile.rb?
56
+ # See card CC-232
57
+ raise PolicyfileNotFound, "Policyfile not found at path #{policyfile_expanded_path}"
58
+ end
59
+
60
+ if installing_from_lock?
61
+ install_from_lock
62
+ elsif cookbooks_to_update.empty? # means update everything
63
+ generate_lock_and_install
64
+ else
65
+ update_lock_and_install(cookbooks_to_update, exclude_deps)
66
+ end
67
+ end
68
+
69
+ def policyfile_content
70
+ @policyfile_content ||= IO.read(policyfile_expanded_path)
71
+ end
72
+
73
+ def policyfile_compiler
74
+ @policyfile_compiler ||= ChefCLI::PolicyfileCompiler.evaluate(policyfile_content, policyfile_expanded_path, ui: ui, chef_config: chef_config)
75
+ end
76
+
77
+ def expanded_run_list
78
+ policyfile_compiler.expanded_run_list.to_s
79
+ end
80
+
81
+ def policyfile_lock_content
82
+ @policyfile_lock_content ||= IO.read(policyfile_lock_expanded_path) if File.exist?(policyfile_lock_expanded_path)
83
+ end
84
+
85
+ def policyfile_lock
86
+ return nil if policyfile_lock_content.nil?
87
+ @policyfile_lock ||= begin
88
+ lock_data = FFI_Yajl::Parser.new.parse(policyfile_lock_content)
89
+ PolicyfileLock.new(storage_config, ui: ui).build_from_lock_data(lock_data)
90
+ end
91
+ end
92
+
93
+ def generate_lock_and_install
94
+ policyfile_compiler.error!
95
+
96
+ ui.msg "Building policy #{policyfile_compiler.name}"
97
+ ui.msg "Expanded run list: " + expanded_run_list + "\n"
98
+
99
+ ui.msg "Caching Cookbooks..."
100
+
101
+ policyfile_compiler.install
102
+
103
+ lock_data = policyfile_compiler.lock.to_lock
104
+
105
+ with_file(policyfile_lock_expanded_path) do |f|
106
+ f.print(FFI_Yajl::Encoder.encode(lock_data, pretty: true ))
107
+ end
108
+
109
+ ui.msg ""
110
+
111
+ ui.msg "Lockfile written to #{policyfile_lock_expanded_path}"
112
+ ui.msg "Policy revision id: #{policyfile_lock.revision_id}"
113
+ rescue => error
114
+ raise PolicyfileInstallError.new("Failed to generate Policyfile.lock", error)
115
+ end
116
+
117
+ def update_lock_and_install(cookbooks_to_update, exclude_deps)
118
+ ui.msg "Updating #{cookbooks_to_update.join(',')} cookbooks #{exclude_deps ? '(excluding dependencies)' : ''}"
119
+ to_update = if exclude_deps
120
+ cookbooks_to_update
121
+ else
122
+ policyfile_lock.solution_dependencies.transitive_deps(cookbooks_to_update)
123
+ end
124
+ prepare_constraints_for_update(to_update)
125
+ prepare_constraints_for_policies
126
+ generate_lock_and_install
127
+ end
128
+
129
+ def prepare_constraints_for_update(to_update)
130
+ ui.msg "Will relax constraints on:"
131
+ to_update.each do |ck|
132
+ ui.msg " - #{ck}"
133
+ end
134
+
135
+ policyfile_lock.cookbook_locks.each do |ck_name, location_spec|
136
+ next if to_update.include?(ck_name)
137
+ # we need to feed policyfile_compiler.cookbook_location_spec_for with a CookbookLocationSpecification
138
+ policyfile_compiler.dsl.cookbook_location_specs[ck_name] = Policyfile::CookbookLocationSpecification.new(
139
+ ck_name,
140
+ Semverse::Constraint.new("=#{location_spec.version}"),
141
+ location_spec.source_options,
142
+ location_spec.storage_config
143
+ )
144
+ end
145
+ end
146
+
147
+ def prepare_constraints_for_policies
148
+ Policyfile::LockApplier
149
+ .new(policyfile_lock, policyfile_compiler)
150
+ .apply!
151
+ end
152
+
153
+ def install_from_lock
154
+ ui.msg "Installing cookbooks from lock"
155
+
156
+ policyfile_lock.install_cookbooks
157
+ rescue => error
158
+ raise PolicyfileInstallError.new("Failed to install cookbooks from lockfile", error)
159
+ end
160
+
161
+ def installing_from_lock?
162
+ !@overwrite && File.exist?(policyfile_lock_expanded_path)
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,112 @@
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 "ffi_yajl" unless defined?(FFI_Yajl)
19
+
20
+ require_relative "../service_exceptions"
21
+ require "chef/server_api"
22
+ require_relative "../policyfile_compiler"
23
+ require_relative "../policyfile/uploader"
24
+ require_relative "../policyfile/storage_config"
25
+
26
+ module ChefCLI
27
+ module PolicyfileServices
28
+ class Push
29
+
30
+ include Policyfile::StorageConfigDelegation
31
+ include ChefCLI::Helpers
32
+
33
+ attr_reader :root_dir
34
+ attr_reader :config
35
+ attr_reader :policy_group
36
+ attr_reader :ui
37
+ attr_reader :storage_config
38
+
39
+ def initialize(policyfile: nil, ui: nil, policy_group: nil, config: nil, root_dir: nil)
40
+ @root_dir = root_dir
41
+ @ui = ui
42
+ @config = config
43
+ @policy_group = policy_group
44
+
45
+ policyfile_rel_path = policyfile || "Policyfile.rb"
46
+ policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
47
+ @storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
48
+
49
+ @http_client = nil
50
+ @policy_data = nil
51
+ end
52
+
53
+ def http_client
54
+ @http_client ||= Chef::ServerAPI.new(config.chef_server_url,
55
+ signing_key_filename: config.client_key,
56
+ client_name: config.node_name)
57
+ end
58
+
59
+ def policy_data
60
+ @policy_data ||= FFI_Yajl::Parser.parse(IO.read(policyfile_lock_expanded_path))
61
+ rescue => error
62
+ raise PolicyfilePushError.new("Error reading lockfile #{policyfile_lock_expanded_path}", error)
63
+ end
64
+
65
+ def uploader
66
+ ChefCLI::Policyfile::Uploader.new(policyfile_lock, policy_group,
67
+ ui: ui,
68
+ http_client: http_client,
69
+ policy_document_native_api: config.policy_document_native_api)
70
+ end
71
+
72
+ def run
73
+ unless File.exist?(policyfile_lock_expanded_path)
74
+ raise LockfileNotFound, "No lockfile at #{policyfile_lock_expanded_path} - you need to run `install` before `push`"
75
+ end
76
+
77
+ validate_lockfile
78
+ write_updated_lockfile
79
+ upload_policy
80
+ end
81
+
82
+ def policyfile_lock
83
+ @policyfile_lock || validate_lockfile
84
+ end
85
+
86
+ private
87
+
88
+ def upload_policy
89
+ uploader.upload
90
+ rescue => error
91
+ raise PolicyfilePushError.new("Failed to upload policy to policy group #{policy_group}", error)
92
+ end
93
+
94
+ def write_updated_lockfile
95
+ with_file(policyfile_lock_expanded_path) do |f|
96
+ f.print(FFI_Yajl::Encoder.encode(policyfile_lock.to_lock, pretty: true ))
97
+ end
98
+ end
99
+
100
+ def validate_lockfile
101
+ return @policyfile_lock if @policyfile_lock
102
+ @policyfile_lock = ChefCLI::PolicyfileLock.new(storage_config).build_from_lock_data(policy_data)
103
+ # TODO: enumerate any cookbook that have been updated
104
+ @policyfile_lock.validate_cookbooks!
105
+ @policyfile_lock
106
+ rescue => error
107
+ raise PolicyfilePushError.new("Invalid lockfile data", error)
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,164 @@
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_relative "../service_exceptions"
22
+ require_relative "../policyfile_lock"
23
+ require "chef/server_api"
24
+ require_relative "../policyfile/uploader"
25
+
26
+ module ChefCLI
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
+ def initialize(archive_file: nil, policy_group: nil, root_dir: nil, ui: nil, config: nil)
41
+ @archive_file = archive_file
42
+ @policy_group = policy_group
43
+ @root_dir = root_dir || Dir.pwd
44
+ @ui = ui
45
+ @config = config
46
+
47
+ @policyfile_lock = nil
48
+ end
49
+
50
+ def archive_file_path
51
+ File.expand_path(archive_file, root_dir)
52
+ end
53
+
54
+ def run
55
+ unless File.exist?(archive_file_path)
56
+ raise InvalidPolicyArchive, "Archive file #{archive_file_path} not found"
57
+ end
58
+ stage_unpacked_archive do |staging_dir|
59
+ read_policyfile_lock(staging_dir)
60
+
61
+ uploader.upload
62
+ end
63
+
64
+ rescue => e
65
+ raise PolicyfilePushArchiveError.new("Failed to publish archived policy", e)
66
+ end
67
+
68
+ # @api private
69
+ def uploader
70
+ ChefCLI::Policyfile::Uploader.new(policyfile_lock, policy_group,
71
+ ui: ui,
72
+ http_client: http_client,
73
+ policy_document_native_api: config.policy_document_native_api)
74
+ end
75
+
76
+ # @api private
77
+ def http_client
78
+ @http_client ||= Chef::ServerAPI.new(config.chef_server_url,
79
+ signing_key_filename: config.client_key,
80
+ client_name: config.node_name)
81
+ end
82
+
83
+ private
84
+
85
+ def read_policyfile_lock(staging_dir)
86
+ policyfile_lock_path = File.join(staging_dir, "Policyfile.lock.json")
87
+
88
+ if looks_like_old_format_archive?(staging_dir)
89
+ raise InvalidPolicyArchive, <<~MESSAGE
90
+ This archive is in an unsupported format.
91
+
92
+ This archive was created with an older version of ChefCLI. This version of
93
+ ChefCLI does not support archives in the older format. Please Re-create the
94
+ archive with a newer version of ChefCLI or Workstation.
95
+ MESSAGE
96
+ end
97
+
98
+ unless File.exist?(policyfile_lock_path)
99
+ raise InvalidPolicyArchive, "Archive does not contain a Policyfile.lock.json"
100
+ end
101
+
102
+ unless File.directory?(File.join(staging_dir, "cookbook_artifacts"))
103
+ raise InvalidPolicyArchive, "Archive does not contain a cookbook_artifacts directory"
104
+ end
105
+
106
+ policy_data = load_policy_data(policyfile_lock_path)
107
+ storage_config = Policyfile::StorageConfig.new.use_policyfile_lock(policyfile_lock_path)
108
+ @policyfile_lock = ChefCLI::PolicyfileLock.new(storage_config).build_from_archive(policy_data)
109
+
110
+ missing_cookbooks = policyfile_lock.cookbook_locks.select do |name, lock|
111
+ !lock.installed?
112
+ end
113
+
114
+ unless missing_cookbooks.empty?
115
+ message = "Archive does not have all cookbooks required by the Policyfile.lock. " +
116
+ "Missing cookbooks: '#{missing_cookbooks.keys.join('", "')}'."
117
+ raise InvalidPolicyArchive, message
118
+ end
119
+ end
120
+
121
+ def load_policy_data(policyfile_lock_path)
122
+ FFI_Yajl::Parser.parse(IO.read(policyfile_lock_path))
123
+ end
124
+
125
+ def stage_unpacked_archive
126
+ p = Process.pid
127
+ t = Time.new.utc.strftime("%Y%m%d%H%M%S")
128
+ Dir.mktmpdir("chefcli-push-archive-#{p}-#{t}") do |staging_dir|
129
+ unpack_to(staging_dir)
130
+ yield staging_dir
131
+ end
132
+ end
133
+
134
+ def unpack_to(staging_dir)
135
+ Mixlib::Archive.new(archive_file_path).extract(staging_dir)
136
+ rescue => e
137
+ raise InvalidPolicyArchive, "Archive file #{archive_file_path} could not be unpacked. #{e}"
138
+ end
139
+
140
+ def looks_like_old_format_archive?(staging_dir)
141
+ cookbooks_dir = File.join(staging_dir, "cookbooks")
142
+ data_bags_dir = File.join(staging_dir, "data_bags")
143
+
144
+ cookbook_artifacts_dir = File.join(staging_dir, "cookbook_artifacts")
145
+ policies_dir = File.join(staging_dir, "policies")
146
+ policy_groups_dir = File.join(staging_dir, "policy_groups")
147
+
148
+ # Old archives just had these two dirs
149
+ have_old_dirs = File.exist?(cookbooks_dir) && File.exist?(data_bags_dir)
150
+
151
+ # New archives created by `chef export` will have all of these; it's
152
+ # also possible we'll encounter an "artisanal" archive, which might
153
+ # only be missing one of these by accident. In that case we want to
154
+ # trigger a different error than we're detecting here.
155
+ have_any_new_dirs = File.exist?(cookbook_artifacts_dir) ||
156
+ File.exist?(policies_dir) ||
157
+ File.exist?(policy_groups_dir)
158
+
159
+ have_old_dirs && !have_any_new_dirs
160
+ end
161
+
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,141 @@
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_relative "../service_exceptions"
19
+ require "chef/server_api"
20
+ require_relative "../policyfile/undo_stack"
21
+ require_relative "../policyfile/undo_record"
22
+
23
+ module ChefCLI
24
+ module PolicyfileServices
25
+
26
+ class RmPolicy
27
+
28
+ attr_reader :policy_name
29
+
30
+ # @api private
31
+ attr_reader :chef_config
32
+
33
+ # @api private
34
+ attr_reader :ui
35
+
36
+ # @api private
37
+ attr_reader :undo_record
38
+
39
+ # @api private
40
+ attr_reader :undo_stack
41
+
42
+ def initialize(config: nil, ui: nil, policy_name: nil)
43
+ @chef_config = config
44
+ @ui = ui
45
+ @policy_name = policy_name
46
+
47
+ @policy_revision_data = nil
48
+ @policy_exists = false
49
+ @policy_group_data = nil
50
+
51
+ @undo_record = Policyfile::UndoRecord.new
52
+ @undo_stack = Policyfile::UndoStack.new
53
+ end
54
+
55
+ def run
56
+ unless policy_exists?
57
+ ui.err("Policy '#{policy_name}' does not exist on the server")
58
+ return false
59
+ end
60
+
61
+ undo_record.description = "delete-policy #{policy_name}"
62
+
63
+ unless policy_has_no_revisions?
64
+ gather_policy_data_for_undo
65
+ end
66
+
67
+ http_client.delete("/policies/#{policy_name}")
68
+ undo_stack.push(undo_record)
69
+ ui.err("Removed policy '#{policy_name}'.")
70
+ rescue => e
71
+ raise DeletePolicyError.new("Failed to delete policy '#{policy_name}'", e)
72
+ end
73
+
74
+ # @api private
75
+ # An instance of Chef::ServerAPI configured with the user's
76
+ # server URL and credentials.
77
+ def http_client
78
+ @http_client ||= Chef::ServerAPI.new(chef_config.chef_server_url,
79
+ signing_key_filename: chef_config.client_key,
80
+ client_name: chef_config.node_name)
81
+ end
82
+
83
+ private
84
+
85
+ def policy_has_no_revisions?
86
+ policy_revision_data.empty? || policy_revision_data["revisions"].empty?
87
+ end
88
+
89
+ def gather_policy_data_for_undo
90
+ revisions = policy_revision_data["revisions"].keys
91
+
92
+ revisions.each do |revision_id|
93
+ policy_revision_data = http_client.get("/policies/#{policy_name}/revisions/#{revision_id}")
94
+ policy_groups = policy_groups_using_revision(revision_id)
95
+ if policy_groups.empty?
96
+ undo_record.add_policy_revision(policy_name, nil, policy_revision_data)
97
+ else
98
+ policy_groups.each do |policy_group|
99
+ undo_record.add_policy_revision(policy_name, policy_group, policy_revision_data)
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def policy_groups_using_revision(revision_id)
106
+ groups = []
107
+ policy_group_data.each do |group_name, group_info|
108
+ next unless group_info.key?("policies") && !group_info["policies"].empty?
109
+ next unless group_info["policies"].key?(policy_name)
110
+ next unless group_info["policies"][policy_name]["revision_id"] == revision_id
111
+ groups << group_name if group_info
112
+ end
113
+ groups
114
+ end
115
+
116
+ def policy_group_data
117
+ @policy_group_data ||= http_client.get("/policy_groups")
118
+ end
119
+
120
+ def policy_exists?
121
+ return true if @policy_exists
122
+ fetch_policy_revision_data
123
+ @policy_exists
124
+ end
125
+
126
+ def policy_revision_data
127
+ return @policy_revision_data if @policy_exists
128
+ fetch_policy_revision_data
129
+ end
130
+
131
+ def fetch_policy_revision_data
132
+ @policy_revision_data = http_client.get("/policies/#{policy_name}")
133
+ @policy_exists = true
134
+ rescue Net::HTTPServerException => e
135
+ raise unless e.response.code == "404"
136
+ @policy_exists = false
137
+ end
138
+
139
+ end
140
+ end
141
+ end