chef 11.10.0.alpha.1 → 11.10.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. data/README.md +57 -36
  2. data/distro/common/html/chef-client.8.html +4 -4
  3. data/distro/common/html/chef-expander.8.html +4 -4
  4. data/distro/common/html/chef-expanderctl.8.html +4 -4
  5. data/distro/common/html/chef-server-webui.8.html +4 -4
  6. data/distro/common/html/chef-server.8.html +4 -4
  7. data/distro/common/html/chef-shell.1.html +4 -4
  8. data/distro/common/html/chef-solo.8.html +4 -4
  9. data/distro/common/html/chef-solr.8.html +5 -5
  10. data/distro/common/html/knife-bootstrap.1.html +4 -4
  11. data/distro/common/html/knife-client.1.html +4 -4
  12. data/distro/common/html/knife-configure.1.html +4 -4
  13. data/distro/common/html/knife-cookbook-site.1.html +4 -4
  14. data/distro/common/html/knife-cookbook.1.html +4 -4
  15. data/distro/common/html/knife-data-bag.1.html +4 -4
  16. data/distro/common/html/knife-environment.1.html +4 -4
  17. data/distro/common/html/knife-exec.1.html +4 -4
  18. data/distro/common/html/knife-index.1.html +4 -4
  19. data/distro/common/html/knife-node.1.html +4 -4
  20. data/distro/common/html/knife-role.1.html +4 -4
  21. data/distro/common/html/knife-search.1.html +4 -4
  22. data/distro/common/html/knife-ssh.1.html +4 -4
  23. data/distro/common/html/knife-status.1.html +4 -4
  24. data/distro/common/html/knife-tag.1.html +4 -4
  25. data/distro/common/html/knife.1.html +4 -4
  26. data/distro/common/man/man1/knife-bootstrap.1 +58 -64
  27. data/distro/common/man/man1/knife-client.1 +19 -22
  28. data/distro/common/man/man1/knife-configure.1 +37 -46
  29. data/distro/common/man/man1/knife-cookbook-site.1 +14 -17
  30. data/distro/common/man/man1/knife-cookbook.1 +15 -18
  31. data/distro/common/man/man1/knife-data-bag.1 +14 -17
  32. data/distro/common/man/man1/knife-delete.1 +38 -47
  33. data/distro/common/man/man1/knife-deps.1 +39 -48
  34. data/distro/common/man/man1/knife-diff.1 +43 -52
  35. data/distro/common/man/man1/knife-download.1 +47 -53
  36. data/distro/common/man/man1/knife-edit.1 +32 -41
  37. data/distro/common/man/man1/knife-environment.1 +14 -17
  38. data/distro/common/man/man1/knife-exec.1 +52 -61
  39. data/distro/common/man/man1/knife-index-rebuild.1 +1 -61
  40. data/distro/common/man/man1/knife-list.1 +47 -59
  41. data/distro/common/man/man1/knife-node.1 +15 -18
  42. data/distro/common/man/man1/knife-raw.1 +28 -46
  43. data/distro/common/man/man1/knife-recipe-list.1 +1 -61
  44. data/distro/common/man/man1/knife-role.1 +19 -25
  45. data/distro/common/man/man1/knife-search.1 +53 -62
  46. data/distro/common/man/man1/knife-show.1 +36 -28
  47. data/distro/common/man/man1/knife-ssh.1 +55 -61
  48. data/distro/common/man/man1/knife-status.1 +34 -43
  49. data/distro/common/man/man1/knife-tag.1 +14 -17
  50. data/distro/common/man/man1/knife-upload.1 +47 -56
  51. data/distro/common/man/man1/knife-user.1 +17 -20
  52. data/distro/common/man/man1/knife-xargs.1 +60 -69
  53. data/lib/chef/application.rb +3 -1
  54. data/lib/chef/application/windows_service.rb +0 -1
  55. data/lib/chef/client.rb +41 -152
  56. data/lib/chef/config.rb +19 -23
  57. data/lib/chef/data_bag.rb +1 -1
  58. data/lib/chef/data_bag_item.rb +1 -1
  59. data/lib/chef/exceptions.rb +8 -0
  60. data/lib/chef/formatters/doc.rb +15 -0
  61. data/lib/chef/formatters/error_inspectors/api_error_formatting.rb +2 -1
  62. data/lib/chef/http.rb +18 -8
  63. data/lib/chef/http/authenticator.rb +4 -0
  64. data/lib/chef/http/cookie_manager.rb +3 -0
  65. data/lib/chef/http/decompressor.rb +4 -0
  66. data/lib/chef/http/json_input.rb +4 -0
  67. data/lib/chef/http/json_output.rb +4 -0
  68. data/lib/chef/http/validate_content_length.rb +94 -0
  69. data/lib/chef/knife.rb +0 -1
  70. data/lib/chef/knife/configure.rb +6 -6
  71. data/lib/chef/knife/cookbook_create.rb +2 -2
  72. data/lib/chef/knife/core/subcommand_loader.rb +49 -3
  73. data/lib/chef/knife/ssh.rb +34 -4
  74. data/lib/chef/mixin/path_sanity.rb +1 -0
  75. data/lib/chef/monologger.rb +1 -2
  76. data/lib/chef/node.rb +7 -0
  77. data/lib/chef/policy_builder.rb +49 -0
  78. data/lib/chef/policy_builder/expand_node_object.rb +230 -0
  79. data/lib/chef/policy_builder/policyfile.rb +338 -0
  80. data/lib/chef/provider/file.rb +15 -5
  81. data/lib/chef/provider/group.rb +6 -2
  82. data/lib/chef/provider/group/windows.rb +12 -2
  83. data/lib/chef/provider/http_request.rb +3 -2
  84. data/lib/chef/provider/package.rb +1 -0
  85. data/lib/chef/provider/package/aix.rb +1 -1
  86. data/lib/chef/provider/service/debian.rb +7 -2
  87. data/lib/chef/resource/file.rb +8 -1
  88. data/lib/chef/resource/package.rb +9 -0
  89. data/lib/chef/resource/service.rb +0 -1
  90. data/lib/chef/rest.rb +2 -0
  91. data/lib/chef/run_context.rb +1 -1
  92. data/lib/chef/util/file_edit.rb +1 -1
  93. data/lib/chef/util/windows/net_group.rb +7 -6
  94. data/lib/chef/version.rb +1 -1
  95. data/lib/chef/win32/version.rb +31 -18
  96. data/spec/data/cookbooks/preseed/templates/default/preseed-template-variables.seed +1 -0
  97. data/spec/functional/resource/file_spec.rb +0 -1
  98. data/spec/functional/resource/group_spec.rb +96 -16
  99. data/spec/functional/resource/package_spec.rb +17 -0
  100. data/spec/functional/resource/user_spec.rb +2 -2
  101. data/spec/functional/win32/versions_spec.rb +39 -0
  102. data/spec/integration/client/client_spec.rb +27 -28
  103. data/spec/spec_helper.rb +2 -0
  104. data/spec/support/platform_helpers.rb +7 -1
  105. data/spec/support/shared/functional/file_resource.rb +83 -43
  106. data/spec/unit/application_spec.rb +7 -5
  107. data/spec/unit/client_spec.rb +10 -3
  108. data/spec/unit/config_spec.rb +0 -30
  109. data/spec/unit/cookbook_spec.rb +1 -0
  110. data/spec/unit/data_bag_item_spec.rb +8 -0
  111. data/spec/unit/data_bag_spec.rb +6 -0
  112. data/spec/unit/http_spec.rb +48 -0
  113. data/spec/unit/knife/core/subcommand_loader_spec.rb +77 -1
  114. data/spec/unit/knife/ssh_spec.rb +107 -0
  115. data/spec/unit/mixin/path_sanity_spec.rb +6 -0
  116. data/spec/unit/mixin/securable_spec.rb +77 -3
  117. data/spec/unit/monologger_spec.rb +45 -0
  118. data/spec/unit/node_spec.rb +16 -0
  119. data/spec/unit/policy_builder/expand_node_object_spec.rb +320 -0
  120. data/spec/unit/policy_builder/policyfile_spec.rb +399 -0
  121. data/spec/unit/policy_builder_spec.rb +26 -0
  122. data/spec/unit/provider/deploy_spec.rb +3 -0
  123. data/spec/unit/provider/group/windows_spec.rb +1 -0
  124. data/spec/unit/provider/http_request_spec.rb +23 -1
  125. data/spec/unit/provider/service/debian_service_spec.rb +50 -19
  126. data/spec/unit/recipe_spec.rb +4 -0
  127. data/spec/unit/resource/package_spec.rb +5 -0
  128. data/spec/unit/rest_spec.rb +375 -278
  129. data/spec/unit/run_context_spec.rb +4 -0
  130. metadata +96 -59
  131. checksums.yaml +0 -7
