chef-dk 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +190 -190
  3. data/Gemfile +26 -26
  4. data/LICENSE +201 -201
  5. data/README.md +292 -276
  6. data/Rakefile +18 -18
  7. data/bin/chef +25 -25
  8. data/chef-dk.gemspec +62 -0
  9. data/lib/chef-dk.rb +19 -19
  10. data/lib/chef-dk/authenticated_http.rb +40 -40
  11. data/lib/chef-dk/builtin_commands.rb +60 -60
  12. data/lib/chef-dk/chef_runner.rb +98 -98
  13. data/lib/chef-dk/cli.rb +200 -200
  14. data/lib/chef-dk/command/base.rb +79 -79
  15. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
  16. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
  17. data/lib/chef-dk/command/delete_policy.rb +122 -122
  18. data/lib/chef-dk/command/delete_policy_group.rb +122 -122
  19. data/lib/chef-dk/command/diff.rb +316 -316
  20. data/lib/chef-dk/command/env.rb +90 -90
  21. data/lib/chef-dk/command/exec.rb +45 -45
  22. data/lib/chef-dk/command/export.rb +151 -151
  23. data/lib/chef-dk/command/gem.rb +47 -47
  24. data/lib/chef-dk/command/generate.rb +120 -120
  25. data/lib/chef-dk/command/generator_commands.rb +80 -80
  26. data/lib/chef-dk/command/generator_commands/app.rb +107 -107
  27. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
  28. data/lib/chef-dk/command/generator_commands/base.rb +121 -121
  29. data/lib/chef-dk/command/generator_commands/cookbook.rb +153 -119
  30. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  31. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  32. data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -177
  33. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
  34. data/lib/chef-dk/command/generator_commands/policyfile.rb +127 -86
  35. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  36. data/lib/chef-dk/command/generator_commands/repo.rb +125 -96
  37. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  38. data/lib/chef-dk/command/install.rb +121 -121
  39. data/lib/chef-dk/command/provision.rb +438 -438
  40. data/lib/chef-dk/command/push.rb +118 -118
  41. data/lib/chef-dk/command/push_archive.rb +126 -126
  42. data/lib/chef-dk/command/shell_init.rb +180 -180
  43. data/lib/chef-dk/command/show_policy.rb +165 -165
  44. data/lib/chef-dk/command/undelete.rb +155 -155
  45. data/lib/chef-dk/command/update.rb +129 -129
  46. data/lib/chef-dk/command/verify.rb +534 -490
  47. data/lib/chef-dk/commands_map.rb +115 -115
  48. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  49. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  50. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  51. data/lib/chef-dk/component_test.rb +173 -171
  52. data/lib/chef-dk/configurable.rb +57 -57
  53. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  54. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  55. data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
  56. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  57. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
  58. data/lib/chef-dk/exceptions.rb +126 -113
  59. data/lib/chef-dk/generator.rb +163 -163
  60. data/lib/chef-dk/helpers.rb +159 -159
  61. data/lib/chef-dk/pager.rb +106 -106
  62. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -122
  63. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
  64. data/lib/chef-dk/policyfile/community_cookbook_source.rb +97 -82
  65. data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
  66. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +141 -133
  67. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  68. data/lib/chef-dk/policyfile/cookbook_sources.rb +22 -21
  69. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +90 -0
  70. data/lib/chef-dk/policyfile/differ.rb +266 -266
  71. data/lib/chef-dk/policyfile/dsl.rb +223 -197
  72. data/lib/chef-dk/policyfile/lister.rb +232 -232
  73. data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
  74. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  75. data/lib/chef-dk/policyfile/reports/install.rb +70 -70
  76. data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
  77. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  78. data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
  79. data/lib/chef-dk/policyfile/storage_config.rb +100 -100
  80. data/lib/chef-dk/policyfile/undo_record.rb +142 -142
  81. data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
  82. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  83. data/lib/chef-dk/policyfile_compiler.rb +380 -322
  84. data/lib/chef-dk/policyfile_lock.rb +552 -552
  85. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  86. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
  87. data/lib/chef-dk/policyfile_services/export_repo.rb +309 -309
  88. data/lib/chef-dk/policyfile_services/install.rb +125 -125
  89. data/lib/chef-dk/policyfile_services/push.rb +114 -114
  90. data/lib/chef-dk/policyfile_services/push_archive.rb +173 -173
  91. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
  92. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
  93. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
  94. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  95. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
  96. data/lib/chef-dk/service_exception_inspectors.rb +25 -25
  97. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
  98. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
  99. data/lib/chef-dk/service_exceptions.rb +143 -143
  100. data/lib/chef-dk/shell_out.rb +36 -36
  101. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
  102. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +100 -100
  103. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  104. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
  105. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
  106. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
  107. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  108. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
  109. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
  110. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
  111. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +58 -58
  112. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  113. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -0
  114. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  115. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  116. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -0
  117. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  118. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  119. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -8
  120. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
  121. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -0
  122. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  123. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
  124. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
  125. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +117 -104
  126. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -24
  127. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -23
  128. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -8
  129. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +27 -27
  130. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +67 -48
  131. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  132. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  133. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -201
  134. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  135. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  136. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  137. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -20
  138. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  139. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +21 -16
  140. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +32 -27
  141. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +7 -7
  142. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  143. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +20 -20
  144. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -11
  145. data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +9 -9
  146. data/lib/chef-dk/ui.rb +58 -58
  147. data/lib/chef-dk/version.rb +20 -20
  148. data/lib/kitchen/provisioner/policyfile_zero.rb +189 -193
  149. data/spec/shared/a_file_generator.rb +125 -125
  150. data/spec/shared/a_generated_file.rb +12 -12
  151. data/spec/shared/command_with_ui_object.rb +11 -11
  152. data/spec/shared/custom_generator_cookbook.rb +117 -117
  153. data/spec/shared/fixture_cookbook_checksums.rb +47 -47
  154. data/spec/shared/setup_git_cookbooks.rb +53 -53
  155. data/spec/spec_helper.rb +50 -49
  156. data/spec/test_helpers.rb +84 -84
  157. data/spec/unit/chef_runner_spec.rb +111 -111
  158. data/spec/unit/cli_spec.rb +357 -357
  159. data/spec/unit/command/base_spec.rb +169 -169
  160. data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -181
  161. data/spec/unit/command/clean_policy_revisions_spec.rb +181 -181
  162. data/spec/unit/command/delete_policy_group_spec.rb +207 -207
  163. data/spec/unit/command/delete_policy_spec.rb +207 -207
  164. data/spec/unit/command/diff_spec.rb +312 -312
  165. data/spec/unit/command/env_spec.rb +52 -52
  166. data/spec/unit/command/exec_spec.rb +179 -179
  167. data/spec/unit/command/export_spec.rb +189 -189
  168. data/spec/unit/command/generate_spec.rb +142 -142
  169. data/spec/unit/command/generator_commands/app_spec.rb +169 -169
  170. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -32
  171. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
  172. data/spec/unit/command/generator_commands/cookbook_spec.rb +450 -320
  173. data/spec/unit/command/generator_commands/generator_generator_spec.rb +229 -229
  174. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -32
  175. data/spec/unit/command/generator_commands/policyfile_spec.rb +225 -125
  176. data/spec/unit/command/generator_commands/recipe_spec.rb +34 -34
  177. data/spec/unit/command/generator_commands/repo_spec.rb +367 -283
  178. data/spec/unit/command/generator_commands/template_spec.rb +32 -32
  179. data/spec/unit/command/install_spec.rb +179 -179
  180. data/spec/unit/command/provision_spec.rb +592 -592
  181. data/spec/unit/command/push_archive_spec.rb +153 -153
  182. data/spec/unit/command/push_spec.rb +199 -199
  183. data/spec/unit/command/shell_init_spec.rb +329 -329
  184. data/spec/unit/command/show_policy_spec.rb +235 -235
  185. data/spec/unit/command/undelete_spec.rb +246 -246
  186. data/spec/unit/command/update_spec.rb +251 -251
  187. data/spec/unit/command/verify_spec.rb +325 -323
  188. data/spec/unit/commands_map_spec.rb +57 -57
  189. data/spec/unit/component_test_spec.rb +126 -126
  190. data/spec/unit/cookbook_metadata_spec.rb +98 -98
  191. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  192. data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
  193. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  194. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  195. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  196. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  197. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  198. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  199. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  200. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  201. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  202. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  203. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  204. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  205. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  206. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  207. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  208. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  209. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  210. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  211. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  212. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  213. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  214. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  215. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  216. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  217. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  218. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
  219. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  220. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  221. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  222. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  223. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  224. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  225. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  226. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  227. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  228. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  229. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  230. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  231. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  232. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  233. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  234. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  235. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  236. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  237. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  238. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  239. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  240. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  241. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  242. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  243. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  244. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  245. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  246. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  247. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  248. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  249. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  250. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  251. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  252. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  253. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  254. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  255. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  256. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  257. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  258. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  259. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  260. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  261. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  262. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  263. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  264. data/spec/unit/generator_spec.rb +120 -120
  265. data/spec/unit/helpers_spec.rb +92 -92
  266. data/spec/unit/pager_spec.rb +119 -119
  267. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -66
  268. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
  269. data/spec/unit/policyfile/community_cookbook_source_spec.rb +84 -51
  270. data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
  271. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +257 -252
  272. data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
  273. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +130 -0
  274. data/spec/unit/policyfile/differ_spec.rb +687 -687
  275. data/spec/unit/policyfile/lister_spec.rb +272 -272
  276. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
  277. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  278. data/spec/unit/policyfile/reports/install_spec.rb +115 -115
  279. data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
  280. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
  281. data/spec/unit/policyfile/storage_config_spec.rb +172 -172
  282. data/spec/unit/policyfile/undo_record_spec.rb +260 -260
  283. data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
  284. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  285. data/spec/unit/policyfile_demands_spec.rb +997 -876
  286. data/spec/unit/policyfile_evaluation_spec.rb +557 -441
  287. data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
  288. data/spec/unit/policyfile_lock_install_spec.rb +138 -138
  289. data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
  290. data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
  291. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  292. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
  293. data/spec/unit/policyfile_services/export_repo_spec.rb +439 -439
  294. data/spec/unit/policyfile_services/install_spec.rb +191 -191
  295. data/spec/unit/policyfile_services/push_archive_spec.rb +345 -345
  296. data/spec/unit/policyfile_services/push_spec.rb +233 -233
  297. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
  298. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
  299. data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
  300. data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
  301. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
  302. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
  303. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
  304. data/spec/unit/shell_out_spec.rb +34 -34
  305. data/warning.txt +9 -0
  306. metadata +18 -5
