knife-windows 1.0.0.rc.1 → 1.0.0.rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +5 -5
- data/.travis.yml +20 -20
- data/CHANGELOG.md +75 -74
- data/DOC_CHANGES.md +323 -323
- data/Gemfile +12 -12
- data/LICENSE +201 -201
- data/README.md +393 -292
- data/RELEASE_NOTES.md +79 -74
- data/Rakefile +21 -16
- data/appveyor.yml +42 -42
- data/ci.gemfile +15 -15
- data/features/knife_help.feature +20 -20
- data/features/support/env.rb +5 -5
- data/knife-windows.gemspec +28 -28
- data/lib/chef/knife/bootstrap/windows-chef-client-msi.erb +247 -241
- data/lib/chef/knife/bootstrap_windows_base.rb +388 -368
- data/lib/chef/knife/bootstrap_windows_ssh.rb +110 -110
- data/lib/chef/knife/bootstrap_windows_winrm.rb +102 -113
- data/lib/chef/knife/core/windows_bootstrap_context.rb +361 -362
- data/lib/chef/knife/knife_windows_base.rb +33 -0
- data/lib/chef/knife/windows_cert_generate.rb +155 -155
- data/lib/chef/knife/windows_cert_install.rb +68 -68
- data/lib/chef/knife/windows_helper.rb +36 -36
- data/lib/chef/knife/windows_listener_create.rb +107 -107
- data/lib/chef/knife/winrm.rb +212 -191
- data/lib/chef/knife/winrm_base.rb +118 -125
- data/lib/chef/knife/winrm_knife_base.rb +218 -201
- data/lib/chef/knife/winrm_session.rb +80 -71
- data/lib/chef/knife/winrm_shared_options.rb +47 -47
- data/lib/chef/knife/wsman_endpoint.rb +44 -44
- data/lib/chef/knife/wsman_test.rb +96 -96
- data/lib/knife-windows/path_helper.rb +234 -234
- data/lib/knife-windows/version.rb +6 -6
- data/spec/assets/win_template_rendered_with_bootstrap_install_command.txt +217 -0
- data/spec/assets/win_template_rendered_without_bootstrap_install_command.txt +329 -0
- data/spec/assets/win_template_unrendered.txt +246 -0
- data/spec/functional/bootstrap_download_spec.rb +216 -140
- data/spec/spec_helper.rb +87 -72
- data/spec/unit/knife/bootstrap_options_spec.rb +146 -146
- data/spec/unit/knife/bootstrap_template_spec.rb +92 -92
- data/spec/unit/knife/bootstrap_windows_winrm_spec.rb +240 -161
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +151 -101
- data/spec/unit/knife/windows_cert_generate_spec.rb +90 -90
- data/spec/unit/knife/windows_cert_install_spec.rb +51 -51
- data/spec/unit/knife/windows_listener_create_spec.rb +76 -76
- data/spec/unit/knife/winrm_session_spec.rb +55 -46
- data/spec/unit/knife/winrm_spec.rb +504 -376
- data/spec/unit/knife/wsman_test_spec.rb +175 -175
- metadata +28 -8
@@ -1,92 +1,92 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Chirag Jog (<chirag@clogeny.com>)
|
3
|
-
# Copyright:: Copyright (c) 2013 Chirag Jog
|
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
|
-
TEMPLATE_FILE = File.expand_path(File.dirname(__FILE__)) + "/../../../lib/chef/knife/bootstrap/windows-chef-client-msi.erb"
|
20
|
-
|
21
|
-
require 'spec_helper'
|
22
|
-
|
23
|
-
describe Chef::Knife::BootstrapWindowsWinrm do
|
24
|
-
let(:template_file) { TEMPLATE_FILE }
|
25
|
-
let(:options) { [] }
|
26
|
-
let(:rendered_template) do
|
27
|
-
knife.instance_variable_set("@template_file", template_file)
|
28
|
-
knife.parse_options(options)
|
29
|
-
# Avoid referencing a validation keyfile we won't find during #render_template
|
30
|
-
template = IO.read(template_file).chomp
|
31
|
-
knife.render_template(template)
|
32
|
-
end
|
33
|
-
|
34
|
-
before(:all) do
|
35
|
-
@original_config = Chef::Config.hash_dup
|
36
|
-
@original_knife_config = Chef::Config[:knife].dup
|
37
|
-
end
|
38
|
-
|
39
|
-
after(:all) do
|
40
|
-
Chef::Config.configuration = @original_config
|
41
|
-
Chef::Config[:knife] = @original_knife_config
|
42
|
-
end
|
43
|
-
|
44
|
-
before(:each) do
|
45
|
-
Chef::Log.logger = Logger.new(StringIO.new)
|
46
|
-
@knife = Chef::Knife::BootstrapWindowsWinrm.new
|
47
|
-
# Merge default settings in.
|
48
|
-
@knife.merge_configs
|
49
|
-
@knife.config[:template_file] = template_file
|
50
|
-
@stdout = StringIO.new
|
51
|
-
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
|
52
|
-
@stderr = StringIO.new
|
53
|
-
allow(@knife.ui).to receive(:stderr).and_return(@stderr)
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "specifying no_proxy with various entries" do
|
57
|
-
subject(:knife) { described_class.new }
|
58
|
-
let(:options){ ["--bootstrap-proxy", "", "--bootstrap-no-proxy", setting] }
|
59
|
-
|
60
|
-
context "via --bootstrap-no-proxy" do
|
61
|
-
let(:setting) { "api.opscode.com" }
|
62
|
-
|
63
|
-
it "renders the client.rb with a single FQDN no_proxy entry" do
|
64
|
-
expect(rendered_template).to match(%r{.*no_proxy\s*\"api.opscode.com\".*})
|
65
|
-
end
|
66
|
-
end
|
67
|
-
context "via --bootstrap-no-proxy multiple" do
|
68
|
-
let(:setting) { "api.opscode.com,172.16.10.*" }
|
69
|
-
|
70
|
-
it "renders the client.rb with comma-separated FQDN and wildcard IP address no_proxy entries" do
|
71
|
-
expect(rendered_template).to match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "specifying --msi-url" do
|
77
|
-
subject(:knife) { described_class.new }
|
78
|
-
|
79
|
-
context "with explicitly provided --msi-url" do
|
80
|
-
let(:options) { ["--msi-url", "file:///something.msi"] }
|
81
|
-
|
82
|
-
it "bootstrap batch file must fetch from provided url" do
|
83
|
-
expect(rendered_template).to match(%r{.*REMOTE_SOURCE_MSI_URL=file:///something\.msi.*})
|
84
|
-
end
|
85
|
-
end
|
86
|
-
context "with no provided --msi-url" do
|
87
|
-
it "bootstrap batch file must fetch from provided url" do
|
88
|
-
expect(rendered_template).to match(%r{.*REMOTE_SOURCE_MSI_URL=https://www\.chef\.io/.*})
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
1
|
+
#
|
2
|
+
# Author:: Chirag Jog (<chirag@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Chirag Jog
|
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
|
+
TEMPLATE_FILE = File.expand_path(File.dirname(__FILE__)) + "/../../../lib/chef/knife/bootstrap/windows-chef-client-msi.erb"
|
20
|
+
|
21
|
+
require 'spec_helper'
|
22
|
+
|
23
|
+
describe Chef::Knife::BootstrapWindowsWinrm do
|
24
|
+
let(:template_file) { TEMPLATE_FILE }
|
25
|
+
let(:options) { [] }
|
26
|
+
let(:rendered_template) do
|
27
|
+
knife.instance_variable_set("@template_file", template_file)
|
28
|
+
knife.parse_options(options)
|
29
|
+
# Avoid referencing a validation keyfile we won't find during #render_template
|
30
|
+
template = IO.read(template_file).chomp
|
31
|
+
knife.render_template(template)
|
32
|
+
end
|
33
|
+
|
34
|
+
before(:all) do
|
35
|
+
@original_config = Chef::Config.hash_dup
|
36
|
+
@original_knife_config = Chef::Config[:knife].dup
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:all) do
|
40
|
+
Chef::Config.configuration = @original_config
|
41
|
+
Chef::Config[:knife] = @original_knife_config
|
42
|
+
end
|
43
|
+
|
44
|
+
before(:each) do
|
45
|
+
Chef::Log.logger = Logger.new(StringIO.new)
|
46
|
+
@knife = Chef::Knife::BootstrapWindowsWinrm.new
|
47
|
+
# Merge default settings in.
|
48
|
+
@knife.merge_configs
|
49
|
+
@knife.config[:template_file] = template_file
|
50
|
+
@stdout = StringIO.new
|
51
|
+
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
|
52
|
+
@stderr = StringIO.new
|
53
|
+
allow(@knife.ui).to receive(:stderr).and_return(@stderr)
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "specifying no_proxy with various entries" do
|
57
|
+
subject(:knife) { described_class.new }
|
58
|
+
let(:options){ ["--bootstrap-proxy", "", "--bootstrap-no-proxy", setting] }
|
59
|
+
|
60
|
+
context "via --bootstrap-no-proxy" do
|
61
|
+
let(:setting) { "api.opscode.com" }
|
62
|
+
|
63
|
+
it "renders the client.rb with a single FQDN no_proxy entry" do
|
64
|
+
expect(rendered_template).to match(%r{.*no_proxy\s*\"api.opscode.com\".*})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
context "via --bootstrap-no-proxy multiple" do
|
68
|
+
let(:setting) { "api.opscode.com,172.16.10.*" }
|
69
|
+
|
70
|
+
it "renders the client.rb with comma-separated FQDN and wildcard IP address no_proxy entries" do
|
71
|
+
expect(rendered_template).to match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "specifying --msi-url" do
|
77
|
+
subject(:knife) { described_class.new }
|
78
|
+
|
79
|
+
context "with explicitly provided --msi-url" do
|
80
|
+
let(:options) { ["--msi-url", "file:///something.msi"] }
|
81
|
+
|
82
|
+
it "bootstrap batch file must fetch from provided url" do
|
83
|
+
expect(rendered_template).to match(%r{.*REMOTE_SOURCE_MSI_URL=file:///something\.msi.*})
|
84
|
+
end
|
85
|
+
end
|
86
|
+
context "with no provided --msi-url" do
|
87
|
+
it "bootstrap batch file must fetch from provided url" do
|
88
|
+
expect(rendered_template).to match(%r{.*REMOTE_SOURCE_MSI_URL=https://www\.chef\.io/.*})
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -1,161 +1,240 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Adam Edwards(<adamed@getchef.com>)
|
3
|
-
# Copyright:: Copyright (c) 2014 Chef Software, Inc.
|
4
|
-
# License:: Apache License, Version 2.0
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
|
-
require 'spec_helper'
|
20
|
-
|
21
|
-
Chef::Knife::Winrm.load_deps
|
22
|
-
|
23
|
-
describe Chef::Knife::BootstrapWindowsWinrm do
|
24
|
-
before(:all) do
|
25
|
-
Chef::Config.reset
|
26
|
-
end
|
27
|
-
|
28
|
-
before do
|
29
|
-
# Kernel.stub(:sleep).and_return 10
|
30
|
-
allow(bootstrap).to receive(:sleep).and_return(10)
|
31
|
-
allow(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(true)
|
32
|
-
end
|
33
|
-
|
34
|
-
after do
|
35
|
-
# Kernel.unstub(:sleep)
|
36
|
-
allow(bootstrap).to receive(:sleep).and_return(10)
|
37
|
-
end
|
38
|
-
|
39
|
-
let(:bootstrap) { Chef::Knife::BootstrapWindowsWinrm.new(['winrm', '-d', 'windows-chef-client-msi', '-x', 'Administrator', 'localhost']) }
|
40
|
-
let(:session) { Chef::Knife::Winrm::WinrmSession.new({ :host => 'winrm.cloudapp.net', :port => '5986', :transport => :ssl }) }
|
41
|
-
|
42
|
-
let(:initial_fail_count) { 4 }
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
1
|
+
#
|
2
|
+
# Author:: Adam Edwards(<adamed@getchef.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'spec_helper'
|
20
|
+
|
21
|
+
Chef::Knife::Winrm.load_deps
|
22
|
+
|
23
|
+
describe Chef::Knife::BootstrapWindowsWinrm do
|
24
|
+
before(:all) do
|
25
|
+
Chef::Config.reset
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
# Kernel.stub(:sleep).and_return 10
|
30
|
+
allow(bootstrap).to receive(:sleep).and_return(10)
|
31
|
+
allow(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
# Kernel.unstub(:sleep)
|
36
|
+
allow(bootstrap).to receive(:sleep).and_return(10)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:bootstrap) { Chef::Knife::BootstrapWindowsWinrm.new(['winrm', '-d', 'windows-chef-client-msi', '-x', 'Administrator', 'localhost']) }
|
40
|
+
let(:session) { Chef::Knife::Winrm::WinrmSession.new({ :host => 'winrm.cloudapp.net', :port => '5986', :transport => :ssl }) }
|
41
|
+
|
42
|
+
let(:initial_fail_count) { 4 }
|
43
|
+
|
44
|
+
context "knife secret-file && knife secret options are passed" do
|
45
|
+
before do
|
46
|
+
Chef::Config.reset
|
47
|
+
Chef::Config[:knife][:encrypted_data_bag_secret_file] = "/tmp/encrypted_data_bag_secret"
|
48
|
+
Chef::Config[:knife][:encrypted_data_bag_secret] = "data_bag_secret_key_passed_under_knife_secret_option"
|
49
|
+
end
|
50
|
+
it "gives preference to secret key passed under knife's secret-file option" do
|
51
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
52
|
+
Chef::Config[:knife][:encrypted_data_bag_secret_file]).
|
53
|
+
and_return("data_bag_secret_key_passed_under_knife_secret_file_option")
|
54
|
+
expect(bootstrap.load_correct_secret).to eq(
|
55
|
+
"data_bag_secret_key_passed_under_knife_secret_file_option")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "cli secret-file && cli secret options are passed" do
|
60
|
+
before do
|
61
|
+
Chef::Config.reset
|
62
|
+
bootstrap.config[:encrypted_data_bag_secret_file] = "/tmp/encrypted_data_bag_secret"
|
63
|
+
bootstrap.config[:encrypted_data_bag_secret] = "data_bag_secret_key_passed_under_cli_secret_option"
|
64
|
+
end
|
65
|
+
it "gives preference to secret key passed under cli's secret-file option" do
|
66
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
67
|
+
bootstrap.config[:encrypted_data_bag_secret_file]).
|
68
|
+
and_return("data_bag_secret_key_passed_under_cli_secret_file_option")
|
69
|
+
expect(bootstrap.load_correct_secret).to eq(
|
70
|
+
"data_bag_secret_key_passed_under_cli_secret_file_option")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "knife secret-file, knife secret, cli secret-file && cli secret options are passed" do
|
75
|
+
before do
|
76
|
+
Chef::Config.reset
|
77
|
+
Chef::Config[:knife][:encrypted_data_bag_secret_file] = "/tmp/knife_encrypted_data_bag_secret"
|
78
|
+
Chef::Config[:knife][:encrypted_data_bag_secret] = "data_bag_secret_key_passed_under_knife_secret_option"
|
79
|
+
bootstrap.config[:encrypted_data_bag_secret_file] = "/tmp/cli_encrypted_data_bag_secret"
|
80
|
+
bootstrap.config[:encrypted_data_bag_secret] = "data_bag_secret_key_passed_under_cli_secret_option"
|
81
|
+
end
|
82
|
+
it "gives preference to secret key passed under cli's secret-file option" do
|
83
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
84
|
+
Chef::Config[:knife][:encrypted_data_bag_secret_file]).
|
85
|
+
and_return("data_bag_secret_key_passed_under_knife_secret_file_option")
|
86
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
87
|
+
bootstrap.config[:encrypted_data_bag_secret_file]).
|
88
|
+
and_return("data_bag_secret_key_passed_under_cli_secret_file_option")
|
89
|
+
expect(bootstrap.load_correct_secret).to eq(
|
90
|
+
"data_bag_secret_key_passed_under_cli_secret_file_option")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "knife secret-file && cli secret options are passed" do
|
95
|
+
before do
|
96
|
+
Chef::Config.reset
|
97
|
+
Chef::Config[:knife][:encrypted_data_bag_secret_file] = "/tmp/encrypted_data_bag_secret"
|
98
|
+
bootstrap.config[:encrypted_data_bag_secret] = "data_bag_secret_key_passed_under_cli_secret_option"
|
99
|
+
end
|
100
|
+
it "gives preference to secret key passed under cli's secret option" do
|
101
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
102
|
+
Chef::Config[:knife][:encrypted_data_bag_secret_file]).
|
103
|
+
and_return("data_bag_secret_key_passed_under_knife_secret_file_option")
|
104
|
+
expect(bootstrap.load_correct_secret).to eq(
|
105
|
+
"data_bag_secret_key_passed_under_cli_secret_option")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "knife secret && cli secret-file options are passed" do
|
110
|
+
before do
|
111
|
+
Chef::Config.reset
|
112
|
+
Chef::Config[:knife][:encrypted_data_bag_secret] = "data_bag_secret_key_passed_under_knife_secret_option"
|
113
|
+
bootstrap.config[:encrypted_data_bag_secret_file] = "/tmp/encrypted_data_bag_secret"
|
114
|
+
end
|
115
|
+
it "gives preference to secret key passed under cli's secret-file option" do
|
116
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
117
|
+
bootstrap.config[:encrypted_data_bag_secret_file]).
|
118
|
+
and_return("data_bag_secret_key_passed_under_cli_secret_file_option")
|
119
|
+
expect(bootstrap.load_correct_secret).to eq(
|
120
|
+
"data_bag_secret_key_passed_under_cli_secret_file_option")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "cli secret-file option is passed" do
|
125
|
+
before do
|
126
|
+
Chef::Config.reset
|
127
|
+
bootstrap.config[:encrypted_data_bag_secret_file] = "/tmp/encrypted_data_bag_secret"
|
128
|
+
end
|
129
|
+
it "takes the secret key passed under cli's secret-file option" do
|
130
|
+
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
131
|
+
bootstrap.config[:encrypted_data_bag_secret_file]).
|
132
|
+
and_return("data_bag_secret_key_passed_under_cli_secret_file_option")
|
133
|
+
expect(bootstrap.load_correct_secret).to eq(
|
134
|
+
"data_bag_secret_key_passed_under_cli_secret_file_option")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should retry if a 401 is received from WinRM' do
|
139
|
+
call_result_sequence = Array.new(initial_fail_count) {lambda {raise WinRM::WinRMHTTPTransportError.new('', '401')}}
|
140
|
+
call_result_sequence.push(0)
|
141
|
+
allow(bootstrap).to receive(:run_command).and_return(*call_result_sequence)
|
142
|
+
allow(bootstrap).to receive(:print)
|
143
|
+
allow(bootstrap.ui).to receive(:info)
|
144
|
+
|
145
|
+
expect(bootstrap).to receive(:run_command).exactly(call_result_sequence.length).times
|
146
|
+
bootstrap.send(:wait_for_remote_response, 2)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should retry if something other than a 401 is received from WinRM' do
|
150
|
+
call_result_sequence = Array.new(initial_fail_count) {lambda {raise WinRM::WinRMHTTPTransportError.new('', '500')}}
|
151
|
+
call_result_sequence.push(0)
|
152
|
+
allow(bootstrap).to receive(:run_command).and_return(*call_result_sequence)
|
153
|
+
allow(bootstrap).to receive(:print)
|
154
|
+
allow(bootstrap.ui).to receive(:info)
|
155
|
+
|
156
|
+
expect(bootstrap).to receive(:run_command).exactly(call_result_sequence.length).times
|
157
|
+
bootstrap.send(:wait_for_remote_response, 2)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should keep retrying at 10s intervals if the timeout in minutes has not elapsed' do
|
161
|
+
call_result_sequence = Array.new(initial_fail_count) {lambda {raise WinRM::WinRMHTTPTransportError.new('', '500')}}
|
162
|
+
call_result_sequence.push(0)
|
163
|
+
allow(bootstrap).to receive(:run_command).and_return(*call_result_sequence)
|
164
|
+
allow(bootstrap).to receive(:print)
|
165
|
+
allow(bootstrap.ui).to receive(:info)
|
166
|
+
|
167
|
+
expect(bootstrap).to receive(:run_command).exactly(call_result_sequence.length).times
|
168
|
+
bootstrap.send(:wait_for_remote_response, 2)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should have a wait timeout of 2 minutes by default' do
|
172
|
+
allow(bootstrap).to receive(:run_command).and_raise(WinRM::WinRMHTTPTransportError.new('','500'))
|
173
|
+
allow(bootstrap).to receive(:create_bootstrap_bat_command).and_raise(SystemExit)
|
174
|
+
expect(bootstrap).to receive(:wait_for_remote_response).with(2)
|
175
|
+
allow(bootstrap).to receive(:validate_name_args!).and_return(nil)
|
176
|
+
allow(bootstrap.ui).to receive(:info)
|
177
|
+
bootstrap.config[:auth_timeout] = bootstrap.options[:auth_timeout][:default]
|
178
|
+
expect { bootstrap.bootstrap }.to raise_error(SystemExit)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should not a wait for timeout on Errno::ECONNREFUSED' do
|
182
|
+
allow(bootstrap).to receive(:run_command).and_raise(Errno::ECONNREFUSED.new)
|
183
|
+
allow(bootstrap.ui).to receive(:info)
|
184
|
+
bootstrap.config[:auth_timeout] = bootstrap.options[:auth_timeout][:default]
|
185
|
+
expect(bootstrap.ui).to receive(:error).with("Connection refused connecting to localhost:5985.")
|
186
|
+
|
187
|
+
# wait_for_remote_response is protected method, So define singleton test method to call it.
|
188
|
+
bootstrap.define_singleton_method(:test_wait_for_remote_response){wait_for_remote_response(bootstrap.options[:auth_timeout][:default])}
|
189
|
+
expect { bootstrap.test_wait_for_remote_response }.to raise_error(Errno::ECONNREFUSED)
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should stop retrying if more than 2 minutes has elapsed' do
|
193
|
+
times = [ Time.new(2014, 4, 1, 22, 25), Time.new(2014, 4, 1, 22, 51), Time.new(2014, 4, 1, 22, 28) ]
|
194
|
+
allow(Time).to receive(:now).and_return(*times)
|
195
|
+
run_command_result = lambda {raise WinRM::WinRMHTTPTransportError, '401'}
|
196
|
+
allow(bootstrap).to receive(:validate_name_args!).and_return(nil)
|
197
|
+
allow(bootstrap).to receive(:run_command).and_return(run_command_result)
|
198
|
+
allow(bootstrap).to receive(:print)
|
199
|
+
allow(bootstrap.ui).to receive(:info)
|
200
|
+
allow(bootstrap.ui).to receive(:error)
|
201
|
+
expect(bootstrap).to receive(:run_command).exactly(1).times
|
202
|
+
bootstrap.config[:auth_timeout] = bootstrap.options[:auth_timeout][:default]
|
203
|
+
expect { bootstrap.bootstrap }.to raise_error RuntimeError
|
204
|
+
end
|
205
|
+
|
206
|
+
context "when validation_key is not present" do
|
207
|
+
context "using chef 11", :chef_lt_12_only do
|
208
|
+
before do
|
209
|
+
allow(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(false)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'raises an exception if validation_key is not present in chef 11' do
|
213
|
+
expect(bootstrap.ui).to receive(:error)
|
214
|
+
expect { bootstrap.bootstrap }.to raise_error(SystemExit)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context "using chef 12", :chef_gte_12_only do
|
219
|
+
before do
|
220
|
+
allow(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(false)
|
221
|
+
bootstrap.client_builder = instance_double("Chef::Knife::Bootstrap::ClientBuilder", :run => nil, :client_path => nil)
|
222
|
+
Chef::Config[:knife] = {:chef_node_name => 'foo.example.com'}
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'raises an exception if winrm_authentication_protocol is basic and transport is plaintext' do
|
226
|
+
Chef::Config[:knife] = {:winrm_authentication_protocol => 'basic', :winrm_transport => 'plaintext', :chef_node_name => 'foo.example.com'}
|
227
|
+
expect(bootstrap.ui).to receive(:error)
|
228
|
+
expect { bootstrap.run }.to raise_error(SystemExit)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'raises an exception if chef_node_name is not present ' do
|
232
|
+
Chef::Config[:knife] = {:chef_node_name => nil}
|
233
|
+
expect(bootstrap.client_builder).not_to receive(:run)
|
234
|
+
expect(bootstrap.client_builder).not_to receive(:client_path)
|
235
|
+
expect(bootstrap.ui).to receive(:error)
|
236
|
+
expect { bootstrap.bootstrap }.to raise_error(SystemExit)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|