@@ -169,6 +169,7 @@ shared_examples_for Chef::Client do
169
169
 
170
170
  it "should identify the node and run ohai, then register the client" do
171
171
  mock_chef_rest_for_node = mock("Chef::REST (node)")
172
+ mock_chef_rest_for_cookbook_sync = mock("Chef::REST (cookbook sync)")
172
173
  mock_chef_rest_for_node_save = mock("Chef::REST (node save)")
173
174
  mock_chef_runner = mock("Chef::Runner")
174
175
 
@@ -201,7 +202,8 @@ shared_examples_for Chef::Client do
201
202
  # ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
202
203
  #
203
204
  Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
204
- mock_chef_rest_for_node.should_receive(:post_rest).with("environments/_default/cookbook_versions", {:run_list => []}).and_return({})
205
+ Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(mock_chef_rest_for_cookbook_sync)
206
+ mock_chef_rest_for_cookbook_sync.should_receive(:post).with("environments/_default/cookbook_versions", {:run_list => []}).and_return({})
205
207
 
206
208
  # --Client#converge
207
209
  Chef::Runner.should_receive(:new).and_return(mock_chef_runner)
@@ -274,6 +276,7 @@ shared_examples_for Chef::Client do
274
276
  Chef::Client.clear_notifications
275
277
  Chef::Node.stub!(:find_or_create).and_return(@node)