@@ -1,197 +1,223 @@
1
- #
2
- # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require 'chef-dk/policyfile/cookbook_sources'
19
- require 'chef-dk/policyfile/cookbook_location_specification'
20
- require 'chef-dk/policyfile/storage_config'
21
-
22
- require 'chef/node/attribute'
23
-
24
- module ChefDK
25
- module Policyfile
26
- class DSL
27
-
28
- include StorageConfigDelegation
29
-
30
- attr_writer :name
31
-
32
- attr_reader :errors
33
- attr_reader :run_list
34
- attr_reader :default_source
35
- attr_reader :cookbook_location_specs
36
-
37
- attr_reader :named_run_lists
38
- attr_reader :node_attributes
39
-
40
- attr_reader :storage_config
41
-
42
- def initialize(storage_config)
43
- @name = nil
44
- @errors = []
45
- @run_list = []
46
- @named_run_lists = {}
47
- @default_source = [ NullCookbookSource.new ]
48
- @cookbook_location_specs = {}
49
- @storage_config = storage_config
50
-
51
- @node_attributes = Chef::Node::Attribute.new({}, {}, {}, {})
52
- end
53
-
54
- def name(name = nil)
55
- unless name.nil?
56
- @name = name
57
- end
58
- @name
59
- end
60
-
61
- def run_list(*run_list_items)
62
- run_list_items = run_list_items.flatten
63
- @run_list = run_list_items unless run_list_items.empty?
64
- @run_list
65
- end
66
-
67
- def named_run_list(name, *run_list_items)
68
- @named_run_lists[name] = run_list_items.flatten
69
- end
70
-
71
- def default_source(source_type = nil, source_argument = nil)
72
- return @default_source if source_type.nil?
73
- case source_type
74
- when :community, :supermarket
75
- set_default_community_source(source_argument)
76
- when :chef_server
77
- set_default_chef_server_source(source_argument)
78
- when :chef_repo
79
- set_default_chef_repo_source(source_argument)
80
- else
81
- @errors << "Invalid default_source type '#{source_type.inspect}'"
82
- end
83
- end
84
-
85
- def cookbook(name, *version_and_source_opts)
86
- source_options =
87
- if version_and_source_opts.last.is_a?(Hash)
88
- version_and_source_opts.pop
89
- else
90
- {}
91
- end
92
-
93
- constraint = version_and_source_opts.first || ">= 0.0.0"
94
- spec = CookbookLocationSpecification.new(name, constraint, source_options, storage_config)
95
-
96
-
97
- if existing_source = @cookbook_location_specs[name]
98
- err = "Cookbook '#{name}' assigned to conflicting sources\n\n"
99
- err << "Previous source: #{existing_source.source_options.inspect}\n"
100
- err << "Conflicts with: #{source_options.inspect}\n"
101
- @errors << err
102
- else
103
- @cookbook_location_specs[name] = spec
104
- @errors += spec.errors
105
- end
106
- end
107
-
108
- def default
109
- @node_attributes.default
110
- end
111
-
112
- def override
113
- @node_attributes.override
114
- end
115
-
116
- def eval_policyfile(policyfile_string)
117
- @policyfile_filename = policyfile_filename
118
- instance_eval(policyfile_string, policyfile_filename)
119
- validate!
120
- self
121
- rescue SyntaxError => e
122
- @errors << "Invalid ruby syntax in policyfile '#{policyfile_filename}':\n\n#{e.message}"
123
- rescue SignalException, SystemExit
124
- # allow signal from kill, ctrl-C, etc. to bubble up:
125
- raise
126
- rescue Exception => e
127
- error_message = "Evaluation of policyfile '#{policyfile_filename}' raised an exception\n"
128
- error_message << " Exception: #{e.class.name} \"#{e.to_s}\"\n\n"
129
- trace = filtered_bt(policyfile_filename, e)
130
- error_message << " Relevant Code:\n"
131
- error_message << " #{error_context(policyfile_string, policyfile_filename, e)}\n\n"
132
- unless trace.empty?
133
- error_message << " Backtrace:\n"
134
- # TODO: need a way to disable filtering
135
- error_message << filtered_bt(policyfile_filename, e).inject("") { |formatted_trace, line| formatted_trace << " #{line}\n" }
136
- end
137
- @errors << error_message
138
- end
139
-
140
- private
141
-
142
- def set_default_community_source(source_uri)
143
- set_default_source(CommunityCookbookSource.new(source_uri))
144
- end
145
-
146
- def set_default_chef_server_source(source_uri)
147
- if source_uri.nil?
148
- @errors << "You must specify the server's URI when using a default_source :chef_server"
149
- else
150
- set_default_source(ChefServerCookbookSource.new(source_uri))
151
- end
152
- end
153
-
154
- def set_default_chef_repo_source(path)
155
- if path.nil?
156
- @errors << "You must specify the path to the chef-repo when using a default_source :chef_repo"
157
- else
158
- set_default_source(ChefRepoCookbookSource.new(path))
159
- end
160
- end
161
-
162
- def set_default_source(source)
163
- @default_source.delete_at(0) if @default_source[0].null?
164
- @default_source << source
165
- end
166
-
167
- def validate!
168
- if @run_list.empty?
169
- @errors << "Invalid run_list. run_list cannot be empty"
170
- end
171
- end
172
-
173
- def error_context(policyfile_string, policyfile_filename, exception)
174
- if line_number_to_show = culprit_line_number(policyfile_filename, exception)
175
- code = policyfile_string.lines.to_a[line_number_to_show - 1].strip
176
- "#{line_number_to_show}: #{code}"
177
- else
178
- "Could not find relevant code from backtrace"
179
- end
180
- end
181
-
182
- def culprit_line_number(policyfile_filename, exception)
183
- if most_proximate_backtrace_line = filtered_bt(policyfile_filename, exception).first
184
- most_proximate_backtrace_line[/^(?:.\:)?[^:]+:([\d]+)/,1].to_i
185
- else
186
- nil
187
- end
188
- end
189
-
190
- def filtered_bt(policyfile_filename, exception)
191
- policyfile_filename_matcher = /^#{Regexp.escape(policyfile_filename)}/
192
- exception.backtrace.select {|line| line =~ policyfile_filename_matcher }
193
- end
194
-
195
- end
196
- end
197
- end
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef-dk/policyfile/cookbook_sources'
19
+ require 'chef-dk/policyfile/cookbook_location_specification'
20
+ require 'chef-dk/policyfile/storage_config'
21
+
22
+ require 'chef/node/attribute'
23
+
24
+ module ChefDK
25
+ module Policyfile
26
+ class DSL
27
+
28
+ include StorageConfigDelegation
29
+
30
+ attr_writer :name
31
+
32
+ attr_reader :errors
33
+ attr_reader :run_list
34
+ attr_reader :default_source
35
+ attr_reader :cookbook_location_specs
36
+
37
+ attr_reader :named_run_lists
38
+ attr_reader :node_attributes
39
+
40
+ attr_reader :storage_config
41
+
42
+ def initialize(storage_config)
43
+ @name = nil
44
+ @errors = []
45
+ @run_list = []
46
+ @named_run_lists = {}
47
+ @default_source = [ NullCookbookSource.new ]
48
+ @cookbook_location_specs = {}
49
+ @storage_config = storage_config
50
+
51
+ @node_attributes = Chef::Node::Attribute.new({}, {}, {}, {})
52
+ end
53
+
54
+ def name(name = nil)
55
+ unless name.nil?
56
+ @name = name
57
+ end
58
+ @name
59
+ end
60
+
61
+ def run_list(*run_list_items)
62
+ run_list_items = run_list_items.flatten
63
+ @run_list = run_list_items unless run_list_items.empty?
64
+ @run_list
65
+ end
66
+
67
+ def named_run_list(name, *run_list_items)
68
+ @named_run_lists[name] = run_list_items.flatten
69
+ end
70
+
71
+ def default_source(source_type = nil, source_argument = nil, &block)
72
+ return @default_source if source_type.nil?
73
+ case source_type
74
+ when :community, :supermarket
75
+ set_default_community_source(source_argument, &block)
76
+ when :delivery_supermarket
77
+ set_default_delivery_supermarket_source(source_argument, &block)
78
+ when :chef_server
79
+ set_default_chef_server_source(source_argument, &block)
80
+ when :chef_repo
81
+ set_default_chef_repo_source(source_argument, &block)
82
+ else
83
+ @errors << "Invalid default_source type '#{source_type.inspect}'"
84
+ end
85
+ end
86
+
87
+ def cookbook(name, *version_and_source_opts)
88
+ source_options =
89
+ if version_and_source_opts.last.is_a?(Hash)
90
+ version_and_source_opts.pop
91
+ else
92
+ {}
93
+ end
94
+
95
+ constraint = version_and_source_opts.first || ">= 0.0.0"
96
+ spec = CookbookLocationSpecification.new(name, constraint, source_options, storage_config)
97
+
98
+
99
+ if existing_source = @cookbook_location_specs[name]
100
+ err = "Cookbook '#{name}' assigned to conflicting sources\n\n"
101
+ err << "Previous source: #{existing_source.source_options.inspect}\n"
102
+ err << "Conflicts with: #{source_options.inspect}\n"
103
+ @errors << err
104
+ else
105
+ @cookbook_location_specs[name] = spec
106
+ @errors += spec.errors
107
+ end
108
+ end
109
+
110
+ def default
111
+ @node_attributes.default
112
+ end
113
+
114
+ def override
115
+ @node_attributes.override
116
+ end
117
+
118
+ def eval_policyfile(policyfile_string)
119
+ @policyfile_filename = policyfile_filename
120
+ instance_eval(policyfile_string, policyfile_filename)
121
+ validate!
122
+ self
123
+ rescue SyntaxError => e
124
+ @errors << "Invalid ruby syntax in policyfile '#{policyfile_filename}':\n\n#{e.message}"
125
+ rescue SignalException, SystemExit
126
+ # allow signal from kill, ctrl-C, etc. to bubble up:
127
+ raise
128
+ rescue Exception => e
129
+ error_message = "Evaluation of policyfile '#{policyfile_filename}' raised an exception\n"
130
+ error_message << " Exception: #{e.class.name} \"#{e.to_s}\"\n\n"
131
+ trace = filtered_bt(policyfile_filename, e)
132
+ error_message << " Relevant Code:\n"
133
+ error_message << " #{error_context(policyfile_string, policyfile_filename, e)}\n\n"
134
+ unless trace.empty?
135
+ error_message << " Backtrace:\n"
136
+ # TODO: need a way to disable filtering
137
+ error_message << filtered_bt(policyfile_filename, e).inject("") { |formatted_trace, line| formatted_trace << " #{line}\n" }
138
+ end
139
+ @errors << error_message
140
+ end
141
+
142
+ private
143
+
144
+ def set_default_community_source(source_uri, &block)
145
+ set_default_source(CommunityCookbookSource.new(source_uri, &block))
146
+ end
147
+
148
+ def set_default_delivery_supermarket_source(source_uri, &block)
149
+ if source_uri.nil?
150
+ @errors << "You must specify the server's URI when using a default_source :delivery_supermarket"
151
+ else
152
+ set_default_source(DeliverySupermarketSource.new(source_uri, &block))
153
+ end
154
+ end
155
+
156
+ def set_default_chef_server_source(source_uri, &block)
157
+ if source_uri.nil?
158
+ @errors << "You must specify the server's URI when using a default_source :chef_server"
159
+ else
160
+ set_default_source(ChefServerCookbookSource.new(source_uri))
161
+ end
162
+ end
163
+
164
+ def set_default_chef_repo_source(path, &block)
165
+ if path.nil?
166
+ @errors << "You must specify the path to the chef-repo when using a default_source :chef_repo"
167
+ else
168
+ set_default_source(ChefRepoCookbookSource.new(File.expand_path(path, storage_config.relative_paths_root), &block))
169
+ end
170
+ end
171
+
172
+ def set_default_source(source)
173
+ @default_source.delete_at(0) if @default_source[0].null?
174
+ @default_source << source
175
+ end
176
+
177
+ def validate!
178
+ if @run_list.empty?
179
+ @errors << "Invalid run_list. run_list cannot be empty"
180
+ end
181
+
182
+ handle_preferred_cookbooks_conflicts
183
+ end
184
+
185
+ def handle_preferred_cookbooks_conflicts
186
+ conflicting_source_messages = []
187
+ default_source.combination(2).each do |source_a, source_b|
188
+ conflicting_preferences = source_a.preferred_cookbooks & source_b.preferred_cookbooks
189
+ next if conflicting_preferences.empty?
190
+ conflicting_source_messages << "#{source_a.desc} and #{source_b.desc} are both set as the preferred source for cookbook(s) '#{conflicting_preferences.join(', ')}'"
191
+ end
192
+ unless conflicting_source_messages.empty?
193
+ msg = "Multiple sources are marked as the preferred source for some cookbooks. Only one source can be preferred for a cookbook.\n"
194
+ msg << conflicting_source_messages.join("\n") << "\n"
195
+ @errors << msg
196
+ end
197
+ end
198
+
199
+ def error_context(policyfile_string, policyfile_filename, exception)
200
+ if line_number_to_show = culprit_line_number(policyfile_filename, exception)
201
+ code = policyfile_string.lines.to_a[line_number_to_show - 1].strip
202
+ "#{line_number_to_show}: #{code}"
203
+ else
204
+ "Could not find relevant code from backtrace"
205
+ end
206
+ end
207
+
208
+ def culprit_line_number(policyfile_filename, exception)
209
+ if most_proximate_backtrace_line = filtered_bt(policyfile_filename, exception).first
210
+ most_proximate_backtrace_line[/^(?:.\:)?[^:]+:([\d]+)/,1].to_i
211
+ else
212
+ nil
213
+ end
214
+ end
215
+
216
+ def filtered_bt(policyfile_filename, exception)
217
+ policyfile_filename_matcher = /^#{Regexp.escape(policyfile_filename)}/
218
+ exception.backtrace.select {|line| line =~ policyfile_filename_matcher }
219
+ end
220
+
221
+ end
222
+ end
223
+ end
@@ -1,232 +1,232 @@
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 'set'
19
-
20
- require 'chef-dk/authenticated_http'
21
- require 'chef-dk/service_exceptions'
22
-
23
- module ChefDK
24
- module Policyfile
25
-
26
- class RevIDLockDataMap
27
-
28
- attr_reader :policy_name
29
- attr_reader :lock_info_by_rev_id
30
-
31
- def initialize(policy_name, lock_info_by_rev_id)
32
- @policy_name = policy_name
33
- @lock_info_by_rev_id = lock_info_by_rev_id
34
- end
35
-
36
-
37
- def cb_info_for(rev_id, cookbook_name)
38
- lock = lock_info_by_rev_id[rev_id]
39
- cookbook_lock = lock["cookbook_locks"][cookbook_name]
40
-
41
- if cookbook_lock
42
- [cookbook_lock["version"], cookbook_lock["identifier"] ]
43
- else
44
- nil
45
- end
46
- end
47
-
48
- def cbs_with_differing_ids
49
- cbs_with_differing_ids = Set.new
50
- all_cookbook_names.each do |cookbook_name|
51
- all_identifiers = lock_info_by_rev_id.inject(Set.new) do |id_set, (_rev_id, rev_info)|
52
- cookbook_lock = rev_info["cookbook_locks"][cookbook_name]
53
- identifier = cookbook_lock && cookbook_lock["identifier"]
54
- id_set << identifier
55
- end
56
- cbs_with_differing_ids << cookbook_name if all_identifiers.size > 1
57
- end
58
- cbs_with_differing_ids
59
- end
60
-
61
- def all_cookbook_names
62
- lock_info_by_rev_id.inject(Set.new) do |cb_set, (_rev_id, rev_info)|
63
- cb_set.merge(rev_info["cookbook_locks"].keys)
64
- end
65
- end
66
- end
67
-
68
- class PolicyGroupRevIDMap
69
-
70
- include Enumerable
71
-
72
- attr_reader :policy_name
73
- attr_reader :revision_ids_by_group
74
-
75
- def initialize(policy_name, revision_ids_by_group)
76
- @policy_name = policy_name
77
- @revision_ids_by_group = revision_ids_by_group
78
- end
79
-
80
- def unique_revision_ids
81
- revision_ids_by_group.values.uniq
82
- end
83
-
84
- def policy_group_names
85
- revision_ids_by_group.keys
86
- end
87
-
88
- def max_group_name_length
89
- policy_group_names.map(&:size).max
90
- end
91
-
92
- def format_revision_ids
93
- revision_ids_by_group.inject({}) do |map, (group_name, rev_id)|
94
- map[group_name] = yield rev_id
95
- map
96
- end
97
- end
98
-
99
- def empty?
100
- policy_group_names.empty?
101
- end
102
-
103
- def each
104
- revision_ids_by_group.each do |group_name, rev_id|
105
- yield group_name, rev_id
106
- end
107
- end
108
- end
109
-
110
- class Lister
111
-
112
- attr_accessor :policy_lock_content
113
-
114
- attr_reader :config
115
-
116
- def initialize(config: nil)
117
- @config = config
118
- @policies_by_name = nil
119
- @policies_by_group = nil
120
- @policy_lock_content = {}
121
- @active_revisions = nil
122
- end
123
-
124
- # A Hash with the following format
125
- # {
126
- # "appserver" => {
127
- # "1111111111111111111111111111111111111111111111111111111111111111" => {},
128
- # "2222222222222222222222222222222222222222222222222222222222222222" => {}
129
- # },
130
- def policies_by_name
131
- @policies_by_name || fetch_policy_lists
132
- @policies_by_name
133
- end
134
-
135
- # A Hash with the following format:
136
- # "dev" => {
137
- # "appserver" => "1111111111111111111111111111111111111111111111111111111111111111",
138
- # "load-balancer" => "5555555555555555555555555555555555555555555555555555555555555555",
139
- # "db" => "9999999999999999999999999999999999999999999999999999999999999999"
140
- # }
141
- def policies_by_group
142
- @policies_by_group || fetch_policy_lists
143
- @policies_by_group
144
- end
145
-
146
- def revision_info_for(policy_name, _revision_id_list)
147
- RevIDLockDataMap.new(policy_name, policy_lock_content[policy_name])
148
- end
149
-
150
- def revision_ids_by_group_for_each_policy
151
- policies_by_name.each do |policy_name, _policies|
152
- rev_id_by_group = revision_ids_by_group_for(policy_name)
153
- yield policy_name, rev_id_by_group
154
- end
155
- end
156
-
157
- def revision_ids_by_group_for(policy_name)
158
- map = policies_by_group.inject({}) do |rev_id_map, (group_name, rev_id_map_for_group)|
159
- rev_id_map[group_name] = rev_id_map_for_group[policy_name]
160
- rev_id_map
161
- end
162
- PolicyGroupRevIDMap.new(policy_name, map)
163
- end
164
-
165
- def orphaned_revisions(policy_name)
166
- orphans = []
167
- policies_by_name[policy_name].each do |rev_id, _data|
168
- orphans << rev_id unless active_revisions.include?(rev_id)
169
- end
170
- orphans
171
- end
172
-
173
- def active_revisions
174
- @active_revisions ||= policies_by_group.inject(Set.new) do |set, (_group, policy_name_rev_id_map)|
175
- policy_name_rev_id_map.each do |policy_name, rev_id|
176
- set << rev_id
177
- end
178
- set
179
- end
180
- end
181
-
182
- def empty?
183
- policies_by_name.empty? && policies_by_group.empty?
184
- end
185
-
186
- def http_client
187
- @http_client ||= ChefDK::AuthenticatedHTTP.new(config.chef_server_url,
188
- signing_key_filename: config.client_key,
189
- client_name: config.node_name)
190
- end
191
-
192
- # @api private
193
- # Sets internal copy of policyfile data to policies_by_name and
194
- # policies_by_group. Used for internal testing.
195
- def set!(policies_by_name, policies_by_group)
196
- @policies_by_name = policies_by_name
197
- @policies_by_group = policies_by_group
198
- @active_revisions = nil
199
- end
200
-
201
- private
202
-
203
- def fetch_policy_lists
204
- policy_list_data = http_client.get("policies")
205
- set_policies_by_name_from_api(policy_list_data)
206
-
207
- policy_group_data = http_client.get("policy_groups")
208
- set_policies_by_group_from_api(policy_group_data)
209
- end
210
-
211
- def set_policies_by_name_from_api(policy_list_data)
212
- @policies_by_name = policy_list_data.inject({}) do |map, (policy_name, policy_info)|
213
- map[policy_name] = policy_info["revisions"]
214
- map
215
- end
216
- end
217
-
218
- def set_policies_by_group_from_api(policy_group_data)
219
- @policies_by_group = policy_group_data.inject({}) do |map, (policy_group, policy_info)|
220
- map[policy_group] = (policy_info["policies"] || []).inject({}) do |rev_map, (policy_name, rev_info)|
221
- rev_map[policy_name] = rev_info["revision_id"]; rev_map
222
- end
223
-
224
- map
225
- end
226
- end
227
-
228
- end
229
- end
230
- end
231
-
232
-
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 'set'
19
+
20
+ require 'chef-dk/authenticated_http'
21
+ require 'chef-dk/service_exceptions'
22
+
23
+ module ChefDK
24
+ module Policyfile
25
+
26
+ class RevIDLockDataMap
27
+
28
+ attr_reader :policy_name
29
+ attr_reader :lock_info_by_rev_id
30
+
31
+ def initialize(policy_name, lock_info_by_rev_id)
32
+ @policy_name = policy_name
33
+ @lock_info_by_rev_id = lock_info_by_rev_id
34
+ end
35
+
36
+
37
+ def cb_info_for(rev_id, cookbook_name)
38
+ lock = lock_info_by_rev_id[rev_id]
39
+ cookbook_lock = lock["cookbook_locks"][cookbook_name]
40
+
41
+ if cookbook_lock
42
+ [cookbook_lock["version"], cookbook_lock["identifier"] ]
43
+ else
44
+ nil
45
+ end
46
+ end
47
+
48
+ def cbs_with_differing_ids
49
+ cbs_with_differing_ids = Set.new
50
+ all_cookbook_names.each do |cookbook_name|
51
+ all_identifiers = lock_info_by_rev_id.inject(Set.new) do |id_set, (_rev_id, rev_info)|
52
+ cookbook_lock = rev_info["cookbook_locks"][cookbook_name]
53
+ identifier = cookbook_lock && cookbook_lock["identifier"]
54
+ id_set << identifier
55
+ end
56
+ cbs_with_differing_ids << cookbook_name if all_identifiers.size > 1
57
+ end
58
+ cbs_with_differing_ids
59
+ end
60
+
61
+ def all_cookbook_names
62
+ lock_info_by_rev_id.inject(Set.new) do |cb_set, (_rev_id, rev_info)|
63
+ cb_set.merge(rev_info["cookbook_locks"].keys)
64
+ end
65
+ end
66
+ end
67
+
68
+ class PolicyGroupRevIDMap
69
+
70
+ include Enumerable
71
+
72
+ attr_reader :policy_name
73
+ attr_reader :revision_ids_by_group
74
+
75
+ def initialize(policy_name, revision_ids_by_group)
76
+ @policy_name = policy_name
77
+ @revision_ids_by_group = revision_ids_by_group
78
+ end
79
+
80
+ def unique_revision_ids
81
+ revision_ids_by_group.values.uniq
82
+ end
83
+
84
+ def policy_group_names
85
+ revision_ids_by_group.keys
86
+ end
87
+
88
+ def max_group_name_length
89
+ policy_group_names.map(&:size).max
90
+ end
91
+
92
+ def format_revision_ids
93
+ revision_ids_by_group.inject({}) do |map, (group_name, rev_id)|
94
+ map[group_name] = yield rev_id
95
+ map
96
+ end
97
+ end
98
+
99
+ def empty?
100
+ policy_group_names.empty?
101
+ end
102
+
103
+ def each
104
+ revision_ids_by_group.each do |group_name, rev_id|
105
+ yield group_name, rev_id
106
+ end
107
+ end
108
+ end
109
+
110
+ class Lister
111
+
112
+ attr_accessor :policy_lock_content
113
+
114
+ attr_reader :config
115
+
116
+ def initialize(config: nil)
117
+ @config = config
118
+ @policies_by_name = nil
119
+ @policies_by_group = nil
120
+ @policy_lock_content = {}
121
+ @active_revisions = nil
122
+ end
123
+
124
+ # A Hash with the following format
125
+ # {
126
+ # "appserver" => {
127
+ # "1111111111111111111111111111111111111111111111111111111111111111" => {},
128
+ # "2222222222222222222222222222222222222222222222222222222222222222" => {}
129
+ # },
130
+ def policies_by_name
131
+ @policies_by_name || fetch_policy_lists
132
+ @policies_by_name
133
+ end
134
+
135
+ # A Hash with the following format:
136
+ # "dev" => {
137
+ # "appserver" => "1111111111111111111111111111111111111111111111111111111111111111",
138
+ # "load-balancer" => "5555555555555555555555555555555555555555555555555555555555555555",
139
+ # "db" => "9999999999999999999999999999999999999999999999999999999999999999"
140
+ # }
141
+ def policies_by_group
142
+ @policies_by_group || fetch_policy_lists
143
+ @policies_by_group
144
+ end
145
+
146
+ def revision_info_for(policy_name, _revision_id_list)
147
+ RevIDLockDataMap.new(policy_name, policy_lock_content[policy_name])
148
+ end
149
+
150
+ def revision_ids_by_group_for_each_policy
151
+ policies_by_name.each do |policy_name, _policies|
152
+ rev_id_by_group = revision_ids_by_group_for(policy_name)
153
+ yield policy_name, rev_id_by_group
154
+ end
155
+ end
156
+
157
+ def revision_ids_by_group_for(policy_name)
158
+ map = policies_by_group.inject({}) do |rev_id_map, (group_name, rev_id_map_for_group)|
159
+ rev_id_map[group_name] = rev_id_map_for_group[policy_name]
160
+ rev_id_map
161
+ end
162
+ PolicyGroupRevIDMap.new(policy_name, map)
163
+ end
164
+
165
+ def orphaned_revisions(policy_name)
166
+ orphans = []
167
+ policies_by_name[policy_name].each do |rev_id, _data|
168
+ orphans << rev_id unless active_revisions.include?(rev_id)
169
+ end
170
+ orphans
171
+ end
172
+
173
+ def active_revisions
174
+ @active_revisions ||= policies_by_group.inject(Set.new) do |set, (_group, policy_name_rev_id_map)|
175
+ policy_name_rev_id_map.each do |policy_name, rev_id|
176
+ set << rev_id
177
+ end
178
+ set
179
+ end
180
+ end
181
+
182
+ def empty?
183
+ policies_by_name.empty? && policies_by_group.empty?
184
+ end
185
+
186
+ def http_client
187
+ @http_client ||= ChefDK::AuthenticatedHTTP.new(config.chef_server_url,
188
+ signing_key_filename: config.client_key,
189
+ client_name: config.node_name)
190
+ end
191
+
192
+ # @api private
193
+ # Sets internal copy of policyfile data to policies_by_name and
194
+ # policies_by_group. Used for internal testing.
195
+ def set!(policies_by_name, policies_by_group)
196
+ @policies_by_name = policies_by_name
197
+ @policies_by_group = policies_by_group
198
+ @active_revisions = nil
199
+ end
200
+
201
+ private
202
+
203
+ def fetch_policy_lists
204
+ policy_list_data = http_client.get("policies")
205
+ set_policies_by_name_from_api(policy_list_data)
206
+
207
+ policy_group_data = http_client.get("policy_groups")
208
+ set_policies_by_group_from_api(policy_group_data)
209
+ end
210
+
211
+ def set_policies_by_name_from_api(policy_list_data)
212
+ @policies_by_name = policy_list_data.inject({}) do |map, (policy_name, policy_info)|
213
+ map[policy_name] = policy_info["revisions"]
214
+ map
215
+ end
216
+ end
217
+
218
+ def set_policies_by_group_from_api(policy_group_data)
219
+ @policies_by_group = policy_group_data.inject({}) do |map, (policy_group, policy_info)|
220
+ map[policy_group] = (policy_info["policies"] || []).inject({}) do |rev_map, (policy_name, rev_info)|
221
+ rev_map[policy_name] = rev_info["revision_id"]; rev_map
222
+ end
223
+
224
+ map
225
+ end
226
+ end
227
+
228
+ end
229
+ end
230
+ end
231
+
232
+