chef 12.0.0.alpha.1 → 12.0.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/application.rb +8 -1
  3. data/lib/chef/application/apply.rb +4 -0
  4. data/lib/chef/application/client.rb +7 -7
  5. data/lib/chef/application/solo.rb +21 -13
  6. data/lib/chef/chef_fs/chef_fs_data_store.rb +60 -6
  7. data/lib/chef/chef_fs/config.rb +78 -4
  8. data/lib/chef/chef_fs/data_handler/acl_data_handler.rb +2 -2
  9. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +1 -1
  10. data/lib/chef/chef_fs/data_handler/container_data_handler.rb +1 -1
  11. data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +1 -1
  12. data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +1 -1
  13. data/lib/chef/chef_fs/data_handler/data_handler_base.rb +76 -2
  14. data/lib/chef/chef_fs/data_handler/environment_data_handler.rb +1 -1
  15. data/lib/chef/chef_fs/data_handler/group_data_handler.rb +1 -1
  16. data/lib/chef/chef_fs/data_handler/node_data_handler.rb +1 -1
  17. data/lib/chef/chef_fs/data_handler/organization_data_handler.rb +30 -0
  18. data/lib/chef/chef_fs/data_handler/organization_invites_data_handler.rb +17 -0
  19. data/lib/chef/chef_fs/data_handler/organization_members_data_handler.rb +17 -0
  20. data/lib/chef/chef_fs/data_handler/role_data_handler.rb +1 -1
  21. data/lib/chef/chef_fs/data_handler/user_data_handler.rb +2 -1
  22. data/lib/chef/chef_fs/file_system.rb +0 -1
  23. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +1 -1
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +5 -1
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +73 -13
  27. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +44 -5
  28. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +1 -1
  29. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -3
  30. data/lib/chef/chef_fs/file_system/org_entry.rb +34 -0
  31. data/lib/chef/chef_fs/file_system/organization_invites_entry.rb +58 -0
  32. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +57 -0
  33. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +13 -4
  34. data/lib/chef/chef_fs/knife.rb +1 -1
  35. data/lib/chef/client.rb +8 -2
  36. data/lib/chef/config.rb +75 -57
  37. data/lib/chef/config_fetcher.rb +6 -21
  38. data/lib/chef/dsl/data_query.rb +48 -3
  39. data/lib/chef/dsl/platform_introspection.rb +42 -0
  40. data/lib/chef/dsl/reboot_pending.rb +6 -3
  41. data/lib/chef/encrypted_data_bag_item.rb +1 -1
  42. data/lib/chef/encrypted_data_bag_item/encryptor.rb +12 -0
  43. data/lib/chef/exceptions.rb +2 -0
  44. data/lib/chef/http/basic_client.rb +14 -0
  45. data/lib/chef/http/json_output.rb +7 -2
  46. data/lib/chef/knife.rb +36 -121
  47. data/lib/chef/knife/bootstrap.rb +68 -54
  48. data/lib/chef/knife/bootstrap/archlinux-gems.erb +6 -1
  49. data/lib/chef/knife/bootstrap/chef-aix.erb +5 -0
  50. data/lib/chef/knife/bootstrap/chef-full.erb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +70 -29
  52. data/lib/chef/knife/search.rb +56 -12
  53. data/lib/chef/knife/serve.rb +1 -1
  54. data/lib/chef/local_mode.rb +10 -4
  55. data/lib/chef/mixin/deep_merge.rb +6 -3
  56. data/lib/chef/mixin/shell_out.rb +33 -17
  57. data/lib/chef/null_logger.rb +72 -0
  58. data/lib/chef/platform.rb +2 -1
  59. data/lib/chef/platform/provider_mapping.rb +1 -1
  60. data/lib/chef/platform/rebooter.rb +54 -0
  61. data/lib/chef/provider/ifconfig.rb +15 -16
  62. data/lib/chef/provider/link.rb +1 -1
  63. data/lib/chef/provider/mount/mount.rb +1 -1
  64. data/lib/chef/provider/mount/solaris.rb +102 -64
  65. data/lib/chef/provider/package/aix.rb +4 -12
  66. data/lib/chef/provider/package/ips.rb +8 -12
  67. data/lib/chef/provider/package/macports.rb +4 -12
  68. data/lib/chef/provider/package/pacman.rb +2 -6
  69. data/lib/chef/provider/package/portage.rb +2 -6
  70. data/lib/chef/provider/package/rpm.rb +4 -12
  71. data/lib/chef/provider/package/solaris.rb +4 -12
  72. data/lib/chef/provider/reboot.rb +69 -0
  73. data/lib/chef/provider/service/debian.rb +10 -10
  74. data/lib/chef/provider/service/freebsd.rb +89 -73
  75. data/lib/chef/provider/service/gentoo.rb +2 -2
  76. data/lib/chef/provider/service/init.rb +6 -4
  77. data/lib/chef/provider/service/insserv.rb +3 -3
  78. data/lib/chef/provider/service/macosx.rb +2 -2
  79. data/lib/chef/provider/service/simple.rb +6 -4
  80. data/lib/chef/provider/service/solaris.rb +1 -1
  81. data/lib/chef/provider/service/systemd.rb +9 -9
  82. data/lib/chef/provider/service/upstart.rb +6 -6
  83. data/lib/chef/provider/subversion.rb +6 -6
  84. data/lib/chef/provider/user/dscl.rb +32 -28
  85. data/lib/chef/provider/user/windows.rb +6 -6
  86. data/lib/chef/provider/whyrun_safe_ruby_block.rb +1 -1
  87. data/lib/chef/providers.rb +1 -0
  88. data/lib/chef/recipe.rb +0 -1
  89. data/lib/chef/resource.rb +3 -5
  90. data/lib/chef/resource/mount.rb +9 -0
  91. data/lib/chef/resource/reboot.rb +48 -0
  92. data/lib/chef/resources.rb +1 -0
  93. data/lib/chef/run_context.rb +25 -0
  94. data/lib/chef/search/query.rb +122 -14
  95. data/lib/chef/util/path_helper.rb +54 -6
  96. data/lib/chef/util/windows/net_user.rb +4 -1
  97. data/lib/chef/version.rb +1 -1
  98. data/lib/chef/win32/api/file.rb +1 -5
  99. data/lib/chef/win32/api/net.rb +1 -0
  100. data/lib/chef/workstation_config_loader.rb +177 -0
  101. data/spec/functional/http/simple_spec.rb +57 -1
  102. data/spec/functional/mixin/shell_out_spec.rb +2 -2
  103. data/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +51 -0
  104. data/spec/functional/rebooter_spec.rb +105 -0
  105. data/spec/functional/resource/deploy_revision_spec.rb +0 -4
  106. data/spec/functional/resource/file_spec.rb +26 -3
  107. data/spec/functional/resource/group_spec.rb +5 -3
  108. data/spec/functional/resource/link_spec.rb +16 -16
  109. data/spec/functional/resource/reboot_spec.rb +103 -0
  110. data/spec/integration/client/client_spec.rb +4 -8
  111. data/spec/integration/client/ipv6_spec.rb +1 -1
  112. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -2
  113. data/spec/integration/knife/delete_spec.rb +39 -0
  114. data/spec/integration/knife/deps_spec.rb +30 -20
  115. data/spec/integration/knife/download_spec.rb +77 -1
  116. data/spec/integration/knife/list_spec.rb +221 -0
  117. data/spec/integration/knife/raw_spec.rb +1 -1
  118. data/spec/integration/knife/show_spec.rb +2 -2
  119. data/spec/integration/knife/upload_spec.rb +154 -1
  120. data/spec/support/pedant/run_pedant.rb +0 -1
  121. data/spec/support/shared/functional/http.rb +8 -1
  122. data/spec/support/shared/integration/integration_helper.rb +11 -19
  123. data/spec/support/shared/unit/platform_introspector.rb +22 -0
  124. data/spec/unit/application/apply.rb +11 -1
  125. data/spec/unit/application/solo_spec.rb +19 -3
  126. data/spec/unit/chef_fs/config_spec.rb +58 -0
  127. data/spec/unit/config_fetcher_spec.rb +1 -3
  128. data/spec/unit/config_spec.rb +247 -220
  129. data/spec/unit/dsl/data_query_spec.rb +165 -23
  130. data/spec/unit/dsl/reboot_pending_spec.rb +1 -7
  131. data/spec/unit/encrypted_data_bag_item_spec.rb +1 -1
  132. data/spec/unit/knife/bootstrap_spec.rb +354 -182
  133. data/spec/unit/knife/core/bootstrap_context_spec.rb +67 -30
  134. data/spec/unit/knife_spec.rb +3 -30
  135. data/spec/unit/mixin/deep_merge_spec.rb +14 -0
  136. data/spec/unit/mixin/shell_out_spec.rb +134 -64
  137. data/spec/unit/provider/ifconfig/debian_spec.rb +19 -9
  138. data/spec/unit/provider/ifconfig/redhat_spec.rb +16 -14
  139. data/spec/unit/provider/ifconfig_spec.rb +3 -3
  140. data/spec/unit/provider/link_spec.rb +5 -5
  141. data/spec/unit/provider/mount/mount_spec.rb +10 -1
  142. data/spec/unit/provider/mount/solaris_spec.rb +185 -11
  143. data/spec/unit/provider/package/aix_spec.rb +5 -17
  144. data/spec/unit/provider/package/ips_spec.rb +8 -21
  145. data/spec/unit/provider/package/macports_spec.rb +12 -12
  146. data/spec/unit/provider/package/pacman_spec.rb +4 -12
  147. data/spec/unit/provider/package/portage_spec.rb +5 -15
  148. data/spec/unit/provider/package/rpm_spec.rb +7 -22
  149. data/spec/unit/provider/package/solaris_spec.rb +5 -16
  150. data/spec/unit/provider/service/arch_service_spec.rb +8 -14
  151. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  152. data/spec/unit/provider/service/freebsd_service_spec.rb +457 -225
  153. data/spec/unit/provider/service/gentoo_service_spec.rb +2 -2
  154. data/spec/unit/provider/service/init_service_spec.rb +10 -10
  155. data/spec/unit/provider/service/insserv_service_spec.rb +3 -4
  156. data/spec/unit/provider/service/invokercd_service_spec.rb +8 -9
  157. data/spec/unit/provider/service/macosx_spec.rb +5 -5
  158. data/spec/unit/provider/service/simple_service_spec.rb +4 -6
  159. data/spec/unit/provider/service/solaris_smf_service_spec.rb +1 -3
  160. data/spec/unit/provider/service/systemd_service_spec.rb +20 -20
  161. data/spec/unit/provider/service/upstart_service_spec.rb +15 -17
  162. data/spec/unit/provider/subversion_spec.rb +5 -6
  163. data/spec/unit/provider/user/dscl_spec.rb +2 -1
  164. data/spec/unit/provider/user/windows_spec.rb +7 -0
  165. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +2 -2
  166. data/spec/unit/resource/mount_spec.rb +9 -0
  167. data/spec/unit/resource_spec.rb +0 -4
  168. data/spec/unit/rest_spec.rb +1 -1
  169. data/spec/unit/run_context_spec.rb +15 -0
  170. data/spec/unit/search/query_spec.rb +196 -40
  171. data/spec/unit/util/path_helper_spec.rb +111 -28
  172. data/spec/unit/workstation_config_loader_spec.rb +283 -0
  173. metadata +36 -20
  174. data/lib/chef/knife/bootstrap/centos5-gems.erb +0 -62
  175. data/lib/chef/knife/bootstrap/fedora13-gems.erb +0 -44
  176. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +0 -53
  177. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +0 -48
  178. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +0 -46
  179. data/spec/support/shared/integration/chef_zero_support.rb +0 -130
  180. data/spec/unit/knife/config_file_selection_spec.rb +0 -135