276
278
  @node.stub!(:save)
279
+ @client.load_node
277
280
  @client.build_node
278
281
  end
279
282
 
@@ -329,7 +332,10 @@ shared_examples_for Chef::Client do
329
332
  @node[:roles].should be_nil
330
333
  @node[:recipes].should be_nil
331
334
 
332
- @client.build_node
335
+ @client.policy_builder.stub!(:node).and_return(@node)
336
+
337
+ # chefspec and possibly others use the return value of this method
338
+ @client.build_node.should == @node
333
339
 
334
340
  # check post-conditions.
335
341
  @node[:roles].should_not be_nil
@@ -434,7 +440,8 @@ shared_examples_for Chef::Client do
434
440
 
435
441
  @node.should_receive(:save).and_return(nil)
436
442
 
437
- @client.build_node
443
+ @client.policy_builder.stub(:node).and_return(@node)
444
+ @client.policy_builder.build_node
438
445
 
439
446
  @node[:roles].should_not be_nil
440
447
  @node[:roles].should eql(['test_role'])
@@ -121,29 +121,6 @@ describe Chef::Config do
121
121
 
122
122
  end
123
123
 
124
- describe "config attribute writer: log_method=" do
125
- describe "when given an object that responds to sync= e.g. IO" do
126
- it "should configure itself to use the IO as log_location" do
127
- Chef::Config.log_location = STDOUT
128
- Chef::Config.log_location.should == STDOUT
129
- end
130
- end
131
-
132
- describe "when given an object that is stringable (to_str)" do
133
- before do
134
- @mockfile = mock("File", :path => "/var/log/chef/client.log", :sync= => true)
135
- File.should_receive(:new).
136
- with("/var/log/chef/client.log", "a").
137
- and_return(@mockfile)
138
- end
139
-
140
- it "should configure itself to use a File object based upon the String" do
141
- Chef::Config.log_location = "/var/log/chef/client.log"
142
- Chef::Config.log_location.path.should == "/var/log/chef/client.log"
143
- end
144
- end
145
- end
146
-
147
124
  describe "class method: plaform_specific_path" do
148
125
  it "should return given path on non-windows systems" do
