chef-cli 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +32 -0
- data/LICENSE +201 -0
- data/Rakefile +70 -0
- data/bin/chef +25 -0
- data/chef-cli.gemspec +53 -0
- data/lib/chef-cli.rb +19 -0
- data/lib/chef-cli/authenticated_http.rb +22 -0
- data/lib/chef-cli/builtin_commands.rb +62 -0
- data/lib/chef-cli/chef_runner.rb +114 -0
- data/lib/chef-cli/chef_server_api_multi.rb +73 -0
- data/lib/chef-cli/cli.rb +206 -0
- data/lib/chef-cli/command/base.rb +89 -0
- data/lib/chef-cli/command/clean_policy_cookbooks.rb +115 -0
- data/lib/chef-cli/command/clean_policy_revisions.rb +112 -0
- data/lib/chef-cli/command/delete_policy.rb +121 -0
- data/lib/chef-cli/command/delete_policy_group.rb +121 -0
- data/lib/chef-cli/command/describe_cookbook.rb +98 -0
- data/lib/chef-cli/command/diff.rb +316 -0
- data/lib/chef-cli/command/env.rb +99 -0
- data/lib/chef-cli/command/exec.rb +45 -0
- data/lib/chef-cli/command/export.rb +156 -0
- data/lib/chef-cli/command/gem.rb +48 -0
- data/lib/chef-cli/command/generate.rb +123 -0
- data/lib/chef-cli/command/generator_commands.rb +83 -0
- data/lib/chef-cli/command/generator_commands/attribute.rb +37 -0
- data/lib/chef-cli/command/generator_commands/base.rb +157 -0
- data/lib/chef-cli/command/generator_commands/build_cookbook.rb +126 -0
- data/lib/chef-cli/command/generator_commands/chef_exts/generator_desc_resource.rb +40 -0
- data/lib/chef-cli/command/generator_commands/chef_exts/quieter_doc_formatter.rb +38 -0
- data/lib/chef-cli/command/generator_commands/chef_exts/recipe_dsl_ext.rb +39 -0
- data/lib/chef-cli/command/generator_commands/cookbook.rb +251 -0
- data/lib/chef-cli/command/generator_commands/cookbook_code_file.rb +100 -0
- data/lib/chef-cli/command/generator_commands/cookbook_file.rb +46 -0
- data/lib/chef-cli/command/generator_commands/generator_generator.rb +175 -0
- data/lib/chef-cli/command/generator_commands/helpers.rb +37 -0
- data/lib/chef-cli/command/generator_commands/policyfile.rb +125 -0
- data/lib/chef-cli/command/generator_commands/recipe.rb +37 -0
- data/lib/chef-cli/command/generator_commands/repo.rb +140 -0
- data/lib/chef-cli/command/generator_commands/resource.rb +37 -0
- data/lib/chef-cli/command/generator_commands/template.rb +47 -0
- data/lib/chef-cli/command/install.rb +121 -0
- data/lib/chef-cli/command/provision.rb +38 -0
- data/lib/chef-cli/command/push.rb +118 -0
- data/lib/chef-cli/command/push_archive.rb +126 -0
- data/lib/chef-cli/command/shell_init.rb +185 -0
- data/lib/chef-cli/command/show_policy.rb +164 -0
- data/lib/chef-cli/command/undelete.rb +155 -0
- data/lib/chef-cli/command/update.rb +140 -0
- data/lib/chef-cli/command/verify.rb +548 -0
- data/lib/chef-cli/commands_map.rb +113 -0
- data/lib/chef-cli/completions/bash.sh.erb +5 -0
- data/lib/chef-cli/completions/chef.fish.erb +10 -0
- data/lib/chef-cli/completions/zsh.zsh.erb +21 -0
- data/lib/chef-cli/component_test.rb +226 -0
- data/lib/chef-cli/configurable.rb +88 -0
- data/lib/chef-cli/cookbook_metadata.rb +45 -0
- data/lib/chef-cli/cookbook_omnifetch.rb +32 -0
- data/lib/chef-cli/cookbook_profiler/git.rb +152 -0
- data/lib/chef-cli/cookbook_profiler/identifiers.rb +72 -0
- data/lib/chef-cli/cookbook_profiler/null_scm.rb +31 -0
- data/lib/chef-cli/dist.rb +31 -0
- data/lib/chef-cli/exceptions.rb +153 -0
- data/lib/chef-cli/generator.rb +165 -0
- data/lib/chef-cli/helpers.rb +170 -0
- data/lib/chef-cli/pager.rb +104 -0
- data/lib/chef-cli/policyfile/artifactory_cookbook_source.rb +102 -0
- data/lib/chef-cli/policyfile/attribute_merge_checker.rb +110 -0
- data/lib/chef-cli/policyfile/chef_repo_cookbook_source.rb +138 -0
- data/lib/chef-cli/policyfile/chef_server_cookbook_source.rb +99 -0
- data/lib/chef-cli/policyfile/chef_server_lock_fetcher.rb +167 -0
- data/lib/chef-cli/policyfile/community_cookbook_source.rb +95 -0
- data/lib/chef-cli/policyfile/comparison_base.rb +123 -0
- data/lib/chef-cli/policyfile/cookbook_location_specification.rb +154 -0
- data/lib/chef-cli/policyfile/cookbook_locks.rb +466 -0
- data/lib/chef-cli/policyfile/cookbook_sources.rb +23 -0
- data/lib/chef-cli/policyfile/delivery_supermarket_source.rb +89 -0
- data/lib/chef-cli/policyfile/differ.rb +263 -0
- data/lib/chef-cli/policyfile/dsl.rb +288 -0
- data/lib/chef-cli/policyfile/git_lock_fetcher.rb +265 -0
- data/lib/chef-cli/policyfile/included_policies_cookbook_source.rb +156 -0
- data/lib/chef-cli/policyfile/lister.rb +229 -0
- data/lib/chef-cli/policyfile/local_lock_fetcher.rb +132 -0
- data/lib/chef-cli/policyfile/lock_applier.rb +80 -0
- data/lib/chef-cli/policyfile/lock_fetcher_mixin.rb +37 -0
- data/lib/chef-cli/policyfile/null_cookbook_source.rb +49 -0
- data/lib/chef-cli/policyfile/policyfile_location_specification.rb +128 -0
- data/lib/chef-cli/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -0
- data/lib/chef-cli/policyfile/remote_lock_fetcher.rb +108 -0
- data/lib/chef-cli/policyfile/reports/install.rb +69 -0
- data/lib/chef-cli/policyfile/reports/table_printer.rb +57 -0
- data/lib/chef-cli/policyfile/reports/upload.rb +70 -0
- data/lib/chef-cli/policyfile/solution_dependencies.rb +311 -0
- data/lib/chef-cli/policyfile/source_uri.rb +57 -0
- data/lib/chef-cli/policyfile/storage_config.rb +112 -0
- data/lib/chef-cli/policyfile/undo_record.rb +139 -0
- data/lib/chef-cli/policyfile/undo_stack.rb +128 -0
- data/lib/chef-cli/policyfile/uploader.rb +222 -0
- data/lib/chef-cli/policyfile_compiler.rb +528 -0
- data/lib/chef-cli/policyfile_lock.rb +581 -0
- data/lib/chef-cli/policyfile_services/clean_policies.rb +95 -0
- data/lib/chef-cli/policyfile_services/clean_policy_cookbooks.rb +123 -0
- data/lib/chef-cli/policyfile_services/export_repo.rb +419 -0
- data/lib/chef-cli/policyfile_services/install.rb +167 -0
- data/lib/chef-cli/policyfile_services/push.rb +112 -0
- data/lib/chef-cli/policyfile_services/push_archive.rb +164 -0
- data/lib/chef-cli/policyfile_services/rm_policy.rb +141 -0
- data/lib/chef-cli/policyfile_services/rm_policy_group.rb +85 -0
- data/lib/chef-cli/policyfile_services/show_policy.rb +234 -0
- data/lib/chef-cli/policyfile_services/undelete.rb +108 -0
- data/lib/chef-cli/policyfile_services/update_attributes.rb +110 -0
- data/lib/chef-cli/service_exception_inspectors.rb +24 -0
- data/lib/chef-cli/service_exception_inspectors/base.rb +39 -0
- data/lib/chef-cli/service_exception_inspectors/http.rb +119 -0
- data/lib/chef-cli/service_exceptions.rb +142 -0
- data/lib/chef-cli/shell_out.rb +36 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/Berksfile +3 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/README.md +146 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/kitchen.yml +21 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +8 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/chefignore +110 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/cookbook_readmes/README.md +66 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/delivery-config.json +17 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/delivery-project.toml +34 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/gitignore +22 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/README.md +20 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +6 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +4 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/environments/README.md +9 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/environments/example.json +13 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/policyfiles/README.md +24 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/roles/README.md +9 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/repo/roles/example.json +13 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/spec_helper.rb +2 -0
- data/lib/chef-cli/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -0
- data/lib/chef-cli/skeletons/code_generator/metadata.rb +8 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/attribute.rb +11 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/build_cookbook.rb +175 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/cookbook.rb +167 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/cookbook_file.rb +23 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/helpers.rb +19 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/policyfile.rb +7 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/recipe.rb +50 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/repo.rb +71 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/resource.rb +12 -0
- data/lib/chef-cli/skeletons/code_generator/recipes/template.rb +31 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/CHANGELOG.md.erb +11 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/README.md.erb +4 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +9 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/helpers.rb.erb +39 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +16 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen.yml.erb +38 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen_dokken.yml.erb +36 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +32 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/metadata.rb.erb +20 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/recipe.rb.erb +5 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/recipe_spec.rb.erb +29 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/resource.rb.erb +1 -0
- data/lib/chef-cli/skeletons/code_generator/templates/default/template.erb +0 -0
- data/lib/chef-cli/ui.rb +57 -0
- data/lib/chef-cli/version.rb +20 -0
- data/lib/kitchen/provisioner/policyfile_zero.rb +195 -0
- data/spec/shared/a_file_generator.rb +125 -0
- data/spec/shared/a_generated_file.rb +12 -0
- data/spec/shared/command_with_ui_object.rb +11 -0
- data/spec/shared/custom_generator_cookbook.rb +136 -0
- data/spec/shared/fixture_cookbook_checksums.rb +46 -0
- data/spec/shared/setup_git_committer_config.rb +54 -0
- data/spec/shared/setup_git_cookbooks.rb +53 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/test_helpers.rb +84 -0
- data/spec/unit/chef_runner_spec.rb +139 -0
- data/spec/unit/chef_server_api_multi_spec.rb +120 -0
- data/spec/unit/cli_spec.rb +375 -0
- data/spec/unit/command/base_spec.rb +195 -0
- data/spec/unit/command/clean_policy_cookbooks_spec.rb +180 -0
- data/spec/unit/command/clean_policy_revisions_spec.rb +180 -0
- data/spec/unit/command/delete_policy_group_spec.rb +206 -0
- data/spec/unit/command/delete_policy_spec.rb +206 -0
- data/spec/unit/command/diff_spec.rb +311 -0
- data/spec/unit/command/env_spec.rb +86 -0
- data/spec/unit/command/exec_spec.rb +178 -0
- data/spec/unit/command/export_spec.rb +199 -0
- data/spec/unit/command/generate_spec.rb +142 -0
- data/spec/unit/command/generator_commands/attribute_spec.rb +31 -0
- data/spec/unit/command/generator_commands/base_spec.rb +180 -0
- data/spec/unit/command/generator_commands/build_cookbook_spec.rb +377 -0
- data/spec/unit/command/generator_commands/chef_exts/generator_desc_resource_spec.rb +77 -0
- data/spec/unit/command/generator_commands/chef_exts/recipe_dsl_ext_spec.rb +111 -0
- data/spec/unit/command/generator_commands/cookbook_file_spec.rb +31 -0
- data/spec/unit/command/generator_commands/cookbook_spec.rb +769 -0
- data/spec/unit/command/generator_commands/generator_generator_spec.rb +227 -0
- data/spec/unit/command/generator_commands/helpers_spec.rb +31 -0
- data/spec/unit/command/generator_commands/policyfile_spec.rb +223 -0
- data/spec/unit/command/generator_commands/recipe_spec.rb +37 -0
- data/spec/unit/command/generator_commands/repo_spec.rb +374 -0
- data/spec/unit/command/generator_commands/resource_spec.rb +31 -0
- data/spec/unit/command/generator_commands/template_spec.rb +31 -0
- data/spec/unit/command/install_spec.rb +179 -0
- data/spec/unit/command/push_archive_spec.rb +153 -0
- data/spec/unit/command/push_spec.rb +198 -0
- data/spec/unit/command/shell_init_spec.rb +339 -0
- data/spec/unit/command/show_policy_spec.rb +234 -0
- data/spec/unit/command/undelete_spec.rb +244 -0
- data/spec/unit/command/update_spec.rb +283 -0
- data/spec/unit/command/verify_spec.rb +341 -0
- data/spec/unit/commands_map_spec.rb +57 -0
- data/spec/unit/component_test_spec.rb +128 -0
- data/spec/unit/configurable_spec.rb +68 -0
- data/spec/unit/cookbook_metadata_spec.rb +96 -0
- data/spec/unit/cookbook_profiler/git_spec.rb +176 -0
- data/spec/unit/cookbook_profiler/identifiers_spec.rb +81 -0
- data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -0
- data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -0
- data/spec/unit/fixtures/command/cli_test_command.rb +26 -0
- data/spec/unit/fixtures/command/explicit_path_example.rb +7 -0
- data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -0
- data/spec/unit/fixtures/configurable/test_configurable.rb +10 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -0
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -0
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -0
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -0
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -0
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -0
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -0
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -0
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -0
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/kitchen.yml +16 -0
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -0
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -0
- data/spec/unit/fixtures/cookbooks_api/chef_server_universe.json +56 -0
- data/spec/unit/fixtures/cookbooks_api/pruned_chef_server_universe.json +30 -0
- data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1322 -0
- data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -0
- data/spec/unit/fixtures/cookbooks_api/universe.json +1 -0
- data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +33 -0
- data/spec/unit/fixtures/dev_cookbooks/README.md +16 -0
- data/spec/unit/fixtures/dev_cookbooks/bar-cookbook.gitbundle +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/bin/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/bin/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_component/bin/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/berkshelf/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/test-kitchen/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/bin/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/bin/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef-dk/.keep +0 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -0
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/bin/.keep +0 -0
- data/spec/unit/fixtures/example_app/Policyfile.rb +0 -0
- data/spec/unit/fixtures/example_cookbook/.gitignore +17 -0
- data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -0
- data/spec/unit/fixtures/example_cookbook/Berksfile +3 -0
- data/spec/unit/fixtures/example_cookbook/README.md +4 -0
- data/spec/unit/fixtures/example_cookbook/chefignore +96 -0
- data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -0
- data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -0
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -0
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -0
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -0
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/extra/extra_file.txt +0 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
- data/spec/unit/generator_spec.rb +119 -0
- data/spec/unit/pager_spec.rb +117 -0
- data/spec/unit/policyfile/artifactory_cookbook_source_spec.rb +59 -0
- data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -0
- data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -0
- data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +55 -0
- data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -0
- data/spec/unit/policyfile/community_cookbook_source_spec.rb +83 -0
- data/spec/unit/policyfile/comparison_base_spec.rb +340 -0
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +347 -0
- data/spec/unit/policyfile/cookbook_locks_spec.rb +527 -0
- data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +129 -0
- data/spec/unit/policyfile/differ_spec.rb +686 -0
- data/spec/unit/policyfile/git_lock_fetcher_spec.rb +155 -0
- data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -0
- data/spec/unit/policyfile/lister_spec.rb +268 -0
- data/spec/unit/policyfile/local_lock_fetcher_spec.rb +199 -0
- data/spec/unit/policyfile/lock_applier_spec.rb +100 -0
- data/spec/unit/policyfile/lock_fetcher_mixin_spec.rb +60 -0
- data/spec/unit/policyfile/null_cookbook_source_spec.rb +34 -0
- data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -0
- data/spec/unit/policyfile/remote_lock_fetcher_spec.rb +129 -0
- data/spec/unit/policyfile/reports/install_spec.rb +114 -0
- data/spec/unit/policyfile/reports/upload_spec.rb +94 -0
- data/spec/unit/policyfile/solution_dependencies_spec.rb +170 -0
- data/spec/unit/policyfile/source_uri_spec.rb +36 -0
- data/spec/unit/policyfile/storage_config_spec.rb +180 -0
- data/spec/unit/policyfile/undo_record_spec.rb +258 -0
- data/spec/unit/policyfile/undo_stack_spec.rb +265 -0
- data/spec/unit/policyfile/uploader_spec.rb +410 -0
- data/spec/unit/policyfile_demands_spec.rb +1197 -0
- data/spec/unit/policyfile_evaluation_spec.rb +628 -0
- data/spec/unit/policyfile_includes_dsl_spec.rb +220 -0
- data/spec/unit/policyfile_includes_spec.rb +720 -0
- data/spec/unit/policyfile_install_with_includes_spec.rb +232 -0
- data/spec/unit/policyfile_lock_build_spec.rb +1065 -0
- data/spec/unit/policyfile_lock_install_spec.rb +137 -0
- data/spec/unit/policyfile_lock_serialization_spec.rb +424 -0
- data/spec/unit/policyfile_lock_validation_spec.rb +608 -0
- data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -0
- data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +272 -0
- data/spec/unit/policyfile_services/export_repo_spec.rb +473 -0
- data/spec/unit/policyfile_services/install_spec.rb +209 -0
- data/spec/unit/policyfile_services/push_archive_spec.rb +359 -0
- data/spec/unit/policyfile_services/push_spec.rb +249 -0
- data/spec/unit/policyfile_services/rm_policy_group_spec.rb +237 -0
- data/spec/unit/policyfile_services/rm_policy_spec.rb +263 -0
- data/spec/unit/policyfile_services/show_policy_spec.rb +887 -0
- data/spec/unit/policyfile_services/undelete_spec.rb +302 -0
- data/spec/unit/policyfile_services/update_attributes_spec.rb +229 -0
- data/spec/unit/policyfile_services/update_spec.rb +162 -0
- data/spec/unit/service_exception_inspectors/base_spec.rb +41 -0
- data/spec/unit/service_exception_inspectors/http_spec.rb +138 -0
- data/spec/unit/shell_out_spec.rb +34 -0
- metadata +796 -0
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright:: Copyright (c) 2014-2018 Chef Software Inc.
|
|
4
|
+
# License:: Apache License, Version 2.0
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require "digest/sha2" unless defined?(Digest::SHA2)
|
|
20
|
+
|
|
21
|
+
require_relative "policyfile/storage_config"
|
|
22
|
+
require_relative "policyfile/cookbook_locks"
|
|
23
|
+
require_relative "policyfile/solution_dependencies"
|
|
24
|
+
require_relative "ui"
|
|
25
|
+
|
|
26
|
+
module ChefCLI
|
|
27
|
+
|
|
28
|
+
class PolicyfileLock
|
|
29
|
+
|
|
30
|
+
class InstallReport
|
|
31
|
+
|
|
32
|
+
attr_reader :ui
|
|
33
|
+
attr_reader :policyfile_lock
|
|
34
|
+
|
|
35
|
+
def initialize(ui: nil, policyfile_lock: nil)
|
|
36
|
+
@ui = ui
|
|
37
|
+
@policyfile_lock = policyfile_lock
|
|
38
|
+
|
|
39
|
+
@cookbook_name_width = nil
|
|
40
|
+
@cookbook_version_width = nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def installing_fixed_version_cookbook(cookbook_spec)
|
|
44
|
+
verb = cookbook_spec.installed? ? "Using " : "Installing"
|
|
45
|
+
ui.msg("#{verb} #{format_fixed_version_cookbook(cookbook_spec)}")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def installing_cookbook(cookbook_lock)
|
|
49
|
+
verb = cookbook_lock.installed? ? "Using " : "Installing"
|
|
50
|
+
ui.msg("#{verb} #{format_cookbook(cookbook_lock)}")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def format_cookbook(cookbook_lock)
|
|
56
|
+
"#{cookbook_lock.name.ljust(cookbook_name_width)} #{cookbook_lock.version.to_s.ljust(cookbook_version_width)}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def cookbook_name_width
|
|
60
|
+
policyfile_lock.cookbook_locks.map { |name, _| name.size }.max
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def cookbook_version_width
|
|
64
|
+
policyfile_lock.cookbook_locks.map { |_, lock| lock.version.size }.max
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
RUN_LIST_ITEM_FORMAT = /\Arecipe\[[^\s]+::[^\s]+\]\Z/.freeze
|
|
69
|
+
|
|
70
|
+
def self.build(storage_config)
|
|
71
|
+
lock = new(storage_config)
|
|
72
|
+
yield lock
|
|
73
|
+
lock
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.build_from_compiler(compiler, storage_config)
|
|
77
|
+
lock = new(storage_config)
|
|
78
|
+
lock.build_from_compiler(compiler)
|
|
79
|
+
lock
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
include Policyfile::StorageConfigDelegation
|
|
83
|
+
|
|
84
|
+
attr_accessor :name
|
|
85
|
+
attr_accessor :run_list
|
|
86
|
+
attr_accessor :named_run_lists
|
|
87
|
+
attr_accessor :default_attributes
|
|
88
|
+
attr_accessor :override_attributes
|
|
89
|
+
|
|
90
|
+
attr_reader :solution_dependencies
|
|
91
|
+
|
|
92
|
+
attr_reader :storage_config
|
|
93
|
+
|
|
94
|
+
attr_reader :cookbook_locks
|
|
95
|
+
|
|
96
|
+
attr_reader :included_policy_locks
|
|
97
|
+
|
|
98
|
+
attr_reader :install_report
|
|
99
|
+
|
|
100
|
+
def initialize(storage_config, ui: nil)
|
|
101
|
+
@name = nil
|
|
102
|
+
@run_list = []
|
|
103
|
+
@named_run_lists = {}
|
|
104
|
+
@cookbook_locks = {}
|
|
105
|
+
@relative_paths_root = Dir.pwd
|
|
106
|
+
@storage_config = storage_config
|
|
107
|
+
@ui = ui || UI.null
|
|
108
|
+
|
|
109
|
+
@default_attributes = {}
|
|
110
|
+
@override_attributes = {}
|
|
111
|
+
|
|
112
|
+
@solution_dependencies = Policyfile::SolutionDependencies.new
|
|
113
|
+
|
|
114
|
+
@included_policy_locks = []
|
|
115
|
+
|
|
116
|
+
@install_report = InstallReport.new(ui: @ui, policyfile_lock: self)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def lock_data_for(cookbook_name)
|
|
120
|
+
@cookbook_locks[cookbook_name]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def cached_cookbook(name)
|
|
124
|
+
cached_cookbook = Policyfile::CachedCookbook.new(name, storage_config)
|
|
125
|
+
yield cached_cookbook if block_given?
|
|
126
|
+
@cookbook_locks[name] = cached_cookbook
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def local_cookbook(name)
|
|
130
|
+
local_cookbook = Policyfile::LocalCookbook.new(name, storage_config)
|
|
131
|
+
yield local_cookbook if block_given?
|
|
132
|
+
@cookbook_locks[name] = local_cookbook
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def dependencies
|
|
136
|
+
yield solution_dependencies
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def to_lock
|
|
140
|
+
{}.tap do |lock|
|
|
141
|
+
lock["revision_id"] = revision_id
|
|
142
|
+
lock["name"] = name
|
|
143
|
+
lock["run_list"] = run_list
|
|
144
|
+
lock["named_run_lists"] = named_run_lists unless named_run_lists.empty?
|
|
145
|
+
lock["included_policy_locks"] = included_policy_locks
|
|
146
|
+
lock["cookbook_locks"] = cookbook_locks_for_lockfile
|
|
147
|
+
lock["default_attributes"] = default_attributes
|
|
148
|
+
lock["override_attributes"] = override_attributes
|
|
149
|
+
lock["solution_dependencies"] = solution_dependencies.to_lock
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Returns a fingerprint of the PolicyfileLock by computing the SHA1 hash of
|
|
154
|
+
# #canonical_revision_string
|
|
155
|
+
def revision_id
|
|
156
|
+
Digest::SHA256.new.hexdigest(canonical_revision_string)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Generates a string representation of the lock data in a specialized
|
|
160
|
+
# format suitable for generating a checksum of the lock itself. Only data
|
|
161
|
+
# that modifies the behavior of a chef-client using the lockfile is
|
|
162
|
+
# included in this format; for example, a modification to the source
|
|
163
|
+
# options in a `Policyfile.rb` that yields identical code (such as
|
|
164
|
+
# switching to a github fork at the same revision) will not cause a change
|
|
165
|
+
# in the PolicyfileLock's canonical_revision_string.
|
|
166
|
+
#
|
|
167
|
+
# This format is intended to be used only for generating an identifier for
|
|
168
|
+
# a particular revision of a PolicyfileLock. It should not be used as a
|
|
169
|
+
# serialization format, and is not guaranteed to be a stable interface.
|
|
170
|
+
def canonical_revision_string
|
|
171
|
+
canonical_rev_text = ""
|
|
172
|
+
|
|
173
|
+
canonical_rev_text << "name:#{name}\n"
|
|
174
|
+
|
|
175
|
+
run_list.each do |item|
|
|
176
|
+
canonical_rev_text << "run-list-item:#{item}\n"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
named_run_lists.each do |name, run_list|
|
|
180
|
+
run_list.each do |item|
|
|
181
|
+
canonical_rev_text << "named-run-list:#{name};run-list-item:#{item}\n"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
cookbook_locks_for_lockfile.each do |name, lock|
|
|
186
|
+
canonical_rev_text << "cookbook:#{name};id:#{lock["identifier"]}\n"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
canonical_rev_text << "default_attributes:#{canonicalize(default_attributes)}\n"
|
|
190
|
+
|
|
191
|
+
canonical_rev_text << "override_attributes:#{canonicalize(override_attributes)}\n"
|
|
192
|
+
|
|
193
|
+
canonical_rev_text
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def cookbook_locks_for_lockfile
|
|
197
|
+
cookbook_locks.inject({}) do |locks_map, (name, location_spec)|
|
|
198
|
+
location_spec.validate!
|
|
199
|
+
location_spec.gather_profile_data
|
|
200
|
+
locks_map[name] = location_spec.to_lock
|
|
201
|
+
locks_map
|
|
202
|
+
end.sort.to_h
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def validate_cookbooks!
|
|
206
|
+
cookbook_locks.each do |name, cookbook_lock|
|
|
207
|
+
cookbook_lock.validate!
|
|
208
|
+
cookbook_lock.refresh!
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Check that versions and dependencies are still valid. First we need to
|
|
212
|
+
# refresh the dependency info for everything that has changed, then we
|
|
213
|
+
# check that the new versions and dependencies are valid for the working
|
|
214
|
+
# set of cookbooks. We can't do this in a single loop because the user
|
|
215
|
+
# may have modified two cookbooks such that the versions and constraints
|
|
216
|
+
# are only valid when both changes are considered together.
|
|
217
|
+
cookbook_locks.each do |name, cookbook_lock|
|
|
218
|
+
if cookbook_lock.updated?
|
|
219
|
+
solution_dependencies.update_cookbook_dep(name, cookbook_lock.version, cookbook_lock.dependencies)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
cookbook_locks.each do |name, cookbook_lock|
|
|
223
|
+
if cookbook_lock.updated?
|
|
224
|
+
solution_dependencies.test_conflict!(cookbook_lock.name, cookbook_lock.version)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
true
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def build_from_compiler(compiler)
|
|
232
|
+
@name = compiler.name
|
|
233
|
+
|
|
234
|
+
@run_list = compiler.normalized_run_list
|
|
235
|
+
|
|
236
|
+
@named_run_lists = compiler.normalized_named_run_lists
|
|
237
|
+
|
|
238
|
+
compiler.all_cookbook_location_specs.each do |cookbook_name, spec|
|
|
239
|
+
if spec.mirrors_canonical_upstream?
|
|
240
|
+
cached_cookbook(cookbook_name) do |cached_cb|
|
|
241
|
+
cached_cb.cache_key = spec.cache_key
|
|
242
|
+
cached_cb.origin = spec.uri
|
|
243
|
+
cached_cb.source_options = spec.source_options_for_lock
|
|
244
|
+
end
|
|
245
|
+
else
|
|
246
|
+
local_cookbook(cookbook_name) do |local_cb|
|
|
247
|
+
local_cb.source = spec.relative_path
|
|
248
|
+
local_cb.source_options = spec.source_options_for_lock
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
@default_attributes = compiler.default_attributes
|
|
254
|
+
@override_attributes = compiler.override_attributes
|
|
255
|
+
|
|
256
|
+
@solution_dependencies = compiler.solution_dependencies
|
|
257
|
+
|
|
258
|
+
@included_policy_locks = compiler.included_policies.map do |policy|
|
|
259
|
+
{
|
|
260
|
+
"name" => policy.name,
|
|
261
|
+
"revision_id" => policy.revision_id,
|
|
262
|
+
"source_options" => policy.source_options_for_lock,
|
|
263
|
+
}
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
self
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def build_from_lock_data(lock_data)
|
|
270
|
+
set_name_from_lock_data(lock_data)
|
|
271
|
+
set_run_list_from_lock_data(lock_data)
|
|
272
|
+
set_named_run_lists_from_lock_data(lock_data)
|
|
273
|
+
set_cookbook_locks_from_lock_data(lock_data)
|
|
274
|
+
set_attributes_from_lock_data(lock_data)
|
|
275
|
+
set_solution_dependencies_from_lock_data(lock_data)
|
|
276
|
+
set_included_policy_locks_from_lock_data(lock_data)
|
|
277
|
+
self
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def build_from_archive(lock_data)
|
|
281
|
+
set_name_from_lock_data(lock_data)
|
|
282
|
+
set_run_list_from_lock_data(lock_data)
|
|
283
|
+
set_named_run_lists_from_lock_data(lock_data)
|
|
284
|
+
set_cookbook_locks_as_archives_from_lock_data(lock_data)
|
|
285
|
+
set_attributes_from_lock_data(lock_data)
|
|
286
|
+
set_solution_dependencies_from_lock_data(lock_data)
|
|
287
|
+
set_included_policy_locks_from_lock_data(lock_data)
|
|
288
|
+
self
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def install_cookbooks
|
|
292
|
+
# note: duplicates PolicyfileCompiler#ensure_cache_dir_exists
|
|
293
|
+
ensure_cache_dir_exists
|
|
294
|
+
|
|
295
|
+
cookbook_locks.each do |cookbook_name, cookbook_lock|
|
|
296
|
+
install_report.installing_cookbook(cookbook_lock)
|
|
297
|
+
cookbook_lock.install_locked
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def ensure_cache_dir_exists
|
|
302
|
+
# note: duplicates PolicyfileCompiler#ensure_cache_dir_exists
|
|
303
|
+
unless File.exist?(cache_path)
|
|
304
|
+
FileUtils.mkdir_p(cache_path)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
private
|
|
309
|
+
|
|
310
|
+
# Generates a canonical JSON representation of the attributes. Based on
|
|
311
|
+
# http://wiki.laptop.org/go/Canonical_JSON but not quite as strict, yet.
|
|
312
|
+
#
|
|
313
|
+
# In particular:
|
|
314
|
+
# - String encoding stuff isn't normalized
|
|
315
|
+
# - We allow floats that fit within the range/precision requirements of
|
|
316
|
+
# IEEE 754-2008 binary64 (double precision) numbers.
|
|
317
|
+
# - +/- Infinity and NaN are banned, but float/numeric size aren't checked.
|
|
318
|
+
# numerics should be in range [-(2**53)+1, (2**53)-1] to comply with
|
|
319
|
+
# IEEE 754-2008
|
|
320
|
+
#
|
|
321
|
+
# Recursive, so absurd nesting levels could cause a SystemError. Invalid
|
|
322
|
+
# input will cause an InvalidPolicyfileAttribute exception.
|
|
323
|
+
def canonicalize(attributes)
|
|
324
|
+
unless attributes.kind_of?(Hash)
|
|
325
|
+
raise "Top level attributes must be a Hash (you gave: #{attributes})"
|
|
326
|
+
end
|
|
327
|
+
canonicalize_elements(attributes)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def canonicalize_elements(item)
|
|
331
|
+
case item
|
|
332
|
+
when Hash
|
|
333
|
+
# Hash keys will sort differently based on the encoding, but after a
|
|
334
|
+
# JSON round trip everything will be UTF-8, so we have to normalize the
|
|
335
|
+
# keys to UTF-8 first so that the sort order uses the UTF-8 strings.
|
|
336
|
+
item_with_normalized_keys = item.inject({}) do |normalized_item, (key, value)|
|
|
337
|
+
validate_attr_key(key)
|
|
338
|
+
normalized_item[key.encode("utf-8")] = value
|
|
339
|
+
normalized_item
|
|
340
|
+
end
|
|
341
|
+
elements = item_with_normalized_keys.keys.sort.map do |key|
|
|
342
|
+
k = '"' << key << '":'
|
|
343
|
+
v = canonicalize_elements(item_with_normalized_keys[key])
|
|
344
|
+
k << v
|
|
345
|
+
end
|
|
346
|
+
"{" << elements.join(",") << "}"
|
|
347
|
+
when String
|
|
348
|
+
'"' << item.encode("utf-8") << '"'
|
|
349
|
+
when Array
|
|
350
|
+
elements = item.map { |i| canonicalize_elements(i) }
|
|
351
|
+
"[" << elements.join(",") << "]"
|
|
352
|
+
when Integer
|
|
353
|
+
item.to_s
|
|
354
|
+
when Float
|
|
355
|
+
unless item.finite?
|
|
356
|
+
raise InvalidPolicyfileAttribute, "Floating point numbers cannot be infinite or NaN. You gave #{item.inspect}"
|
|
357
|
+
end
|
|
358
|
+
# Support for floats assumes that any implementation of our JSON
|
|
359
|
+
# canonicalization routine will use IEEE-754 doubles. In decimal terms,
|
|
360
|
+
# doubles give 15-17 digits of precision, so we err on the safe side
|
|
361
|
+
# and only use 15 digits in the string conversion. We use the `g`
|
|
362
|
+
# format, which is a documented-enough "do what I mean" where floats
|
|
363
|
+
# >= 0.1 and < precsion are represented as floating point literals, and
|
|
364
|
+
# other numbers use the exponent notation with a lowercase 'e'. Note
|
|
365
|
+
# that both Ruby and Erlang document what their `g` does but have some
|
|
366
|
+
# differences both subtle and non-subtle:
|
|
367
|
+
#
|
|
368
|
+
# ```ruby
|
|
369
|
+
# format("%.15g", 0.1) #=> "0.1"
|
|
370
|
+
# format("%.15g", 1_000_000_000.0) #=> "1000000000"
|
|
371
|
+
# ```
|
|
372
|
+
#
|
|
373
|
+
# Whereas:
|
|
374
|
+
#
|
|
375
|
+
# ```erlang
|
|
376
|
+
# lists:flatten(io_lib:format("~.15g", [0.1])). %=> "0.100000000000000"
|
|
377
|
+
# lists:flatten(io_lib:format("~.15e", [1000000000.0])). %=> "1.00000000000000e+9"
|
|
378
|
+
# ```
|
|
379
|
+
#
|
|
380
|
+
# Other implementations should normalize to ruby's %.15g behavior.
|
|
381
|
+
Kernel.format("%.15g", item)
|
|
382
|
+
when NilClass
|
|
383
|
+
"null"
|
|
384
|
+
when TrueClass
|
|
385
|
+
"true"
|
|
386
|
+
when FalseClass
|
|
387
|
+
"false"
|
|
388
|
+
else
|
|
389
|
+
raise InvalidPolicyfileAttribute,
|
|
390
|
+
"Invalid type in attributes. Only Hash, Array, String, Integer, Float, true, false, and nil are accepted. You gave #{item.inspect} (#{item.class})"
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def validate_attr_key(key)
|
|
395
|
+
unless key.kind_of?(String)
|
|
396
|
+
raise InvalidPolicyfileAttribute,
|
|
397
|
+
"Attribute keys must be Strings (other types are not allowed in JSON). You gave: #{key.inspect} (#{key.class})"
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def set_name_from_lock_data(lock_data)
|
|
402
|
+
name_attribute = lock_data["name"]
|
|
403
|
+
|
|
404
|
+
raise InvalidLockfile, "lockfile does not have a `name' attribute" if name_attribute.nil?
|
|
405
|
+
|
|
406
|
+
unless name_attribute.kind_of?(String)
|
|
407
|
+
raise InvalidLockfile, "lockfile's name attribute must be a String (got: #{name_attribute.inspect})"
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
if name_attribute.empty?
|
|
411
|
+
raise InvalidLockfile, "lockfile's name attribute cannot be an empty string"
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
@name = name_attribute
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def set_run_list_from_lock_data(lock_data)
|
|
418
|
+
run_list_attribute = lock_data["run_list"]
|
|
419
|
+
|
|
420
|
+
raise InvalidLockfile, "lockfile does not have a run_list attribute" if run_list_attribute.nil?
|
|
421
|
+
|
|
422
|
+
unless run_list_attribute.kind_of?(Array)
|
|
423
|
+
raise InvalidLockfile, "lockfile's run_list must be an array of run list items (got: #{run_list_attribute.inspect})"
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
bad_run_list_items = run_list_attribute.select { |e| e !~ RUN_LIST_ITEM_FORMAT }
|
|
427
|
+
|
|
428
|
+
unless bad_run_list_items.empty?
|
|
429
|
+
msg = "lockfile's run_list items must be formatted like `recipe[$COOKBOOK_NAME::$RECIPE_NAME]'. Invalid items: `#{bad_run_list_items.join("' `")}'"
|
|
430
|
+
raise InvalidLockfile, msg
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
@run_list = run_list_attribute
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def set_named_run_lists_from_lock_data(lock_data)
|
|
437
|
+
return unless lock_data.key?("named_run_lists")
|
|
438
|
+
|
|
439
|
+
lock_data_named_run_lists = lock_data["named_run_lists"]
|
|
440
|
+
|
|
441
|
+
unless lock_data_named_run_lists.kind_of?(Hash)
|
|
442
|
+
msg = "lockfile's named_run_lists must be a Hash (JSON object). (got: #{lock_data_named_run_lists.inspect})"
|
|
443
|
+
raise InvalidLockfile, msg
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
lock_data_named_run_lists.each do |name, run_list|
|
|
447
|
+
unless name.kind_of?(String)
|
|
448
|
+
msg = "Keys in lockfile's named_run_lists must be Strings. (got: #{name.inspect})"
|
|
449
|
+
raise InvalidLockfile, msg
|
|
450
|
+
end
|
|
451
|
+
unless run_list.kind_of?(Array)
|
|
452
|
+
msg = "Values in lockfile's named_run_lists must be Arrays. (got: #{run_list.inspect})"
|
|
453
|
+
raise InvalidLockfile, msg
|
|
454
|
+
end
|
|
455
|
+
bad_run_list_items = run_list.select { |e| e !~ RUN_LIST_ITEM_FORMAT }
|
|
456
|
+
unless bad_run_list_items.empty?
|
|
457
|
+
msg = "lockfile's run_list items must be formatted like `recipe[$COOKBOOK_NAME::$RECIPE_NAME]'. Invalid items: `#{bad_run_list_items.join("' `")}'"
|
|
458
|
+
raise InvalidLockfile, msg
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
@named_run_lists = lock_data_named_run_lists
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def set_cookbook_locks_from_lock_data(lock_data)
|
|
465
|
+
cookbook_lock_data = lock_data["cookbook_locks"]
|
|
466
|
+
|
|
467
|
+
if cookbook_lock_data.nil?
|
|
468
|
+
raise InvalidLockfile, "lockfile does not have a cookbook_locks attribute"
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
unless cookbook_lock_data.kind_of?(Hash)
|
|
472
|
+
raise InvalidLockfile, "lockfile's cookbook_locks attribute must be a Hash (JSON object). (got: #{cookbook_lock_data.inspect})"
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
lock_data["cookbook_locks"].each do |name, lock_info|
|
|
476
|
+
build_cookbook_lock_from_lock_data(name, lock_info)
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def set_cookbook_locks_as_archives_from_lock_data(lock_data)
|
|
481
|
+
cookbook_lock_data = lock_data["cookbook_locks"]
|
|
482
|
+
|
|
483
|
+
if cookbook_lock_data.nil?
|
|
484
|
+
raise InvalidLockfile, "lockfile does not have a cookbook_locks attribute"
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
unless cookbook_lock_data.kind_of?(Hash)
|
|
488
|
+
raise InvalidLockfile, "lockfile's cookbook_locks attribute must be a Hash (JSON object). (got: #{cookbook_lock_data.inspect})"
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
lock_data["cookbook_locks"].each do |name, lock_info|
|
|
492
|
+
build_cookbook_lock_as_archive_from_lock_data(name, lock_info)
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def set_attributes_from_lock_data(lock_data)
|
|
497
|
+
default_attr_data = lock_data["default_attributes"]
|
|
498
|
+
|
|
499
|
+
if default_attr_data.nil?
|
|
500
|
+
raise InvalidLockfile, "lockfile does not have a `default_attributes` attribute"
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
unless default_attr_data.kind_of?(Hash)
|
|
504
|
+
raise InvalidLockfile, "lockfile's `default_attributes` attribute must be a Hash (JSON object). (got: #{default_attr_data.inspect})"
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
override_attr_data = lock_data["override_attributes"]
|
|
508
|
+
|
|
509
|
+
if override_attr_data.nil?
|
|
510
|
+
raise InvalidLockfile, "lockfile does not have a `override_attributes` attribute"
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
unless override_attr_data.kind_of?(Hash)
|
|
514
|
+
raise InvalidLockfile, "lockfile's `override_attributes` attribute must be a Hash (JSON object). (got: #{override_attr_data.inspect})"
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
@default_attributes = default_attr_data
|
|
518
|
+
@override_attributes = override_attr_data
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def set_solution_dependencies_from_lock_data(lock_data)
|
|
522
|
+
soln_deps = lock_data["solution_dependencies"]
|
|
523
|
+
|
|
524
|
+
if soln_deps.nil?
|
|
525
|
+
raise InvalidLockfile, "lockfile does not have a solution_dependencies attribute"
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
unless soln_deps.kind_of?(Hash)
|
|
529
|
+
raise InvalidLockfile, "lockfile's solution_dependencies attribute must be a Hash (JSON object). (got: #{soln_deps.inspect})"
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
s = Policyfile::SolutionDependencies.from_lock(lock_data["solution_dependencies"])
|
|
533
|
+
@solution_dependencies = s
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
def set_included_policy_locks_from_lock_data(lock_data)
|
|
537
|
+
locks = lock_data["included_policy_locks"]
|
|
538
|
+
if locks.nil?
|
|
539
|
+
@included_policy_locks = []
|
|
540
|
+
else
|
|
541
|
+
locks.each do |lock_info|
|
|
542
|
+
if !(%w{revision_id name source_options}.all? { |key| !lock_info[key].nil? })
|
|
543
|
+
raise InvalidLockfile, "lockfile included policy missing one of the required keys"
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
@included_policy_locks = locks
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
def build_cookbook_lock_from_lock_data(name, lock_info)
|
|
551
|
+
unless lock_info.kind_of?(Hash)
|
|
552
|
+
raise InvalidLockfile, "lockfile cookbook_locks entries must be a Hash (JSON object). (got: #{lock_info.inspect})"
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
if lock_info["cache_key"].nil?
|
|
556
|
+
local_cookbook(name).build_from_lock_data(lock_info)
|
|
557
|
+
else
|
|
558
|
+
cached_cookbook(name).build_from_lock_data(lock_info)
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
def build_cookbook_lock_as_archive_from_lock_data(name, lock_info)
|
|
563
|
+
unless lock_info.kind_of?(Hash)
|
|
564
|
+
raise InvalidLockfile, "lockfile cookbook_locks entries must be a Hash (JSON object). (got: #{lock_info.inspect})"
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
if lock_info["cache_key"].nil?
|
|
568
|
+
local_cookbook = Policyfile::LocalCookbook.new(name, storage_config)
|
|
569
|
+
local_cookbook.build_from_lock_data(lock_info)
|
|
570
|
+
archived = Policyfile::ArchivedCookbook.new(local_cookbook, storage_config)
|
|
571
|
+
@cookbook_locks[name] = archived
|
|
572
|
+
else
|
|
573
|
+
cached_cookbook = Policyfile::CachedCookbook.new(name, storage_config)
|
|
574
|
+
cached_cookbook.build_from_lock_data(lock_info)
|
|
575
|
+
archived = Policyfile::ArchivedCookbook.new(cached_cookbook, storage_config)
|
|
576
|
+
@cookbook_locks[name] = archived
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
end
|
|
581
|
+
end
|