@@ -24,43 +24,185 @@ class DataQueryDSLTester
24
24
  end
25
25
 
26
26
  describe Chef::DSL::DataQuery do
27
- before(:each) do
28
- @language = DataQueryDSLTester.new
29
- @node = Hash.new
30
- @language.stub(:node).and_return(@node)
27
+ let(:node) { Hash.new }
28
+
29
+ let(:language) do
30
+ language = DataQueryDSLTester.new
31
+ language.stub(:node).and_return(@node)
32
+ language
31
33
  end
32
34
 
33
- describe "when loading data bags and items" do
35
+ describe "::data_bag" do
34
36
  it "lists the items in a data bag" do
35
- Chef::DataBag.should_receive(:load).with("bag_name").and_return("item_1" => "http://url_for/item_1", "item_2" => "http://url_for/item_2")
36
- @language.data_bag("bag_name").sort.should == %w[item_1 item_2]
37
+ allow(Chef::DataBag).to receive(:load)
38
+ .with("bag_name")
39
+ .and_return("item_1" => "http://url_for/item_1", "item_2" => "http://url_for/item_2")
40
+ expect( language.data_bag("bag_name").sort ).to eql %w(item_1 item_2)
37
41
  end
42
+ end
38
43
 
39
- it "validates the name of the data bag you're trying to load" do
40
- lambda {@language.data_bag("!# %^&& ")}.should raise_error(Chef::Exceptions::InvalidDataBagName)
44
+ shared_examples_for "a data bag item" do
45
+ it "validates the name of the data bag you're trying to load an item from" do
46
+ expect{ language.send(method_name, " %%^& ", "item_name") }.to raise_error(Chef::Exceptions::InvalidDataBagName)
41
47
  end