149
126
  platform_mock :unix do
@@ -354,13 +331,6 @@ describe Chef::Config do
354
331
  end
355
332
  end
356
333
 
357
- describe "Chef::Config[:log_location]" do
358
- it "raises ConfigurationError when log_location directory is missing" do
359
- missing_path = "/tmp/non-existing-dir/file"
360
- expect{Chef::Config.log_location = missing_path}.to raise_error Chef::Exceptions::ConfigurationError
361
- end
362
- end
363
-
364
334
  describe "Chef::Config[:event_handlers]" do
365
335
  it "sets a event_handlers to an empty array by default" do
366
336
  Chef::Config[:event_handlers].should eq([])
@@ -70,6 +70,7 @@ describe Chef::CookbookVersion do
70
70
 
71
71
  it "should allow you to include a fully-qualified recipe using the DSL" do
72
72
  # DSL method include_recipe allows multiple arguments, so extract the first
73
+ @node.should_receive(:loaded_recipe).with(:openldap, "gigantor")
73
74
  recipe = @run_context.include_recipe("openldap::gigantor").first
74
75
 
75
76
  recipe.recipe_name.should == "gigantor"
@@ -70,6 +70,14 @@ describe Chef::DataBagItem do
70
70
  lambda { @data_bag_item.raw_data = { "id" => "h1-_" } }.should_not raise_error(ArgumentError)
71
71
  end
72
72
 
73
+ it "should accept alphanum.alphanum for the id" do
74
+ lambda { @data_bag_item.raw_data = { "id" => "foo.bar" } }.should_not raise_error(ArgumentError)
75
+ end
76
+
77
+ it "should accept .alphanum for the id" do
78
+ lambda { @data_bag_item.raw_data = { "id" => ".bozo" } }.should_not raise_error(ArgumentError)
79
+ end
80
+
73
81
  it "should raise an exception if the id contains anything but alphanum/-/_" do
74
82
  lambda { @data_bag_item.raw_data = { "id" => "!@#" } }.should raise_error(ArgumentError)
75
83
  end
@@ -47,6 +47,12 @@ describe Chef::DataBag do
47
47
  it "should throw an ArgumentError if you feed it anything but a string" do
48
48
  lambda { @data_bag.name Hash.new }.should raise_error(ArgumentError)
49
49
  end
50
+
51
+ [ ".", "-", "_", "1"].each do |char|
52
+ it "should allow a '#{char}' character in the data bag name" do
53
+ @data_bag.name("clown#{char}clown").should == "clown#{char}clown"
54
+ end
55
+ end
50
56
  end
51
57
 
52
58
  describe "deserialize" do
@@ -0,0 +1,48 @@
1
+ #
2
+ # Author:: Xabier de Zuazo (xabier@onddo.com)
3
+ # Copyright:: Copyright (c) 2014 Onddo Labs, SL.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ require 'chef/http'
22
+ require 'chef/http/basic_client'
23
+
24
+ describe Chef::HTTP do
25
+
26
+ describe "head" do
27
+
28
+ it 'should return nil for a "200 Success" response (CHEF-4762)' do
29
+ resp = Net::HTTPOK.new("1.1", 200, "OK")
30
+ resp.should_receive(:read_body).and_return(nil)
31
+ http = Chef::HTTP.new("")
32
+ Chef::HTTP::BasicClient.any_instance.should_receive(:request).and_return(["request", resp])
33
+
34
+ http.head("http://www.getchef.com/").should eql(nil)
35
+ end
36
+
37
+ it 'should return false for a "304 Not Modified" response (CHEF-4762)' do
38
+ resp = Net::HTTPNotModified.new("1.1", 304, "Not Modified")
39
+ resp.should_receive(:read_body).and_return(nil)
40
+ http = Chef::HTTP.new("")
41
+ Chef::HTTP::BasicClient.any_instance.should_receive(:request).and_return(["request", resp])
42
+
43
+ http.head("http://www.getchef.com/").should eql(false)
44
+ end
45
+
46
+ end # head
47
+
48
+ end
@@ -20,6 +20,7 @@ require 'spec_helper'
20
20
 
21
21
  describe Chef::Knife::SubcommandLoader do
