chef-dk 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +190 -190
- data/Gemfile +26 -0
- data/LICENSE +201 -201
- data/README.md +276 -276
- data/Rakefile +18 -18
- data/bin/chef +25 -25
- data/lib/chef-dk.rb +19 -19
- data/lib/chef-dk/authenticated_http.rb +40 -40
- data/lib/chef-dk/builtin_commands.rb +60 -60
- data/lib/chef-dk/chef_runner.rb +98 -98
- data/lib/chef-dk/cli.rb +200 -200
- data/lib/chef-dk/command/base.rb +79 -75
- data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
- data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
- data/lib/chef-dk/command/delete_policy.rb +122 -122
- data/lib/chef-dk/command/delete_policy_group.rb +122 -122
- data/lib/chef-dk/command/diff.rb +316 -316
- data/lib/chef-dk/command/env.rb +90 -90
- data/lib/chef-dk/command/exec.rb +45 -45
- data/lib/chef-dk/command/export.rb +151 -153
- data/lib/chef-dk/command/gem.rb +47 -47
- data/lib/chef-dk/command/generate.rb +120 -118
- data/lib/chef-dk/command/generator_commands.rb +80 -80
- data/lib/chef-dk/command/generator_commands/app.rb +107 -107
- data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
- data/lib/chef-dk/command/generator_commands/base.rb +121 -121
- data/lib/chef-dk/command/generator_commands/cookbook.rb +119 -108
- data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
- data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
- data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -0
- data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
- data/lib/chef-dk/command/generator_commands/policyfile.rb +86 -83
- data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
- data/lib/chef-dk/command/generator_commands/repo.rb +96 -96
- data/lib/chef-dk/command/generator_commands/template.rb +46 -46
- data/lib/chef-dk/command/install.rb +121 -121
- data/lib/chef-dk/command/provision.rb +438 -438
- data/lib/chef-dk/command/push.rb +118 -118
- data/lib/chef-dk/command/push_archive.rb +126 -126
- data/lib/chef-dk/command/shell_init.rb +180 -180
- data/lib/chef-dk/command/show_policy.rb +165 -165
- data/lib/chef-dk/command/undelete.rb +155 -155
- data/lib/chef-dk/command/update.rb +129 -129
- data/lib/chef-dk/command/verify.rb +490 -453
- data/lib/chef-dk/commands_map.rb +115 -115
- data/lib/chef-dk/completions/bash.sh.erb +5 -5
- data/lib/chef-dk/completions/chef.fish.erb +10 -10
- data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
- data/lib/chef-dk/component_test.rb +171 -171
- data/lib/chef-dk/configurable.rb +57 -52
- data/lib/chef-dk/cookbook_metadata.rb +45 -45
- data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
- data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
- data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
- data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
- data/lib/chef-dk/exceptions.rb +113 -113
- data/lib/chef-dk/generator.rb +163 -162
- data/lib/chef-dk/helpers.rb +159 -159
- data/lib/chef-dk/pager.rb +106 -106
- data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +122 -122
- data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
- data/lib/chef-dk/policyfile/community_cookbook_source.rb +82 -82
- data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +133 -133
- data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
- data/lib/chef-dk/policyfile/cookbook_sources.rb +21 -21
- data/lib/chef-dk/policyfile/differ.rb +266 -266
- data/lib/chef-dk/policyfile/dsl.rb +197 -197
- data/lib/chef-dk/policyfile/lister.rb +232 -232
- data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
- data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
- data/lib/chef-dk/policyfile/reports/install.rb +70 -70
- data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
- data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
- data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
- data/lib/chef-dk/policyfile/storage_config.rb +100 -100
- data/lib/chef-dk/policyfile/undo_record.rb +142 -142
- data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
- data/lib/chef-dk/policyfile/uploader.rb +213 -213
- data/lib/chef-dk/policyfile_compiler.rb +322 -322
- data/lib/chef-dk/policyfile_lock.rb +552 -552
- data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
- data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
- data/lib/chef-dk/policyfile_services/export_repo.rb +309 -281
- data/lib/chef-dk/policyfile_services/install.rb +125 -125
- data/lib/chef-dk/policyfile_services/push.rb +114 -114
- data/lib/chef-dk/policyfile_services/push_archive.rb +173 -173
- data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
- data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
- data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
- data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
- data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
- data/lib/chef-dk/service_exception_inspectors.rb +25 -25
- data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
- data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
- data/lib/chef-dk/service_exceptions.rb +143 -143
- data/lib/chef-dk/shell_out.rb +36 -36
- data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
- data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +100 -100
- data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
- data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +57 -57
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +8 -8
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
- data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -3
- data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
- data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
- data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
- data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +104 -92
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -24
- data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -23
- data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -8
- data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +27 -27
- data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +48 -47
- data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -201
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
- data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +20 -16
- data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
- data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +16 -16
- data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +27 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +7 -7
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +20 -20
- data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -11
- data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +9 -9
- data/lib/chef-dk/ui.rb +58 -58
- data/lib/chef-dk/version.rb +20 -20
- data/lib/kitchen/provisioner/policyfile_zero.rb +193 -164
- data/spec/shared/a_file_generator.rb +125 -125
- data/spec/shared/a_generated_file.rb +12 -12
- data/spec/shared/command_with_ui_object.rb +11 -11
- data/spec/shared/custom_generator_cookbook.rb +117 -117
- data/spec/shared/fixture_cookbook_checksums.rb +47 -47
- data/spec/shared/setup_git_cookbooks.rb +53 -53
- data/spec/spec_helper.rb +49 -48
- data/spec/test_helpers.rb +84 -84
- data/spec/unit/chef_runner_spec.rb +111 -110
- data/spec/unit/cli_spec.rb +357 -357
- data/spec/unit/command/base_spec.rb +169 -136
- data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -181
- data/spec/unit/command/clean_policy_revisions_spec.rb +181 -181
- data/spec/unit/command/delete_policy_group_spec.rb +207 -207
- data/spec/unit/command/delete_policy_spec.rb +207 -207
- data/spec/unit/command/diff_spec.rb +312 -312
- data/spec/unit/command/env_spec.rb +52 -52
- data/spec/unit/command/exec_spec.rb +179 -179
- data/spec/unit/command/export_spec.rb +189 -189
- data/spec/unit/command/generate_spec.rb +142 -142
- data/spec/unit/command/generator_commands/app_spec.rb +169 -169
- data/spec/unit/command/generator_commands/attribute_spec.rb +32 -32
- data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
- data/spec/unit/command/generator_commands/cookbook_spec.rb +320 -240
- data/spec/unit/command/generator_commands/generator_generator_spec.rb +229 -0
- data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -32
- data/spec/unit/command/generator_commands/policyfile_spec.rb +125 -125
- data/spec/unit/command/generator_commands/recipe_spec.rb +34 -34
- data/spec/unit/command/generator_commands/repo_spec.rb +283 -283
- data/spec/unit/command/generator_commands/template_spec.rb +32 -32
- data/spec/unit/command/install_spec.rb +179 -179
- data/spec/unit/command/provision_spec.rb +592 -592
- data/spec/unit/command/push_archive_spec.rb +153 -153
- data/spec/unit/command/push_spec.rb +199 -199
- data/spec/unit/command/shell_init_spec.rb +329 -329
- data/spec/unit/command/show_policy_spec.rb +235 -235
- data/spec/unit/command/undelete_spec.rb +246 -246
- data/spec/unit/command/update_spec.rb +251 -251
- data/spec/unit/command/verify_spec.rb +323 -322
- data/spec/unit/commands_map_spec.rb +57 -57
- data/spec/unit/component_test_spec.rb +126 -126
- data/spec/unit/cookbook_metadata_spec.rb +98 -98
- data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
- data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
- data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
- data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
- data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
- data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
- data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
- data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
- data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
- data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
- data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
- data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
- data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
- data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
- data/spec/unit/fixtures/example_cookbook/README.md +4 -4
- data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
- data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
- data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
- data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
- data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
- data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
- data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
- data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
- data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
- data/spec/unit/generator_spec.rb +120 -120
- data/spec/unit/helpers_spec.rb +92 -92
- data/spec/unit/pager_spec.rb +119 -119
- data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +66 -66
- data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
- data/spec/unit/policyfile/community_cookbook_source_spec.rb +51 -51
- data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +252 -252
- data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
- data/spec/unit/policyfile/differ_spec.rb +687 -687
- data/spec/unit/policyfile/lister_spec.rb +272 -272
- data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
- data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
- data/spec/unit/policyfile/reports/install_spec.rb +115 -115
- data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
- data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
- data/spec/unit/policyfile/storage_config_spec.rb +172 -172
- data/spec/unit/policyfile/undo_record_spec.rb +260 -260
- data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
- data/spec/unit/policyfile/uploader_spec.rb +410 -410
- data/spec/unit/policyfile_demands_spec.rb +876 -876
- data/spec/unit/policyfile_evaluation_spec.rb +441 -441
- data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
- data/spec/unit/policyfile_lock_install_spec.rb +138 -138
- data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
- data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
- data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
- data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
- data/spec/unit/policyfile_services/export_repo_spec.rb +439 -416
- data/spec/unit/policyfile_services/install_spec.rb +191 -191
- data/spec/unit/policyfile_services/push_archive_spec.rb +345 -345
- data/spec/unit/policyfile_services/push_spec.rb +233 -233
- data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
- data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
- data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
- data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
- data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
- data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
- data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
- data/spec/unit/shell_out_spec.rb +34 -34
- metadata +9 -3
|
@@ -1,95 +1,95 @@
|
|
|
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 'chef-dk/exceptions'
|
|
19
|
-
require 'chef-dk/service_exceptions'
|
|
20
|
-
require 'chef-dk/policyfile/lister'
|
|
21
|
-
|
|
22
|
-
module ChefDK
|
|
23
|
-
module PolicyfileServices
|
|
24
|
-
class CleanPolicies
|
|
25
|
-
|
|
26
|
-
Orphan = Struct.new(:policy_name, :revision_id)
|
|
27
|
-
|
|
28
|
-
attr_reader :chef_config
|
|
29
|
-
attr_reader :ui
|
|
30
|
-
|
|
31
|
-
def initialize(config: nil, ui: nil)
|
|
32
|
-
@chef_config = config
|
|
33
|
-
@ui = ui
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def run
|
|
37
|
-
revisions_to_remove = orphaned_policies
|
|
38
|
-
|
|
39
|
-
if revisions_to_remove.empty?
|
|
40
|
-
ui.err("No policy revisions deleted")
|
|
41
|
-
return true
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
results = revisions_to_remove.map do |policy|
|
|
45
|
-
[ remove_policy(policy), policy ]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
failures = results.select { |result, _policy| result.kind_of?(Exception) }
|
|
49
|
-
|
|
50
|
-
unless failures.empty?
|
|
51
|
-
details = failures.map do |result, policy|
|
|
52
|
-
"- #{policy.policy_name} (#{policy.revision_id}): #{result.class} #{result}"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
message = "Failed to delete some policy revisions:\n" + details.join("\n") + "\n"
|
|
56
|
-
|
|
57
|
-
raise PolicyfileCleanError.new(message, MultipleErrors.new("multiple errors"))
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
true
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def orphaned_policies
|
|
64
|
-
policy_lister.policies_by_name.keys.inject([]) do |orphans, policy_name|
|
|
65
|
-
orphans + policy_lister.orphaned_revisions(policy_name).map do |revision_id|
|
|
66
|
-
Orphan.new(policy_name, revision_id)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
rescue => e
|
|
70
|
-
raise PolicyfileCleanError.new("Failed to list policies for cleaning.", e)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def policy_lister
|
|
74
|
-
@policy_lister ||= Policyfile::Lister.new(config: chef_config)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def http_client
|
|
78
|
-
@http_client ||= ChefDK::AuthenticatedHTTP.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 remove_policy(policy)
|
|
86
|
-
ui.msg("DELETE #{policy.policy_name} #{policy.revision_id}")
|
|
87
|
-
http_client.delete("/policies/#{policy.policy_name}/revisions/#{policy.revision_id}")
|
|
88
|
-
:ok
|
|
89
|
-
rescue => e
|
|
90
|
-
e
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2015 Chef Software Inc.
|
|
3
|
+
# License:: Apache License, Version 2.0
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
require 'chef-dk/exceptions'
|
|
19
|
+
require 'chef-dk/service_exceptions'
|
|
20
|
+
require 'chef-dk/policyfile/lister'
|
|
21
|
+
|
|
22
|
+
module ChefDK
|
|
23
|
+
module PolicyfileServices
|
|
24
|
+
class CleanPolicies
|
|
25
|
+
|
|
26
|
+
Orphan = Struct.new(:policy_name, :revision_id)
|
|
27
|
+
|
|
28
|
+
attr_reader :chef_config
|
|
29
|
+
attr_reader :ui
|
|
30
|
+
|
|
31
|
+
def initialize(config: nil, ui: nil)
|
|
32
|
+
@chef_config = config
|
|
33
|
+
@ui = ui
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def run
|
|
37
|
+
revisions_to_remove = orphaned_policies
|
|
38
|
+
|
|
39
|
+
if revisions_to_remove.empty?
|
|
40
|
+
ui.err("No policy revisions deleted")
|
|
41
|
+
return true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
results = revisions_to_remove.map do |policy|
|
|
45
|
+
[ remove_policy(policy), policy ]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
failures = results.select { |result, _policy| result.kind_of?(Exception) }
|
|
49
|
+
|
|
50
|
+
unless failures.empty?
|
|
51
|
+
details = failures.map do |result, policy|
|
|
52
|
+
"- #{policy.policy_name} (#{policy.revision_id}): #{result.class} #{result}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
message = "Failed to delete some policy revisions:\n" + details.join("\n") + "\n"
|
|
56
|
+
|
|
57
|
+
raise PolicyfileCleanError.new(message, MultipleErrors.new("multiple errors"))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def orphaned_policies
|
|
64
|
+
policy_lister.policies_by_name.keys.inject([]) do |orphans, policy_name|
|
|
65
|
+
orphans + policy_lister.orphaned_revisions(policy_name).map do |revision_id|
|
|
66
|
+
Orphan.new(policy_name, revision_id)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
rescue => e
|
|
70
|
+
raise PolicyfileCleanError.new("Failed to list policies for cleaning.", e)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def policy_lister
|
|
74
|
+
@policy_lister ||= Policyfile::Lister.new(config: chef_config)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def http_client
|
|
78
|
+
@http_client ||= ChefDK::AuthenticatedHTTP.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 remove_policy(policy)
|
|
86
|
+
ui.msg("DELETE #{policy.policy_name} #{policy.revision_id}")
|
|
87
|
+
http_client.delete("/policies/#{policy.policy_name}/revisions/#{policy.revision_id}")
|
|
88
|
+
:ok
|
|
89
|
+
rescue => e
|
|
90
|
+
e
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -1,125 +1,125 @@
|
|
|
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 PolicyfileServices
|
|
25
|
-
|
|
26
|
-
class CleanPolicyCookbooks
|
|
27
|
-
|
|
28
|
-
attr_reader :chef_config
|
|
29
|
-
|
|
30
|
-
attr_reader :ui
|
|
31
|
-
|
|
32
|
-
def initialize(config: nil, ui: nil)
|
|
33
|
-
@chef_config = config
|
|
34
|
-
@ui = ui
|
|
35
|
-
|
|
36
|
-
@all_cookbooks = nil
|
|
37
|
-
@active_cookbooks = nil
|
|
38
|
-
@all_policies = nil
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def run
|
|
42
|
-
gc_cookbooks
|
|
43
|
-
rescue => e
|
|
44
|
-
raise PolicyCookbookCleanError.new("Failed to cleanup policy cookbooks", e)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def gc_cookbooks
|
|
48
|
-
cookbooks = cookbooks_to_clean
|
|
49
|
-
|
|
50
|
-
if cookbooks.empty?
|
|
51
|
-
ui.msg("No cookbooks deleted.")
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
cookbooks.each do |name, identifiers|
|
|
55
|
-
identifiers.each do |identifier|
|
|
56
|
-
http_client.delete("/cookbook_artifacts/#{name}/#{identifier}")
|
|
57
|
-
ui.msg("DELETE #{name} #{identifier}")
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def all_cookbooks
|
|
64
|
-
cookbook_list = http_client.get("/cookbook_artifacts")
|
|
65
|
-
cookbook_list.inject({}) do |cb_map, (name, cb_info)|
|
|
66
|
-
cb_map[name] = cb_info["versions"].map { |v| v["identifier"] }
|
|
67
|
-
cb_map
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def active_cookbooks
|
|
72
|
-
policy_revisions_by_name.inject({}) do |cb_map, (policy_name, revision_ids)|
|
|
73
|
-
revision_ids.each do |revision_id|
|
|
74
|
-
cookbook_revisions_in_policy(policy_name, revision_id).each do |cb_name, identifier|
|
|
75
|
-
cb_map[cb_name] ||= Set.new
|
|
76
|
-
cb_map[cb_name] << identifier
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
cb_map
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def cookbooks_to_clean
|
|
84
|
-
active_cbs = active_cookbooks
|
|
85
|
-
|
|
86
|
-
all_cookbooks.inject({}) do |cb_map, (cb_name, revisions)|
|
|
87
|
-
active_revs = active_cbs[cb_name] || Set.new
|
|
88
|
-
inactive_revs = Set.new(revisions) - active_revs
|
|
89
|
-
cb_map[cb_name] = inactive_revs unless inactive_revs.empty?
|
|
90
|
-
|
|
91
|
-
cb_map
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# @api private
|
|
96
|
-
def policy_revisions_by_name
|
|
97
|
-
policies_list = http_client.get("/policies")
|
|
98
|
-
policies_list.inject({}) do |policies_map, (name, policy_info)|
|
|
99
|
-
policies_map[name] = policy_info["revisions"].keys
|
|
100
|
-
policies_map
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# @api private
|
|
105
|
-
def cookbook_revisions_in_policy(name, revision_id)
|
|
106
|
-
policy_revision_data = http_client.get("/policies/#{name}/revisions/#{revision_id}")
|
|
107
|
-
|
|
108
|
-
policy_revision_data["cookbook_locks"].inject({}) do |cb_map, (cb_name, lock_info)|
|
|
109
|
-
cb_map[cb_name] = lock_info["identifier"]
|
|
110
|
-
cb_map
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# @api private
|
|
115
|
-
# An instance of ChefDK::AuthenticatedHTTP configured with the user's
|
|
116
|
-
# server URL and credentials.
|
|
117
|
-
def http_client
|
|
118
|
-
@http_client ||= ChefDK::AuthenticatedHTTP.new(chef_config.chef_server_url,
|
|
119
|
-
signing_key_filename: chef_config.client_key,
|
|
120
|
-
client_name: chef_config.node_name)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
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 PolicyfileServices
|
|
25
|
+
|
|
26
|
+
class CleanPolicyCookbooks
|
|
27
|
+
|
|
28
|
+
attr_reader :chef_config
|
|
29
|
+
|
|
30
|
+
attr_reader :ui
|
|
31
|
+
|
|
32
|
+
def initialize(config: nil, ui: nil)
|
|
33
|
+
@chef_config = config
|
|
34
|
+
@ui = ui
|
|
35
|
+
|
|
36
|
+
@all_cookbooks = nil
|
|
37
|
+
@active_cookbooks = nil
|
|
38
|
+
@all_policies = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def run
|
|
42
|
+
gc_cookbooks
|
|
43
|
+
rescue => e
|
|
44
|
+
raise PolicyCookbookCleanError.new("Failed to cleanup policy cookbooks", e)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def gc_cookbooks
|
|
48
|
+
cookbooks = cookbooks_to_clean
|
|
49
|
+
|
|
50
|
+
if cookbooks.empty?
|
|
51
|
+
ui.msg("No cookbooks deleted.")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
cookbooks.each do |name, identifiers|
|
|
55
|
+
identifiers.each do |identifier|
|
|
56
|
+
http_client.delete("/cookbook_artifacts/#{name}/#{identifier}")
|
|
57
|
+
ui.msg("DELETE #{name} #{identifier}")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def all_cookbooks
|
|
64
|
+
cookbook_list = http_client.get("/cookbook_artifacts")
|
|
65
|
+
cookbook_list.inject({}) do |cb_map, (name, cb_info)|
|
|
66
|
+
cb_map[name] = cb_info["versions"].map { |v| v["identifier"] }
|
|
67
|
+
cb_map
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def active_cookbooks
|
|
72
|
+
policy_revisions_by_name.inject({}) do |cb_map, (policy_name, revision_ids)|
|
|
73
|
+
revision_ids.each do |revision_id|
|
|
74
|
+
cookbook_revisions_in_policy(policy_name, revision_id).each do |cb_name, identifier|
|
|
75
|
+
cb_map[cb_name] ||= Set.new
|
|
76
|
+
cb_map[cb_name] << identifier
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
cb_map
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def cookbooks_to_clean
|
|
84
|
+
active_cbs = active_cookbooks
|
|
85
|
+
|
|
86
|
+
all_cookbooks.inject({}) do |cb_map, (cb_name, revisions)|
|
|
87
|
+
active_revs = active_cbs[cb_name] || Set.new
|
|
88
|
+
inactive_revs = Set.new(revisions) - active_revs
|
|
89
|
+
cb_map[cb_name] = inactive_revs unless inactive_revs.empty?
|
|
90
|
+
|
|
91
|
+
cb_map
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @api private
|
|
96
|
+
def policy_revisions_by_name
|
|
97
|
+
policies_list = http_client.get("/policies")
|
|
98
|
+
policies_list.inject({}) do |policies_map, (name, policy_info)|
|
|
99
|
+
policies_map[name] = policy_info["revisions"].keys
|
|
100
|
+
policies_map
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @api private
|
|
105
|
+
def cookbook_revisions_in_policy(name, revision_id)
|
|
106
|
+
policy_revision_data = http_client.get("/policies/#{name}/revisions/#{revision_id}")
|
|
107
|
+
|
|
108
|
+
policy_revision_data["cookbook_locks"].inject({}) do |cb_map, (cb_name, lock_info)|
|
|
109
|
+
cb_map[cb_name] = lock_info["identifier"]
|
|
110
|
+
cb_map
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# @api private
|
|
115
|
+
# An instance of ChefDK::AuthenticatedHTTP configured with the user's
|
|
116
|
+
# server URL and credentials.
|
|
117
|
+
def http_client
|
|
118
|
+
@http_client ||= ChefDK::AuthenticatedHTTP.new(chef_config.chef_server_url,
|
|
119
|
+
signing_key_filename: chef_config.client_key,
|
|
120
|
+
client_name: chef_config.node_name)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
@@ -1,281 +1,309 @@
|
|
|
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 'fileutils'
|
|
19
|
-
require 'tmpdir'
|
|
20
|
-
require 'zlib'
|
|
21
|
-
|
|
22
|
-
require 'archive/tar/minitar'
|
|
23
|
-
|
|
24
|
-
require 'chef-dk/service_exceptions'
|
|
25
|
-
require 'chef-dk/policyfile_lock'
|
|
26
|
-
require 'chef-dk/policyfile/storage_config'
|
|
27
|
-
|
|
28
|
-
module ChefDK
|
|
29
|
-
module PolicyfileServices
|
|
30
|
-
|
|
31
|
-
class ExportRepo
|
|
32
|
-
|
|
33
|
-
# Policy groups provide namespaces for policies so that a Chef Server can
|
|
34
|
-
# have multiple active iterations of a policy at once, but we don't need
|
|
35
|
-
# this when serving a single exported policy via Chef Zero, so hardcode
|
|
36
|
-
# it to a "well known" value:
|
|
37
|
-
POLICY_GROUP = 'local'.freeze
|
|
38
|
-
|
|
39
|
-
include Policyfile::StorageConfigDelegation
|
|
40
|
-
|
|
41
|
-
attr_reader :storage_config
|
|
42
|
-
attr_reader :root_dir
|
|
43
|
-
attr_reader :export_dir
|
|
44
|
-
|
|
45
|
-
def initialize(policyfile: nil, export_dir: nil, root_dir: nil, archive: false, force: false)
|
|
46
|
-
@root_dir = root_dir
|
|
47
|
-
@export_dir = File.expand_path(export_dir)
|
|
48
|
-
@archive = archive
|
|
49
|
-
@force_export = force
|
|
50
|
-
|
|
51
|
-
@policy_data = nil
|
|
52
|
-
@policyfile_lock = nil
|
|
53
|
-
|
|
54
|
-
policyfile_rel_path = policyfile || "Policyfile.rb"
|
|
55
|
-
policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
|
|
56
|
-
@storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
|
|
57
|
-
|
|
58
|
-
@staging_dir = nil
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def archive?
|
|
62
|
-
@archive
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def policy_name
|
|
66
|
-
policyfile_lock.name
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def run
|
|
70
|
-
assert_lockfile_exists!
|
|
71
|
-
assert_export_dir_clean!
|
|
72
|
-
|
|
73
|
-
validate_lockfile
|
|
74
|
-
write_updated_lockfile
|
|
75
|
-
export
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def policy_data
|
|
79
|
-
@policy_data ||= FFI_Yajl::Parser.parse(IO.read(policyfile_lock_expanded_path))
|
|
80
|
-
rescue => error
|
|
81
|
-
raise PolicyfileExportRepoError.new("Error reading lockfile #{policyfile_lock_expanded_path}", error)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def policyfile_lock
|
|
85
|
-
@policyfile_lock || validate_lockfile
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def archive_file_location
|
|
89
|
-
return nil unless archive?
|
|
90
|
-
filename = "#{policyfile_lock.name}-#{policyfile_lock.revision_id}.tgz"
|
|
91
|
-
File.join(export_dir, filename)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def export
|
|
95
|
-
with_staging_dir do
|
|
96
|
-
create_repo_structure
|
|
97
|
-
copy_cookbooks
|
|
98
|
-
create_policyfile_data_item
|
|
99
|
-
copy_policyfile_lock
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
FileUtils.mkdir_p(
|
|
141
|
-
FileUtils.mkdir_p(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
FileUtils.
|
|
156
|
-
|
|
157
|
-
metadata
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
|
|
177
|
-
#
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
def
|
|
270
|
-
File.join(
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
def
|
|
274
|
-
File.join(
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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 'fileutils'
|
|
19
|
+
require 'tmpdir'
|
|
20
|
+
require 'zlib'
|
|
21
|
+
|
|
22
|
+
require 'archive/tar/minitar'
|
|
23
|
+
|
|
24
|
+
require 'chef-dk/service_exceptions'
|
|
25
|
+
require 'chef-dk/policyfile_lock'
|
|
26
|
+
require 'chef-dk/policyfile/storage_config'
|
|
27
|
+
|
|
28
|
+
module ChefDK
|
|
29
|
+
module PolicyfileServices
|
|
30
|
+
|
|
31
|
+
class ExportRepo
|
|
32
|
+
|
|
33
|
+
# Policy groups provide namespaces for policies so that a Chef Server can
|
|
34
|
+
# have multiple active iterations of a policy at once, but we don't need
|
|
35
|
+
# this when serving a single exported policy via Chef Zero, so hardcode
|
|
36
|
+
# it to a "well known" value:
|
|
37
|
+
POLICY_GROUP = 'local'.freeze
|
|
38
|
+
|
|
39
|
+
include Policyfile::StorageConfigDelegation
|
|
40
|
+
|
|
41
|
+
attr_reader :storage_config
|
|
42
|
+
attr_reader :root_dir
|
|
43
|
+
attr_reader :export_dir
|
|
44
|
+
|
|
45
|
+
def initialize(policyfile: nil, export_dir: nil, root_dir: nil, archive: false, force: false)
|
|
46
|
+
@root_dir = root_dir
|
|
47
|
+
@export_dir = File.expand_path(export_dir)
|
|
48
|
+
@archive = archive
|
|
49
|
+
@force_export = force
|
|
50
|
+
|
|
51
|
+
@policy_data = nil
|
|
52
|
+
@policyfile_lock = nil
|
|
53
|
+
|
|
54
|
+
policyfile_rel_path = policyfile || "Policyfile.rb"
|
|
55
|
+
policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
|
|
56
|
+
@storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
|
|
57
|
+
|
|
58
|
+
@staging_dir = nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def archive?
|
|
62
|
+
@archive
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def policy_name
|
|
66
|
+
policyfile_lock.name
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def run
|
|
70
|
+
assert_lockfile_exists!
|
|
71
|
+
assert_export_dir_clean!
|
|
72
|
+
|
|
73
|
+
validate_lockfile
|
|
74
|
+
write_updated_lockfile
|
|
75
|
+
export
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def policy_data
|
|
79
|
+
@policy_data ||= FFI_Yajl::Parser.parse(IO.read(policyfile_lock_expanded_path))
|
|
80
|
+
rescue => error
|
|
81
|
+
raise PolicyfileExportRepoError.new("Error reading lockfile #{policyfile_lock_expanded_path}", error)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def policyfile_lock
|
|
85
|
+
@policyfile_lock || validate_lockfile
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def archive_file_location
|
|
89
|
+
return nil unless archive?
|
|
90
|
+
filename = "#{policyfile_lock.name}-#{policyfile_lock.revision_id}.tgz"
|
|
91
|
+
File.join(export_dir, filename)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def export
|
|
95
|
+
with_staging_dir do
|
|
96
|
+
create_repo_structure
|
|
97
|
+
copy_cookbooks
|
|
98
|
+
create_policyfile_data_item
|
|
99
|
+
copy_policyfile_lock
|
|
100
|
+
create_client_rb
|
|
101
|
+
if archive?
|
|
102
|
+
create_archive
|
|
103
|
+
else
|
|
104
|
+
mv_staged_repo
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
rescue => error
|
|
108
|
+
msg = "Failed to export policy (in #{policyfile_filename}) to #{export_dir}"
|
|
109
|
+
raise PolicyfileExportRepoError.new(msg, error)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
def with_staging_dir
|
|
115
|
+
p = Process.pid
|
|
116
|
+
t = Time.new.utc.strftime("%Y%m%d%H%M%S")
|
|
117
|
+
Dir.mktmpdir("chefdk-export-#{p}-#{t}") do |d|
|
|
118
|
+
begin
|
|
119
|
+
@staging_dir = d
|
|
120
|
+
yield
|
|
121
|
+
ensure
|
|
122
|
+
@staging_dir = nil
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def create_archive
|
|
128
|
+
Zlib::GzipWriter.open(archive_file_location) do |gz_file|
|
|
129
|
+
Dir.chdir(staging_dir) do
|
|
130
|
+
Archive::Tar::Minitar.pack(".", gz_file)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def staging_dir
|
|
136
|
+
@staging_dir
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def create_repo_structure
|
|
140
|
+
FileUtils.mkdir_p(export_dir)
|
|
141
|
+
FileUtils.mkdir_p(cookbooks_staging_dir)
|
|
142
|
+
FileUtils.mkdir_p(policyfiles_data_bag_staging_dir)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def copy_cookbooks
|
|
146
|
+
policyfile_lock.cookbook_locks.each do |name, lock|
|
|
147
|
+
copy_cookbook(lock)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def copy_cookbook(lock)
|
|
152
|
+
dirname = "#{lock.name}-#{lock.dotted_decimal_identifier}"
|
|
153
|
+
export_path = File.join(staging_dir, "cookbooks", dirname)
|
|
154
|
+
metadata_rb_path = File.join(export_path, "metadata.rb")
|
|
155
|
+
FileUtils.cp_r(lock.cookbook_path, export_path)
|
|
156
|
+
FileUtils.rm_f(metadata_rb_path)
|
|
157
|
+
metadata = lock.cookbook_version.metadata
|
|
158
|
+
metadata.version(lock.dotted_decimal_identifier)
|
|
159
|
+
|
|
160
|
+
metadata_json_path = File.join(export_path, "metadata.json")
|
|
161
|
+
|
|
162
|
+
File.open(metadata_json_path, "wb+") do |f|
|
|
163
|
+
f.print(FFI_Yajl::Encoder.encode(metadata.to_hash, pretty: true ))
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def create_policyfile_data_item
|
|
168
|
+
lock_data = policyfile_lock.to_lock.dup
|
|
169
|
+
|
|
170
|
+
lock_data["id"] = policy_id
|
|
171
|
+
|
|
172
|
+
data_item = {
|
|
173
|
+
"id" => policy_id,
|
|
174
|
+
"name" => "data_bag_item_policyfiles_#{policy_id}",
|
|
175
|
+
"data_bag" => "policyfiles",
|
|
176
|
+
"raw_data" => lock_data,
|
|
177
|
+
# we'd prefer to leave this out, but the "compatibility mode"
|
|
178
|
+
# implementation in chef-client relies on magical class inflation
|
|
179
|
+
"json_class" => "Chef::DataBagItem"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
File.open(item_path, "wb+") do |f|
|
|
183
|
+
f.print(FFI_Yajl::Encoder.encode(data_item, pretty: true ))
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def copy_policyfile_lock
|
|
188
|
+
File.open(lockfile_staging_path, "wb+") do |f|
|
|
189
|
+
f.print(FFI_Yajl::Encoder.encode(policyfile_lock.to_lock, pretty: true ))
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def create_client_rb
|
|
194
|
+
File.open(client_rb_staging_path, "wb+") do |f|
|
|
195
|
+
f.print( <<-CONFIG )
|
|
196
|
+
### Chef Client Configuration ###
|
|
197
|
+
# The settings in this file will configure chef to apply the exported policy in
|
|
198
|
+
# this directory. To use it, run:
|
|
199
|
+
#
|
|
200
|
+
# chef-client -c client.rb -z
|
|
201
|
+
#
|
|
202
|
+
|
|
203
|
+
use_policyfile true
|
|
204
|
+
|
|
205
|
+
# compatibility mode settings are used because chef-zero doesn't yet support
|
|
206
|
+
# native mode:
|
|
207
|
+
deployment_group '#{policy_name}-local'
|
|
208
|
+
versioned_cookbooks true
|
|
209
|
+
policy_document_native_api false
|
|
210
|
+
|
|
211
|
+
CONFIG
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def mv_staged_repo
|
|
216
|
+
# If we got here, either these dirs are empty/don't exist or force is
|
|
217
|
+
# set to true.
|
|
218
|
+
FileUtils.rm_rf(cookbooks_dir)
|
|
219
|
+
FileUtils.rm_rf(policyfiles_data_bag_dir)
|
|
220
|
+
|
|
221
|
+
FileUtils.mv(cookbooks_staging_dir, export_dir)
|
|
222
|
+
FileUtils.mkdir_p(export_data_bag_dir)
|
|
223
|
+
FileUtils.mv(policyfiles_data_bag_staging_dir, export_data_bag_dir)
|
|
224
|
+
FileUtils.mv(lockfile_staging_path, export_dir)
|
|
225
|
+
FileUtils.mv(client_rb_staging_path, export_dir)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def validate_lockfile
|
|
229
|
+
return @policyfile_lock if @policyfile_lock
|
|
230
|
+
@policyfile_lock = ChefDK::PolicyfileLock.new(storage_config).build_from_lock_data(policy_data)
|
|
231
|
+
# TODO: enumerate any cookbook that have been updated
|
|
232
|
+
@policyfile_lock.validate_cookbooks!
|
|
233
|
+
@policyfile_lock
|
|
234
|
+
rescue PolicyfileExportRepoError
|
|
235
|
+
raise
|
|
236
|
+
rescue => error
|
|
237
|
+
raise PolicyfileExportRepoError.new("Invalid lockfile data", error)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def write_updated_lockfile
|
|
241
|
+
File.open(policyfile_lock_expanded_path, "wb+") do |f|
|
|
242
|
+
f.print(FFI_Yajl::Encoder.encode(policyfile_lock.to_lock, pretty: true ))
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def assert_lockfile_exists!
|
|
247
|
+
unless File.exist?(policyfile_lock_expanded_path)
|
|
248
|
+
raise LockfileNotFound, "No lockfile at #{policyfile_lock_expanded_path} - you need to run `install` before `push`"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def assert_export_dir_clean!
|
|
253
|
+
if !force_export? && !conflicting_fs_entries.empty? && !archive?
|
|
254
|
+
msg = "Export dir (#{export_dir}) not clean. Refusing to export. (Conflicting files: #{conflicting_fs_entries.join(', ')})"
|
|
255
|
+
raise ExportDirNotEmpty, msg
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def force_export?
|
|
260
|
+
@force_export
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def conflicting_fs_entries
|
|
264
|
+
Dir.glob(File.join(cookbooks_dir, "*")) +
|
|
265
|
+
Dir.glob(File.join(policyfiles_data_bag_dir, "*")) +
|
|
266
|
+
Dir.glob(File.join(export_dir, "Policyfile.lock.json"))
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def cookbooks_dir
|
|
270
|
+
File.join(export_dir, "cookbooks")
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def export_data_bag_dir
|
|
274
|
+
File.join(export_dir, "data_bags")
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def policyfiles_data_bag_dir
|
|
278
|
+
File.join(export_data_bag_dir, "policyfiles")
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def policy_id
|
|
282
|
+
"#{policyfile_lock.name}-#{POLICY_GROUP}"
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def item_path
|
|
286
|
+
File.join(staging_dir, "data_bags", "policyfiles", "#{policy_id}.json")
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def cookbooks_staging_dir
|
|
290
|
+
File.join(staging_dir, "cookbooks")
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def policyfiles_data_bag_staging_dir
|
|
294
|
+
File.join(staging_dir, "data_bags", "policyfiles")
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def lockfile_staging_path
|
|
298
|
+
File.join(staging_dir, "Policyfile.lock.json")
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def client_rb_staging_path
|
|
302
|
+
File.join(staging_dir, "client.rb")
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|