42
48
 
43
- it "fetches a data bag item" do
44
- @item = Chef::DataBagItem.new
45
- @item.data_bag("bag_name")
46
- @item.raw_data = {"id" => "item_name", "FUU" => "FUU"}
47
- Chef::DataBagItem.should_receive(:load).with("bag_name", "item_name").and_return(@item)
48
- @language.data_bag_item("bag_name", "item_name").should == @item
49
+ it "validates the id of the data bag item you're trying to load" do
50
+ expect{ language.send(method_name, "bag_name", " 987 (*&()") }.to raise_error(Chef::Exceptions::InvalidDataBagItemID)
49
51
  end
50
52
 
51
- it "validates the name of the data bag you're trying to load an item from" do
52
- lambda {@language.data_bag_item(" %%^& ", "item_name")}.should raise_error(Chef::Exceptions::InvalidDataBagName)
53
+ it "validates that the id of the data bag item is not nil" do
54
+ expect{ language.send(method_name, "bag_name", nil) }.to raise_error(Chef::Exceptions::InvalidDataBagItemID)
53
55
  end
56
+ end
54
57
 
55
- it "validates the id of the data bag item you're trying to load" do
56
- lambda {@language.data_bag_item("bag_name", " 987 (*&()")}.should raise_error(Chef::Exceptions::InvalidDataBagItemID)
58
+ describe "::data_bag_item" do
59
+ let(:bag_name) { "bag_name" }
60
+
61
+ let(:item_name) { "item_name" }
62
+
63
+ let(:raw_data) {{
64
+ "id" => item_name,
65
+ "greeting" => "hello",
66
+ "nested" => {
67
+ "a1" => [1, 2, 3],
68
+ "a2" => { "b1" => true }
69
+ }
70
+ }}
71
+
72
+ let(:item) do
73
+ item = Chef::DataBagItem.new
74
+ item.data_bag(bag_name)
75
+ item.raw_data = raw_data
76
+ item
57
77
  end
58
78
 
59
- it "validates that the id of the data bag item is not nil" do
60
- lambda {@language.data_bag_item("bag_name", nil)}.should raise_error(Chef::Exceptions::InvalidDataBagItemID)
79
+ it "fetches a data bag item" do
80
+ allow( Chef::DataBagItem ).to receive(:load).with(bag_name, item_name).and_return(item)
81
+ expect( language.data_bag_item(bag_name, item_name) ).to eql item
61
82
  end
62
83
 
63
- end
84
+ include_examples "a data bag item" do
85
+ let(:method_name) { :data_bag_item }
86
+ end
64
87
 
65
- end
88
+ context "when the item is encrypted" do
89
+ let(:default_secret) { "abc123SECRET" }
90
+
91
+ let(:encoded_data) { Chef::EncryptedDataBagItem.encrypt_data_bag_item(raw_data, default_secret) }
92
+
93
+ let(:item) do
94
+ item = Chef::DataBagItem.new
95
+ item.data_bag(bag_name)
96
+ item.raw_data = encoded_data
97
+ item
98
+ end
99
+
100
+ before do
101
+ allow( Chef::DataBagItem ).to receive(:load).with(bag_name, item_name).and_return(item)
102
+ end
66
103
 
104
+ shared_examples_for "encryption detected" do
105
+ let(:encoded_data) do
106
+ Chef::Config[:data_bag_encrypt_version] = version
107
+ Chef::EncryptedDataBagItem.encrypt_data_bag_item(raw_data, default_secret)
108
+ end
109
+
110
+ before do
111
+ allow( Chef::EncryptedDataBagItem ).to receive(:load_secret).and_return(default_secret)
112
+ end
113
+
114
+ it "detects encrypted data bag" do
115
+ expect( encryptor ).to receive(:encryptor_keys).at_least(:once).and_call_original
116
+ expect( Chef::Log ).to receive(:debug).with(/Data bag item looks encrypted/)
117
+ language.data_bag_item(bag_name, item_name)
118
+ end
119
+ end
120
+
121
+ context "when encryption version is 1" do
122
+ include_examples "encryption detected" do
123
+ let(:version) { 1 }
124
+ let(:encryptor) { Chef::EncryptedDataBagItem::Encryptor::Version1Encryptor }
125
+ end
126
+ end
127
+
128
+ context "when encryption version is 2" do
129
+ include_examples "encryption detected" do
130
+ let(:version) { 2 }
131
+ let(:encryptor) { Chef::EncryptedDataBagItem::Encryptor::Version2Encryptor }
132
+ end
133
+ end
134
+
135
+ context "when encryption version is 3", :ruby_20_only do
136
+ include_examples "encryption detected" do
137
+ let(:version) { 3 }
138
+ let(:encryptor) { Chef::EncryptedDataBagItem::Encryptor::Version3Encryptor }
139
+ end
140
+ end
141
+
142
+ shared_examples_for "an encrypted data bag item" do
143
+ it "returns an encrypted data bag item" do
144
+ expect( language.data_bag_item(bag_name, item_name, secret) ).to be_a_kind_of(Chef::EncryptedDataBagItem)
145
+ end
146
+
147
+ it "decrypts the contents of the data bag item" do
148
+ expect( language.data_bag_item(bag_name, item_name, secret).to_hash ).to eql raw_data
149
+ end
150
+ end
151
+
152
+ context "when a secret is supplied" do
153
+ include_examples "an encrypted data bag item" do
154
+ let(:secret) { default_secret }
155
+ end
156
+ end
157
+
158
+ context "when a secret is not supplied" do
159
+ before do
160
+ allow( Chef::Config ).to receive(:[]).and_call_original
161
+ expect( Chef::Config ).to receive(:[]).with(:encrypted_data_bag_secret).and_return(path)
162
+ expect( Chef::EncryptedDataBagItem ).to receive(:load_secret).and_call_original
163
+ end
164
+
165
+ context "when a secret is located at Chef::Config[:encrypted_data_bag_secret]" do
166
+ let(:path) { "/tmp/my_secret" }
167
+
168
+ before do
169
+ expect( File ).to receive(:exist?).with(path).and_return(true)
170
+ expect( IO ).to receive(:read).with(path).and_return(default_secret)
171
+ end
172
+
173
+ include_examples "an encrypted data bag item" do
174
+ let(:secret) { nil }
175
+ end
176
+ end
177
+
178
+ shared_examples_for "no secret file" do
179
+ it "should fail to load the data bag item" do
180
+ expect( Chef::Log ).to receive(:error).with(/Failed to load secret for encrypted data bag item/)
181
+ expect( Chef::Log ).to receive(:error).with(/Failed to load data bag item/)
182
+ expect{ language.data_bag_item(bag_name, item_name) }.to raise_error(error_type, error_message)
183
+ end
184
+ end
185
+
186
+ context "when Chef::Config[:encrypted_data_bag_secret] is not configured" do
187
+ include_examples "no secret file" do
188
+ let(:path) { nil }
189
+ let(:error_type) { ArgumentError }
190
+ let(:error_message) { /No secret specified and no secret found/ }
191
+ end
192
+ end
193
+
194
+ context "when Chef::Config[:encrypted_data_bag_secret] does not exist" do
195
+ include_examples "no secret file" do
196
+ before do
197
+ expect( File ).to receive(:exist?).with(path).and_return(false)
198
+ end
199
+
200
+ let(:path) { "/tmp/my_secret" }
201
+ let(:error_type) { Errno::ENOENT }
202
+ let(:error_message) { /file not found/ }
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
@@ -21,7 +21,7 @@ require "spec_helper"
21
21
 