22
22
  before do
23
+
23
24
  @home = File.join(CHEF_SPEC_DATA, 'knife-home')
24
25
  @env = {'HOME' => @home}
25
26
  @loader = Chef::Knife::SubcommandLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands'), @env)
@@ -46,7 +47,7 @@ describe Chef::Knife::SubcommandLoader do
46
47
  $LOAD_PATH.should_receive(:map).and_return([])
47
48
  if Gem::Specification.respond_to? :latest_specs
48
49
  Gem::Specification.should_receive(:latest_specs).with(true).and_return(gems)
49
- gems[0].should_receive(:matches_for_glob).with(/chef\/knife\/\*\.rb{(.*),\.rb,(.*)}/).and_return(gem_files)
50
+ gems[0].should_receive(:matches_for_glob).with(/chef\/knife\/\*\.rb\{(.*),\.rb,(.*)\}/).and_return(gem_files)
50
51
  else
51
52
  Gem.source_index.should_receive(:latest_specs).with(true).and_return(gems)
52
53
  gems[0].should_receive(:require_paths).twice.and_return(['lib'])
@@ -71,4 +72,79 @@ describe Chef::Knife::SubcommandLoader do
71
72
  expected_command = File.join(CHEF_SPEC_DATA, 'knife-site-subcommands', 'plugins', 'knife', 'example_subcommand.rb')
72
73
  @loader.site_subcommands.should include(expected_command)
73
74
  end
75
+
76
+ describe "finding 3rd party plugins" do
77
+ let(:env_home) { "/home/alice" }
78
+ let(:manifest_path) { env_home + "/.chef/plugin_manifest.json" }
79
+
80
+ before do
81
+ env_dup = ENV.to_hash
82
+ ENV.stub(:[]).and_return { |key| env_dup[key] }
83
+ ENV.stub(:[]).with("HOME").and_return(env_home)
84
+ end
85
+
86
+ context "when there is not a ~/.chef/plugin_manifest.json file" do
87
+ before do
88
+ File.stub(:exist?).with(manifest_path).and_return(false)
89
+ end
90
+
91
+ it "searches rubygems for plugins" do
92
+ if Gem::Specification.respond_to?(:latest_specs)
93
+ Gem::Specification.should_receive(:latest_specs).and_call_original
94
+ else
95
+ Gem.source_index.should_receive(:latest_specs).and_call_original
96
+ end
97
+ @loader.subcommand_files.each do |require_path|
98
+ require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
99
+ end
100
+ end
101
+
102
+ context "and HOME environment variable is not set" do
103
+ before do
104
+ ENV.stub(:[]).with("HOME").and_return(nil)
105
+ end
106
+
107
+ it "searches rubygems for plugins" do
108
+ if Gem::Specification.respond_to?(:latest_specs)
109
+ Gem::Specification.should_receive(:latest_specs).and_call_original
110
+ else
111
+ Gem.source_index.should_receive(:latest_specs).and_call_original
112
+ end
113
+ @loader.subcommand_files.each do |require_path|
114
+ require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
115
+ end
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ context "when there is a ~/.chef/plugin_manifest.json file" do
122
+ let(:ec2_server_create_plugin) { "/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_server_create.rb" }
123
+
124
+ let(:manifest_content) do
125
+ { "plugins" => {
126
+ "knife-ec2" => {
127
+ "paths" => [
128
+ ec2_server_create_plugin
129
+ ]
130
+ }
131
+ }
132
+ }
133
+ end
134
+
135
+ let(:manifest_json) { Chef::JSONCompat.to_json(manifest_content) }
136
+
137
+ before do
138
+ File.stub(:exist?).with(manifest_path).and_return(true)
139
+ File.stub(:read).with(manifest_path).and_return(manifest_json)
140
+ end
141
+
142
+ it "uses paths from the manifest instead of searching gems" do
143
+ Gem::Specification.should_not_receive(:latest_specs).and_call_original
144
+ @loader.subcommand_files.should include(ec2_server_create_plugin)
145
+ end
146
+
147
+ end
148
+ end
149
+
74
150
  end
@@ -280,4 +280,111 @@ describe Chef::Knife::Ssh do
280
280
  end
