chef 11.4.4 → 11.6.0.hotfix.1
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.
- data/README.md +1 -1
- data/Rakefile +18 -1
- data/bin/chef-service-manager +37 -0
- data/distro/common/html/chef-client.8.html +4 -4
- data/distro/common/html/chef-expander.8.html +4 -4
- data/distro/common/html/chef-expanderctl.8.html +4 -4
- data/distro/common/html/chef-server-webui.8.html +4 -4
- data/distro/common/html/chef-server.8.html +4 -4
- data/distro/common/html/chef-shell.1.html +4 -4
- data/distro/common/html/chef-solo.8.html +12 -18
- data/distro/common/html/chef-solr.8.html +4 -4
- data/distro/common/html/knife-bootstrap.1.html +4 -4
- data/distro/common/html/knife-client.1.html +4 -4
- data/distro/common/html/knife-configure.1.html +4 -4
- data/distro/common/html/knife-cookbook-site.1.html +4 -4
- data/distro/common/html/knife-cookbook.1.html +7 -10
- data/distro/common/html/knife-data-bag.1.html +7 -10
- data/distro/common/html/knife-environment.1.html +6 -8
- data/distro/common/html/knife-exec.1.html +4 -4
- data/distro/common/html/knife-index.1.html +4 -4
- data/distro/common/html/knife-node.1.html +4 -4
- data/distro/common/html/knife-role.1.html +4 -4
- data/distro/common/html/knife-search.1.html +4 -4
- data/distro/common/html/knife-ssh.1.html +4 -4
- data/distro/common/html/knife-status.1.html +4 -4
- data/distro/common/html/knife-tag.1.html +4 -4
- data/distro/common/html/knife.1.html +4 -4
- data/distro/common/man/man1/chef-shell.1 +1 -1
- data/distro/common/man/man1/knife-bootstrap.1 +1 -1
- data/distro/common/man/man1/knife-client.1 +1 -1
- data/distro/common/man/man1/knife-configure.1 +1 -1
- data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
- data/distro/common/man/man1/knife-cookbook.1 +2 -15
- data/distro/common/man/man1/knife-data-bag.1 +2 -15
- data/distro/common/man/man1/knife-environment.1 +2 -12
- data/distro/common/man/man1/knife-exec.1 +1 -1
- data/distro/common/man/man1/knife-index.1 +1 -1
- data/distro/common/man/man1/knife-node.1 +1 -1
- data/distro/common/man/man1/knife-role.1 +1 -1
- data/distro/common/man/man1/knife-search.1 +1 -1
- data/distro/common/man/man1/knife-ssh.1 +1 -1
- data/distro/common/man/man1/knife-status.1 +1 -1
- data/distro/common/man/man1/knife-tag.1 +1 -1
- data/distro/common/man/man1/knife.1 +1 -1
- data/distro/common/man/man8/chef-client.8 +1 -1
- data/distro/common/man/man8/chef-expander.8 +1 -1
- data/distro/common/man/man8/chef-expanderctl.8 +1 -1
- data/distro/common/man/man8/chef-server-webui.8 +1 -1
- data/distro/common/man/man8/chef-server.8 +1 -1
- data/distro/common/man/man8/chef-solo.8 +4 -36
- data/distro/common/man/man8/chef-solr.8 +1 -1
- data/distro/debian/etc/init.d/chef-client +4 -2
- data/distro/windows/service_manager.rb +2 -146
- data/lib/chef.rb +1 -1
- data/lib/chef/application.rb +5 -12
- data/lib/chef/application/apply.rb +2 -0
- data/lib/chef/application/client.rb +12 -12
- data/lib/chef/application/knife.rb +2 -2
- data/lib/chef/application/solo.rb +4 -5
- data/lib/chef/application/windows_service.rb +113 -56
- data/lib/chef/application/windows_service_manager.rb +179 -0
- data/lib/chef/chef_fs.rb +2 -4
- data/lib/chef/chef_fs/chef_fs_data_store.rb +371 -0
- data/lib/chef/chef_fs/command_line.rb +145 -93
- data/lib/chef/chef_fs/config.rb +205 -0
- data/lib/chef/chef_fs/data_handler/acl_data_handler.rb +26 -0
- data/lib/chef/chef_fs/data_handler/client_data_handler.rb +38 -0
- data/lib/chef/chef_fs/data_handler/container_data_handler.rb +29 -0
- data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +38 -0
- data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +56 -0
- data/lib/chef/chef_fs/data_handler/data_handler_base.rb +128 -0
- data/lib/chef/chef_fs/data_handler/environment_data_handler.rb +40 -0
- data/lib/chef/chef_fs/data_handler/group_data_handler.rb +51 -0
- data/lib/chef/chef_fs/data_handler/node_data_handler.rb +36 -0
- data/lib/chef/chef_fs/data_handler/role_data_handler.rb +40 -0
- data/lib/chef/chef_fs/data_handler/user_data_handler.rb +27 -0
- data/lib/chef/chef_fs/file_system.rb +195 -127
- data/lib/chef/chef_fs/file_system/acl_dir.rb +64 -0
- data/lib/chef/chef_fs/file_system/acl_entry.rb +58 -0
- data/lib/chef/chef_fs/file_system/acls_dir.rb +68 -0
- data/lib/chef/chef_fs/file_system/already_exists_error.rb +31 -0
- data/lib/chef/chef_fs/file_system/base_fs_object.rb +98 -39
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +85 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +71 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +55 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_data_bags_dir.rb +36 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +14 -63
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +93 -3
- data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +35 -9
- data/lib/chef/chef_fs/file_system/cookbook_dir.rb +67 -32
- data/lib/chef/chef_fs/file_system/cookbook_file.rb +13 -6
- data/lib/chef/chef_fs/file_system/cookbook_frozen_error.rb +31 -0
- data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +102 -21
- data/lib/chef/chef_fs/file_system/data_bag_dir.rb +12 -21
- data/lib/chef/chef_fs/file_system/data_bags_dir.rb +14 -8
- data/lib/chef/chef_fs/file_system/default_environment_cannot_be_modified_error.rb +36 -0
- data/lib/chef/chef_fs/file_system/environments_dir.rb +60 -0
- data/lib/chef/chef_fs/file_system/file_system_entry.rb +8 -8
- data/lib/chef/chef_fs/file_system/file_system_error.rb +3 -1
- data/lib/chef/chef_fs/file_system/memory_dir.rb +52 -0
- data/lib/chef/chef_fs/file_system/memory_file.rb +17 -0
- data/lib/chef/chef_fs/file_system/memory_root.rb +21 -0
- data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +48 -0
- data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +2 -2
- data/lib/chef/chef_fs/file_system/nodes_dir.rb +17 -9
- data/lib/chef/chef_fs/file_system/nonexistent_fs_object.rb +0 -4
- data/lib/chef/chef_fs/file_system/not_found_error.rb +2 -2
- data/lib/chef/chef_fs/file_system/operation_failed_error.rb +34 -0
- data/lib/chef/chef_fs/file_system/operation_not_allowed_error.rb +48 -0
- data/lib/chef/chef_fs/file_system/rest_list_dir.rb +42 -13
- data/lib/chef/chef_fs/file_system/rest_list_entry.rb +81 -27
- data/lib/chef/chef_fs/knife.rb +68 -29
- data/lib/chef/chef_fs/parallelizer.rb +129 -0
- data/lib/chef/chef_fs/path_utils.rb +29 -3
- data/lib/chef/chef_fs/raw_request.rb +79 -0
- data/lib/chef/client.rb +46 -20
- data/lib/chef/config.rb +59 -61
- data/lib/chef/cookbook/chefignore.rb +2 -1
- data/lib/chef/cookbook/synchronizer.rb +8 -6
- data/lib/chef/cookbook/syntax_check.rb +17 -2
- data/lib/chef/cookbook_uploader.rb +10 -1
- data/lib/chef/cookbook_version.rb +0 -109
- data/lib/chef/data_bag.rb +15 -6
- data/lib/chef/deprecation/mixin/template.rb +49 -0
- data/lib/chef/deprecation/provider/cookbook_file.rb +55 -0
- data/lib/chef/deprecation/provider/file.rb +197 -0
- data/lib/chef/deprecation/provider/remote_file.rb +86 -0
- data/lib/chef/deprecation/provider/template.rb +63 -0
- data/lib/chef/deprecation/warnings.rb +38 -0
- data/lib/chef/encrypted_data_bag_item.rb +153 -61
- data/lib/chef/environment.rb +34 -3
- data/lib/chef/event_dispatch/base.rb +3 -0
- data/lib/chef/exceptions.rb +27 -2
- data/lib/chef/file_access_control/unix.rb +64 -7
- data/lib/chef/file_access_control/windows.rb +22 -11
- data/lib/chef/file_content_management/content_base.rb +56 -0
- data/lib/chef/file_content_management/deploy.rb +38 -0
- data/lib/chef/file_content_management/deploy/cp.rb +48 -0
- data/lib/chef/file_content_management/deploy/mv_unix.rb +77 -0
- data/lib/chef/file_content_management/deploy/mv_windows.rb +95 -0
- data/lib/chef/file_content_management/tempfile.rb +61 -0
- data/lib/chef/formatters/doc.rb +1 -1
- data/lib/chef/formatters/error_descriptor.rb +5 -4
- data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +23 -3
- data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +4 -0
- data/lib/chef/json_compat.rb +3 -0
- data/lib/chef/knife.rb +12 -3
- data/lib/chef/knife/bootstrap.rb +46 -2
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/centos5-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/chef-full.erb +4 -4
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +3 -3
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +3 -3
- data/lib/chef/knife/client_show.rb +2 -5
- data/lib/chef/knife/configure.rb +3 -3
- data/lib/chef/knife/cookbook_create.rb +6 -5
- data/lib/chef/knife/cookbook_download.rb +13 -5
- data/lib/chef/knife/cookbook_site_share.rb +1 -0
- data/lib/chef/knife/cookbook_test.rb +1 -0
- data/lib/chef/knife/cookbook_upload.rb +4 -9
- data/lib/chef/knife/core/bootstrap_context.rb +10 -4
- data/lib/chef/knife/core/generic_presenter.rb +16 -0
- data/lib/chef/knife/core/node_editor.rb +1 -1
- data/lib/chef/knife/core/subcommand_loader.rb +43 -12
- data/lib/chef/knife/core/ui.rb +19 -4
- data/lib/chef/knife/delete.rb +76 -9
- data/lib/chef/knife/deps.rb +139 -0
- data/lib/chef/knife/diff.rb +22 -5
- data/lib/chef/knife/download.rb +16 -3
- data/lib/chef/knife/edit.rb +76 -0
- data/lib/chef/knife/environment_show.rb +2 -7
- data/lib/chef/knife/list.rb +91 -47
- data/lib/chef/knife/node_run_list_set.rb +66 -0
- data/lib/chef/knife/node_show.rb +1 -7
- data/lib/chef/knife/raw.rb +20 -64
- data/lib/chef/knife/role_show.rb +2 -4
- data/lib/chef/knife/search.rb +5 -6
- data/lib/chef/knife/show.rb +34 -11
- data/lib/chef/knife/ssh.rb +8 -0
- data/lib/chef/knife/upload.rb +23 -4
- data/lib/chef/knife/user_show.rb +2 -5
- data/lib/chef/knife/xargs.rb +265 -0
- data/lib/chef/log.rb +2 -2
- data/lib/chef/mixin/file_class.rb +0 -9
- data/lib/chef/mixin/language_include_recipe.rb +1 -1
- data/lib/chef/mixin/params_validate.rb +19 -9
- data/lib/chef/mixin/template.rb +126 -36
- data/lib/chef/mixin/windows_architecture_helper.rb +91 -0
- data/lib/chef/monkey_patches/file.rb +26 -0
- data/lib/chef/monkey_patches/net-ssh-multi.rb +140 -0
- data/lib/chef/monkey_patches/securerandom.rb +44 -0
- data/lib/chef/monologger.rb +93 -0
- data/lib/chef/node.rb +4 -0
- data/lib/chef/platform.rb +4 -490
- data/lib/chef/platform/provider_mapping.rb +529 -0
- data/lib/chef/{monkey_patches/dir.rb → platform/query_helpers.rb} +25 -19
- data/lib/chef/provider.rb +12 -9
- data/lib/chef/provider/batch.rb +35 -0
- data/lib/chef/provider/cookbook_file.rb +9 -78
- data/lib/chef/provider/cookbook_file/content.rb +49 -0
- data/lib/chef/provider/deploy.rb +24 -20
- data/lib/chef/provider/deploy/revision.rb +27 -0
- data/lib/chef/provider/directory.rb +19 -22
- data/lib/chef/provider/execute.rb +22 -5
- data/lib/chef/provider/file.rb +299 -217
- data/lib/chef/provider/file/content.rb +39 -0
- data/lib/chef/provider/git.rb +76 -43
- data/lib/chef/provider/group/usermod.rb +2 -2
- data/lib/chef/provider/ifconfig.rb +25 -35
- data/lib/chef/provider/ifconfig/debian.rb +71 -0
- data/lib/chef/provider/ifconfig/redhat.rb +47 -0
- data/lib/chef/provider/link.rb +10 -3
- data/lib/chef/provider/mount.rb +1 -1
- data/lib/chef/provider/mount/mount.rb +8 -3
- data/lib/chef/provider/mount/windows.rb +4 -1
- data/lib/chef/provider/package/portage.rb +9 -4
- data/lib/chef/provider/package/rubygems.rb +45 -10
- data/lib/chef/provider/package/smartos.rb +47 -36
- data/lib/chef/provider/package/yum.rb +19 -12
- data/lib/chef/provider/package/zypper.rb +45 -55
- data/lib/chef/provider/powershell_script.rb +77 -0
- data/lib/chef/provider/remote_directory.rb +5 -6
- data/lib/chef/provider/remote_file.rb +12 -108
- data/lib/chef/provider/remote_file/cache_control_data.rb +165 -0
- data/lib/chef/provider/remote_file/content.rb +75 -0
- data/lib/chef/provider/remote_file/fetcher.rb +43 -0
- data/lib/chef/provider/remote_file/ftp.rb +183 -0
- data/lib/chef/provider/remote_file/http.rb +124 -0
- data/lib/chef/provider/remote_file/local_file.rb +47 -0
- data/lib/chef/provider/route.rb +6 -2
- data/lib/chef/provider/script.rb +14 -2
- data/lib/chef/provider/service/macosx.rb +16 -10
- data/lib/chef/provider/service/solaris.rb +6 -5
- data/lib/chef/provider/template.rb +16 -78
- data/lib/chef/provider/template/content.rb +61 -0
- data/lib/chef/provider/user/solaris.rb +90 -0
- data/lib/chef/provider/user/useradd.rb +76 -63
- data/lib/chef/provider/windows_script.rb +73 -0
- data/lib/chef/providers.rb +16 -0
- data/lib/chef/resource.rb +23 -2
- data/lib/chef/resource/batch.rb +31 -0
- data/lib/chef/resource/conditional.rb +4 -0
- data/lib/chef/resource/conditional_action_not_nothing.rb +48 -0
- data/lib/chef/resource/file.rb +31 -3
- data/lib/chef/resource/link.rb +17 -0
- data/lib/chef/resource/lwrp_base.rb +1 -1
- data/lib/chef/resource/mount.rb +29 -2
- data/lib/chef/resource/powershell_script.rb +31 -0
- data/lib/chef/resource/remote_file.rb +47 -1
- data/lib/chef/resource/route.rb +1 -1
- data/lib/chef/resource/template.rb +145 -0
- data/lib/chef/resource/windows_script.rb +62 -0
- data/lib/chef/resource_collection.rb +45 -11
- data/lib/chef/resource_reporter.rb +81 -52
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/rest.rb +13 -4
- data/lib/chef/rest/rest_request.rb +5 -1
- data/lib/chef/run_context/cookbook_compiler.rb +3 -3
- data/lib/chef/run_list/run_list_expansion.rb +1 -1
- data/lib/chef/run_lock.rb +7 -1
- data/lib/chef/runner.rb +0 -1
- data/lib/chef/scan_access_control.rb +6 -1
- data/lib/chef/search/query.rb +2 -2
- data/lib/chef/shell/shell_session.rb +2 -2
- data/lib/chef/util/backup.rb +84 -0
- data/lib/chef/util/diff.rb +145 -0
- data/lib/chef/util/file_edit.rb +1 -1
- data/lib/chef/util/selinux.rb +100 -0
- data/lib/chef/util/windows/net_user.rb +14 -1
- data/lib/chef/util/windows/volume.rb +2 -2
- data/lib/chef/version.rb +1 -1
- data/lib/chef/version/platform.rb +42 -0
- data/lib/chef/version_class.rb +1 -1
- data/lib/chef/version_constraint.rb +6 -5
- data/lib/chef/version_constraint/platform.rb +26 -0
- data/lib/chef/win32/api/file.rb +8 -2
- data/lib/chef/win32/version.rb +25 -8
- data/spec/data/apt/chef-integration-test-1.0/debian/changelog +5 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/compat +1 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/control +13 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/copyright +34 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/files +1 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/rules +13 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/source/format +1 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/changelog +11 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/compat +1 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/control +13 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/copyright +34 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/files +1 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/rules +13 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/source/format +1 -0
- data/spec/data/apt/chef-integration-test_1.0-1_amd64.changes +22 -0
- data/spec/data/apt/chef-integration-test_1.0-1_amd64.deb +0 -0
- data/spec/data/apt/chef-integration-test_1.0.orig.tar.gz +0 -0
- data/spec/data/apt/chef-integration-test_1.1-1_amd64.changes +22 -0
- data/spec/data/apt/chef-integration-test_1.1-1_amd64.deb +0 -0
- data/spec/data/apt/chef-integration-test_1.1.orig.tar.gz +0 -0
- data/spec/data/apt/var/www/apt/conf/distributions +7 -0
- data/spec/data/apt/var/www/apt/conf/incoming +4 -0
- data/spec/data/apt/var/www/apt/conf/pulls +3 -0
- data/spec/data/apt/var/www/apt/db/checksums.db +0 -0
- data/spec/data/apt/var/www/apt/db/contents.cache.db +0 -0
- data/spec/data/apt/var/www/apt/db/packages.db +0 -0
- data/spec/data/apt/var/www/apt/db/references.db +0 -0
- data/spec/data/apt/var/www/apt/db/release.caches.db +0 -0
- data/spec/data/apt/var/www/apt/db/version +4 -0
- data/spec/data/apt/var/www/apt/dists/sid/Release +19 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages +16 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages.gz +0 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Release +5 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-i386/Packages +0 -0
- data/spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.0-1_amd64.deb +0 -0
- data/spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.1-1_amd64.deb +0 -0
- data/spec/data/bootstrap/encrypted_data_bag_secret +1 -0
- data/spec/data/bootstrap/secret.erb +9 -0
- data/spec/data/cookbooks/ignorken/recipes/default.rb +1 -0
- data/spec/data/cookbooks/ignorken/recipes/ignoreme.rb +2 -0
- data/spec/data/cookbooks/openldap/files/default/.dotfile +1 -0
- data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +1 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +1 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +1 -0
- data/spec/data/cookbooks/openldap/templates/default/all_windows_line_endings.erb +4 -0
- data/spec/data/cookbooks/openldap/templates/default/helper_test.erb +1 -0
- data/spec/data/cookbooks/openldap/templates/default/helpers_via_partial_test.erb +1 -0
- data/spec/data/cookbooks/openldap/templates/default/no_windows_line_endings.erb +4 -0
- data/spec/data/cookbooks/openldap/templates/default/some_windows_line_endings.erb +4 -0
- data/spec/data/cookbooks/preseed/files/default/preseed-file.seed +1 -0
- data/spec/data/cookbooks/preseed/templates/default/preseed-template.seed +1 -0
- data/spec/data/file-providers-method-snapshot-chef-11-4.json +127 -0
- data/spec/data/git_bundles/example-repo.gitbundle +0 -0
- data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
- data/spec/data/knife_subcommand/test_yourself.rb +8 -0
- data/spec/data/null_config.rb +1 -0
- data/spec/data/partial_one.erb +1 -1
- data/spec/data/remote_file/nyan_cat.png.gz +0 -0
- data/spec/functional/file_content_management/deploy_strategies_spec.rb +238 -0
- data/spec/functional/knife/exec_spec.rb +2 -2
- data/spec/functional/provider/remote_file/cache_control_data_spec.rb +101 -0
- data/spec/functional/resource/batch_spec.rb +64 -0
- data/spec/functional/resource/cookbook_file_spec.rb +2 -3
- data/spec/functional/resource/deploy_revision_spec.rb +180 -0
- data/spec/functional/resource/directory_spec.rb +2 -2
- data/spec/functional/resource/file_spec.rb +17 -1
- data/spec/functional/resource/git_spec.rb +259 -0
- data/spec/functional/resource/link_spec.rb +422 -388
- data/spec/functional/resource/package_spec.rb +297 -0
- data/spec/functional/resource/powershell_spec.rb +188 -0
- data/spec/functional/resource/registry_spec.rb +8 -4
- data/spec/functional/resource/remote_directory_spec.rb +2 -2
- data/spec/functional/resource/remote_file_spec.rb +97 -29
- data/spec/functional/resource/template_spec.rb +173 -17
- data/spec/functional/resource/user_spec.rb +547 -0
- data/spec/functional/run_lock_spec.rb +5 -0
- data/spec/functional/shell_spec.rb +2 -1
- data/spec/functional/win32/service_manager_spec.rb +269 -0
- data/spec/functional/win32/versions_spec.rb +78 -0
- data/spec/integration/knife/chef_repo_path_spec.rb +805 -0
- data/spec/integration/knife/chef_repository_file_system_spec.rb +276 -0
- data/spec/integration/knife/chefignore_spec.rb +271 -0
- data/spec/integration/knife/delete_spec.rb +944 -0
- data/spec/integration/knife/deps_spec.rb +648 -0
- data/spec/integration/knife/diff_spec.rb +536 -0
- data/spec/integration/knife/download_spec.rb +962 -0
- data/spec/integration/knife/list_spec.rb +633 -0
- data/spec/integration/knife/raw_spec.rb +166 -0
- data/spec/integration/knife/redirection_spec.rb +57 -0
- data/spec/integration/knife/show_spec.rb +158 -0
- data/spec/integration/knife/upload_spec.rb +1060 -0
- data/spec/integration/solo/solo_spec.rb +41 -0
- data/spec/spec_helper.rb +55 -1
- data/spec/support/chef_helpers.rb +32 -0
- data/spec/support/platform_helpers.rb +40 -0
- data/spec/support/platforms/win32/spec_service.rb +59 -0
- data/spec/support/shared/functional/directory_resource.rb +43 -16
- data/spec/support/shared/functional/file_resource.rb +661 -20
- data/spec/support/shared/functional/securable_resource.rb +109 -8
- data/spec/support/shared/functional/securable_resource_with_reporting.rb +39 -31
- data/spec/support/shared/integration/integration_helper.rb +166 -0
- data/spec/support/shared/integration/knife_support.rb +171 -0
- data/spec/support/shared/unit/execute_resource.rb +125 -0
- data/spec/support/shared/unit/file_system_support.rb +8 -48
- data/spec/support/shared/unit/provider/file.rb +609 -0
- data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +407 -0
- data/spec/support/shared/unit/script_resource.rb +52 -0
- data/spec/support/shared/unit/windows_script_resource.rb +48 -0
- data/spec/tiny_server.rb +13 -11
- data/spec/unit/application/client_spec.rb +39 -1
- data/spec/unit/application/knife_spec.rb +12 -0
- data/spec/unit/application/solo_spec.rb +1 -1
- data/spec/unit/application_spec.rb +57 -2
- data/spec/unit/chef_fs/diff_spec.rb +30 -31
- data/spec/unit/chef_fs/file_pattern_spec.rb +2 -2
- data/spec/unit/chef_fs/file_system_spec.rb +2 -3
- data/spec/unit/client_spec.rb +20 -1
- data/spec/unit/config_spec.rb +70 -52
- data/spec/unit/cookbook/synchronizer_spec.rb +49 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +28 -3
- data/spec/unit/cookbook_loader_spec.rb +3 -2
- data/spec/unit/daemon_spec.rb +7 -7
- data/spec/unit/data_bag_spec.rb +7 -0
- data/spec/unit/deprecation_spec.rb +86 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +183 -88
- data/spec/unit/environment_spec.rb +98 -0
- data/spec/unit/exceptions_spec.rb +6 -1
- data/spec/unit/file_access_control_spec.rb +21 -1
- data/spec/unit/file_content_management/deploy/cp_spec.rb +46 -0
- data/spec/unit/file_content_management/deploy/mv_unix_spec.rb +103 -0
- data/spec/unit/file_content_management/deploy/mv_windows_spec.rb +179 -0
- data/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb +38 -2
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -2
- data/spec/unit/knife/bootstrap_spec.rb +128 -29
- data/spec/unit/knife/configure_spec.rb +42 -26
- data/spec/unit/knife/cookbook_download_spec.rb +24 -3
- data/spec/unit/knife/cookbook_upload_spec.rb +8 -4
- data/spec/unit/knife/core/bootstrap_context_spec.rb +78 -61
- data/spec/unit/knife/core/subcommand_loader_spec.rb +20 -0
- data/spec/unit/knife/core/ui_spec.rb +41 -0
- data/spec/unit/knife/node_run_list_set_spec.rb +140 -0
- data/spec/unit/knife_spec.rb +21 -0
- data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +1 -0
- data/spec/unit/mixin/params_validate_spec.rb +35 -0
- data/spec/unit/mixin/template_spec.rb +69 -57
- data/spec/unit/mixin/windows_architecture_helper_spec.rb +83 -0
- data/spec/unit/node_spec.rb +7 -0
- data/spec/unit/platform_spec.rb +15 -1
- data/spec/unit/provider/cookbook_file/content_spec.rb +40 -0
- data/spec/unit/provider/cookbook_file_spec.rb +26 -183
- data/spec/unit/provider/cron/solaris_spec.rb +1 -1
- data/spec/unit/provider/deploy/revision_spec.rb +19 -11
- data/spec/unit/provider/deploy_spec.rb +2 -2
- data/spec/unit/provider/directory_spec.rb +23 -23
- data/spec/unit/provider/execute_spec.rb +27 -1
- data/spec/unit/provider/file/content_spec.rb +101 -0
- data/spec/unit/provider/file_spec.rb +25 -484
- data/spec/unit/provider/git_spec.rb +224 -28
- data/spec/unit/provider/group/usermod_spec.rb +3 -1
- data/spec/unit/provider/ifconfig/debian_spec.rb +89 -0
- data/spec/unit/provider/ifconfig/redhat_spec.rb +71 -0
- data/spec/unit/provider/ifconfig_spec.rb +0 -33
- data/spec/unit/provider/mount/mount_spec.rb +33 -2
- data/spec/unit/provider/mount/windows_spec.rb +4 -1
- data/spec/unit/provider/mount_spec.rb +16 -6
- data/spec/unit/provider/package/portage_spec.rb +44 -0
- data/spec/unit/provider/package/rubygems_spec.rb +44 -1
- data/spec/unit/provider/package/smartos_spec.rb +3 -2
- data/spec/unit/provider/package/yum_spec.rb +36 -39
- data/spec/unit/provider/package/zypper_spec.rb +84 -22
- data/spec/unit/provider/package_spec.rb +0 -4
- data/spec/unit/provider/powershell_spec.rb +38 -0
- data/spec/unit/provider/remote_directory_spec.rb +0 -4
- data/spec/unit/provider/remote_file/cache_control_data_spec.rb +211 -0
- data/spec/unit/provider/remote_file/content_spec.rb +230 -0
- data/spec/unit/provider/remote_file/fetcher_spec.rb +75 -0
- data/spec/unit/provider/remote_file/ftp_spec.rb +224 -0
- data/spec/unit/provider/remote_file/http_spec.rb +319 -0
- data/spec/unit/provider/remote_file/local_file_spec.rb +60 -0
- data/spec/unit/provider/remote_file_spec.rb +33 -295
- data/spec/unit/provider/route_spec.rb +25 -9
- data/spec/unit/provider/service/macosx_spec.rb +176 -152
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +21 -18
- data/spec/unit/provider/service/systemd_service_spec.rb +2 -2
- data/spec/unit/provider/service/upstart_service_spec.rb +2 -2
- data/spec/unit/provider/service_spec.rb +3 -3
- data/spec/unit/provider/template/content_spec.rb +78 -0
- data/spec/unit/provider/template_spec.rb +52 -184
- data/spec/unit/provider/user/solaris_spec.rb +80 -0
- data/spec/unit/provider/user/useradd_spec.rb +12 -358
- data/spec/unit/resource/batch_spec.rb +48 -0
- data/spec/unit/resource/conditional_action_not_nothing_spec.rb +45 -0
- data/spec/unit/resource/execute_spec.rb +3 -101
- data/spec/unit/resource/file_spec.rb +0 -5
- data/spec/unit/resource/group_spec.rb +9 -0
- data/spec/unit/resource/ifconfig_spec.rb +60 -1
- data/spec/unit/resource/link_spec.rb +1 -0
- data/spec/unit/resource/mount_spec.rb +37 -0
- data/spec/unit/resource/powershell_spec.rb +48 -0
- data/spec/unit/resource/remote_file_spec.rb +44 -4
- data/spec/unit/resource/route_spec.rb +1 -1
- data/spec/unit/resource/script_spec.rb +13 -36
- data/spec/unit/resource/template_spec.rb +111 -8
- data/spec/unit/resource/user_spec.rb +7 -0
- data/spec/unit/resource_collection_spec.rb +61 -32
- data/spec/unit/resource_reporter_spec.rb +115 -102
- data/spec/unit/resource_spec.rb +170 -1
- data/spec/unit/rest/auth_credentials_spec.rb +2 -2
- data/spec/unit/rest_spec.rb +6 -2
- data/spec/unit/run_context/cookbook_compiler_spec.rb +9 -0
- data/spec/unit/runner_spec.rb +1 -1
- data/spec/unit/scan_access_control_spec.rb +4 -2
- data/spec/unit/shell/shell_session_spec.rb +15 -2
- data/spec/unit/util/backup_spec.rb +149 -0
- data/spec/unit/util/diff_spec.rb +596 -0
- data/spec/unit/util/selinux_spec.rb +172 -0
- data/spec/unit/version/platform_spec.rb +61 -0
- data/spec/unit/version_constraint/platform_spec.rb +46 -0
- data/spec/unit/version_constraint_spec.rb +5 -0
- metadata +233 -10
- data/lib/chef/chef_fs/file_system/data_bag_item.rb +0 -59
- data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +0 -237
- data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +0 -568
- data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +0 -220
|
@@ -112,14 +112,18 @@ describe Chef::Resource::RegistryKey, :windows_only do
|
|
|
112
112
|
#Reporting setup
|
|
113
113
|
before do
|
|
114
114
|
@node.name("windowsbox")
|
|
115
|
+
|
|
115
116
|
@rest_client = mock("Chef::REST (mock)")
|
|
116
|
-
@rest_client.stub!(:create_url).and_return("reports/nodes/windowsbox/runs
|
|
117
|
+
@rest_client.stub!(:create_url).and_return("reports/nodes/windowsbox/runs/#{@run_id}");
|
|
117
118
|
@rest_client.stub!(:raw_http_request).and_return({"result"=>"ok"});
|
|
118
|
-
@rest_client.stub!(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/windowsbox/runs
|
|
119
|
+
@rest_client.stub!(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/windowsbox/runs/#{@run_id}"});
|
|
119
120
|
|
|
120
121
|
@resource_reporter = Chef::ResourceReporter.new(@rest_client)
|
|
121
122
|
@events.register(@resource_reporter)
|
|
122
|
-
@resource_reporter.
|
|
123
|
+
@run_id = @resource_reporter.run_id
|
|
124
|
+
@run_status = Chef::RunStatus.new(@node, @events)
|
|
125
|
+
|
|
126
|
+
@resource_reporter.run_started(@run_status)
|
|
123
127
|
|
|
124
128
|
@new_resource.cookbook_name = "monkey"
|
|
125
129
|
@cookbook_version = mock("Cookbook::Version", :version => "1.2.3")
|
|
@@ -537,7 +541,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
|
|
|
537
541
|
@report["resources"][0]["type"].should == "registry_key"
|
|
538
542
|
@report["resources"][0]["name"].should == resource_name
|
|
539
543
|
@report["resources"][0]["id"].should == reg_parent + '\ReportKey'
|
|
540
|
-
#Not testing for before or after values to match since
|
|
544
|
+
#Not testing for before or after values to match since
|
|
541
545
|
#after -> new_resource.values and
|
|
542
546
|
#before -> current_resource.values
|
|
543
547
|
@report["resources"][0]["result"].should == "delete_key"
|
|
@@ -22,7 +22,7 @@ describe Chef::Resource::RemoteDirectory do
|
|
|
22
22
|
include_context Chef::Resource::Directory
|
|
23
23
|
|
|
24
24
|
let(:directory_base) { "directory_spec" }
|
|
25
|
-
let(:default_mode) {
|
|
25
|
+
let(:default_mode) { ((0100777 - File.umask) & 07777).to_s(8) }
|
|
26
26
|
|
|
27
27
|
def create_resource
|
|
28
28
|
cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
|
|
@@ -48,7 +48,7 @@ describe Chef::Resource::RemoteDirectory do
|
|
|
48
48
|
FileUtils.touch(@existing2)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
let
|
|
51
|
+
let(:resource) do
|
|
52
52
|
create_resource
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -20,17 +20,22 @@ require 'spec_helper'
|
|
|
20
20
|
require 'tiny_server'
|
|
21
21
|
|
|
22
22
|
describe Chef::Resource::RemoteFile do
|
|
23
|
+
|
|
24
|
+
let(:file_cache_path) { Dir.mktmpdir }
|
|
25
|
+
|
|
26
|
+
before(:each) do
|
|
27
|
+
@old_file_cache = Chef::Config[:file_cache_path]
|
|
28
|
+
Chef::Config[:file_cache_path] = file_cache_path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
after(:each) do
|
|
32
|
+
Chef::Config[:file_cache_path] = @old_file_cache
|
|
33
|
+
FileUtils.rm_rf(file_cache_path)
|
|
34
|
+
end
|
|
35
|
+
|
|
23
36
|
include_context Chef::Resource::File
|
|
24
37
|
|
|
25
38
|
let(:file_base) { "remote_file_spec" }
|
|
26
|
-
let(:source) { 'http://localhost:9000/nyan_cat.png' }
|
|
27
|
-
let(:expected_content) do
|
|
28
|
-
content = File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png'), "rb") do |f|
|
|
29
|
-
f.read
|
|
30
|
-
end
|
|
31
|
-
content.force_encoding(Encoding::BINARY) if content.respond_to?(:force_encoding)
|
|
32
|
-
content
|
|
33
|
-
end
|
|
34
39
|
|
|
35
40
|
def create_resource
|
|
36
41
|
node = Chef::Node.new
|
|
@@ -41,28 +46,14 @@ describe Chef::Resource::RemoteFile do
|
|
|
41
46
|
resource
|
|
42
47
|
end
|
|
43
48
|
|
|
44
|
-
let
|
|
49
|
+
let(:resource) do
|
|
45
50
|
create_resource
|
|
46
51
|
end
|
|
47
52
|
|
|
48
|
-
let(:default_mode)
|
|
49
|
-
# TODO: Lots of ugly here :(
|
|
50
|
-
# RemoteFile uses FileUtils.cp. FileUtils does a copy by opening the
|
|
51
|
-
# destination file and writing to it. Before 1.9.3, it does not preserve
|
|
52
|
-
# the mode of the copied file. In 1.9.3 and after, it does. So we have to
|
|
53
|
-
# figure out what the default mode ought to be via heuristic.
|
|
54
|
-
|
|
55
|
-
t = Tempfile.new("get-the-mode")
|
|
56
|
-
path = t.path
|
|
57
|
-
path_2 = t.path + "fileutils-mode-test"
|
|
58
|
-
FileUtils.cp(path, path_2)
|
|
59
|
-
t.close
|
|
60
|
-
m = File.stat(path_2).mode
|
|
61
|
-
(07777 & m).to_s(8)
|
|
62
|
-
end
|
|
53
|
+
let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
@server = TinyServer::Manager.new
|
|
55
|
+
def start_tiny_server(server_opts={})
|
|
56
|
+
@server = TinyServer::Manager.new(server_opts)
|
|
66
57
|
@server.start
|
|
67
58
|
@api = TinyServer::API.instance
|
|
68
59
|
@api.clear
|
|
@@ -71,13 +62,90 @@ describe Chef::Resource::RemoteFile do
|
|
|
71
62
|
f.read
|
|
72
63
|
end
|
|
73
64
|
}
|
|
65
|
+
@api.get("/nyan_cat.png.gz", 200, nil, { 'Content-Type' => 'application/gzip', 'Content-Encoding' => 'gzip' } ) {
|
|
66
|
+
File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png.gz'), "rb") do |f|
|
|
67
|
+
f.read
|
|
68
|
+
end
|
|
69
|
+
}
|
|
74
70
|
end
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
def stop_tiny_server
|
|
77
73
|
@server.stop
|
|
74
|
+
@server = @api = nil
|
|
78
75
|
end
|
|
79
76
|
|
|
80
|
-
|
|
77
|
+
context "when fetching files over HTTP" do
|
|
78
|
+
before(:all) do
|
|
79
|
+
start_tiny_server
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
after(:all) do
|
|
83
|
+
stop_tiny_server
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context "when using normal encoding" do
|
|
87
|
+
let(:source) { 'http://localhost:9000/nyan_cat.png' }
|
|
88
|
+
let(:expected_content) do
|
|
89
|
+
content = File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png'), "rb") do |f|
|
|
90
|
+
f.read
|
|
91
|
+
end
|
|
92
|
+
content.force_encoding(Encoding::BINARY) if content.respond_to?(:force_encoding)
|
|
93
|
+
content
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it_behaves_like "a file resource"
|
|
97
|
+
|
|
98
|
+
it_behaves_like "a securable resource with reporting"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "when using gzip encoding" do
|
|
102
|
+
let(:source) { 'http://localhost:9000/nyan_cat.png.gz' }
|
|
103
|
+
let(:expected_content) do
|
|
104
|
+
content = File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png.gz'), "rb") do |f|
|
|
105
|
+
f.read
|
|
106
|
+
end
|
|
107
|
+
content.force_encoding(Encoding::BINARY) if content.respond_to?(:force_encoding)
|
|
108
|
+
content
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it_behaves_like "a file resource"
|
|
112
|
+
|
|
113
|
+
it_behaves_like "a securable resource with reporting"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "when fetching files over HTTPS" do
|
|
118
|
+
|
|
119
|
+
before(:all) do
|
|
120
|
+
cert_text = File.read(File.expand_path("ssl/chef-rspec.cert", CHEF_SPEC_DATA))
|
|
121
|
+
cert = OpenSSL::X509::Certificate.new(cert_text)
|
|
122
|
+
key_text = File.read(File.expand_path("ssl/chef-rspec.key", CHEF_SPEC_DATA))
|
|
123
|
+
key = OpenSSL::PKey::RSA.new(key_text)
|
|
124
|
+
|
|
125
|
+
server_opts = { :SSLEnable => true,
|
|
126
|
+
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
|
|
127
|
+
:SSLCertificate => cert,
|
|
128
|
+
:SSLPrivateKey => key }
|
|
129
|
+
|
|
130
|
+
start_tiny_server(server_opts)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
after(:all) do
|
|
134
|
+
stop_tiny_server
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
let(:source) { 'https://localhost:9000/nyan_cat.png' }
|
|
138
|
+
|
|
139
|
+
let(:expected_content) do
|
|
140
|
+
content = File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png'), "rb") do |f|
|
|
141
|
+
f.read
|
|
142
|
+
end
|
|
143
|
+
content.force_encoding(Encoding::BINARY) if content.respond_to?(:force_encoding)
|
|
144
|
+
content
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it_behaves_like "a file resource"
|
|
148
|
+
|
|
149
|
+
end
|
|
81
150
|
|
|
82
|
-
it_behaves_like "a securable resource with reporting"
|
|
83
151
|
end
|
|
@@ -20,6 +20,10 @@ require 'spec_helper'
|
|
|
20
20
|
|
|
21
21
|
describe Chef::Resource::Template do
|
|
22
22
|
|
|
23
|
+
def binread(file)
|
|
24
|
+
File.open(file,"rb") {|f| f.read }
|
|
25
|
+
end
|
|
26
|
+
|
|
23
27
|
include_context Chef::Resource::File
|
|
24
28
|
|
|
25
29
|
let(:file_base) { "template_spec" }
|
|
@@ -42,29 +46,19 @@ describe Chef::Resource::Template do
|
|
|
42
46
|
resource = Chef::Resource::Template.new(path, run_context)
|
|
43
47
|
resource.source('openldap_stuff.conf.erb')
|
|
44
48
|
resource.cookbook('openldap')
|
|
49
|
+
|
|
50
|
+
# NOTE: partials rely on `cookbook_name` getting set by chef internals and
|
|
51
|
+
# ignore the user-set `cookbook` attribute.
|
|
52
|
+
resource.cookbook_name = "openldap"
|
|
53
|
+
|
|
45
54
|
resource
|
|
46
55
|
end
|
|
47
56
|
|
|
48
|
-
let
|
|
57
|
+
let(:resource) do
|
|
49
58
|
create_resource
|
|
50
59
|
end
|
|
51
60
|
|
|
52
|
-
let(:default_mode)
|
|
53
|
-
# TODO: Lots of ugly here :(
|
|
54
|
-
# RemoteFile uses FileUtils.cp. FileUtils does a copy by opening the
|
|
55
|
-
# destination file and writing to it. Before 1.9.3, it does not preserve
|
|
56
|
-
# the mode of the copied file. In 1.9.3 and after, it does. So we have to
|
|
57
|
-
# figure out what the default mode ought to be via heuristic.
|
|
58
|
-
|
|
59
|
-
t = Tempfile.new("get-the-mode")
|
|
60
|
-
path = t.path
|
|
61
|
-
path_2 = t.path + "fileutils-mode-test"
|
|
62
|
-
FileUtils.cp(path, path_2)
|
|
63
|
-
t.close
|
|
64
|
-
m = File.stat(path_2).mode
|
|
65
|
-
(07777 & m).to_s(8)
|
|
66
|
-
end
|
|
67
|
-
|
|
61
|
+
let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
|
|
68
62
|
|
|
69
63
|
it_behaves_like "a file resource"
|
|
70
64
|
|
|
@@ -86,4 +80,166 @@ describe Chef::Resource::Template do
|
|
|
86
80
|
IO.read(path).should == expected_content
|
|
87
81
|
end
|
|
88
82
|
end
|
|
83
|
+
|
|
84
|
+
describe "when the template resource defines helper methods" do
|
|
85
|
+
|
|
86
|
+
include_context "diff disabled"
|
|
87
|
+
|
|
88
|
+
let(:resource) do
|
|
89
|
+
r = create_resource
|
|
90
|
+
r.source "helper_test.erb"
|
|
91
|
+
r
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
let(:expected_content) { "value from helper method" }
|
|
95
|
+
|
|
96
|
+
shared_examples "a template with helpers" do
|
|
97
|
+
it "generates expected content by calling helper methods" do
|
|
98
|
+
resource.run_action(:create)
|
|
99
|
+
binread(path).strip.should == expected_content
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "using single helper syntax" do
|
|
104
|
+
before do
|
|
105
|
+
resource.helper(:helper_method) { "value from helper method" }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it_behaves_like "a template with helpers"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context "using single helper syntax referencing @node" do
|
|
112
|
+
before do
|
|
113
|
+
node.set[:helper_test_attr] = "value from helper method"
|
|
114
|
+
resource.helper(:helper_method) { "#{@node[:helper_test_attr]}" }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it_behaves_like "a template with helpers"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "using an inline block to define helpers" do
|
|
121
|
+
before do
|
|
122
|
+
resource.helpers do
|
|
123
|
+
def helper_method
|
|
124
|
+
"value from helper method"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it_behaves_like "a template with helpers"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "using an inline block referencing @node" do
|
|
133
|
+
before do
|
|
134
|
+
node.set[:helper_test_attr] = "value from helper method"
|
|
135
|
+
|
|
136
|
+
resource.helpers do
|
|
137
|
+
def helper_method
|
|
138
|
+
@node[:helper_test_attr]
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it_behaves_like "a template with helpers"
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
context "using a module from a library" do
|
|
148
|
+
|
|
149
|
+
module ExampleModule
|
|
150
|
+
def helper_method
|
|
151
|
+
"value from helper method"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
before do
|
|
156
|
+
resource.helpers(ExampleModule)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it_behaves_like "a template with helpers"
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
context "using a module from a library referencing @node" do
|
|
163
|
+
|
|
164
|
+
module ExampleModuleReferencingATNode
|
|
165
|
+
def helper_method
|
|
166
|
+
@node[:helper_test_attr]
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
before do
|
|
171
|
+
node.set[:helper_test_attr] = "value from helper method"
|
|
172
|
+
|
|
173
|
+
resource.helpers(ExampleModuleReferencingATNode)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it_behaves_like "a template with helpers"
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
context "using helpers with partial templates" do
|
|
181
|
+
before do
|
|
182
|
+
resource.source("helpers_via_partial_test.erb")
|
|
183
|
+
resource.helper(:helper_method) { "value from helper method" }
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it_behaves_like "a template with helpers"
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
describe "when template source contains windows style line endings" do
|
|
192
|
+
|
|
193
|
+
include_context "diff disabled"
|
|
194
|
+
|
|
195
|
+
let(:expected_content) {
|
|
196
|
+
"Template rendering libraries\r\nshould support\r\ndifferent line endings\r\n\r\n"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
context "for all lines" do
|
|
200
|
+
let(:resource) do
|
|
201
|
+
r = create_resource
|
|
202
|
+
r.source "all_windows_line_endings.erb"
|
|
203
|
+
r
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "output should contain windows line endings" do
|
|
207
|
+
resource.run_action(:create)
|
|
208
|
+
binread(path).each_line do |line|
|
|
209
|
+
line.should end_with("\r\n")
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
context "for some lines" do
|
|
215
|
+
let(:resource) do
|
|
216
|
+
r = create_resource
|
|
217
|
+
r.source "some_windows_line_endings.erb"
|
|
218
|
+
r
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "output should contain windows line endings" do
|
|
222
|
+
resource.run_action(:create)
|
|
223
|
+
binread(path).each_line do |line|
|
|
224
|
+
line.should end_with("\r\n")
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
context "for no lines" do
|
|
230
|
+
let(:resource) do
|
|
231
|
+
r = create_resource
|
|
232
|
+
r.source "no_windows_line_endings.erb"
|
|
233
|
+
r
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "output should not contain windows line endings" do
|
|
237
|
+
resource.run_action(:create)
|
|
238
|
+
IO.read(path).each_line do |line|
|
|
239
|
+
line.should_not end_with("\r\n")
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
89
245
|
end
|
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
|
4
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
|
5
|
+
# License:: Apache License, Version 2.0
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
require 'spec_helper'
|
|
21
|
+
require 'chef/mixin/shell_out'
|
|
22
|
+
|
|
23
|
+
metadata = { :unix_only => true,
|
|
24
|
+
:requires_root => true,
|
|
25
|
+
:provider => {:user => Chef::Provider::User::Useradd}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe Chef::Resource::User, metadata do
|
|
29
|
+
|
|
30
|
+
include Chef::Mixin::ShellOut
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Utility code for /etc/passwd interaction, avoid any caching of user records:
|
|
34
|
+
PwEntry = Struct.new(:name, :passwd, :uid, :gid, :gecos, :home, :shell)
|
|
35
|
+
|
|
36
|
+
class UserNotFound < StandardError; end
|
|
37
|
+
|
|
38
|
+
def pw_entry
|
|
39
|
+
passwd_file = File.open("/etc/passwd", "rb") {|f| f.read}
|
|
40
|
+
matcher = /^#{Regexp.escape(username)}.+$/
|
|
41
|
+
if passwd_entry = passwd_file.scan(matcher).first
|
|
42
|
+
PwEntry.new(*passwd_entry.split(':'))
|
|
43
|
+
else
|
|
44
|
+
raise UserNotFound, "no entry matching #{matcher.inspect} found in /etc/passwd"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def etc_shadow
|
|
49
|
+
File.open("/etc/shadow") {|f| f.read }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def supports_quote_in_username?
|
|
53
|
+
OHAI_SYSTEM["platform_family"] == "debian"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
before do
|
|
57
|
+
# Silence shell_out live stream
|
|
58
|
+
Chef::Log.level = :warn
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
after do
|
|
62
|
+
begin
|
|
63
|
+
pw_entry # will raise if the user doesn't exist
|
|
64
|
+
shell_out!("userdel", "-f", "-r", username, :returns => [0,12])
|
|
65
|
+
rescue UserNotFound
|
|
66
|
+
# nothing to remove
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
let(:node) do
|
|
71
|
+
n = Chef::Node.new
|
|
72
|
+
n.consume_external_attrs(OHAI_SYSTEM.data.dup, {})
|
|
73
|
+
n
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
let(:events) do
|
|
77
|
+
Chef::EventDispatch::Dispatcher.new
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
let(:run_context) do
|
|
81
|
+
Chef::RunContext.new(node, {}, events)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
let(:username) do
|
|
85
|
+
"chef-functional-test"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
let(:uid) { nil }
|
|
89
|
+
let(:home) { nil }
|
|
90
|
+
let(:manage_home) { false }
|
|
91
|
+
let(:password) { nil }
|
|
92
|
+
let(:system) { false }
|
|
93
|
+
let(:comment) { nil }
|
|
94
|
+
|
|
95
|
+
let(:user_resource) do
|
|
96
|
+
r = Chef::Resource::User.new("TEST USER RESOURCE", run_context)
|
|
97
|
+
r.username(username)
|
|
98
|
+
r.uid(uid)
|
|
99
|
+
r.home(home)
|
|
100
|
+
r.comment(comment)
|
|
101
|
+
r.manage_home(manage_home)
|
|
102
|
+
r.password(password)
|
|
103
|
+
r.system(system)
|
|
104
|
+
r
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
let(:skip) { false }
|
|
108
|
+
|
|
109
|
+
describe "action :create" do
|
|
110
|
+
|
|
111
|
+
context "when the user does not exist beforehand" do
|
|
112
|
+
before do
|
|
113
|
+
if reason = skip
|
|
114
|
+
pending(reason)
|
|
115
|
+
end
|
|
116
|
+
user_resource.run_action(:create)
|
|
117
|
+
user_resource.should be_updated_by_last_action
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
it "ensures the user exists" do
|
|
122
|
+
pw_entry.name.should == username
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# On Debian, the only constraints are that usernames must neither start
|
|
126
|
+
# with a dash ('-') nor plus ('+') nor tilde ('~') nor contain a colon
|
|
127
|
+
# (':'), a comma (','), or a whitespace (space: ' ', end of line: '\n',
|
|
128
|
+
# tabulation: '\t', etc.). Note that using a slash ('/') may break the
|
|
129
|
+
# default algorithm for the definition of the user's home directory.
|
|
130
|
+
|
|
131
|
+
context "and the username contains a single quote" do
|
|
132
|
+
let(:skip) do
|
|
133
|
+
if supports_quote_in_username?
|
|
134
|
+
false
|
|
135
|
+
else
|
|
136
|
+
"Platform #{OHAI_SYSTEM["platform"]} not expected to support username w/ quote"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
let(:username) { "t'bilisi" }
|
|
141
|
+
|
|
142
|
+
it "ensures the user exists" do
|
|
143
|
+
pw_entry.name.should == username
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
context "when uid is set" do
|
|
149
|
+
# Should verify uid not in use...
|
|
150
|
+
let(:uid) { 1999 }
|
|
151
|
+
|
|
152
|
+
it "ensures the user has the given uid" do
|
|
153
|
+
pw_entry.uid.should == "1999"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context "when comment is set" do
|
|
158
|
+
let(:comment) { "hello this is dog" }
|
|
159
|
+
|
|
160
|
+
it "ensures the comment is set" do
|
|
161
|
+
pw_entry.gecos.should == "hello this is dog"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context "in standard gecos format" do
|
|
165
|
+
let(:comment) { "Bobo T. Clown,some building,555-555-5555,@boboclown" }
|
|
166
|
+
|
|
167
|
+
it "ensures the comment is set" do
|
|
168
|
+
pw_entry.gecos.should == comment
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
context "to a string containing multibyte characters" do
|
|
173
|
+
let(:comment) { "(╯°□°)╯︵ ┻━┻" }
|
|
174
|
+
|
|
175
|
+
it "ensures the comment is set" do
|
|
176
|
+
actual = pw_entry.gecos
|
|
177
|
+
actual.force_encoding(Encoding::UTF_8) if "".respond_to?(:force_encoding)
|
|
178
|
+
actual.should == comment
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context "to a string containing an apostrophe `'`" do
|
|
183
|
+
let(:comment) { "don't go" }
|
|
184
|
+
|
|
185
|
+
it "ensures the comment is set" do
|
|
186
|
+
pw_entry.gecos.should == comment
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context "when home is set" do
|
|
192
|
+
let(:home) { "/home/#{username}" }
|
|
193
|
+
|
|
194
|
+
it "ensures the user's home is set to the given path" do
|
|
195
|
+
pw_entry.home.should == "/home/#{username}"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
if OHAI_SYSTEM["platform_family"] == "rhel"
|
|
199
|
+
# Inconsistent behavior. See: CHEF-2205
|
|
200
|
+
it "creates the home dir when not explicitly asked to on RHEL (XXX)" do
|
|
201
|
+
File.should exist("/home/#{username}")
|
|
202
|
+
end
|
|
203
|
+
else
|
|
204
|
+
it "does not create the home dir without `manage_home'" do
|
|
205
|
+
File.should_not exist("/home/#{username}")
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
context "and manage_home is enabled" do
|
|
210
|
+
let(:manage_home) { true }
|
|
211
|
+
|
|
212
|
+
it "ensures the user's home directory exists" do
|
|
213
|
+
File.should exist("/home/#{username}")
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
context "when a password is specified" do
|
|
219
|
+
# openssl passwd -1 "secretpassword"
|
|
220
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
221
|
+
it "sets the user's shadow password" do
|
|
222
|
+
pw_entry.passwd.should == "x"
|
|
223
|
+
expected_shadow = "chef-functional-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
|
|
224
|
+
etc_shadow.should include(expected_shadow)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
context "when a system user is specified" do
|
|
229
|
+
let(:system) { true }
|
|
230
|
+
let(:uid_min) do
|
|
231
|
+
# from `man useradd`, login user means uid will be between
|
|
232
|
+
# UID_SYS_MIN and UID_SYS_MAX defined in /etc/login.defs. On my
|
|
233
|
+
# Ubuntu 13.04 system, these are commented out, so we'll look at
|
|
234
|
+
# UID_MIN to find the lower limit of the non-system-user range, and
|
|
235
|
+
# use that value in our assertions.
|
|
236
|
+
login_defs = File.open("/etc/login.defs", "rb") {|f| f.read }
|
|
237
|
+
uid_min_scan = /^UID_MIN\s+(\d+)/
|
|
238
|
+
login_defs.match(uid_min_scan)[1]
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it "ensures the user has the properties of a system user" do
|
|
242
|
+
pw_entry.uid.to_i.should be < uid_min.to_i
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end # when the user does not exist beforehand
|
|
246
|
+
|
|
247
|
+
context "when the user already exists" do
|
|
248
|
+
|
|
249
|
+
let(:expect_updated?) { true }
|
|
250
|
+
|
|
251
|
+
let(:existing_uid) { nil }
|
|
252
|
+
let(:existing_home) { nil }
|
|
253
|
+
let(:existing_manage_home) { false }
|
|
254
|
+
let(:existing_password) { nil }
|
|
255
|
+
let(:existing_system) { false }
|
|
256
|
+
let(:existing_comment) { nil }
|
|
257
|
+
|
|
258
|
+
let(:existing_user) do
|
|
259
|
+
r = Chef::Resource::User.new("TEST USER RESOURCE", run_context)
|
|
260
|
+
# username is identity attr, must match.
|
|
261
|
+
r.username(username)
|
|
262
|
+
r.uid(existing_uid)
|
|
263
|
+
r.home(existing_home)
|
|
264
|
+
r.comment(existing_comment)
|
|
265
|
+
r.manage_home(existing_manage_home)
|
|
266
|
+
r.password(existing_password)
|
|
267
|
+
r.system(existing_system)
|
|
268
|
+
r
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
before do
|
|
272
|
+
if reason = skip
|
|
273
|
+
pending(reason)
|
|
274
|
+
end
|
|
275
|
+
existing_user.run_action(:create)
|
|
276
|
+
existing_user.should be_updated_by_last_action
|
|
277
|
+
user_resource.run_action(:create)
|
|
278
|
+
user_resource.updated_by_last_action?.should == expect_updated?
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
context "and all properties are in the desired state" do
|
|
282
|
+
let(:uid) { 1999 }
|
|
283
|
+
let(:home) { "/home/bobo" }
|
|
284
|
+
let(:manage_home) { true }
|
|
285
|
+
# openssl passwd -1 "secretpassword"
|
|
286
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
287
|
+
let(:system) { false }
|
|
288
|
+
let(:comment) { "hello this is dog" }
|
|
289
|
+
|
|
290
|
+
let(:existing_uid) { uid }
|
|
291
|
+
let(:existing_home) { home }
|
|
292
|
+
let(:existing_manage_home) { manage_home }
|
|
293
|
+
let(:existing_password) { password }
|
|
294
|
+
let(:existing_system) { false }
|
|
295
|
+
let(:existing_comment) { comment }
|
|
296
|
+
|
|
297
|
+
let(:expect_updated?) { false }
|
|
298
|
+
|
|
299
|
+
it "does not update the user" do
|
|
300
|
+
user_resource.should_not be_updated
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
context "and the uid is updated" do
|
|
305
|
+
let(:uid) { 1999 }
|
|
306
|
+
let(:existing_uid) { 1998 }
|
|
307
|
+
|
|
308
|
+
it "ensures the uid is set to the desired value" do
|
|
309
|
+
pw_entry.uid.should == "1999"
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
context "and the comment is updated" do
|
|
314
|
+
let(:comment) { "hello this is dog" }
|
|
315
|
+
let(:existing_comment) { "woof" }
|
|
316
|
+
|
|
317
|
+
it "ensures the comment field is set to the desired value" do
|
|
318
|
+
pw_entry.gecos.should == "hello this is dog"
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
context "and home directory is updated" do
|
|
323
|
+
let(:existing_home) { "/home/foo" }
|
|
324
|
+
let(:home) { "/home/bar" }
|
|
325
|
+
it "ensures the home directory is set to the desired value" do
|
|
326
|
+
pw_entry.home.should == "/home/bar"
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
context "and manage_home is enabled" do
|
|
330
|
+
let(:existing_manage_home) { true }
|
|
331
|
+
let(:manage_home) { true }
|
|
332
|
+
it "moves the home directory to the new location" do
|
|
333
|
+
File.should_not exist("/home/foo")
|
|
334
|
+
File.should exist("/home/bar")
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
context "and manage_home wasn't enabled but is now" do
|
|
339
|
+
let(:existing_manage_home) { false }
|
|
340
|
+
let(:manage_home) { true }
|
|
341
|
+
|
|
342
|
+
if OHAI_SYSTEM["platform_family"] == "rhel"
|
|
343
|
+
# Inconsistent behavior. See: CHEF-2205
|
|
344
|
+
it "created the home dir b/c of CHEF-2205 so it still exists" do
|
|
345
|
+
# This behavior seems contrary to expectation and non-convergent.
|
|
346
|
+
File.should_not exist("/home/foo")
|
|
347
|
+
File.should exist("/home/bar")
|
|
348
|
+
end
|
|
349
|
+
else
|
|
350
|
+
it "does not create the home dir in the desired location (XXX)" do
|
|
351
|
+
# This behavior seems contrary to expectation and non-convergent.
|
|
352
|
+
File.should_not exist("/home/foo")
|
|
353
|
+
File.should_not exist("/home/bar")
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
context "and manage_home was enabled but is not now" do
|
|
359
|
+
let(:existing_manage_home) { true }
|
|
360
|
+
let(:manage_home) { false }
|
|
361
|
+
|
|
362
|
+
it "leaves the old home directory around (XXX)" do
|
|
363
|
+
# Would it be better to remove the old home?
|
|
364
|
+
File.should exist("/home/foo")
|
|
365
|
+
File.should_not exist("/home/bar")
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
context "and a password is added" do
|
|
371
|
+
# openssl passwd -1 "secretpassword"
|
|
372
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
373
|
+
|
|
374
|
+
it "ensures the password is set" do
|
|
375
|
+
pw_entry.passwd.should == "x"
|
|
376
|
+
expected_shadow = "chef-functional-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
|
|
377
|
+
etc_shadow.should include(expected_shadow)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
context "and the password is updated" do
|
|
383
|
+
# openssl passwd -1 "OLDpassword"
|
|
384
|
+
let(:existing_password) { "$1$1dVmwm4z$CftsFn8eBDjDRUytYKkXB." }
|
|
385
|
+
# openssl passwd -1 "secretpassword"
|
|
386
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
387
|
+
|
|
388
|
+
it "ensures the password is set to the desired value" do
|
|
389
|
+
pw_entry.passwd.should == "x"
|
|
390
|
+
expected_shadow = "chef-functional-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
|
|
391
|
+
etc_shadow.should include(expected_shadow)
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
context "and the user is changed from not-system to system" do
|
|
396
|
+
let(:existing_system) { false }
|
|
397
|
+
let(:system) { true }
|
|
398
|
+
|
|
399
|
+
let(:expect_updated?) { false }
|
|
400
|
+
|
|
401
|
+
it "does not modify the user at all" do
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
context "and the user is changed from system to not-system" do
|
|
406
|
+
let(:existing_system) { true }
|
|
407
|
+
let(:system) { false }
|
|
408
|
+
|
|
409
|
+
let(:expect_updated?) { false }
|
|
410
|
+
|
|
411
|
+
it "does not modify the user at all" do
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
end # when the user already exists
|
|
416
|
+
end # action :create
|
|
417
|
+
|
|
418
|
+
shared_context "user exists for lock/unlock" do
|
|
419
|
+
let(:user_locked_context?) { false }
|
|
420
|
+
|
|
421
|
+
def shadow_entry
|
|
422
|
+
etc_shadow.lines.select {|l| l.include?(username) }.first
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def shadow_password
|
|
426
|
+
shadow_entry.split(':')[1]
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
before do
|
|
430
|
+
# create user and setup locked/unlocked state
|
|
431
|
+
user_resource.dup.run_action(:create)
|
|
432
|
+
|
|
433
|
+
if user_locked_context?
|
|
434
|
+
shell_out!("usermod -L #{username}")
|
|
435
|
+
shadow_password.should include("!")
|
|
436
|
+
elsif password
|
|
437
|
+
shadow_password.should_not include("!")
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
describe "action :lock" do
|
|
443
|
+
context "when the user does not exist" do
|
|
444
|
+
it "raises a sensible error" do
|
|
445
|
+
expect { user_resource.run_action(:lock) }.to raise_error(Chef::Exceptions::User)
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
context "when the user exists" do
|
|
450
|
+
|
|
451
|
+
include_context "user exists for lock/unlock"
|
|
452
|
+
|
|
453
|
+
before do
|
|
454
|
+
user_resource.run_action(:lock)
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
context "and the user is not locked" do
|
|
458
|
+
# user will be locked if it has no password
|
|
459
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
460
|
+
|
|
461
|
+
it "locks the user's password" do
|
|
462
|
+
shadow_password.should include("!")
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
context "and the user is locked" do
|
|
467
|
+
# user will be locked if it has no password
|
|
468
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
469
|
+
let(:user_locked_context?) { true }
|
|
470
|
+
it "does not update the user" do
|
|
471
|
+
user_resource.should_not be_updated_by_last_action
|
|
472
|
+
end
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
end # action :lock
|
|
476
|
+
|
|
477
|
+
describe "action :unlock" do
|
|
478
|
+
context "when the user does not exist" do
|
|
479
|
+
it "raises a sensible error" do
|
|
480
|
+
expect { user_resource.run_action(:unlock) }.to raise_error(Chef::Exceptions::User)
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
context "when the user exists" do
|
|
485
|
+
|
|
486
|
+
include_context "user exists for lock/unlock"
|
|
487
|
+
|
|
488
|
+
before do
|
|
489
|
+
begin
|
|
490
|
+
user_resource.run_action(:unlock)
|
|
491
|
+
@error = nil
|
|
492
|
+
rescue Exception => e
|
|
493
|
+
@error = e
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
context "and has no password" do
|
|
498
|
+
|
|
499
|
+
# TODO: platform_family should be setup in spec_helper w/ tags
|
|
500
|
+
if OHAI_SYSTEM["platform_family"] == "suse"
|
|
501
|
+
# suse gets this right:
|
|
502
|
+
it "errors out trying to unlock the user" do
|
|
503
|
+
@error.should be_a(Mixlib::ShellOut::ShellCommandFailed)
|
|
504
|
+
@error.message.should include("Cannot unlock the password")
|
|
505
|
+
end
|
|
506
|
+
else
|
|
507
|
+
|
|
508
|
+
# borked on all other platforms:
|
|
509
|
+
it "is marked as updated but doesn't modify the user (XXX)" do
|
|
510
|
+
# This should be an error instead; note that usermod still exits 0
|
|
511
|
+
# (which is probably why this case silently fails):
|
|
512
|
+
#
|
|
513
|
+
# DEBUG: ---- Begin output of usermod -U chef-functional-test ----
|
|
514
|
+
# DEBUG: STDOUT:
|
|
515
|
+
# DEBUG: STDERR: usermod: unlocking the user's password would result in a passwordless account.
|
|
516
|
+
# You should set a password with usermod -p to unlock this user's password.
|
|
517
|
+
# DEBUG: ---- End output of usermod -U chef-functional-test ----
|
|
518
|
+
# DEBUG: Ran usermod -U chef-functional-test returned 0
|
|
519
|
+
@error.should be_nil
|
|
520
|
+
pw_entry.passwd.should == 'x'
|
|
521
|
+
shadow_password.should == "!"
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
context "and has a password" do
|
|
527
|
+
let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
|
|
528
|
+
context "and the user is not locked" do
|
|
529
|
+
it "does not update the user" do
|
|
530
|
+
user_resource.should_not be_updated_by_last_action
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
context "and the user is locked" do
|
|
535
|
+
let(:user_locked_context?) { true }
|
|
536
|
+
|
|
537
|
+
it "unlocks the user's password" do
|
|
538
|
+
shadow_entry = etc_shadow.lines.select {|l| l.include?(username) }.first
|
|
539
|
+
shadow_password = shadow_entry.split(':')[1]
|
|
540
|
+
shadow_password.should_not include("!")
|
|
541
|
+
end
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
end # action :unlock
|
|
546
|
+
|
|
547
|
+
end
|