22
22
  describe Chef::DSL::RebootPending do
23
23
  describe "reboot_pending?" do
24
- describe "in isoloation" do
24
+ describe "in isolation" do
25
25
  let(:recipe) { Object.new.extend(Chef::DSL::RebootPending) }
26
26
 
27
27
  before do
@@ -74,12 +74,6 @@ describe Chef::DSL::RebootPending do
74
74
  end
75
75
  end
76
76
 
77
- context "platform is not supported" do
78
- it 'should raise an exception' do
79
- recipe.stub_chain(:node, :[]).with(:platform).and_return('msdos')
80
- expect { recipe.reboot_pending? }.to raise_error(Chef::Exceptions::UnsupportedPlatform)
81
- end
82
- end
83
77
  end # describe in isolation
84
78
 
85
79
  describe "in a recipe" do
@@ -451,7 +451,7 @@ describe Chef::EncryptedDataBagItem do
451
451
  end
452
452
 
453
453
  it "load_secret(nil) emits a reasonable error message" do
454
- lambda { Chef::EncryptedDataBagItem.load_secret(nil) }.should raise_error(ArgumentError, "No secret specified to load_secret and no secret found at #{Chef::Config.platform_specific_path('/etc/chef/encrypted_data_bag_secret')}")
454
+ lambda { Chef::EncryptedDataBagItem.load_secret(nil) }.should raise_error(ArgumentError, /No secret specified and no secret found at #{Chef::Config[:encrypted_data_bag_secret]}/)
455
455
  end
456
456
  end
457
457
 
@@ -22,111 +22,200 @@ Chef::Knife::Bootstrap.load_deps
22
22
  require 'net/ssh'
23
23
 
24
24
  describe Chef::Knife::Bootstrap do
25
- before(:each) do
25
+ let(:knife) do
26
26
  Chef::Log.logger = Logger.new(StringIO.new)
27
- @knife = Chef::Knife::Bootstrap.new
28
- # Merge default settings in.
29
- @knife.merge_configs
30
- @knife.config[:template_file] = File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb"))
31
- @stdout = StringIO.new
32
- @knife.ui.stub(:stdout).and_return(@stdout)
33
- @stderr = StringIO.new
34
- @knife.ui.stub(:stderr).and_return(@stderr)
35
- end
27
+ Chef::Config[:knife][:bootstrap_template] = bootstrap_template unless bootstrap_template.nil?
36
28
 
37
- it "should return a name of default bootstrap template" do
38
- @knife.find_template.should be_a_kind_of(String)
39
- end
29
+ k = Chef::Knife::Bootstrap.new
30
+ k.merge_configs
40
31
 
41
- it "should error if template can not be found" do
42
- @knife.config[:template_file] = false
43
- @knife.config[:distro] = 'penultimate'
44
- lambda { @knife.find_template }.should raise_error
32
+ k.ui.stub(:stderr).and_return(stderr)
33
+ k
45
34
  end
46
35
 
47
- it "should look for templates early in the run" do
48
- File.stub(:exists?).and_return(true)
49
- @knife.name_args = ['shatner']
50
- @knife.stub(:read_template).and_return("")
51
- @knife.stub(:knife_ssh).and_return(true)
52
- @knife_ssh = @knife.knife_ssh
53
- @knife.should_receive(:find_template).ordered
54
- @knife.should_receive(:knife_ssh).ordered
55
- @knife_ssh.should_receive(:run) # rspec appears to keep order per object
56
- @knife.run
57
- end
36
+ let(:stderr) { StringIO.new }
58
37
 
59
- it "should load the specified template" do
60
- @knife.config[:distro] = 'fedora13-gems'
61
- lambda { @knife.find_template }.should_not raise_error
62
- end
38
+ let(:bootstrap_template) { nil }
63
39
 
64
- it "should load the specified template from a Ruby gem" do
65
- @knife.config[:template_file] = false
66
- Gem.stub(:find_files).and_return(["/Users/schisamo/.rvm/gems/ruby-1.9.2-p180@chef-0.10/gems/knife-windows-0.5.4/lib/chef/knife/bootstrap/fake-bootstrap-template.erb"])
67
- File.stub(:exists?).and_return(true)
68
- IO.stub(:read).and_return('random content')
69
- @knife.config[:distro] = 'fake-bootstrap-template'
70
- lambda { @knife.find_template }.should_not raise_error
40
+ it "should use chef-full as default template" do
41
+ knife.bootstrap_template.should be_a_kind_of(String)
42
+ File.basename(knife.bootstrap_template).should eq("chef-full")
71
43
  end
72
44
 
73
- it "should return an empty run_list" do
74
- @knife.instance_variable_set("@template_file", @knife.config[:template_file])
75
- template_string = @knife.read_template
76
- @knife.render_template(template_string).should == '{"run_list":[]}'
77
- end
45
+ context "when finding templates" do
46
+ context "when :bootstrap_template config is set to a file" do
47
+ context "that doesn't exist" do
48
+ let(:bootstrap_template) { "/opt/blah/not/exists/template.erb" }
78
49
 
79
- it "should have role[base] in the run_list" do
80
- @knife.instance_variable_set("@template_file", @knife.config[:template_file])
81
- template_string = @knife.read_template
82
- @knife.parse_options(["-r","role[base]"])
83
- @knife.render_template(template_string).should == '{"run_list":["role[base]"]}'
84
- end
50
+ it "raises an error" do
51
+ lambda { knife.find_template }.should raise_error
52
+ end
53
+ end
85
54
 
86
- it "should have role[base] and recipe[cupcakes] in the run_list" do
87
- @knife.instance_variable_set("@template_file", @knife.config[:template_file])
88
- template_string = @knife.read_template
89
- @knife.parse_options(["-r", "role[base],recipe[cupcakes]"])
90
- @knife.render_template(template_string).should == '{"run_list":["role[base]","recipe[cupcakes]"]}'
91
- end
55
+ context "that exists" do
56
+ let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")) }
57
+
58
+ it "loads the given file as the template" do
59
+ Chef::Log.should_receive(:debug)
60
+ knife.find_template.should eq(File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")))
61
+ end
62
+ end
63
+ end
64
+
65
+ context "when :bootstrap_template config is set to a template name" do
66
+ let(:bootstrap_template) { "example" }
67
+
68
+ let(:builtin_template_path) { File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/chef/knife/bootstrap', "example.erb"))}
69
+
70
+ let(:chef_config_dir_template_path) { "/knife/chef/config/bootstrap/example.erb" }
71
+
72
+ let(:env_home_template_path) { "/env/home/.chef/bootstrap/example.erb" }
73
+
74
+ let(:gem_files_template_path) { "/Users/schisamo/.rvm/gems/ruby-1.9.2-p180@chef-0.10/gems/knife-windows-0.5.4/lib/chef/knife/bootstrap/fake-bootstrap-template.erb" }
75
+
76
+ def configure_chef_config_dir
77
+ Chef::Knife.stub(:chef_config_dir).and_return("/knife/chef/config")
78
+ end
79
+
80
+ def configure_env_home
81
+ ENV['HOME'] = "/env/home"
82
+ end
83
+
84
+ def configure_gem_files
85
+ Gem.stub(:find_files).and_return([ gem_files_template_path ])
86
+ end
87
+
88
+ before(:each) do
89
+ @original_home = ENV['HOME']
90
+ ENV['HOME'] = nil
91
+ File.should_receive(:exists?).with(bootstrap_template).and_return(false)
92
+ end
93
+
94
+ after(:each) do
95
+ ENV['HOME'] = @original_home
96
+ end
97
+
98
+ context "when file is available everywhere" do
99
+ before do
100
+ configure_chef_config_dir
101
+ configure_env_home
102
+ configure_gem_files
103
+
104
+ File.should_receive(:exists?).with(builtin_template_path).and_return(true)
105
+ end
106
+
107
+ it "should load the template from built-in templates" do
108
+ knife.find_template.should eq(builtin_template_path)
109
+ end
110
+ end
111
+
112
+ context "when file is available in chef_config_dir" do
113
+ before do
114
+ configure_chef_config_dir
115
+ configure_env_home
116
+ configure_gem_files
92
117
 
93
- it "should have foo => {bar => baz} in the first_boot" do
94
- @knife.instance_variable_set("@template_file", @knife.config[:template_file])
95
- template_string = @knife.read_template
96
- @knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
97
- expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
98
- actual_hash = FFI_Yajl::Parser.new.parse(@knife.render_template(template_string))
99
- actual_hash.should == expected_hash
118
+ File.should_receive(:exists?).with(builtin_template_path).and_return(false)
119
+ File.should_receive(:exists?).with(chef_config_dir_template_path).and_return(true)
120
+
121
+ it "should load the template from chef_config_dir" do
122
+ knife.find_template.should eq(chef_config_dir_template_path)
123
+ end
124
+ end
125
+ end
126
+
127
+ context "when file is available in ENV['HOME']" do
128
+ before do
129
+ configure_chef_config_dir
130
+ configure_env_home
131
+ configure_gem_files
132
+
133
+ File.should_receive(:exists?).with(builtin_template_path).and_return(false)
134
+ File.should_receive(:exists?).with(chef_config_dir_template_path).and_return(false)
135
+ File.should_receive(:exists?).with(env_home_template_path).and_return(true)
136
+ end
137
+
138
+ it "should load the template from chef_config_dir" do
139
+ knife.find_template.should eq(env_home_template_path)
140
+ end
141
+ end
142
+
143
+ context "when file is available in Gem files" do
144
+ before do
145
+ configure_chef_config_dir
146
+ configure_gem_files
147
+
148
+ File.should_receive(:exists?).with(builtin_template_path).and_return(false)
149
+ File.should_receive(:exists?).with(chef_config_dir_template_path).and_return(false)
150
+ File.should_receive(:exists?).with(gem_files_template_path).and_return(true)
151
+ end
152
+
153
+ it "should load the template from Gem files" do
154
+ knife.find_template.should eq(gem_files_template_path)
155
+ end
156
+ end
157
+ end
100
158
  end
101
159
 
102
- it "should create a hint file when told to" do
103
- @knife.config[:template_file] = File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test-hints.erb"))
104
- @knife.instance_variable_set("@template_file", @knife.config[:template_file])
105
- template_string = @knife.read_template
106
- @knife.parse_options(["--hint", "openstack"])
107
- @knife.render_template(template_string).should match /\/etc\/chef\/ohai\/hints\/openstack.json/
160
+ ["-d", "--distro", "-t", "--bootstrap-template", "--template-file"].each do |t|
161
+ context "when #{t} option is given in the command line" do
162
+ it "sets the knife :bootstrap_template config" do
163
+ knife.parse_options([t,"blahblah"])
164
+ knife.merge_configs
165
+ knife.bootstrap_template.should eq("blahblah")
166
+ end
167
+ end
108
168
  end
109
169
 
110
- it "should populate a hint file with JSON when given a file to read" do
111
- @knife.stub(:find_template).and_return(true)
112
- @knife.config[:template_file] = File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test-hints.erb"))
113
- ::File.stub(:read).and_return('{ "foo" : "bar" }')
114
- @knife.instance_variable_set("@template_file", @knife.config[:template_file])
115
- template_string = @knife.read_template
116
- @knife.stub(:read_template).and_return('{ "foo" : "bar" }')
117
- @knife.parse_options(["--hint", "openstack=hints/openstack.json"])
118
- @knife.render_template(template_string).should match /\{\"foo\":\"bar\"\}/
170
+ context "with run_list template" do
171
+ let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")) }
172
+
173
+ it "should return an empty run_list" do
174
+ knife.render_template.should == '{"run_list":[]}'
175
+ end
176
+
177
+ it "should have role[base] in the run_list" do
178
+ knife.parse_options(["-r","role[base]"])
179
+ knife.merge_configs
180
+ knife.render_template.should == '{"run_list":["role[base]"]}'
181
+ end
182
+
183
+ it "should have role[base] and recipe[cupcakes] in the run_list" do
184
+ knife.parse_options(["-r", "role[base],recipe[cupcakes]"])
185
+ knife.merge_configs
186
+ knife.render_template.should == '{"run_list":["role[base]","recipe[cupcakes]"]}'
187
+ end
188
+
189
+ it "should have foo => {bar => baz} in the first_boot" do
190
+ knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
191
+ knife.merge_configs
192
+ expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
193
+ actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
194
+ actual_hash.should == expected_hash
195
+ end
119
196
  end
120
197
 
121
- it "should take the node name from ARGV" do
122
- @knife.name_args = ['barf']
123
- @knife.name_args.first.should == "barf"
198
+ context "with hints template" do
199
+ let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test-hints.erb")) }
200
+
201
+ it "should create a hint file when told to" do
202
+ knife.parse_options(["--hint", "openstack"])
203
+ knife.merge_configs
204
+ knife.render_template.should match /\/etc\/chef\/ohai\/hints\/openstack.json/
205
+ end
206
+
207
+ it "should populate a hint file with JSON when given a file to read" do
208
+ ::File.stub(:read).and_return('{ "foo" : "bar" }')
209
+ knife.parse_options(["--hint", "openstack=hints/openstack.json"])
210
+ knife.merge_configs
211
+ knife.render_template.should match /\{\"foo\":\"bar\"\}/
212
+ end
124
213
  end
125
214
 
126
215
  describe "specifying no_proxy with various entries" do
127
216
  subject(:knife) do
128
217
  k = described_class.new
129
- k.instance_variable_set("@template_file", template_file)
218
+ Chef::Config[:knife][:bootstrap_template] = template_file
130
219
  k.parse_options(options)
131
220
  k.merge_configs
132
221
  k
@@ -139,8 +228,7 @@ describe Chef::Knife::Bootstrap do
139
228
  let(:options){ ["--bootstrap-no-proxy", setting, "-s", "foo"] }
140
229
  let(:template_file) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "no_proxy.erb")) }
141
230
  let(:rendered_template) do
142
- template_string = knife.read_template
143
- knife.render_template(template_string)
231
+ knife.render_template
144
232
  end
145
233
 
146
234
  context "via --bootstrap-no-proxy" do
@@ -158,19 +246,57 @@ describe Chef::Knife::Bootstrap do
158
246
  rendered_template.should match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
159
247
  end
160
248
  end
249
+
250
+ context "via --ssl-verify-mode none" do
251
+ let(:options) { ["--node-ssl-verify-mode", "none"] }
252
+
253
+ it "renders the client.rb with ssl_verify_mode set to :verify_none" do
254
+ rendered_template.should match(/ssl_verify_mode :verify_none/)
255
+ end
256
+ end
257
+
258
+ context "via --node-ssl-verify-mode peer" do
259
+ let(:options) { ["--node-ssl-verify-mode", "peer"] }
260
+
261
+ it "renders the client.rb with ssl_verify_mode set to :verify_peer" do
262
+ rendered_template.should match(/ssl_verify_mode :verify_peer/)
263
+ end
264
+ end
265
+
266
+ context "via --node-ssl-verify-mode all" do
267
+ let(:options) { ["--node-ssl-verify-mode", "all"] }
268
+
269
+ it "raises error" do
270
+ lambda{ rendered_template }.should raise_error
271
+ end
272
+ end
273
+
274
+ context "via --node-verify-api-cert" do
275
+ let(:options) { ["--node-verify-api-cert"] }
276
+
277
+ it "renders the client.rb with verify_api_cert set to true" do
278
+ rendered_template.should match(/verify_api_cert true/)
279
+ end
280
+ end
281
+
282
+ context "via --no-node-verify-api-cert" do
283
+ let(:options) { ["--no-node-verify-api-cert"] }
284
+
285
+ it "renders the client.rb with verify_api_cert set to false" do
286
+ rendered_template.should match(/verify_api_cert false/)
287
+ end
288
+ end
161
289
  end
162
290
 
163
291
  describe "specifying the encrypted data bag secret key" do
164
- subject(:knife) { described_class.new }
165
292
  let(:secret) { "supersekret" }
166
293
  let(:secret_file) { File.join(CHEF_SPEC_DATA, 'bootstrap', 'encrypted_data_bag_secret') }
167
294
  let(:options) { [] }
168
- let(:template_file) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "secret.erb")) }
295
+ let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "secret.erb")) }
169
296
  let(:rendered_template) do