281
281
  end
282
282
  end
283
+
284
+ describe "#configure_password" do
285
+ before do
286
+ @knife.config.delete(:ssh_password_ng)
287
+ @knife.config.delete(:ssh_password)
288
+ end
289
+
290
+ context "when setting ssh_password_ng from knife ssh" do
291
+ # in this case ssh_password_ng exists, but ssh_password does not
292
+ it "should prompt for a password when ssh_passsword_ng is nil" do
293
+ @knife.config[:ssh_password_ng] = nil
294
+ @knife.should_receive(:get_password).and_return("mysekretpassw0rd")
295
+ @knife.configure_password
296
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
297
+ end
298
+
299
+ it "should set ssh_password to false if ssh_password_ng is false" do
300
+ @knife.config[:ssh_password_ng] = false
301
+ @knife.should_not_receive(:get_password)
302
+ @knife.configure_password
303
+ @knife.config[:ssh_password].should be_false
304
+ end
305
+
306
+ it "should set ssh_password to ssh_password_ng if we set a password" do
307
+ @knife.config[:ssh_password_ng] = "mysekretpassw0rd"
308
+ @knife.should_not_receive(:get_password)
309
+ @knife.configure_password
310
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
311
+ end
312
+ end
313
+
314
+ context "when setting ssh_password from knife bootstrap / knife * server create" do
315
+ # in this case ssh_password exists, but ssh_password_ng does not
316
+ it "should set ssh_password to nil when ssh_password is nil" do
317
+ @knife.config[:ssh_password] = nil
318
+ @knife.should_not_receive(:get_password)
319
+ @knife.configure_password
320
+ @knife.config[:ssh_password].should be_nil
321
+ end
322
+
323
+ it "should set ssh_password to false when ssh_password is false" do
324
+ @knife.config[:ssh_password] = false
325
+ @knife.should_not_receive(:get_password)
326
+ @knife.configure_password
327
+ @knife.config[:ssh_password].should be_false
328
+ end
329
+
330
+ it "should set ssh_password to ssh_password if we set a password" do
331
+ @knife.config[:ssh_password] = "mysekretpassw0rd"
332
+ @knife.should_not_receive(:get_password)
333
+ @knife.configure_password
334
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
335
+ end
336
+ end
337
+ context "when setting ssh_password in the config variable" do
338
+ before(:each) do
339
+ Chef::Config[:knife][:ssh_password] = "my_knife_passw0rd"
340
+ end
341
+ context "when setting ssh_password_ng from knife ssh" do
342
+ # in this case ssh_password_ng exists, but ssh_password does not
343
+ it "should prompt for a password when ssh_passsword_ng is nil" do
344
+ @knife.config[:ssh_password_ng] = nil
345
+ @knife.should_receive(:get_password).and_return("mysekretpassw0rd")
346
+ @knife.configure_password
347
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
348
+ end
349
+
350
+ it "should set ssh_password to the configured knife.rb value if ssh_password_ng is false" do
351
+ @knife.config[:ssh_password_ng] = false
352
+ @knife.should_not_receive(:get_password)
353
+ @knife.configure_password
354
+ @knife.config[:ssh_password].should == "my_knife_passw0rd"
355
+ end
356
+
357
+ it "should set ssh_password to ssh_password_ng if we set a password" do
358
+ @knife.config[:ssh_password_ng] = "mysekretpassw0rd"
359
+ @knife.should_not_receive(:get_password)
360
+ @knife.configure_password
361
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
362
+ end
363
+ end
364
+
365
+ context "when setting ssh_password from knife bootstrap / knife * server create" do
366
+ # in this case ssh_password exists, but ssh_password_ng does not
367
+ it "should set ssh_password to the configured knife.rb value when ssh_password is nil" do
368
+ @knife.config[:ssh_password] = nil
369
+ @knife.should_not_receive(:get_password)
370
+ @knife.configure_password
371
+ @knife.config[:ssh_password].should == "my_knife_passw0rd"
372
+ end
373
+
374
+ it "should set ssh_password to the configured knife.rb value when ssh_password is false" do
375
+ @knife.config[:ssh_password] = false
376
+ @knife.should_not_receive(:get_password)
377
+ @knife.configure_password
378
+ @knife.config[:ssh_password].should == "my_knife_passw0rd"
379
+ end
380
+
381
+ it "should set ssh_password to ssh_password if we set a password" do
382
+ @knife.config[:ssh_password] = "mysekretpassw0rd"
383
+ @knife.should_not_receive(:get_password)
384
+ @knife.configure_password
385
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
386
+ end
387
+ end
388
+ end
389
+ end
283
390
  end
