chef 10.34.6 → 11.0.0.beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CONTRIBUTING.md +155 -0
- data/README.md +89 -0
- data/Rakefile +4 -12
- data/bin/chef-apply +25 -0
- data/bin/chef-shell +34 -0
- data/bin/shef +6 -5
- 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/{shef.1.html → chef-shell.1.html} +49 -46
- data/distro/common/html/chef-solo.8.html +18 -12
- 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 +10 -7
- data/distro/common/html/knife-data-bag.1.html +10 -7
- data/distro/common/html/knife-environment.1.html +8 -6
- data/distro/common/html/knife-exec.1.html +9 -9
- 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 +8 -13
- data/distro/common/man/man1/{shef.1 → chef-shell.1} +21 -57
- 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 +15 -2
- data/distro/common/man/man1/knife-data-bag.1 +15 -2
- data/distro/common/man/man1/knife-environment.1 +12 -2
- data/distro/common/man/man1/knife-exec.1 +4 -7
- 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 +3 -6
- 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 +36 -4
- data/distro/common/man/man8/chef-solr.8 +1 -1
- data/distro/common/markdown/man1/{shef.mkd → chef-shell.mkd} +49 -43
- data/distro/common/markdown/man1/knife-exec.mkd +11 -6
- data/distro/common/markdown/man1/knife.mkd +4 -9
- data/distro/debian/etc/default/chef-client +0 -1
- data/distro/debian/etc/init.d/chef-client +2 -2
- data/lib/chef.rb +2 -5
- data/lib/chef/api_client.rb +20 -130
- data/lib/chef/api_client/registration.rb +126 -0
- data/lib/chef/application.rb +71 -14
- data/lib/chef/application/apply.rb +160 -0
- data/lib/chef/application/client.rb +25 -18
- data/lib/chef/application/knife.rb +0 -2
- data/lib/chef/application/solo.rb +23 -8
- data/lib/chef/application/windows_service.rb +5 -2
- data/lib/chef/applications.rb +1 -0
- data/lib/chef/chef_fs.rb +11 -0
- data/lib/chef/chef_fs/command_line.rb +232 -0
- data/lib/chef/chef_fs/file_pattern.rb +312 -0
- data/lib/chef/chef_fs/file_system.rb +358 -0
- data/lib/chef/chef_fs/file_system/base_fs_dir.rb +47 -0
- data/lib/chef/chef_fs/file_system/base_fs_object.rb +121 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +109 -0
- data/{spec/unit/monkey_patches/uri_spec.rb → lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb} +12 -15
- data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +84 -0
- data/lib/chef/chef_fs/file_system/cookbook_dir.rb +188 -0
- data/lib/chef/chef_fs/file_system/cookbook_file.rb +78 -0
- data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +54 -0
- data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +68 -0
- data/lib/chef/chef_fs/file_system/data_bag_dir.rb +78 -0
- data/lib/chef/chef_fs/file_system/data_bag_item.rb +59 -0
- data/lib/chef/chef_fs/file_system/data_bags_dir.rb +66 -0
- data/lib/chef/chef_fs/file_system/file_system_entry.rb +90 -0
- data/lib/chef/{index_queue.rb → chef_fs/file_system/file_system_error.rb} +14 -12
- data/lib/chef/{resource/whyrun_safe_ruby_block.rb → chef_fs/file_system/file_system_root_dir.rb} +10 -10
- data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +31 -0
- data/lib/chef/chef_fs/file_system/nodes_dir.rb +47 -0
- data/lib/chef/{provider/whyrun_safe_ruby_block.rb → chef_fs/file_system/nonexistent_fs_object.rb} +19 -9
- data/lib/chef/chef_fs/file_system/not_found_error.rb +31 -0
- data/lib/chef/chef_fs/file_system/rest_list_dir.rb +84 -0
- data/lib/chef/chef_fs/file_system/rest_list_entry.rb +123 -0
- data/lib/chef/chef_fs/knife.rb +77 -0
- data/lib/chef/chef_fs/path_utils.rb +64 -0
- data/lib/chef/client.rb +44 -21
- data/lib/chef/config.rb +52 -43
- data/lib/chef/cookbook/synchronizer.rb +6 -8
- data/lib/chef/cookbook/syntax_check.rb +61 -14
- data/lib/chef/cookbook_loader.rb +39 -26
- data/lib/chef/cookbook_uploader.rb +17 -19
- data/lib/chef/cookbook_version.rb +3 -302
- data/lib/chef/daemon.rb +3 -18
- data/lib/chef/data_bag.rb +4 -97
- data/lib/chef/data_bag_item.rb +2 -65
- data/lib/chef/digester.rb +73 -0
- data/lib/chef/dsl.rb +6 -0
- data/lib/chef/dsl/data_query.rb +66 -0
- data/lib/chef/dsl/include_attribute.rb +60 -0
- data/lib/chef/dsl/include_recipe.rb +42 -0
- data/lib/chef/dsl/platform_introspection.rb +213 -0
- data/lib/chef/dsl/recipe.rb +84 -0
- data/lib/chef/dsl/registry_helper.rb +59 -0
- data/lib/chef/encrypted_data_bag_item.rb +74 -19
- data/lib/chef/environment.rb +9 -180
- data/lib/chef/exceptions.rb +87 -14
- data/lib/chef/formatters/base.rb +4 -1
- data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +0 -4
- data/lib/chef/json_compat.rb +1 -97
- data/lib/chef/knife.rb +90 -41
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/chef-full.erb +3 -3
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
- data/lib/chef/knife/configure.rb +1 -2
- data/lib/chef/knife/cookbook_metadata.rb +1 -0
- data/lib/chef/knife/cookbook_test.rb +3 -2
- data/lib/chef/knife/cookbook_upload.rb +12 -7
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/core/generic_presenter.rb +26 -13
- data/lib/chef/knife/core/node_editor.rb +36 -16
- data/lib/chef/knife/core/node_presenter.rb +1 -1
- data/lib/chef/knife/core/text_formatter.rb +23 -37
- data/lib/chef/knife/core/ui.rb +15 -9
- data/lib/chef/knife/delete.rb +39 -0
- data/lib/chef/knife/diff.rb +46 -0
- data/lib/chef/knife/download.rb +50 -0
- data/lib/chef/knife/environment_show.rb +7 -0
- data/lib/chef/knife/exec.rb +5 -5
- data/lib/chef/knife/help_topics.rb +1 -1
- data/lib/chef/knife/index_rebuild.rb +91 -7
- data/lib/chef/knife/list.rb +109 -0
- data/lib/chef/knife/raw.rb +108 -0
- data/lib/chef/knife/search.rb +40 -22
- data/lib/chef/knife/show.rb +32 -0
- data/lib/chef/knife/ssh.rb +6 -2
- data/lib/chef/knife/upload.rb +50 -0
- data/lib/chef/mixin/checksum.rb +3 -3
- data/lib/chef/mixin/deep_merge.rb +55 -197
- data/lib/chef/mixin/language.rb +9 -222
- data/lib/chef/mixin/language_include_attribute.rb +6 -38
- data/lib/chef/mixin/language_include_recipe.rb +3 -35
- data/lib/chef/mixin/params_validate.rb +6 -19
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +8 -61
- data/lib/chef/mixin/securable.rb +32 -7
- data/lib/chef/mixin/template.rb +40 -0
- data/lib/chef/mixins.rb +0 -4
- data/lib/chef/monkey_patches/net_http.rb +0 -34
- data/lib/chef/node.rb +133 -309
- data/lib/chef/node/attribute.rb +333 -473
- data/lib/chef/node/attribute_collections.rb +199 -0
- data/lib/chef/node/immutable_collections.rb +186 -0
- data/lib/chef/platform.rb +7 -22
- data/lib/chef/provider.rb +2 -49
- data/lib/chef/provider/breakpoint.rb +6 -6
- data/lib/chef/provider/cookbook_file.rb +5 -33
- data/lib/chef/provider/deploy.rb +2 -1
- data/lib/chef/provider/directory.rb +14 -17
- data/lib/chef/provider/file.rb +19 -52
- data/lib/chef/provider/group.rb +31 -51
- data/lib/chef/provider/group/dscl.rb +13 -53
- data/lib/chef/provider/group/gpasswd.rb +19 -14
- data/lib/chef/provider/group/groupadd.rb +1 -41
- data/lib/chef/provider/group/groupmod.rb +36 -46
- data/lib/chef/provider/group/pw.rb +16 -59
- data/lib/chef/provider/group/suse.rb +13 -16
- data/lib/chef/provider/group/usermod.rb +18 -40
- data/lib/chef/provider/group/windows.rb +6 -13
- data/lib/chef/provider/http_request.rb +25 -42
- data/lib/chef/provider/link.rb +2 -0
- data/lib/chef/provider/lwrp_base.rb +150 -0
- data/lib/chef/provider/package/portage.rb +4 -9
- data/lib/chef/provider/package/rpm.rb +2 -2
- data/lib/chef/provider/package/rubygems.rb +9 -41
- data/lib/chef/provider/package/yum.rb +12 -19
- data/lib/chef/provider/registry_key.rb +156 -0
- data/lib/chef/provider/remote_directory.rb +2 -0
- data/lib/chef/provider/remote_file.rb +21 -12
- data/lib/chef/provider/ruby_block.rb +5 -2
- data/lib/chef/provider/service.rb +15 -0
- data/lib/chef/provider/service/init.rb +9 -7
- data/lib/chef/provider/service/macosx.rb +15 -73
- data/lib/chef/provider/service/simple.rb +1 -1
- data/lib/chef/provider/service/solaris.rb +3 -3
- data/lib/chef/provider/template.rb +22 -25
- data/lib/chef/provider/template_finder.rb +61 -0
- data/lib/chef/provider/user.rb +0 -1
- data/lib/chef/provider/user/dscl.rb +175 -568
- data/lib/chef/provider/user/useradd.rb +30 -47
- data/lib/chef/providers.rb +3 -2
- data/lib/chef/recipe.rb +14 -8
- data/lib/chef/resource.rb +13 -154
- data/lib/chef/resource/group.rb +1 -11
- data/lib/chef/resource/http_request.rb +2 -1
- data/lib/chef/resource/lwrp_base.rb +127 -0
- data/lib/chef/resource/mount.rb +10 -11
- data/lib/chef/resource/registry_key.rb +86 -0
- data/lib/chef/resource/remote_directory.rb +6 -5
- data/lib/chef/resource/remote_file.rb +22 -31
- data/lib/chef/resource/ruby_block.rb +2 -2
- data/lib/chef/resource/service.rb +14 -0
- data/lib/chef/resource/user.rb +0 -18
- data/lib/chef/resource_collection.rb +25 -21
- data/lib/chef/resources.rb +2 -1
- data/lib/chef/rest.rb +50 -131
- data/lib/chef/rest/auth_credentials.rb +4 -20
- data/lib/chef/rest/rest_request.rb +2 -7
- data/lib/chef/role.rb +1 -97
- data/lib/chef/run_context.rb +108 -130
- data/lib/chef/run_context/cookbook_compiler.rb +280 -0
- data/lib/chef/run_list.rb +0 -2
- data/lib/chef/run_list/run_list_expansion.rb +0 -15
- data/lib/chef/run_lock.rb +90 -0
- data/lib/chef/runner.rb +28 -5
- data/lib/chef/sandbox.rb +15 -148
- data/lib/chef/scan_access_control.rb +2 -4
- data/lib/chef/shef/ext.rb +3 -575
- data/lib/chef/{shef.rb → shell.rb} +35 -40
- data/lib/chef/shell/ext.rb +593 -0
- data/lib/chef/{shef → shell}/model_wrapper.rb +3 -3
- data/lib/chef/{shef/shef_rest.rb → shell/shell_rest.rb} +4 -4
- data/lib/chef/{shef/shef_session.rb → shell/shell_session.rb} +17 -15
- data/lib/chef/shell_out.rb +7 -0
- data/lib/chef/util/windows/net_group.rb +1 -5
- data/lib/chef/version.rb +3 -3
- data/lib/chef/win32/api/process.rb +0 -1
- data/lib/chef/win32/handle.rb +1 -8
- data/lib/chef/win32/registry.rb +371 -0
- data/spec/data/big_json.json +1 -2
- data/spec/data/big_json_plus_one.json +1 -2
- data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
- data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
- data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
- data/spec/data/nodes/default.rb +3 -3
- data/spec/data/nodes/test.example.com.rb +3 -3
- data/spec/data/nodes/test.rb +3 -3
- data/spec/data/partial_one.erb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
- data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
- data/spec/data/{knife-home/.chef/plugins/knife/example_home_subcommand.rb → run_context/cookbooks/circular-dep1/recipes/default.rb} +0 -0
- data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
- data/spec/data/{lwrp_const_scoping/resources/conflict.rb → run_context/cookbooks/circular-dep2/recipes/default.rb} +0 -0
- data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
- data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
- data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
- data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
- data/spec/data/shef-config.rb +7 -0
- data/spec/functional/dsl/registry_helper_spec.rb +63 -0
- data/spec/functional/knife/cookbook_delete_spec.rb +1 -1
- data/spec/functional/knife/exec_spec.rb +2 -2
- data/spec/functional/knife/ssh_spec.rb +5 -1
- data/spec/functional/resource/cookbook_file_spec.rb +7 -19
- data/spec/functional/resource/directory_spec.rb +4 -0
- data/spec/functional/resource/file_spec.rb +56 -22
- data/spec/functional/resource/link_spec.rb +2 -0
- data/spec/functional/resource/registry_spec.rb +576 -0
- data/spec/functional/resource/remote_directory_spec.rb +142 -36
- data/spec/functional/resource/remote_file_spec.rb +18 -0
- data/spec/functional/resource/template_spec.rb +23 -2
- data/spec/functional/run_lock_spec.rb +106 -0
- data/spec/functional/shell_spec.rb +100 -0
- data/spec/functional/win32/registry_helper_spec.rb +632 -0
- data/spec/spec_helper.rb +5 -29
- data/spec/stress/win32/security_spec.rb +1 -1
- data/spec/support/chef_helpers.rb +0 -2
- data/spec/support/platform_helpers.rb +8 -15
- data/spec/support/shared/functional/directory_resource.rb +84 -22
- data/spec/support/shared/functional/file_resource.rb +169 -71
- data/spec/support/shared/functional/securable_resource.rb +143 -119
- data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
- data/spec/support/shared/unit/file_system_support.rb +110 -0
- data/spec/support/shared/unit/platform_introspector.rb +162 -0
- data/spec/unit/api_client/registration_spec.rb +175 -0
- data/spec/unit/api_client_spec.rb +78 -156
- data/spec/unit/application/apply.rb +84 -0
- data/spec/unit/application/client_spec.rb +1 -37
- data/spec/unit/application/knife_spec.rb +5 -0
- data/spec/unit/application_spec.rb +57 -2
- data/spec/unit/checksum/storage/filesystem_spec.rb +1 -1
- data/spec/unit/chef_fs/diff_spec.rb +328 -0
- data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
- data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
- data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
- data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
- data/spec/unit/chef_fs/file_system_spec.rb +136 -0
- data/spec/unit/client_spec.rb +124 -33
- data/spec/unit/config_spec.rb +46 -13
- data/spec/unit/cookbook/synchronizer_spec.rb +1 -49
- data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
- data/spec/unit/cookbook_loader_spec.rb +153 -91
- data/spec/unit/cookbook_manifest_spec.rb +81 -81
- data/spec/unit/cookbook_spec.rb +3 -20
- data/spec/unit/cookbook_version_spec.rb +23 -122
- data/spec/unit/daemon_spec.rb +3 -24
- data/spec/unit/data_bag_spec.rb +6 -4
- data/spec/unit/digester_spec.rb +50 -0
- data/spec/unit/dsl/data_query_spec.rb +66 -0
- data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
- data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +50 -105
- data/spec/unit/environment_spec.rb +0 -130
- data/spec/unit/exceptions_spec.rb +2 -3
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -3
- data/spec/unit/json_compat_spec.rb +15 -7
- data/spec/unit/knife/bootstrap_spec.rb +2 -0
- data/spec/unit/knife/configure_spec.rb +20 -14
- data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
- data/spec/unit/knife/cookbook_test_spec.rb +1 -0
- data/spec/unit/knife/cookbook_upload_spec.rb +43 -8
- data/spec/unit/knife/core/bootstrap_context_spec.rb +1 -1
- data/spec/unit/knife/core/ui_spec.rb +156 -125
- data/spec/unit/knife/data_bag_create_spec.rb +9 -0
- data/spec/unit/knife/data_bag_edit_spec.rb +1 -4
- data/spec/unit/knife/data_bag_from_file_spec.rb +4 -6
- data/spec/unit/knife/data_bag_show_spec.rb +11 -4
- data/spec/unit/knife/index_rebuild_spec.rb +96 -33
- data/spec/unit/knife/knife_help.rb +7 -7
- data/spec/unit/knife/node_edit_spec.rb +6 -33
- data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
- data/spec/unit/knife/ssh_spec.rb +12 -15
- data/spec/unit/knife/status_spec.rb +2 -2
- data/spec/unit/knife_spec.rb +53 -0
- data/spec/unit/lwrp_spec.rb +59 -42
- data/spec/unit/mixin/checksum_spec.rb +2 -2
- data/spec/unit/mixin/deep_merge_spec.rb +101 -799
- data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
- data/spec/unit/mixin/params_validate_spec.rb +4 -37
- data/spec/unit/mixin/securable_spec.rb +5 -3
- data/spec/unit/mixin/template_spec.rb +119 -0
- data/spec/unit/node/attribute_spec.rb +195 -173
- data/spec/unit/node/immutable_collections_spec.rb +139 -0
- data/spec/unit/node_spec.rb +366 -370
- data/spec/unit/platform_spec.rb +9 -10
- data/spec/unit/provider/breakpoint_spec.rb +8 -8
- data/spec/unit/provider/cookbook_file_spec.rb +4 -8
- data/spec/unit/provider/directory_spec.rb +96 -64
- data/spec/unit/provider/env_spec.rb +2 -2
- data/spec/unit/provider/file_spec.rb +48 -39
- data/spec/unit/provider/group/dscl_spec.rb +0 -36
- data/spec/unit/provider/group/gpasswd_spec.rb +9 -16
- data/spec/unit/provider/group/groupadd_spec.rb +4 -3
- data/spec/unit/provider/group/groupmod_spec.rb +1 -0
- data/spec/unit/provider/group/pw_spec.rb +15 -12
- data/spec/unit/provider/group/usermod_spec.rb +6 -21
- data/spec/unit/provider/group/windows_spec.rb +8 -0
- data/spec/unit/provider/group_spec.rb +6 -28
- data/spec/unit/provider/http_request_spec.rb +28 -69
- data/spec/unit/provider/ifconfig_spec.rb +2 -2
- data/spec/unit/provider/ohai_spec.rb +4 -4
- data/spec/unit/provider/package/apt_spec.rb +0 -1
- data/spec/unit/provider/package/ips_spec.rb +0 -1
- data/spec/unit/provider/package/portage_spec.rb +0 -44
- data/spec/unit/provider/package/rpm_spec.rb +0 -12
- data/spec/unit/provider/package/rubygems_spec.rb +1 -44
- data/spec/unit/provider/package/yum_spec.rb +39 -36
- data/spec/unit/provider/package_spec.rb +7 -5
- data/spec/unit/provider/registry_key_spec.rb +269 -0
- data/spec/unit/provider/remote_directory_spec.rb +7 -3
- data/spec/unit/provider/remote_file_spec.rb +36 -0
- data/spec/unit/provider/route_spec.rb +4 -3
- data/spec/unit/provider/ruby_block_spec.rb +8 -0
- data/spec/unit/provider/service/arch_service_spec.rb +5 -5
- data/spec/unit/provider/service/debian_service_spec.rb +1 -1
- data/spec/unit/provider/service/freebsd_service_spec.rb +5 -5
- data/spec/unit/provider/service/init_service_spec.rb +27 -4
- data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
- data/spec/unit/provider/service/invokercd_service_spec.rb +4 -4
- data/spec/unit/provider/service/macosx_spec.rb +11 -66
- data/spec/unit/provider/service/redhat_spec.rb +1 -1
- data/spec/unit/provider/service/simple_service_spec.rb +3 -3
- data/spec/unit/provider/service/upstart_service_spec.rb +9 -9
- data/spec/unit/provider/subversion_spec.rb +1 -1
- data/spec/unit/provider/template_spec.rb +35 -11
- data/spec/unit/provider/user/dscl_spec.rb +285 -681
- data/spec/unit/provider/user/useradd_spec.rb +1 -22
- data/spec/unit/provider/user_spec.rb +1 -1
- data/spec/unit/recipe_spec.rb +10 -8
- data/spec/unit/registry_helper_spec.rb +374 -0
- data/spec/unit/resource/mount_spec.rb +0 -11
- data/spec/unit/resource/registry_key_spec.rb +171 -0
- data/spec/unit/resource/remote_file_spec.rb +21 -23
- data/spec/unit/resource/ruby_block_spec.rb +7 -3
- data/spec/unit/resource/service_spec.rb +11 -0
- data/spec/unit/resource_spec.rb +4 -19
- data/spec/unit/rest/auth_credentials_spec.rb +2 -19
- data/spec/unit/rest_spec.rb +130 -284
- data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
- data/spec/unit/run_context_spec.rb +18 -4
- data/spec/unit/run_list_spec.rb +0 -209
- data/spec/unit/run_lock_spec.rb +37 -0
- data/spec/unit/runner_spec.rb +101 -2
- data/spec/unit/scan_access_control_spec.rb +4 -4
- data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
- data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
- data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +14 -69
- data/spec/unit/shell_out_spec.rb +18 -0
- data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
- metadata +275 -234
- checksums.yaml +0 -15
- data/README.rdoc +0 -177
- data/distro/common/html/knife-recipe.1.html +0 -92
- data/lib/chef/certificate.rb +0 -161
- data/lib/chef/checksum.rb +0 -167
- data/lib/chef/checksum_cache.rb +0 -190
- data/lib/chef/cookbook_version_selector.rb +0 -168
- data/lib/chef/couchdb.rb +0 -246
- data/lib/chef/index_queue/amqp_client.rb +0 -116
- data/lib/chef/index_queue/consumer.rb +0 -76
- data/lib/chef/index_queue/indexable.rb +0 -109
- data/lib/chef/knife/bootstrap/ubuntu12.10-gems.erb +0 -60
- data/lib/chef/monkey_patches/moneta.rb +0 -50
- data/lib/chef/monkey_patches/uri.rb +0 -70
- data/lib/chef/openid_registration.rb +0 -187
- data/lib/chef/provider/user/solaris.rb +0 -90
- data/lib/chef/solr_query.rb +0 -187
- data/lib/chef/solr_query/lucene.treetop +0 -150
- data/lib/chef/solr_query/lucene_nodes.rb +0 -285
- data/lib/chef/solr_query/query_transform.rb +0 -65
- data/lib/chef/solr_query/solr_http_request.rb +0 -132
- data/lib/chef/webui_user.rb +0 -231
- data/spec/data/cookbooks/openldap/files/default/.dotfile +0 -1
- data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +0 -1
- data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +0 -1
- data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +0 -1
- data/spec/data/mac_users/10.7-8.plist.xml +0 -559
- data/spec/data/mac_users/10.7-8.shadow.xml +0 -11
- data/spec/data/mac_users/10.7.plist.xml +0 -559
- data/spec/data/mac_users/10.7.shadow.xml +0 -11
- data/spec/data/mac_users/10.8.plist.xml +0 -559
- data/spec/data/mac_users/10.8.shadow.xml +0 -21
- data/spec/data/mac_users/10.9.plist.xml +0 -560
- data/spec/data/mac_users/10.9.shadow.xml +0 -21
- data/spec/functional/resource/base.rb +0 -40
- data/spec/functional/resource/group_spec.rb +0 -343
- data/spec/functional/resource/user/dscl_spec.rb +0 -199
- data/spec/unit/certificate_spec.rb +0 -76
- data/spec/unit/checksum_cache_spec.rb +0 -209
- data/spec/unit/checksum_spec.rb +0 -94
- data/spec/unit/couchdb_spec.rb +0 -274
- data/spec/unit/index_queue_spec.rb +0 -391
- data/spec/unit/mixin/language_spec.rb +0 -305
- data/spec/unit/openid_registration_spec.rb +0 -153
- data/spec/unit/provider/user/solaris_spec.rb +0 -414
- data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +0 -47
- data/spec/unit/solr_query/query_transform_spec.rb +0 -454
- data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
- data/spec/unit/solr_query_spec.rb +0 -203
- data/spec/unit/webui_user_spec.rb +0 -238
|
@@ -21,9 +21,9 @@ require 'spec_helper'
|
|
|
21
21
|
describe Chef::Provider::Service::Upstart do
|
|
22
22
|
before(:each) do
|
|
23
23
|
@node =Chef::Node.new
|
|
24
|
-
@node
|
|
25
|
-
@node[:platform] = 'ubuntu'
|
|
26
|
-
@node[:platform_version] = '9.10'
|
|
24
|
+
@node.name('upstarter')
|
|
25
|
+
@node.automatic_attrs[:platform] = 'ubuntu'
|
|
26
|
+
@node.automatic_attrs[:platform_version] = '9.10'
|
|
27
27
|
|
|
28
28
|
@events = Chef::EventDispatch::Dispatcher.new
|
|
29
29
|
@run_context = Chef::RunContext.new(@node, {}, @events)
|
|
@@ -38,7 +38,7 @@ describe Chef::Provider::Service::Upstart do
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "should return /etc/event.d as the upstart job directory when running on Ubuntu 9.04" do
|
|
41
|
-
@node[:platform_version] = '9.04'
|
|
41
|
+
@node.automatic_attrs[:platform_version] = '9.04'
|
|
42
42
|
#Chef::Platform.stub!(:find_platform_and_version).and_return([ "ubuntu", "9.04" ])
|
|
43
43
|
@provider = Chef::Provider::Service::Upstart.new(@new_resource, @run_context)
|
|
44
44
|
@provider.instance_variable_get(:@upstart_job_dir).should == "/etc/event.d"
|
|
@@ -46,14 +46,14 @@ describe Chef::Provider::Service::Upstart do
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it "should return /etc/init as the upstart job directory when running on Ubuntu 9.10" do
|
|
49
|
-
@node[:platform_version] = '9.10'
|
|
49
|
+
@node.automatic_attrs[:platform_version] = '9.10'
|
|
50
50
|
@provider = Chef::Provider::Service::Upstart.new(@new_resource, @run_context)
|
|
51
51
|
@provider.instance_variable_get(:@upstart_job_dir).should == "/etc/init"
|
|
52
52
|
@provider.instance_variable_get(:@upstart_conf_suffix).should == ".conf"
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
it "should return /etc/init as the upstart job directory by default" do
|
|
56
|
-
@node[:platform_version] = '9000'
|
|
56
|
+
@node.automatic_attrs[:platform_version] = '9000'
|
|
57
57
|
@provider = Chef::Provider::Service::Upstart.new(@new_resource, @run_context)
|
|
58
58
|
@provider.instance_variable_get(:@upstart_job_dir).should == "/etc/init"
|
|
59
59
|
@provider.instance_variable_get(:@upstart_conf_suffix).should == ".conf"
|
|
@@ -62,7 +62,7 @@ describe Chef::Provider::Service::Upstart do
|
|
|
62
62
|
|
|
63
63
|
describe "load_current_resource" do
|
|
64
64
|
before(:each) do
|
|
65
|
-
@node[:command] = {:ps => "ps -ax"}
|
|
65
|
+
@node.automatic_attrs[:command] = {:ps => "ps -ax"}
|
|
66
66
|
|
|
67
67
|
@current_resource = Chef::Resource::Service.new("rsyslog")
|
|
68
68
|
Chef::Resource::Service.stub!(:new).and_return(@current_resource)
|
|
@@ -97,7 +97,7 @@ describe Chef::Provider::Service::Upstart do
|
|
|
97
97
|
before do
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
it "should set running to true if the status command returns 0" do
|
|
100
|
+
it "should set running to true if the the status command returns 0" do
|
|
101
101
|
@stdout = StringIO.new("rsyslog start/running")
|
|
102
102
|
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
|
|
103
103
|
@provider.load_current_resource
|
|
@@ -113,7 +113,7 @@ describe Chef::Provider::Service::Upstart do
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
describe "when the status command uses the old format" do
|
|
116
|
-
it "should set running to true if the status command returns 0" do
|
|
116
|
+
it "should set running to true if the the status command returns 0" do
|
|
117
117
|
@stdout = StringIO.new("rsyslog (start) running, process 32225")
|
|
118
118
|
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
|
|
119
119
|
@provider.load_current_resource
|
|
@@ -63,7 +63,7 @@ describe Chef::Provider::Subversion do
|
|
|
63
63
|
"Last Changed Author: codeninja\n" +
|
|
64
64
|
"Last Changed Rev: 11410\n" + # Last Changed Rev is preferred to Revision
|
|
65
65
|
"Last Changed Date: 2009-03-25 06:09:56 -0600 (Wed, 25 Mar 2009)\n\n"
|
|
66
|
-
::File.should_receive(:exist?).with("/my/deploy/dir/.svn").and_return(true)
|
|
66
|
+
::File.should_receive(:exist?).at_least(1).times.with("/my/deploy/dir/.svn").and_return(true)
|
|
67
67
|
::File.should_receive(:directory?).with("/my/deploy/dir").and_return(true)
|
|
68
68
|
::Dir.should_receive(:chdir).with("/my/deploy/dir").and_yield
|
|
69
69
|
@stdout.stub!(:string).and_return(example_svn_info)
|
|
@@ -26,7 +26,9 @@ describe Chef::Provider::Template do
|
|
|
26
26
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, @cookbook_repo) }
|
|
27
27
|
|
|
28
28
|
@node = Chef::Node.new
|
|
29
|
-
|
|
29
|
+
cl = Chef::CookbookLoader.new(@cookbook_repo)
|
|
30
|
+
cl.load_cookbooks
|
|
31
|
+
@cookbook_collection = Chef::CookbookCollection.new(cl)
|
|
30
32
|
@events = Chef::EventDispatch::Dispatcher.new
|
|
31
33
|
@run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
|
|
32
34
|
|
|
@@ -45,16 +47,16 @@ describe Chef::Provider::Template do
|
|
|
45
47
|
else
|
|
46
48
|
Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
|
|
47
49
|
end
|
|
48
|
-
group_struct =
|
|
50
|
+
group_struct = mock("Group Ent", :name => "root", :passwd => "x", :gid => 0)
|
|
49
51
|
Etc.stub!(:getpwuid).and_return(passwd_struct)
|
|
50
52
|
Etc.stub!(:getgrgid).and_return(group_struct)
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
describe "when creating the template" do
|
|
54
56
|
|
|
55
|
-
before do
|
|
56
|
-
|
|
57
|
+
before do
|
|
57
58
|
end
|
|
59
|
+
|
|
58
60
|
after do
|
|
59
61
|
FileUtils.rm(@rendered_file_location) if ::File.exist?(@rendered_file_location)
|
|
60
62
|
end
|
|
@@ -87,7 +89,7 @@ describe Chef::Provider::Template do
|
|
|
87
89
|
it "creates the template with the rendered content" do
|
|
88
90
|
@access_controls.stub!(:requires_changes?).and_return(true)
|
|
89
91
|
@access_controls.should_receive(:set_all!)
|
|
90
|
-
@node[:slappiness] = "a warm gun"
|
|
92
|
+
@node.normal[:slappiness] = "a warm gun"
|
|
91
93
|
@provider.should_receive(:backup)
|
|
92
94
|
@provider.run_action(:create)
|
|
93
95
|
IO.read(@rendered_file_location).should == "slappiness is a warm gun"
|
|
@@ -107,12 +109,35 @@ describe Chef::Provider::Template do
|
|
|
107
109
|
it "creates the template with the rendered content for the create if missing action" do
|
|
108
110
|
@access_controls.stub!(:requires_changes?).and_return(true)
|
|
109
111
|
@access_controls.should_receive(:set_all!)
|
|
110
|
-
@node[:slappiness] = "happiness"
|
|
112
|
+
@node.normal[:slappiness] = "happiness"
|
|
111
113
|
@provider.should_receive(:backup)
|
|
112
114
|
@provider.run_action(:create_if_missing)
|
|
113
115
|
IO.read(@rendered_file_location).should == "slappiness is happiness"
|
|
114
116
|
@resource.should be_updated_by_last_action
|
|
115
117
|
end
|
|
118
|
+
|
|
119
|
+
context "and no access control settings are set on the resource" do
|
|
120
|
+
context "on a Unix system" do
|
|
121
|
+
before do
|
|
122
|
+
Chef::Platform.stub!(:windows?).and_return(false)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "sets access control metadata on the new resource" do
|
|
126
|
+
@access_controls.stub!(:requires_changes?).and_return(false)
|
|
127
|
+
@access_controls.should_receive(:set_all!)
|
|
128
|
+
@node.normal[:slappiness] = "happiness"
|
|
129
|
+
@provider.should_receive(:backup)
|
|
130
|
+
@provider.run_action(:create)
|
|
131
|
+
IO.read(@rendered_file_location).should == "slappiness is happiness"
|
|
132
|
+
@resource.should be_updated_by_last_action
|
|
133
|
+
|
|
134
|
+
# Veracity of actual data checked in functional tests
|
|
135
|
+
@resource.owner.should be_a_kind_of(String)
|
|
136
|
+
@resource.group.should be_a_kind_of(String)
|
|
137
|
+
@resource.mode.should be_a_kind_of(String)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
116
141
|
end
|
|
117
142
|
|
|
118
143
|
describe "when the target file has the wrong content" do
|
|
@@ -121,7 +146,7 @@ describe Chef::Provider::Template do
|
|
|
121
146
|
end
|
|
122
147
|
|
|
123
148
|
it "overwrites the file with the updated content when the create action is run" do
|
|
124
|
-
@node[:slappiness] = "a warm gun"
|
|
149
|
+
@node.normal[:slappiness] = "a warm gun"
|
|
125
150
|
@access_controls.stub!(:requires_changes?).and_return(false)
|
|
126
151
|
@access_controls.should_receive(:set_all!)
|
|
127
152
|
@provider.should_receive(:backup)
|
|
@@ -144,7 +169,7 @@ describe Chef::Provider::Template do
|
|
|
144
169
|
it "doesn't overwrite the file when the create if missing action is run" do
|
|
145
170
|
@access_controls.stub!(:requires_changes?).and_return(false)
|
|
146
171
|
@access_controls.should_not_receive(:set_all!)
|
|
147
|
-
@node[:slappiness] = "a warm gun"
|
|
172
|
+
@node.normal[:slappiness] = "a warm gun"
|
|
148
173
|
@provider.should_not_receive(:backup)
|
|
149
174
|
@provider.run_action(:create_if_missing)
|
|
150
175
|
IO.read(@rendered_file_location).should == "blargh"
|
|
@@ -154,7 +179,6 @@ describe Chef::Provider::Template do
|
|
|
154
179
|
|
|
155
180
|
describe "when the target has the correct content" do
|
|
156
181
|
before do
|
|
157
|
-
Chef::ChecksumCache.instance.reset!
|
|
158
182
|
File.open(@rendered_file_location, "w") { |f| f.print "slappiness is a warm gun" }
|
|
159
183
|
@current_resource.checksum('4ff94a87794ed9aefe88e734df5a66fc8727a179e9496cbd88e3b5ec762a5ee9')
|
|
160
184
|
@access_controls = mock("access controls")
|
|
@@ -162,7 +186,7 @@ describe Chef::Provider::Template do
|
|
|
162
186
|
end
|
|
163
187
|
|
|
164
188
|
it "does not backup the original or overwrite it" do
|
|
165
|
-
@node[:slappiness] = "a warm gun"
|
|
189
|
+
@node.normal[:slappiness] = "a warm gun"
|
|
166
190
|
@access_controls.stub!(:requires_changes?).and_return(false)
|
|
167
191
|
@provider.should_not_receive(:backup)
|
|
168
192
|
FileUtils.should_not_receive(:mv)
|
|
@@ -171,7 +195,7 @@ describe Chef::Provider::Template do
|
|
|
171
195
|
end
|
|
172
196
|
|
|
173
197
|
it "does not backup the original or overwrite it on create if missing" do
|
|
174
|
-
@node[:slappiness] = "a warm gun"
|
|
198
|
+
@node.normal[:slappiness] = "a warm gun"
|
|
175
199
|
@access_controls.stub!(:requires_changes?).and_return(false)
|
|
176
200
|
@provider.should_not_receive(:backup)
|
|
177
201
|
FileUtils.should_not_receive(:mv)
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
8
8
|
# You may obtain a copy of the License at
|
|
9
|
-
#
|
|
9
|
+
#
|
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
11
|
+
#
|
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
@@ -20,857 +20,461 @@ ShellCmdResult = Struct.new(:stdout, :stderr, :exitstatus)
|
|
|
20
20
|
|
|
21
21
|
require 'spec_helper'
|
|
22
22
|
require 'ostruct'
|
|
23
|
-
require 'mixlib/shellout'
|
|
24
23
|
|
|
25
24
|
describe Chef::Provider::User::Dscl do
|
|
26
|
-
|
|
27
|
-
node = Chef::Node.new
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Chef::EventDispatch::Dispatcher.new
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
let(:run_context) {
|
|
38
|
-
Chef::RunContext.new(node, {}, events)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let(:new_resource) {
|
|
42
|
-
r = Chef::Resource::User.new("toor")
|
|
43
|
-
r.password(password)
|
|
44
|
-
r.salt(salt)
|
|
45
|
-
r.iterations(iterations)
|
|
46
|
-
r
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let(:provider) {
|
|
50
|
-
Chef::Provider::User::Dscl.new(new_resource, run_context)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let(:mac_version) {
|
|
54
|
-
"10.9.1"
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let(:password) { nil }
|
|
58
|
-
let(:salt) { nil }
|
|
59
|
-
let(:iterations) { nil }
|
|
60
|
-
|
|
61
|
-
let(:salted_sha512_password) {
|
|
62
|
-
"0f543f021c63255e64e121a3585601b8ecfedf6d2\
|
|
63
|
-
705ddac69e682a33db5dbcdb9b56a2520bc8fff63a\
|
|
64
|
-
2ba6b7984c0737ff0b7949455071581f7affcd536d\
|
|
65
|
-
402b6cdb097"
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
let(:salted_sha512_pbkdf2_password) {
|
|
69
|
-
"c734b6e4787c3727bb35e29fdd92b97c\
|
|
70
|
-
1de12df509577a045728255ec7c6c5f5\
|
|
71
|
-
c18efa05ed02b682ffa7ebc05119900e\
|
|
72
|
-
b1d4880833aa7a190afc13e2bf0936b8\
|
|
73
|
-
20123e8c98f0f9bcac2a629d9163caac\
|
|
74
|
-
9464a8c234f3919082400b4f939bb77b\
|
|
75
|
-
c5adbbac718b7eb99463a7b679571e0f\
|
|
76
|
-
1c9fef2ef08d0b9e9c2bcf644eed2ffc"
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
let(:salted_sha512_pbkdf2_salt) {
|
|
80
|
-
"2d942d8364a9ccf2b8e5cb7ed1ff58f78\
|
|
81
|
-
e29dbfee7f9db58859144d061fd0058"
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
let(:salted_sha512_pbkdf2_iterations) {
|
|
85
|
-
25000
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
let(:vagrant_sha_512) {
|
|
89
|
-
"6f75d7190441facc34291ebbea1fc756b242d4f\
|
|
90
|
-
e9bcff141bccb84f1979e27e539539aa31f9f7dcc92c0cea959\
|
|
91
|
-
ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let(:vagrant_sha_512_pbkdf2) {
|
|
95
|
-
"12601a90db17cbf\
|
|
96
|
-
8ba4808e6382fb0d3b9d8a6c1a190477bf680ab21afb\
|
|
97
|
-
6065467136e55cc208a6f74156e3daf20fb13369ef4b\
|
|
98
|
-
7bafa047d80359fb46a48a4adccd548ebb33851b093\
|
|
99
|
-
47cca84341a7f93a27147343f89fb843fb46c0017d2\
|
|
100
|
-
64afa4976baacf941b915bd1ec1ca24c30b3e759e02\
|
|
101
|
-
403e02f59fe7ff5938a7636c"
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
let(:vagrant_sha_512_pbkdf2_salt) {
|
|
105
|
-
"ee954be472fdc60ddf89484781433993625f006af6ec810c08f49a7e413946a1"
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
let(:vagrant_sha_512_pbkdf2_iterations) {
|
|
109
|
-
34482
|
|
110
|
-
}
|
|
111
|
-
|
|
25
|
+
before do
|
|
26
|
+
@node = Chef::Node.new
|
|
27
|
+
@events = Chef::EventDispatch::Dispatcher.new
|
|
28
|
+
@run_context = Chef::RunContext.new(@node, {}, @events)
|
|
29
|
+
@new_resource = Chef::Resource::User.new("toor")
|
|
30
|
+
@provider = Chef::Provider::User::Dscl.new(@new_resource, @run_context)
|
|
31
|
+
end
|
|
32
|
+
|
|
112
33
|
describe "when shelling out to dscl" do
|
|
113
34
|
it "should run dscl with the supplied cmd /Path args" do
|
|
114
35
|
shell_return = ShellCmdResult.new('stdout', 'err', 0)
|
|
115
|
-
provider.should_receive(:shell_out).with("dscl . -cmd /Path args").and_return(shell_return)
|
|
116
|
-
provider.
|
|
36
|
+
@provider.should_receive(:shell_out).with("dscl . -cmd /Path args").and_return(shell_return)
|
|
37
|
+
@provider.safe_dscl("cmd /Path args").should == 'stdout'
|
|
117
38
|
end
|
|
118
39
|
|
|
119
40
|
it "returns an empty string from delete commands" do
|
|
120
41
|
shell_return = ShellCmdResult.new('out', 'err', 23)
|
|
121
|
-
provider.should_receive(:shell_out).with("dscl . -delete /Path args").and_return(shell_return)
|
|
122
|
-
provider.
|
|
42
|
+
@provider.should_receive(:shell_out).with("dscl . -delete /Path args").and_return(shell_return)
|
|
43
|
+
@provider.safe_dscl("delete /Path args").should == ""
|
|
123
44
|
end
|
|
124
45
|
|
|
125
46
|
it "should raise an exception for any other command" do
|
|
126
47
|
shell_return = ShellCmdResult.new('out', 'err', 23)
|
|
127
|
-
provider.should_receive(:shell_out).with('dscl . -cmd /Path arguments').and_return(shell_return)
|
|
128
|
-
lambda { provider.
|
|
48
|
+
@provider.should_receive(:shell_out).with('dscl . -cmd /Path arguments').and_return(shell_return)
|
|
49
|
+
lambda { @provider.safe_dscl("cmd /Path arguments") }.should raise_error(Chef::Exceptions::DsclCommandFailed)
|
|
129
50
|
end
|
|
130
51
|
|
|
131
52
|
it "raises an exception when dscl reports 'no such key'" do
|
|
132
53
|
shell_return = ShellCmdResult.new("No such key: ", 'err', 23)
|
|
133
|
-
provider.should_receive(:shell_out).with('dscl . -cmd /Path args').and_return(shell_return)
|
|
134
|
-
lambda { provider.
|
|
54
|
+
@provider.should_receive(:shell_out).with('dscl . -cmd /Path args').and_return(shell_return)
|
|
55
|
+
lambda { @provider.safe_dscl("cmd /Path args") }.should raise_error(Chef::Exceptions::DsclCommandFailed)
|
|
135
56
|
end
|
|
136
57
|
|
|
137
58
|
it "raises an exception when dscl reports 'eDSRecordNotFound'" do
|
|
138
59
|
shell_return = ShellCmdResult.new("<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)", 'err', -14136)
|
|
139
|
-
provider.should_receive(:shell_out).with('dscl . -cmd /Path args').and_return(shell_return)
|
|
140
|
-
lambda { provider.
|
|
60
|
+
@provider.should_receive(:shell_out).with('dscl . -cmd /Path args').and_return(shell_return)
|
|
61
|
+
lambda { @provider.safe_dscl("cmd /Path args") }.should raise_error(Chef::Exceptions::DsclCommandFailed)
|
|
141
62
|
end
|
|
142
63
|
end
|
|
143
64
|
|
|
144
65
|
describe "get_free_uid" do
|
|
145
66
|
before do
|
|
146
|
-
provider.
|
|
67
|
+
@provider.stub!(:safe_dscl).and_return("\nwheel 200\nstaff 201\n")
|
|
147
68
|
end
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
it "should return the first unused uid number on or above 500" do
|
|
155
|
-
provider.get_free_uid.should eq(202)
|
|
156
|
-
end
|
|
69
|
+
|
|
70
|
+
it "should run safe_dscl with list /Users uid" do
|
|
71
|
+
@provider.should_receive(:safe_dscl).with("list /Users uid")
|
|
72
|
+
@provider.get_free_uid
|
|
157
73
|
end
|
|
158
74
|
|
|
159
75
|
it "should return the first unused uid number on or above 200" do
|
|
160
|
-
provider.get_free_uid.should
|
|
76
|
+
@provider.get_free_uid.should == 202
|
|
161
77
|
end
|
|
162
|
-
|
|
78
|
+
|
|
163
79
|
it "should raise an exception when the search limit is exhausted" do
|
|
164
80
|
search_limit = 1
|
|
165
|
-
lambda { provider.get_free_uid(search_limit) }.should raise_error(RuntimeError)
|
|
81
|
+
lambda { @provider.get_free_uid(search_limit) }.should raise_error(RuntimeError)
|
|
166
82
|
end
|
|
167
83
|
end
|
|
168
84
|
|
|
169
85
|
describe "uid_used?" do
|
|
170
|
-
|
|
171
|
-
provider.
|
|
86
|
+
before do
|
|
87
|
+
@provider.stub!(:safe_dscl).and_return("\naj 500\n")
|
|
172
88
|
end
|
|
173
89
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
90
|
+
it "should run safe_dscl with list /Users uid" do
|
|
91
|
+
@provider.should_receive(:safe_dscl).with("list /Users uid")
|
|
92
|
+
@provider.uid_used?(500)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should return true for a used uid number" do
|
|
96
|
+
@provider.uid_used?(500).should be_true
|
|
97
|
+
end
|
|
178
98
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
99
|
+
it "should return false for an unused uid number" do
|
|
100
|
+
@provider.uid_used?(501).should be_false
|
|
101
|
+
end
|
|
182
102
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
end
|
|
103
|
+
it "should return false if not given any valid uid number" do
|
|
104
|
+
@provider.uid_used?(nil).should be_false
|
|
186
105
|
end
|
|
187
106
|
end
|
|
188
107
|
|
|
189
108
|
describe "when determining the uid to set" do
|
|
190
109
|
it "raises RequestedUIDUnavailable if the requested uid is already in use" do
|
|
191
|
-
provider.stub(:uid_used?).and_return(true)
|
|
192
|
-
provider.should_receive(:get_free_uid).and_return(501)
|
|
193
|
-
lambda { provider.
|
|
110
|
+
@provider.stub!(:uid_used?).and_return(true)
|
|
111
|
+
@provider.should_receive(:get_free_uid).and_return(501)
|
|
112
|
+
lambda { @provider.set_uid }.should raise_error(Chef::Exceptions::RequestedUIDUnavailable)
|
|
194
113
|
end
|
|
195
|
-
|
|
114
|
+
|
|
196
115
|
it "finds a valid, unused uid when none is specified" do
|
|
197
|
-
provider.should_receive(:
|
|
198
|
-
provider.should_receive(:
|
|
199
|
-
provider.should_receive(:get_free_uid).and_return(501)
|
|
200
|
-
provider.
|
|
201
|
-
new_resource.uid.should
|
|
116
|
+
@provider.should_receive(:safe_dscl).with("list /Users uid").and_return('')
|
|
117
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor UniqueID 501")
|
|
118
|
+
@provider.should_receive(:get_free_uid).and_return(501)
|
|
119
|
+
@provider.set_uid
|
|
120
|
+
@new_resource.uid.should == 501
|
|
202
121
|
end
|
|
203
|
-
|
|
122
|
+
|
|
204
123
|
it "sets the uid specified in the resource" do
|
|
205
|
-
new_resource.uid(1000)
|
|
206
|
-
provider.should_receive(:
|
|
207
|
-
provider.should_receive(:
|
|
208
|
-
provider.
|
|
124
|
+
@new_resource.uid(1000)
|
|
125
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor UniqueID 1000").and_return(true)
|
|
126
|
+
@provider.should_receive(:safe_dscl).with("list /Users uid").and_return('')
|
|
127
|
+
@provider.set_uid
|
|
209
128
|
end
|
|
210
129
|
end
|
|
211
130
|
|
|
212
131
|
describe "when modifying the home directory" do
|
|
213
|
-
let(:current_resource) {
|
|
214
|
-
new_resource.dup
|
|
215
|
-
}
|
|
216
|
-
|
|
217
132
|
before do
|
|
218
|
-
new_resource.supports({ :manage_home => true })
|
|
219
|
-
new_resource.home('/Users/toor')
|
|
220
|
-
|
|
221
|
-
|
|
133
|
+
@new_resource.supports({ :manage_home => true })
|
|
134
|
+
@new_resource.home('/Users/toor')
|
|
135
|
+
|
|
136
|
+
@current_resource = @new_resource.dup
|
|
137
|
+
@provider.current_resource = @current_resource
|
|
222
138
|
end
|
|
223
139
|
|
|
224
140
|
it "deletes the home directory when resource#home is nil" do
|
|
225
|
-
new_resource.instance_variable_set(:@home, nil)
|
|
226
|
-
provider.should_receive(:
|
|
227
|
-
provider.
|
|
141
|
+
@new_resource.instance_variable_set(:@home, nil)
|
|
142
|
+
@provider.should_receive(:safe_dscl).with("delete /Users/toor NFSHomeDirectory").and_return(true)
|
|
143
|
+
@provider.modify_home
|
|
228
144
|
end
|
|
229
|
-
|
|
145
|
+
|
|
230
146
|
|
|
231
147
|
it "raises InvalidHomeDirectory when the resource's home directory doesn't look right" do
|
|
232
|
-
new_resource.home('epic-fail')
|
|
233
|
-
lambda { provider.
|
|
148
|
+
@new_resource.home('epic-fail')
|
|
149
|
+
lambda { @provider.modify_home }.should raise_error(Chef::Exceptions::InvalidHomeDirectory)
|
|
234
150
|
end
|
|
235
151
|
|
|
236
152
|
it "moves the users home to the new location if it exists and the target location is different" do
|
|
237
|
-
new_resource.supports(:manage_home => true)
|
|
238
|
-
|
|
153
|
+
@new_resource.supports(:manage_home => true)
|
|
154
|
+
|
|
239
155
|
current_home = CHEF_SPEC_DATA + '/old_home_dir'
|
|
240
156
|
current_home_files = [current_home + '/my-dot-emacs', current_home + '/my-dot-vim']
|
|
241
|
-
current_resource.home(current_home)
|
|
242
|
-
new_resource.gid(23)
|
|
243
|
-
::File.stub(:exists?).with('/old/home/toor').and_return(true)
|
|
244
|
-
::File.stub(:exists?).with('/Users/toor').and_return(true)
|
|
245
|
-
|
|
157
|
+
@current_resource.home(current_home)
|
|
158
|
+
@new_resource.gid(23)
|
|
159
|
+
::File.stub!(:exists?).with('/old/home/toor').and_return(true)
|
|
160
|
+
::File.stub!(:exists?).with('/Users/toor').and_return(true)
|
|
161
|
+
|
|
246
162
|
FileUtils.should_receive(:mkdir_p).with('/Users/toor').and_return(true)
|
|
247
163
|
FileUtils.should_receive(:rmdir).with(current_home)
|
|
248
164
|
::Dir.should_receive(:glob).with("#{CHEF_SPEC_DATA}/old_home_dir/*",::File::FNM_DOTMATCH).and_return(current_home_files)
|
|
249
165
|
FileUtils.should_receive(:mv).with(current_home_files, "/Users/toor", :force => true)
|
|
250
166
|
FileUtils.should_receive(:chown_R).with('toor','23','/Users/toor')
|
|
251
|
-
|
|
252
|
-
provider.should_receive(:
|
|
253
|
-
provider.
|
|
167
|
+
|
|
168
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor NFSHomeDirectory '/Users/toor'")
|
|
169
|
+
@provider.modify_home
|
|
254
170
|
end
|
|
255
171
|
|
|
256
172
|
it "should raise an exception when the systems user template dir (skel) cannot be found" do
|
|
257
|
-
::File.stub(:exists?).and_return(false,false,false)
|
|
258
|
-
lambda { provider.
|
|
173
|
+
::File.stub!(:exists?).and_return(false,false,false)
|
|
174
|
+
lambda { @provider.modify_home }.should raise_error(Chef::Exceptions::User)
|
|
259
175
|
end
|
|
260
176
|
|
|
261
177
|
it "should run ditto to copy any missing files from skel to the new home dir" do
|
|
262
178
|
::File.should_receive(:exists?).with("/System/Library/User\ Template/English.lproj").and_return(true)
|
|
263
179
|
FileUtils.should_receive(:chown_R).with('toor', '', '/Users/toor')
|
|
264
|
-
provider.should_receive(:shell_out!).with("ditto '/System/Library/User Template/English.lproj' '/Users/toor'")
|
|
265
|
-
provider.ditto_home
|
|
180
|
+
@provider.should_receive(:shell_out!).with("ditto '/System/Library/User Template/English.lproj' '/Users/toor'")
|
|
181
|
+
@provider.ditto_home
|
|
266
182
|
end
|
|
267
183
|
|
|
268
184
|
it "creates the user's NFSHomeDirectory and home directory" do
|
|
269
|
-
provider.should_receive(:
|
|
270
|
-
provider.should_receive(:ditto_home)
|
|
271
|
-
provider.
|
|
185
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor NFSHomeDirectory '/Users/toor'").and_return(true)
|
|
186
|
+
@provider.should_receive(:ditto_home)
|
|
187
|
+
@provider.modify_home
|
|
272
188
|
end
|
|
273
189
|
end
|
|
274
190
|
|
|
275
|
-
describe "
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
before do
|
|
280
|
-
::File.stub(:exists?).with("/usr/bin/dscl").and_return(dscl_exists)
|
|
281
|
-
::File.stub(:exists?).with("/usr/bin/plutil").and_return(plutil_exists)
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def run_requirements
|
|
285
|
-
provider.define_resource_requirements
|
|
286
|
-
provider.action = :create
|
|
287
|
-
provider.process_resource_requirements
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
describe "when dscl doesn't exist" do
|
|
291
|
-
let(:dscl_exists) { false }
|
|
292
|
-
|
|
293
|
-
it "should raise an error" do
|
|
294
|
-
lambda { run_requirements }.should raise_error
|
|
295
|
-
end
|
|
191
|
+
describe "osx_shadow_hash?" do
|
|
192
|
+
it "should return true when the string is a shadow hash" do
|
|
193
|
+
@provider.osx_shadow_hash?("0"*8*155).should eql(true)
|
|
296
194
|
end
|
|
297
195
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
it "should raise an error" do
|
|
302
|
-
lambda { run_requirements }.should raise_error
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
describe "when on Mac 10.6" do
|
|
307
|
-
let(:mac_version) {
|
|
308
|
-
"10.6.5"
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
it "should raise an error" do
|
|
312
|
-
lambda { run_requirements }.should raise_error
|
|
313
|
-
end
|
|
196
|
+
it "should return false otherwise" do
|
|
197
|
+
@provider.osx_shadow_hash?("any other string").should eql(false)
|
|
314
198
|
end
|
|
199
|
+
end
|
|
315
200
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
describe "when password is SALTED-SHA512" do
|
|
322
|
-
let(:password) { salted_sha512_password }
|
|
323
|
-
|
|
324
|
-
it "should not raise an error" do
|
|
325
|
-
lambda { run_requirements }.should_not raise_error
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
describe "when password is SALTED-SHA512-PBKDF2" do
|
|
330
|
-
let(:password) { salted_sha512_pbkdf2_password }
|
|
331
|
-
|
|
332
|
-
it "should raise an error" do
|
|
333
|
-
lambda { run_requirements }.should raise_error
|
|
334
|
-
end
|
|
335
|
-
end
|
|
201
|
+
describe "when detecting the format of a password" do
|
|
202
|
+
it "detects a OS X salted sha1" do
|
|
203
|
+
@provider.osx_salted_sha1?("0"*48).should eql(true)
|
|
204
|
+
@provider.osx_salted_sha1?("any other string").should eql(false)
|
|
336
205
|
end
|
|
206
|
+
end
|
|
337
207
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
describe "when password is SALTED-SHA512" do
|
|
345
|
-
let(:password) { salted_sha512_password }
|
|
346
|
-
|
|
347
|
-
it "should raise an error" do
|
|
348
|
-
lambda { run_requirements }.should raise_error
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
describe "when password is SALTED-SHA512-PBKDF2" do
|
|
353
|
-
let(:password) { salted_sha512_pbkdf2_password }
|
|
354
|
-
|
|
355
|
-
describe "when salt and iteration is not set" do
|
|
356
|
-
it "should raise an error" do
|
|
357
|
-
lambda { run_requirements }.should raise_error
|
|
358
|
-
end
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
describe "when salt and iteration is set" do
|
|
362
|
-
let(:salt) { salted_sha512_pbkdf2_salt }
|
|
363
|
-
let(:iterations) { salted_sha512_pbkdf2_iterations }
|
|
364
|
-
|
|
365
|
-
it "should not raise an error" do
|
|
366
|
-
lambda { run_requirements }.should_not raise_error
|
|
367
|
-
end
|
|
368
|
-
end
|
|
369
|
-
end
|
|
370
|
-
end
|
|
208
|
+
describe "guid" do
|
|
209
|
+
it "should run safe_dscl with read /Users/user GeneratedUID to get the users GUID" do
|
|
210
|
+
expected_uuid = "b398449e-cee0-45e0-80f8-b0b5b1bfdeaa"
|
|
211
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor GeneratedUID").and_return(expected_uuid + "\n")
|
|
212
|
+
@provider.guid.should == expected_uuid
|
|
371
213
|
end
|
|
372
214
|
end
|
|
373
215
|
|
|
374
|
-
describe "
|
|
375
|
-
# set this to any of the user plist files under spec/data
|
|
376
|
-
let(:user_plist_file) { nil }
|
|
377
|
-
|
|
378
|
-
before do
|
|
379
|
-
provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
|
|
380
|
-
provider.should_receive(:shell_out).with("plutil -convert xml1 -o - /var/db/dslocal/nodes/Default/users/toor.plist") do
|
|
381
|
-
if user_plist_file.nil?
|
|
382
|
-
ShellCmdResult.new('Can not find the file', 'Sorry!!', 1)
|
|
383
|
-
else
|
|
384
|
-
ShellCmdResult.new(File.read(File.join(CHEF_SPEC_DATA, "mac_users/#{user_plist_file}.plist.xml")), "", 0)
|
|
385
|
-
end
|
|
386
|
-
end
|
|
216
|
+
describe "shadow_hash_set?" do
|
|
387
217
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
218
|
+
it "should run safe_dscl with read /Users/user to see if the AuthenticationAuthority key exists" do
|
|
219
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor")
|
|
220
|
+
@provider.shadow_hash_set?
|
|
391
221
|
end
|
|
392
222
|
|
|
393
|
-
describe "when user
|
|
394
|
-
it "
|
|
395
|
-
|
|
223
|
+
describe "when the user account has an AuthenticationAuthority key" do
|
|
224
|
+
it "uses the shadow hash when there is a ShadowHash field in the AuthenticationAuthority key" do
|
|
225
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: ;ShadowHash;\n")
|
|
226
|
+
@provider.shadow_hash_set?.should be_true
|
|
396
227
|
end
|
|
397
228
|
|
|
398
|
-
it "
|
|
399
|
-
provider.
|
|
400
|
-
provider.
|
|
229
|
+
it "does not use the shadow hash when there is no ShadowHash field in the AuthenticationAuthority key" do
|
|
230
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: \n")
|
|
231
|
+
@provider.shadow_hash_set?.should be_false
|
|
401
232
|
end
|
|
402
233
|
|
|
403
|
-
it "should set username" do
|
|
404
|
-
provider.load_current_resource
|
|
405
|
-
provider.current_resource.username.should eq("toor")
|
|
406
|
-
end
|
|
407
234
|
end
|
|
408
235
|
|
|
409
|
-
describe "
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
let(:mac_version) {
|
|
414
|
-
"10.7.5"
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
let(:user_plist_file) { "10.7" }
|
|
418
|
-
|
|
419
|
-
it "collects the user data correctly" do
|
|
420
|
-
provider.load_current_resource
|
|
421
|
-
provider.current_resource.comment.should eq("vagrant")
|
|
422
|
-
provider.current_resource.uid.should eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
|
|
423
|
-
provider.current_resource.gid.should eq("80")
|
|
424
|
-
provider.current_resource.home.should eq("/Users/vagrant")
|
|
425
|
-
provider.current_resource.shell.should eq("/bin/bash")
|
|
426
|
-
provider.current_resource.password.should eq(vagrant_sha_512)
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
describe "when a plain password is set that is same" do
|
|
430
|
-
let(:password) { "vagrant" }
|
|
431
|
-
|
|
432
|
-
it "diverged_password? should report false" do
|
|
433
|
-
provider.load_current_resource
|
|
434
|
-
provider.diverged_password?.should be_false
|
|
435
|
-
end
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
describe "when a plain password is set that is different" do
|
|
439
|
-
let(:password) { "not_vagrant" }
|
|
440
|
-
|
|
441
|
-
it "diverged_password? should report true" do
|
|
442
|
-
provider.load_current_resource
|
|
443
|
-
provider.diverged_password?.should be_true
|
|
444
|
-
end
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
describe "when iterations change" do
|
|
448
|
-
let(:password) { vagrant_sha_512 }
|
|
449
|
-
let(:iterations) { 12345 }
|
|
450
|
-
|
|
451
|
-
it "diverged_password? should report false" do
|
|
452
|
-
provider.load_current_resource
|
|
453
|
-
provider.diverged_password?.should be_false
|
|
454
|
-
end
|
|
455
|
-
end
|
|
456
|
-
|
|
457
|
-
describe "when shadow hash changes" do
|
|
458
|
-
let(:password) { salted_sha512_password }
|
|
459
|
-
|
|
460
|
-
it "diverged_password? should report true" do
|
|
461
|
-
provider.load_current_resource
|
|
462
|
-
provider.diverged_password?.should be_true
|
|
463
|
-
end
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
describe "when salt change" do
|
|
467
|
-
let(:password) { vagrant_sha_512 }
|
|
468
|
-
let(:salt) { "SOMETHINGRANDOM" }
|
|
469
|
-
|
|
470
|
-
it "diverged_password? should report false" do
|
|
471
|
-
provider.load_current_resource
|
|
472
|
-
provider.diverged_password?.should be_false
|
|
473
|
-
end
|
|
474
|
-
end
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
describe "on 10.8" do
|
|
478
|
-
let(:mac_version) {
|
|
479
|
-
"10.8.3"
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
let(:user_plist_file) { "10.8" }
|
|
483
|
-
|
|
484
|
-
it "collects the user data correctly" do
|
|
485
|
-
provider.load_current_resource
|
|
486
|
-
provider.current_resource.comment.should eq("vagrant")
|
|
487
|
-
provider.current_resource.uid.should eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
|
|
488
|
-
provider.current_resource.gid.should eq("80")
|
|
489
|
-
provider.current_resource.home.should eq("/Users/vagrant")
|
|
490
|
-
provider.current_resource.shell.should eq("/bin/bash")
|
|
491
|
-
provider.current_resource.password.should eq("ea4c2d265d801ba0ec0dfccd\
|
|
492
|
-
253dfc1de91cbe0806b4acc1ed7fe22aebcf6beb5344d0f442e590\
|
|
493
|
-
ffa04d679075da3afb119e41b72b5eaf08ee4aa54693722646d5\
|
|
494
|
-
19ee04843deb8a3e977428d33f625e83887913e5c13b70035961\
|
|
495
|
-
5e00ad7bc3e7a0c98afc3e19d1360272454f8d33a9214d2fbe8b\
|
|
496
|
-
e68d1f9821b26689312366")
|
|
497
|
-
provider.current_resource.salt.should eq("f994ef2f73b7c5594ebd1553300976b20733ce0e24d659783d87f3d81cbbb6a9")
|
|
498
|
-
provider.current_resource.iterations.should eq(39840)
|
|
499
|
-
end
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
describe "on 10.7 upgraded to 10.8" do
|
|
503
|
-
# In this scenario user password is still in 10.7 format
|
|
504
|
-
let(:mac_version) {
|
|
505
|
-
"10.8.3"
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
let(:user_plist_file) { "10.7-8" }
|
|
509
|
-
|
|
510
|
-
it "collects the user data correctly" do
|
|
511
|
-
provider.load_current_resource
|
|
512
|
-
provider.current_resource.comment.should eq("vagrant")
|
|
513
|
-
provider.current_resource.uid.should eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
|
|
514
|
-
provider.current_resource.gid.should eq("80")
|
|
515
|
-
provider.current_resource.home.should eq("/Users/vagrant")
|
|
516
|
-
provider.current_resource.shell.should eq("/bin/bash")
|
|
517
|
-
provider.current_resource.password.should eq("6f75d7190441facc34291ebbea1fc756b242d4f\
|
|
518
|
-
e9bcff141bccb84f1979e27e539539aa31f9f7dcc92c0cea959\
|
|
519
|
-
ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
|
|
520
|
-
end
|
|
521
|
-
|
|
522
|
-
describe "when a plain text password is set" do
|
|
523
|
-
it "reports password needs to be updated" do
|
|
524
|
-
provider.load_current_resource
|
|
525
|
-
provider.diverged_password?.should be_true
|
|
526
|
-
end
|
|
527
|
-
end
|
|
528
|
-
|
|
529
|
-
describe "when a salted-sha512-pbkdf2 shadow is set" do
|
|
530
|
-
let(:password) { salted_sha512_pbkdf2_password }
|
|
531
|
-
let(:salt) { salted_sha512_pbkdf2_salt }
|
|
532
|
-
let(:iterations) { salted_sha512_pbkdf2_iterations }
|
|
533
|
-
|
|
534
|
-
it "reports password needs to be updated" do
|
|
535
|
-
provider.load_current_resource
|
|
536
|
-
provider.diverged_password?.should be_true
|
|
537
|
-
end
|
|
538
|
-
end
|
|
539
|
-
end
|
|
540
|
-
|
|
541
|
-
describe "on 10.9" do
|
|
542
|
-
let(:mac_version) {
|
|
543
|
-
"10.9.1"
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
let(:user_plist_file) { "10.9" }
|
|
547
|
-
|
|
548
|
-
it "collects the user data correctly" do
|
|
549
|
-
provider.load_current_resource
|
|
550
|
-
provider.current_resource.comment.should eq("vagrant")
|
|
551
|
-
provider.current_resource.uid.should eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
|
|
552
|
-
provider.current_resource.gid.should eq("80")
|
|
553
|
-
provider.current_resource.home.should eq("/Users/vagrant")
|
|
554
|
-
provider.current_resource.shell.should eq("/bin/bash")
|
|
555
|
-
provider.current_resource.password.should eq(vagrant_sha_512_pbkdf2)
|
|
556
|
-
provider.current_resource.salt.should eq(vagrant_sha_512_pbkdf2_salt)
|
|
557
|
-
provider.current_resource.iterations.should eq(vagrant_sha_512_pbkdf2_iterations)
|
|
558
|
-
end
|
|
559
|
-
|
|
560
|
-
describe "when a plain password is set that is same" do
|
|
561
|
-
let(:password) { "vagrant" }
|
|
562
|
-
|
|
563
|
-
it "diverged_password? should report false" do
|
|
564
|
-
provider.load_current_resource
|
|
565
|
-
provider.diverged_password?.should be_false
|
|
566
|
-
end
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
describe "when a plain password is set that is different" do
|
|
570
|
-
let(:password) { "not_vagrant" }
|
|
571
|
-
|
|
572
|
-
it "diverged_password? should report true" do
|
|
573
|
-
provider.load_current_resource
|
|
574
|
-
provider.diverged_password?.should be_true
|
|
575
|
-
end
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
describe "when iterations change" do
|
|
579
|
-
let(:password) { vagrant_sha_512_pbkdf2 }
|
|
580
|
-
let(:salt) { vagrant_sha_512_pbkdf2_salt }
|
|
581
|
-
let(:iterations) { 12345 }
|
|
582
|
-
|
|
583
|
-
it "diverged_password? should report true" do
|
|
584
|
-
provider.load_current_resource
|
|
585
|
-
provider.diverged_password?.should be_true
|
|
586
|
-
end
|
|
587
|
-
end
|
|
588
|
-
|
|
589
|
-
describe "when shadow hash changes" do
|
|
590
|
-
let(:password) { salted_sha512_pbkdf2_password }
|
|
591
|
-
let(:salt) { vagrant_sha_512_pbkdf2_salt }
|
|
592
|
-
let(:iterations) { vagrant_sha_512_pbkdf2_iterations }
|
|
593
|
-
|
|
594
|
-
it "diverged_password? should report true" do
|
|
595
|
-
provider.load_current_resource
|
|
596
|
-
provider.diverged_password?.should be_true
|
|
597
|
-
end
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
describe "when salt change" do
|
|
601
|
-
let(:password) { vagrant_sha_512_pbkdf2 }
|
|
602
|
-
let(:salt) { salted_sha512_pbkdf2_salt }
|
|
603
|
-
let(:iterations) { vagrant_sha_512_pbkdf2_iterations }
|
|
604
|
-
|
|
605
|
-
it "diverged_password? should report true" do
|
|
606
|
-
provider.load_current_resource
|
|
607
|
-
provider.diverged_password?.should be_true
|
|
608
|
-
end
|
|
609
|
-
end
|
|
236
|
+
describe "with no AuthenticationAuthority key in the user account" do
|
|
237
|
+
it "does not use the shadow hash" do
|
|
238
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("")
|
|
239
|
+
@provider.shadow_hash_set?.should eql(false)
|
|
610
240
|
end
|
|
611
241
|
end
|
|
612
242
|
end
|
|
613
243
|
|
|
614
|
-
describe "
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
it "should return false otherwise" do
|
|
620
|
-
provider.salted_sha512_pbkdf2?(salted_sha512_password).should be_false
|
|
621
|
-
provider.salted_sha512_pbkdf2?("any other string").should be_false
|
|
622
|
-
end
|
|
623
|
-
end
|
|
624
|
-
|
|
625
|
-
describe "salted_sha512?" do
|
|
626
|
-
it "should return true when the string is a salted_sha512_pbkdf2 hash" do
|
|
627
|
-
provider.salted_sha512_pbkdf2?(salted_sha512_pbkdf2_password).should be_true
|
|
628
|
-
end
|
|
629
|
-
|
|
630
|
-
it "should return false otherwise" do
|
|
631
|
-
provider.salted_sha512?(salted_sha512_pbkdf2_password).should be_false
|
|
632
|
-
provider.salted_sha512?("any other string").should be_false
|
|
633
|
-
end
|
|
634
|
-
end
|
|
635
|
-
|
|
636
|
-
describe "prepare_password_shadow_info" do
|
|
637
|
-
describe "when on Mac 10.7" do
|
|
638
|
-
let(:mac_version) {
|
|
639
|
-
"10.7.1"
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
describe "when the password is plain text" do
|
|
643
|
-
let(:password) { "vagrant" }
|
|
644
|
-
|
|
645
|
-
it "password_shadow_info should have salted-sha-512 format" do
|
|
646
|
-
shadow_info = provider.prepare_password_shadow_info
|
|
647
|
-
shadow_info.should have_key("SALTED-SHA512")
|
|
648
|
-
info = shadow_info["SALTED-SHA512"].string.unpack('H*').first
|
|
649
|
-
provider.salted_sha512?(info).should be_true
|
|
650
|
-
end
|
|
651
|
-
end
|
|
652
|
-
|
|
653
|
-
describe "when the password is salted-sha-512" do
|
|
654
|
-
let(:password) { vagrant_sha_512 }
|
|
655
|
-
|
|
656
|
-
it "password_shadow_info should have salted-sha-512 format" do
|
|
657
|
-
shadow_info = provider.prepare_password_shadow_info
|
|
658
|
-
shadow_info.should have_key("SALTED-SHA512")
|
|
659
|
-
info = shadow_info["SALTED-SHA512"].string.unpack('H*').first
|
|
660
|
-
provider.salted_sha512?(info).should be_true
|
|
661
|
-
info.should eq(vagrant_sha_512)
|
|
662
|
-
end
|
|
663
|
-
end
|
|
244
|
+
describe "when setting or modifying the user password" do
|
|
245
|
+
before do
|
|
246
|
+
@new_resource.password("password")
|
|
247
|
+
@output = StringIO.new
|
|
664
248
|
end
|
|
665
249
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
250
|
+
describe "when using a salted sha1 for the password" do
|
|
251
|
+
before do
|
|
252
|
+
@new_resource.password("F"*48)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it "should write a shadow hash file with the expected salted sha1" do
|
|
256
|
+
uuid = "B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA"
|
|
257
|
+
File.should_receive(:open).with('/var/db/shadow/hash/B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA', "w", 384).and_yield(@output)
|
|
258
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor GeneratedUID").and_return(uuid)
|
|
259
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: ;ShadowHash;\n")
|
|
260
|
+
expected_salted_sha1 = @new_resource.password
|
|
261
|
+
expected_shadow_hash = "00000000"*155
|
|
262
|
+
expected_shadow_hash[168] = expected_salted_sha1
|
|
263
|
+
@provider.modify_password
|
|
264
|
+
@output.string.strip.should == expected_shadow_hash
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
describe "when given a shadow hash file for the password" do
|
|
269
|
+
it "should write the shadow hash file directly to /var/db/shadow/hash/GUID" do
|
|
270
|
+
shadow_hash = '0123456789ABCDE0123456789ABCDEF' * 40
|
|
271
|
+
raise 'oops' unless shadow_hash.size == 1240
|
|
272
|
+
@new_resource.password shadow_hash
|
|
273
|
+
uuid = "B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA"
|
|
274
|
+
File.should_receive(:open).with('/var/db/shadow/hash/B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA', "w", 384).and_yield(@output)
|
|
275
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor GeneratedUID").and_return(uuid)
|
|
276
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: ;ShadowHash;\n")
|
|
277
|
+
@provider.modify_password
|
|
278
|
+
@output.string.strip.should == shadow_hash
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
describe "when given a string for the password" do
|
|
283
|
+
it "should output a salted sha1 and shadow hash file from the specified password" do
|
|
284
|
+
uuid = "B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA"
|
|
285
|
+
File.should_receive(:open).with('/var/db/shadow/hash/B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA', "w", 384).and_yield(@output)
|
|
286
|
+
@new_resource.password("password")
|
|
287
|
+
OpenSSL::Random.stub!(:random_bytes).and_return("\377\377\377\377\377\377\377\377")
|
|
288
|
+
expected_salted_sha1 = "F"*8+"SHA1-"*8
|
|
289
|
+
expected_shadow_hash = "00000000"*155
|
|
290
|
+
expected_shadow_hash[168] = expected_salted_sha1
|
|
291
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor GeneratedUID").and_return(uuid)
|
|
292
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: ;ShadowHash;\n")
|
|
293
|
+
@provider.modify_password
|
|
294
|
+
@output.string.strip.should match(/^0{168}(FFFFFFFF1C1AA7935D4E1190AFEC92343F31F7671FBF126D)0{1071}$/)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it "should write the output directly to the shadow hash file at /var/db/shadow/hash/GUID" do
|
|
299
|
+
shadow_file = StringIO.new
|
|
300
|
+
uuid = "B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA"
|
|
301
|
+
File.should_receive(:open).with("/var/db/shadow/hash/B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA",'w',0600).and_yield(shadow_file)
|
|
302
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor GeneratedUID").and_return(uuid)
|
|
303
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: ;ShadowHash;\n")
|
|
304
|
+
@provider.modify_password
|
|
305
|
+
shadow_file.string.should match(/^0{168}[0-9A-F]{48}0{1071}$/)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it "should run safe_dscl append /Users/user AuthenticationAuthority ;ShadowHash; when no shadow hash set" do
|
|
309
|
+
shadow_file = StringIO.new
|
|
310
|
+
uuid = "B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA"
|
|
311
|
+
File.should_receive(:open).with("/var/db/shadow/hash/B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA",'w',0600).and_yield(shadow_file)
|
|
312
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor GeneratedUID").and_return(uuid)
|
|
313
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority:\n")
|
|
314
|
+
@provider.should_receive(:safe_dscl).with("append /Users/toor AuthenticationAuthority ';ShadowHash;'")
|
|
315
|
+
@provider.modify_password
|
|
316
|
+
shadow_file.string.should match(/^0{168}[0-9A-F]{48}0{1071}$/)
|
|
703
317
|
end
|
|
704
318
|
end
|
|
705
319
|
|
|
706
|
-
describe "
|
|
707
|
-
|
|
708
|
-
|
|
320
|
+
describe "load_current_resource" do
|
|
321
|
+
it "should raise an error if the required binary /usr/bin/dscl doesn't exist" do
|
|
322
|
+
::File.should_receive(:exists?).with("/usr/bin/dscl").and_return(false)
|
|
323
|
+
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::User)
|
|
709
324
|
end
|
|
710
325
|
|
|
711
|
-
it "
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
mock_shellout.stub(:run_command)
|
|
715
|
-
Mixlib::ShellOut.should_receive(:new).and_return(mock_shellout)
|
|
716
|
-
provider.should_receive(:read_user_info)
|
|
717
|
-
provider.should_receive(:dscl_set)
|
|
718
|
-
provider.should_receive(:sleep).with(3)
|
|
719
|
-
provider.should_receive(:save_user_info)
|
|
720
|
-
provider.set_password
|
|
326
|
+
it "shouldn't raise an error if /usr/bin/dscl exists" do
|
|
327
|
+
::File.stub!(:exists?).and_return(true)
|
|
328
|
+
lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::User)
|
|
721
329
|
end
|
|
722
330
|
end
|
|
723
331
|
|
|
724
332
|
describe "when the user does not yet exist and chef is creating it" do
|
|
725
333
|
context "with a numeric gid" do
|
|
726
334
|
before do
|
|
727
|
-
new_resource.comment "#mockssuck"
|
|
728
|
-
new_resource.gid 1001
|
|
335
|
+
@new_resource.comment "#mockssuck"
|
|
336
|
+
@new_resource.gid 1001
|
|
729
337
|
end
|
|
730
338
|
|
|
731
339
|
it "creates the user, comment field, sets uid, gid, configures the home directory, sets the shell, and sets the password" do
|
|
732
|
-
provider.should_receive :dscl_create_user
|
|
733
|
-
provider.should_receive :dscl_create_comment
|
|
734
|
-
provider.should_receive :
|
|
735
|
-
provider.should_receive :dscl_set_gid
|
|
736
|
-
provider.should_receive :
|
|
737
|
-
provider.should_receive :dscl_set_shell
|
|
738
|
-
provider.should_receive :
|
|
739
|
-
provider.create_user
|
|
340
|
+
@provider.should_receive :dscl_create_user
|
|
341
|
+
@provider.should_receive :dscl_create_comment
|
|
342
|
+
@provider.should_receive :set_uid
|
|
343
|
+
@provider.should_receive :dscl_set_gid
|
|
344
|
+
@provider.should_receive :modify_home
|
|
345
|
+
@provider.should_receive :dscl_set_shell
|
|
346
|
+
@provider.should_receive :modify_password
|
|
347
|
+
@provider.create_user
|
|
740
348
|
end
|
|
741
349
|
|
|
742
350
|
it "creates the user and sets the comment field" do
|
|
743
|
-
provider.should_receive(:
|
|
744
|
-
provider.dscl_create_user
|
|
351
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor").and_return(true)
|
|
352
|
+
@provider.dscl_create_user
|
|
745
353
|
end
|
|
746
354
|
|
|
747
355
|
it "sets the comment field" do
|
|
748
|
-
provider.should_receive(:
|
|
749
|
-
provider.dscl_create_comment
|
|
356
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor RealName '#mockssuck'").and_return(true)
|
|
357
|
+
@provider.dscl_create_comment
|
|
750
358
|
end
|
|
751
359
|
|
|
752
|
-
it "should run
|
|
753
|
-
provider.should_receive(:
|
|
754
|
-
provider.dscl_set_gid
|
|
360
|
+
it "should run safe_dscl with create /Users/user PrimaryGroupID to set the users primary group" do
|
|
361
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor PrimaryGroupID '1001'").and_return(true)
|
|
362
|
+
@provider.dscl_set_gid
|
|
755
363
|
end
|
|
756
364
|
|
|
757
|
-
it "should run
|
|
758
|
-
provider.should_receive(:
|
|
759
|
-
provider.dscl_set_shell
|
|
365
|
+
it "should run safe_dscl with create /Users/user UserShell to set the users login shell" do
|
|
366
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor UserShell '/usr/bin/false'").and_return(true)
|
|
367
|
+
@provider.dscl_set_shell
|
|
760
368
|
end
|
|
761
369
|
end
|
|
762
370
|
|
|
763
371
|
context "with a non-numeric gid" do
|
|
764
372
|
before do
|
|
765
|
-
new_resource.comment "#mockssuck"
|
|
766
|
-
new_resource.gid "newgroup"
|
|
373
|
+
@new_resource.comment "#mockssuck"
|
|
374
|
+
@new_resource.gid "newgroup"
|
|
767
375
|
end
|
|
768
376
|
|
|
769
377
|
it "should map the group name to a numeric ID when the group exists" do
|
|
770
|
-
provider.should_receive(:
|
|
771
|
-
provider.should_receive(:
|
|
772
|
-
provider.dscl_set_gid
|
|
378
|
+
@provider.should_receive(:safe_dscl).with("read /Groups/newgroup PrimaryGroupID").ordered.and_return("PrimaryGroupID: 1001\n")
|
|
379
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor PrimaryGroupID '1001'").ordered.and_return(true)
|
|
380
|
+
@provider.dscl_set_gid
|
|
773
381
|
end
|
|
774
382
|
|
|
775
383
|
it "should raise an exception when the group does not exist" do
|
|
776
384
|
shell_return = ShellCmdResult.new("<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)", 'err', -14136)
|
|
777
|
-
provider.should_receive(:shell_out).with('dscl . -read /Groups/newgroup PrimaryGroupID').and_return(shell_return)
|
|
778
|
-
lambda { provider.dscl_set_gid }.should raise_error(Chef::Exceptions::GroupIDNotFound)
|
|
385
|
+
@provider.should_receive(:shell_out).with('dscl . -read /Groups/newgroup PrimaryGroupID').and_return(shell_return)
|
|
386
|
+
lambda { @provider.dscl_set_gid }.should raise_error(Chef::Exceptions::GroupIDNotFound)
|
|
779
387
|
end
|
|
780
388
|
end
|
|
781
389
|
end
|
|
782
390
|
|
|
783
391
|
describe "when the user exists and chef is managing it" do
|
|
784
392
|
before do
|
|
785
|
-
current_resource = new_resource.dup
|
|
786
|
-
provider.current_resource = current_resource
|
|
787
|
-
|
|
788
|
-
# These are all different from current_resource
|
|
789
|
-
new_resource.username "mud"
|
|
790
|
-
new_resource.uid 2342
|
|
791
|
-
new_resource.gid 2342
|
|
792
|
-
new_resource.home '/Users/death'
|
|
793
|
-
new_resource.password 'goaway'
|
|
794
|
-
end
|
|
795
|
-
|
|
393
|
+
@current_resource = @new_resource.dup
|
|
394
|
+
@provider.current_resource = @current_resource
|
|
395
|
+
|
|
396
|
+
# These are all different from @current_resource
|
|
397
|
+
@new_resource.username "mud"
|
|
398
|
+
@new_resource.uid 2342
|
|
399
|
+
@new_resource.gid 2342
|
|
400
|
+
@new_resource.home '/Users/death'
|
|
401
|
+
@new_resource.password 'goaway'
|
|
402
|
+
end
|
|
403
|
+
|
|
796
404
|
it "sets the user, comment field, uid, gid, moves the home directory, sets the shell, and sets the password" do
|
|
797
|
-
provider.should_receive :dscl_create_user
|
|
798
|
-
provider.should_receive :dscl_create_comment
|
|
799
|
-
provider.should_receive :
|
|
800
|
-
provider.should_receive :dscl_set_gid
|
|
801
|
-
provider.should_receive :
|
|
802
|
-
provider.should_receive :dscl_set_shell
|
|
803
|
-
provider.should_receive :
|
|
804
|
-
provider.create_user
|
|
405
|
+
@provider.should_receive :dscl_create_user
|
|
406
|
+
@provider.should_receive :dscl_create_comment
|
|
407
|
+
@provider.should_receive :set_uid
|
|
408
|
+
@provider.should_receive :dscl_set_gid
|
|
409
|
+
@provider.should_receive :modify_home
|
|
410
|
+
@provider.should_receive :dscl_set_shell
|
|
411
|
+
@provider.should_receive :modify_password
|
|
412
|
+
@provider.create_user
|
|
805
413
|
end
|
|
806
414
|
end
|
|
807
415
|
|
|
808
416
|
describe "when changing the gid" do
|
|
809
417
|
before do
|
|
810
|
-
current_resource = new_resource.dup
|
|
811
|
-
provider.current_resource = current_resource
|
|
812
|
-
|
|
813
|
-
# This is different from current_resource
|
|
814
|
-
new_resource.gid 2342
|
|
418
|
+
@current_resource = @new_resource.dup
|
|
419
|
+
@provider.current_resource = @current_resource
|
|
420
|
+
|
|
421
|
+
# This is different from @current_resource
|
|
422
|
+
@new_resource.gid 2342
|
|
815
423
|
end
|
|
816
|
-
|
|
424
|
+
|
|
817
425
|
it "sets the gid" do
|
|
818
|
-
provider.should_receive :dscl_set_gid
|
|
819
|
-
provider.manage_user
|
|
426
|
+
@provider.should_receive :dscl_set_gid
|
|
427
|
+
@provider.manage_user
|
|
820
428
|
end
|
|
821
429
|
end
|
|
822
430
|
|
|
823
|
-
describe "when the user exists" do
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
provider.should_receive(:
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
provider.
|
|
830
|
-
end
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
provider.should_receive(:run_dscl).with("read /Groups/your_group").and_return("GroupMembership: not_you")
|
|
838
|
-
provider.should_receive(:run_dscl).with("read /Groups/real_group").and_return("GroupMembership: toor")
|
|
839
|
-
provider.should_receive(:run_dscl).with("delete /Groups/real_group GroupMembership 'toor'")
|
|
840
|
-
provider.should_receive(:run_dscl).with("delete /Users/toor")
|
|
841
|
-
FileUtils.should_receive(:rm_rf).with("/Users/vagrant")
|
|
842
|
-
provider.remove_user
|
|
843
|
-
end
|
|
431
|
+
describe "when the user exists and chef is removing it" do
|
|
432
|
+
it "removes the user's home directory when the resource is configured to manage home" do
|
|
433
|
+
@new_resource.supports({ :manage_home => true })
|
|
434
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("NFSHomeDirectory: /Users/fuuuuuuuuuuuuu")
|
|
435
|
+
@provider.should_receive(:safe_dscl).with("delete /Users/toor")
|
|
436
|
+
FileUtils.should_receive(:rm_rf).with("/Users/fuuuuuuuuuuuuu")
|
|
437
|
+
@provider.remove_user
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it "removes the user from any group memberships" do
|
|
441
|
+
Etc.stub(:group).and_yield(OpenStruct.new(:name => 'ragefisters', :mem => 'toor'))
|
|
442
|
+
@provider.should_receive(:safe_dscl).with("delete /Users/toor")
|
|
443
|
+
@provider.should_receive(:safe_dscl).with("delete /Groups/ragefisters GroupMembership 'toor'")
|
|
444
|
+
@provider.remove_user
|
|
844
445
|
end
|
|
446
|
+
end
|
|
845
447
|
|
|
846
|
-
|
|
847
|
-
it "determines the user as not locked" do
|
|
848
|
-
provider.should_not be_locked
|
|
849
|
-
end
|
|
850
|
-
end
|
|
448
|
+
describe "when discovering if a user is locked" do
|
|
851
449
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
end
|
|
450
|
+
it "determines the user is not locked when dscl shows an AuthenticationAuthority without a DisabledUser field" do
|
|
451
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor")
|
|
452
|
+
@provider.should_not be_locked
|
|
453
|
+
end
|
|
857
454
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
455
|
+
it "determines the user is locked when dscl shows an AuthenticationAuthority with a DisabledUser field" do
|
|
456
|
+
@provider.should_receive(:safe_dscl).with('read /Users/toor').and_return("\nAuthenticationAuthority: ;DisabledUser;\n")
|
|
457
|
+
@provider.should be_locked
|
|
458
|
+
end
|
|
861
459
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
end
|
|
460
|
+
it "determines the user is not locked when dscl shows no AuthenticationAuthority" do
|
|
461
|
+
@provider.should_receive(:safe_dscl).with('read /Users/toor').and_return("\n")
|
|
462
|
+
@provider.should_not be_locked
|
|
866
463
|
end
|
|
867
464
|
end
|
|
868
465
|
|
|
869
466
|
describe "when locking the user" do
|
|
870
|
-
it "should run
|
|
871
|
-
provider.should_receive(:
|
|
872
|
-
provider.lock_user
|
|
467
|
+
it "should run safe_dscl with append /Users/user AuthenticationAuthority ;DisabledUser; to lock the user account" do
|
|
468
|
+
@provider.should_receive(:safe_dscl).with("append /Users/toor AuthenticationAuthority ';DisabledUser;'")
|
|
469
|
+
@provider.lock_user
|
|
873
470
|
end
|
|
874
471
|
end
|
|
875
472
|
|
|
473
|
+
describe "when unlocking the user" do
|
|
474
|
+
it "removes DisabledUser from the authentication string" do
|
|
475
|
+
@provider.should_receive(:safe_dscl).with("read /Users/toor AuthenticationAuthority").and_return("\nAuthenticationAuthority: ;ShadowHash; ;DisabledUser;\n")
|
|
476
|
+
@provider.should_receive(:safe_dscl).with("create /Users/toor AuthenticationAuthority ';ShadowHash;'")
|
|
477
|
+
@provider.unlock_user
|
|
478
|
+
end
|
|
479
|
+
end
|
|
876
480
|
end
|