170
- knife.instance_variable_set("@template_file", template_file)
171
297
  knife.parse_options(options)
172
- template_string = knife.read_template
173
- knife.render_template(template_string)
298
+ knife.merge_configs
299
+ knife.render_template
174
300
  end
175
301
 
176
302
  context "via --secret" do
@@ -198,10 +324,27 @@ describe Chef::Knife::Bootstrap do
198
324
  end
199
325
  end
200
326
 
201
- context "via Chef::Config[:encrypted_data_bag_secret]" do
202
- before(:each) { Chef::Config[:encrypted_data_bag_secret] = secret_file }
327
+ context "secret via config" do
328
+ before do
329
+ Chef::Config[:knife][:secret] = secret
330
+ end
331
+
332
+ it "creates a secret file" do
333
+ rendered_template.should match(%r{#{secret}})
334
+ end
335
+
336
+ it "renders the client.rb with an encrypted_data_bag_secret entry" do
337
+ rendered_template.should match(%r{encrypted_data_bag_secret\s*"/etc/chef/encrypted_data_bag_secret"})
338
+ end
339
+ end
340
+
341
+ context "secret-file via config" do
203
342
  let(:secret) { IO.read(secret_file) }
204
343
 
344
+ before do
345
+ Chef::Config[:knife][:secret_file] = secret_file
346
+ end
347
+
205
348
  it "creates a secret file" do
206
349
  rendered_template.should match(%r{#{secret}})
207
350
  end
@@ -212,186 +355,215 @@ describe Chef::Knife::Bootstrap do
212
355
  end
213
356
  end
214
357
 
358
+ describe "when transferring trusted certificates" do
359
+ let(:trusted_certs_dir) { File.join(CHEF_SPEC_DATA, 'trusted_certs') }
360
+
361
+ let(:rendered_template) do
362
+ knife.merge_configs
363
+ knife.render_template
364
+ end
365
+
366
+ before do
367
+ Chef::Config[:trusted_certs_dir] = trusted_certs_dir
368
+ IO.stub(:read).and_call_original
369
+ IO.stub(:read).with("/etc/chef/validation.pem").and_return("")
370
+ end
371
+
372
+ def certificates
373
+ Dir[File.join(trusted_certs_dir, "*.{crt,pem}")]
374
+ end
375
+
376
+ it "creates /etc/chef/trusted_certs" do
377
+ rendered_template.should match(%r{mkdir -p /etc/chef/trusted_certs})
378
+ end
379
+
380
+ it "copies the certificates in the directory" do
381
+ certificates.each do |cert|
382
+ IO.should_receive(:read).with(File.expand_path(cert))
383
+ end
384
+
385
+ certificates.each do |cert|
386
+ rendered_template.should match(%r{cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'})
387
+ end
388
+ end
389
+
390
+ it "doesn't create /etc/chef/trusted_certs if :trusted_certs_dir is empty" do
391
+ Dir.should_receive(:glob).with(File.join(trusted_certs_dir, "*.{crt,pem}")).and_return([])
392
+ rendered_template.should_not match(%r{mkdir -p /etc/chef/trusted_certs})
393
+ end
394
+ end
395
+
215
396
  describe "when configuring the underlying knife ssh command" do
216
397
  context "from the command line" do
217
- before do
218
- @knife.name_args = ["foo.example.com"]
219
- @knife.config[:ssh_user] = "rooty"
220
- @knife.config[:ssh_port] = "4001"
221
- @knife.config[:ssh_password] = "open_sesame"
398
+ let(:knife_ssh) do
399
+ knife.name_args = ["foo.example.com"]
400
+ knife.config[:ssh_user] = "rooty"
401
+ knife.config[:ssh_port] = "4001"
402
+ knife.config[:ssh_password] = "open_sesame"
222
403
  Chef::Config[:knife][:ssh_user] = nil
223
404
  Chef::Config[:knife][:ssh_port] = nil
224
- @knife.config[:forward_agent] = true
225
- @knife.config[:identity_file] = "~/.ssh/me.rsa"
226
- @knife.stub(:read_template).and_return("")
227
- @knife_ssh = @knife.knife_ssh
405
+ knife.config[:forward_agent] = true
406
+ knife.config[:identity_file] = "~/.ssh/me.rsa"
407
+ knife.stub(:render_template).and_return("")
408
+ knife.knife_ssh
228
409
  end
229
410
 
230
411
  it "configures the hostname" do
231
- @knife_ssh.name_args.first.should == "foo.example.com"
412
+ knife_ssh.name_args.first.should == "foo.example.com"
232
413
  end
233
414
 
234
415
  it "configures the ssh user" do
235
- @knife_ssh.config[:ssh_user].should == 'rooty'
416
+ knife_ssh.config[:ssh_user].should == 'rooty'
236
417
  end
237
418
 
238
419
  it "configures the ssh password" do
239
- @knife_ssh.config[:ssh_password].should == 'open_sesame'
420
+ knife_ssh.config[:ssh_password].should == 'open_sesame'
240
421
  end
241
422
 
242
423
  it "configures the ssh port" do
243
- @knife_ssh.config[:ssh_port].should == '4001'
424
+ knife_ssh.config[:ssh_port].should == '4001'
244
425
  end
245
426
 
246
427
  it "configures the ssh agent forwarding" do
247
- @knife_ssh.config[:forward_agent].should == true
428
+ knife_ssh.config[:forward_agent].should == true
248
429
  end
249
430
 
250
431
  it "configures the ssh identity file" do
251
- @knife_ssh.config[:identity_file].should == '~/.ssh/me.rsa'
432
+ knife_ssh.config[:identity_file].should == '~/.ssh/me.rsa'
252
433
  end
253
434
  end
435
+
254
436
  context "validating use_sudo_password" do
255
437
  before do
256
- @knife.config[:distro] = "ubuntu"
257
- @knife.config[:ssh_password] = "password"
258
- @knife.stub(:read_template).and_return(IO.read(@knife.find_template).chomp)
438
+ knife.config[:ssh_password] = "password"
439
+ knife.stub(:render_template).and_return("")
259
440
  end
260
441
 
261
442
  it "use_sudo_password contains description and long params for help" do
262
- @knife.options.should have_key(:use_sudo_password) \
263
- and @knife.options[:use_sudo_password][:description].to_s.should_not == ''\
264
- and @knife.options[:use_sudo_password][:long].to_s.should_not == ''
443
+ knife.options.should have_key(:use_sudo_password) \
444
+ and knife.options[:use_sudo_password][:description].to_s.should_not == ''\
445
+ and knife.options[:use_sudo_password][:long].to_s.should_not == ''
265
446
  end
266
447
 
267
448
  it "uses the password from --ssh-password for sudo when --use-sudo-password is set" do
268
- @knife.config[:use_sudo] = true
269
- @knife.config[:use_sudo_password] = true
270
- @knife.ssh_command.should include("echo \'#{@knife.config[:ssh_password]}\' | sudo -S")
449
+ knife.config[:use_sudo] = true
450
+ knife.config[:use_sudo_password] = true
451
+ knife.ssh_command.should include("echo \'#{knife.config[:ssh_password]}\' | sudo -S")
271
452
  end
272
453
 
273
454
  it "should not honor --use-sudo-password when --use-sudo is not set" do
274
- @knife.config[:use_sudo] = false
275
- @knife.config[:use_sudo_password] = true
276
- @knife.ssh_command.should_not include("echo #{@knife.config[:ssh_password]} | sudo -S")
455
+ knife.config[:use_sudo] = false
456
+ knife.config[:use_sudo_password] = true
457
+ knife.ssh_command.should_not include("echo #{knife.config[:ssh_password]} | sudo -S")
277
458
  end
278
459
  end
460
+
279
461
  context "from the knife config file" do
280
- before do
281
- @knife.name_args = ["config.example.com"]
282
- @knife.config[:ssh_user] = nil
283
- @knife.config[:ssh_port] = nil
284
- @knife.config[:ssh_gateway] = nil
285
- @knife.config[:forward_agent] = nil
286
- @knife.config[:identity_file] = nil
287
- @knife.config[:host_key_verify] = nil
462
+ let(:knife_ssh) do
463
+ knife.name_args = ["config.example.com"]
464
+ knife.config[:ssh_user] = nil
465
+ knife.config[:ssh_port] = nil
466
+ knife.config[:ssh_gateway] = nil
467
+ knife.config[:forward_agent] = nil
468
+ knife.config[:identity_file] = nil
469
+ knife.config[:host_key_verify] = nil
288
470
  Chef::Config[:knife][:ssh_user] = "curiosity"
289
471
  Chef::Config[:knife][:ssh_port] = "2430"
290
472
  Chef::Config[:knife][:forward_agent] = true
291
473
  Chef::Config[:knife][:identity_file] = "~/.ssh/you.rsa"
292
474
  Chef::Config[:knife][:ssh_gateway] = "towel.blinkenlights.nl"
293
475
  Chef::Config[:knife][:host_key_verify] = true
294
- @knife.stub(:read_template).and_return("")
295
- @knife_ssh = @knife.knife_ssh
476
+ knife.stub(:render_template).and_return("")
477
+ knife.knife_ssh
296
478
  end
297
479
 
298
480
  it "configures the ssh user" do
299
- @knife_ssh.config[:ssh_user].should == 'curiosity'
481
+ knife_ssh.config[:ssh_user].should == 'curiosity'
300
482
  end
301
483
 
302
484
  it "configures the ssh port" do
303
- @knife_ssh.config[:ssh_port].should == '2430'
485
+ knife_ssh.config[:ssh_port].should == '2430'
304
486
  end
305
487
 
306
488
  it "configures the ssh agent forwarding" do
307
- @knife_ssh.config[:forward_agent].should == true
489
+ knife_ssh.config[:forward_agent].should == true
308
490
  end
309
491
 
310
492
  it "configures the ssh identity file" do
311
- @knife_ssh.config[:identity_file].should == '~/.ssh/you.rsa'
493
+ knife_ssh.config[:identity_file].should == '~/.ssh/you.rsa'
312
494
  end
313
495
 
314
496
  it "configures the ssh gateway" do
315
- @knife_ssh.config[:ssh_gateway].should == 'towel.blinkenlights.nl'
497
+ knife_ssh.config[:ssh_gateway].should == 'towel.blinkenlights.nl'
316
498
  end
317
499
 
318
500
  it "configures the host key verify mode" do
319
- @knife_ssh.config[:host_key_verify].should == true
501
+ knife_ssh.config[:host_key_verify].should == true
320
502
  end
321
503
  end
322
504
 
323
505
  describe "when falling back to password auth when host key auth fails" do
324
- before do
325
- @knife.name_args = ["foo.example.com"]
326
- @knife.config[:ssh_user] = "rooty"
327
- @knife.config[:identity_file] = "~/.ssh/me.rsa"
328
- @knife.stub(:read_template).and_return("")
329
- @knife_ssh = @knife.knife_ssh
506
+ let(:knife_ssh_with_password_auth) do
507
+ knife.name_args = ["foo.example.com"]
508
+ knife.config[:ssh_user] = "rooty"
509
+ knife.config[:identity_file] = "~/.ssh/me.rsa"
510
+ knife.stub(:render_template).and_return("")
511
+ k = knife.knife_ssh
512
+ k.stub(:get_password).and_return('typed_in_password')
513
+ knife.stub(:knife_ssh).and_return(k)
514
+ knife.knife_ssh_with_password_auth
330
515
  end
331
516
 
332
517
  it "prompts the user for a password " do
333
- @knife.stub(:knife_ssh).and_return(@knife_ssh)
334
- @knife_ssh.stub(:get_password).and_return('typed_in_password')
335
- alternate_knife_ssh = @knife.knife_ssh_with_password_auth
336
- alternate_knife_ssh.config[:ssh_password].should == 'typed_in_password'
518
+ knife_ssh_with_password_auth.config[:ssh_password].should == 'typed_in_password'
337
519
  end
338
520
 
339
521
  it "configures knife not to use the identity file that didn't work previously" do
340
- @knife.stub(:knife_ssh).and_return(@knife_ssh)
341
- @knife_ssh.stub(:get_password).and_return('typed_in_password')
342
- alternate_knife_ssh = @knife.knife_ssh_with_password_auth
343
- alternate_knife_ssh.config[:identity_file].should be_nil
522
+ knife_ssh_with_password_auth.config[:identity_file].should be_nil
344
523
  end
345
524
  end
346
525
  end
347
526
 
348
- describe "when running the bootstrap" do
349
- before do
350
- @knife.name_args = ["foo.example.com"]
351
- @knife.config[:ssh_user] = "rooty"
352
- @knife.config[:identity_file] = "~/.ssh/me.rsa"
353
- @knife.stub(:read_template).and_return("")
354
- @knife_ssh = @knife.knife_ssh
355
- @knife.stub(:knife_ssh).and_return(@knife_ssh)
356
- end
527
+ it "verifies that a server to bootstrap was given as a command line arg" do
528
+ knife.name_args = nil
529
+ lambda { knife.run }.should raise_error(SystemExit)
530
+ stderr.string.should match /ERROR:.+FQDN or ip/
531
+ end
357
532
 
358
- it "verifies that a server to bootstrap was given as a command line arg" do
359
- @knife.name_args = nil
360
- lambda { @knife.run }.should raise_error(SystemExit)
361
- @stderr.string.should match /ERROR:.+FQDN or ip/
533
+ describe "when running the bootstrap" do
534
+ let(:knife_ssh) do
535
+ knife.name_args = ["foo.example.com"]
536
+ knife.config[:ssh_user] = "rooty"
537
+ knife.config[:identity_file] = "~/.ssh/me.rsa"
538
+ knife.stub(:render_template).and_return("")
539
+ knife_ssh = knife.knife_ssh
540
+ knife.stub(:knife_ssh).and_return(knife_ssh)
541
+ knife_ssh
362
542
  end
363
543
 
364
544
  it "configures the underlying ssh command and then runs it" do
365
- @knife_ssh.should_receive(:run)
366
- @knife.run
545
+ knife_ssh.should_receive(:run)
546
+ knife.run
367
547
  end
368
548
 
369
549
  it "falls back to password based auth when auth fails the first time" do
370
- @knife.stub(:puts)
550
+ knife.stub(:puts)
371
551
 
372
- @fallback_knife_ssh = @knife_ssh.dup
373
- @knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed.new("no ssh for you"))
374
- @knife.stub(:knife_ssh_with_password_auth).and_return(@fallback_knife_ssh)
375
- @fallback_knife_ssh.should_receive(:run)
376
- @knife.run
552
+ fallback_knife_ssh = knife_ssh.dup
553
+ knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed.new("no ssh for you"))
554
+ knife.stub(:knife_ssh_with_password_auth).and_return(fallback_knife_ssh)
555
+ fallback_knife_ssh.should_receive(:run)
556
+ knife.run
377
557
  end
378
558
 
379
559
  it "raises the exception if config[:ssh_password] is set and an authentication exception is raised" do
380
- @knife.config[:ssh_password] = "password"
381
- @knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed)
382
- lambda { @knife.run }.should raise_error(Net::SSH::AuthenticationFailed)
560
+ knife.config[:ssh_password] = "password"
561
+ knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed)
562
+ lambda { knife.run }.should raise_error(Net::SSH::AuthenticationFailed)
383
563
  end
564
+ end
384
565
 
385
- context "Chef::Config[:encrypted_data_bag_secret] is set" do
386
- let(:secret_file) { File.join(CHEF_SPEC_DATA, 'bootstrap', 'encrypted_data_bag_secret') }
387
- before { Chef::Config[:encrypted_data_bag_secret] = secret_file }
388
-
389
- it "warns the configuration option is deprecated" do
390
- @knife_ssh.should_receive(:run)
391
- @knife.ui.should_receive(:warn).at_least(3).times
392
- @knife.run
393
- end
394
- end
566
+ describe "specifying ssl verification" do
395
567
 
396
568
  end
397
569