@@ -38,6 +38,12 @@ describe Chef::Mixin::PathSanity do
38
38
  Chef::Platform.stub!(:windows?).and_return(false)
39
39
  end
40
40
 
41
+ it "adds all useful PATHs even if environment is an empty hash" do
42
+ env={}
43
+ @sanity.enforce_path_sanity(env)
44
+ env["PATH"].should == "#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
45
+ end
46
+
41
47
  it "adds all useful PATHs that are not yet in PATH to PATH" do
42
48
  env = {"PATH" => ""}
43
49
  @sanity.enforce_path_sanity(env)
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  #
2
3
  # Author:: Mark Mzyk (<mmzyk@opscode.com>)
3
4
  # Copyright:: Copyright (c) 2011 Opscode, Inc.
@@ -29,13 +30,13 @@ describe Chef::Mixin::Securable do
29
30
  it "should accept a group name or id for group" do
30
31
  lambda { @securable.group "root" }.should_not raise_error(ArgumentError)
31
32
  lambda { @securable.group 123 }.should_not raise_error(ArgumentError)
32
- lambda { @securable.group "root*goo" }.should raise_error(ArgumentError)
33
+ lambda { @securable.group "+bad:group" }.should raise_error(ArgumentError)
33
34
  end
34
35
 
35
36
  it "should accept a user name or id for owner" do
36
37
  lambda { @securable.owner "root" }.should_not raise_error(ArgumentError)
37
38
  lambda { @securable.owner 123 }.should_not raise_error(ArgumentError)
38
- lambda { @securable.owner "root*goo" }.should raise_error(ArgumentError)
39
+ lambda { @securable.owner "+bad:owner" }.should raise_error(ArgumentError)
39
40
  end
40
41
 
41
42
  it "allows the owner to be specified as #user" do
@@ -53,8 +54,81 @@ describe Chef::Mixin::Securable do
53
54
  end
54
55
  end
55
56
 
56
- it "should accept a group name or id for group with spaces and backslashes" do
57
+ it "should accept group/owner names with spaces and backslashes" do
57
58
  lambda { @securable.group 'test\ group' }.should_not raise_error(ArgumentError)
59
+ lambda { @securable.owner 'test\ group' }.should_not raise_error(ArgumentError)
60
+ end
61
+
62
+ it "should accept group/owner names that are a single character or digit" do
63
+ lambda { @securable.group 'v' }.should_not raise_error(ArgumentError)
64
+ lambda { @securable.group '1' }.should_not raise_error(ArgumentError)
65
+ lambda { @securable.owner 'v' }.should_not raise_error(ArgumentError)
66
+ lambda { @securable.owner '1' }.should_not raise_error(ArgumentError)
67
+ end
68
+
69
+ it "should not accept group/owner names starting with '-', '+', or '~'" do
70
+ lambda { @securable.group '-test' }.should raise_error(ArgumentError)
71
+ lambda { @securable.group '+test' }.should raise_error(ArgumentError)
72
+ lambda { @securable.group '~test' }.should raise_error(ArgumentError)
73
+ lambda { @securable.group 'te-st' }.should_not raise_error(ArgumentError)
74
+ lambda { @securable.group 'te+st' }.should_not raise_error(ArgumentError)
75
+ lambda { @securable.group 'te~st' }.should_not raise_error(ArgumentError)
76
+ lambda { @securable.owner '-test' }.should raise_error(ArgumentError)
77
+ lambda { @securable.owner '+test' }.should raise_error(ArgumentError)
78
+ lambda { @securable.owner '~test' }.should raise_error(ArgumentError)
79
+ lambda { @securable.owner 'te-st' }.should_not raise_error(ArgumentError)
80
+ lambda { @securable.owner 'te+st' }.should_not raise_error(ArgumentError)
81
+ lambda { @securable.owner 'te~st' }.should_not raise_error(ArgumentError)
82
+ end
83
+
84
+ it "should not accept group/owner names containing ':', ',' or non-space whitespace" do
85
+ lambda { @securable.group ':test' }.should raise_error(ArgumentError)
86
+ lambda { @securable.group 'te:st' }.should raise_error(ArgumentError)
87
+ lambda { @securable.group ',test' }.should raise_error(ArgumentError)
88
+ lambda { @securable.group 'te,st' }.should raise_error(ArgumentError)
89
+ lambda { @securable.group "\ttest" }.should raise_error(ArgumentError)
90
+ lambda { @securable.group "te\tst" }.should raise_error(ArgumentError)
91
+ lambda { @securable.group "\rtest" }.should raise_error(ArgumentError)
92
+ lambda { @securable.group "te\rst" }.should raise_error(ArgumentError)
93
+ lambda { @securable.group "\ftest" }.should raise_error(ArgumentError)
94
+ lambda { @securable.group "te\fst" }.should raise_error(ArgumentError)
95
+ lambda { @securable.group "\0test" }.should raise_error(ArgumentError)
96
+ lambda { @securable.group "te\0st" }.should raise_error(ArgumentError)
97
+ lambda { @securable.owner ':test' }.should raise_error(ArgumentError)
98
+ lambda { @securable.owner 'te:st' }.should raise_error(ArgumentError)
99
+ lambda { @securable.owner ',test' }.should raise_error(ArgumentError)
100
+ lambda { @securable.owner 'te,st' }.should raise_error(ArgumentError)
101
+ lambda { @securable.owner "\ttest" }.should raise_error(ArgumentError)
102
+ lambda { @securable.owner "te\tst" }.should raise_error(ArgumentError)
103
+ lambda { @securable.owner "\rtest" }.should raise_error(ArgumentError)
104
+ lambda { @securable.owner "te\rst" }.should raise_error(ArgumentError)
105
+ lambda { @securable.owner "\ftest" }.should raise_error(ArgumentError)
106
+ lambda { @securable.owner "te\fst" }.should raise_error(ArgumentError)
107
+ lambda { @securable.owner "\0test" }.should raise_error(ArgumentError)
108
+ lambda { @securable.owner "te\0st" }.should raise_error(ArgumentError)
109
+ end
110
+
111
+ it "should accept Active Directory-style domain names pulled in via LDAP (on unix hosts)" do
112
+ lambda { @securable.owner "domain\@user" }.should_not raise_error(ArgumentError)
113
+ lambda { @securable.owner "domain\\user" }.should_not raise_error(ArgumentError)
114
+ lambda { @securable.group "domain\@group" }.should_not raise_error(ArgumentError)
115
+ lambda { @securable.group "domain\\group" }.should_not raise_error(ArgumentError)
116
+ lambda { @securable.group "domain\\group^name" }.should_not raise_error(ArgumentError)
117
+ end
118
+
119
+ it "should not accept group/owner names containing embedded carriage returns" do
120
+ pending "XXX: params_validate needs to be extended to support multi-line regex"
121
+ #lambda { @securable.group "\ntest" }.should raise_error(ArgumentError)
122
+ #lambda { @securable.group "te\nst" }.should raise_error(ArgumentError)
123
+ #lambda { @securable.owner "\ntest" }.should raise_error(ArgumentError)
124
+ #lambda { @securable.owner "te\nst" }.should raise_error(ArgumentError)
125
+ end
126
+
127
+ it "should accept group/owner names in UTF-8" do
128
+ lambda { @securable.group 'tëst' }.should_not raise_error(ArgumentError)
129
+ lambda { @securable.group 'ë' }.should_not raise_error(ArgumentError)
130
+ lambda { @securable.owner 'tëst' }.should_not raise_error(ArgumentError)
131
+ lambda { @securable.owner 'ë' }.should_not raise_error(ArgumentError)
58
132
  end
59
133
 
60
134
  it "should accept a unix file mode in string form as an octal number" do