chef-apply 0.4.6 → 0.4.9

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -7
  3. data/chef-apply.gemspec +3 -3
  4. data/lib/chef_apply/version.rb +1 -1
  5. metadata +3 -38
  6. data/README.md +0 -62
  7. data/spec/fixtures/custom_config.toml +0 -2
  8. data/spec/integration/chef-run_spec.rb +0 -41
  9. data/spec/integration/fixtures/chef_help.out +0 -70
  10. data/spec/integration/fixtures/chef_version.out +0 -1
  11. data/spec/integration/spec_helper.rb +0 -55
  12. data/spec/spec_helper.rb +0 -154
  13. data/spec/support/matchers/output_to_terminal.rb +0 -36
  14. data/spec/unit/action/base_spec.rb +0 -60
  15. data/spec/unit/action/converge_target/ccr_failure_mapper_spec.rb +0 -106
  16. data/spec/unit/action/converge_target_spec.rb +0 -400
  17. data/spec/unit/action/generate_local_policy_spec.rb +0 -114
  18. data/spec/unit/action/generate_temp_cookbook/recipe_lookup_spec.rb +0 -122
  19. data/spec/unit/action/generate_temp_cookbook/temp_cookbook_spec.rb +0 -198
  20. data/spec/unit/action/generate_temp_cookbook_spec.rb +0 -73
  21. data/spec/unit/action/install_chef/minimum_chef_version_spec.rb +0 -90
  22. data/spec/unit/action/install_chef_spec.rb +0 -164
  23. data/spec/unit/cli/options_spec.rb +0 -75
  24. data/spec/unit/cli/validation_spec.rb +0 -81
  25. data/spec/unit/cli_spec.rb +0 -475
  26. data/spec/unit/config_spec.rb +0 -70
  27. data/spec/unit/file_fetcher_spec.rb +0 -40
  28. data/spec/unit/fixtures/multi-error.out +0 -2
  29. data/spec/unit/log_spec.rb +0 -37
  30. data/spec/unit/startup_spec.rb +0 -323
  31. data/spec/unit/target_host/linux_spec.rb +0 -57
  32. data/spec/unit/target_host/windows_spec.rb +0 -43
  33. data/spec/unit/target_host_spec.rb +0 -297
  34. data/spec/unit/target_resolver_spec.rb +0 -380
  35. data/spec/unit/telemeter/sender_spec.rb +0 -140
  36. data/spec/unit/telemeter_spec.rb +0 -191
  37. data/spec/unit/text/error_translation_spec.rb +0 -109
  38. data/spec/unit/ui/error_printer_spec.rb +0 -196
  39. data/spec/unit/ui/terminal_spec.rb +0 -119
  40. data/spec/unit/version_spec.rb +0 -31
@@ -1,57 +0,0 @@
1
- require "spec_helper"
2
- require "chef_apply/target_host"
3
- require "chef_apply/target_host/linux"
4
-
5
- RSpec.describe ChefApply::TargetHost::Linux do
6
- let(:user) { "testuser" }
7
- let(:host) { "mock://#{user}@example.com" }
8
- let(:family) { "linux" }
9
- let(:name) { "linux" }
10
- let(:path) { "/tmp/blah" }
11
-
12
- subject do
13
- ChefApply::TargetHost.mock_instance(host, family: family, name: name)
14
- end
15
-
16
- context "#make_temp_dir" do
17
- it "creates the directory using a properly formed make_temp_dir" do
18
- expect(subject).to receive(:run_command!)
19
- .with("bash -c '#{ChefApply::TargetHost::Linux::MKTEMP_COMMAND}'")
20
- .and_return(instance_double("result", stdout: "/tmp/blah"))
21
- expect(subject.make_temp_dir).to eq "/tmp/blah"
22
- end
23
- end
24
-
25
- context "#mkdir" do
26
- it "uses a properly formed mkdir to create the directory and changes ownership to connected user" do
27
- expect(subject).to receive(:run_command!).with("mkdir -p /tmp/dir")
28
- subject.mkdir("/tmp/dir")
29
- end
30
- end
31
-
32
- context "#chown" do
33
- it "uses a properly formed chown to change owning user to the provided user" do
34
- expect(subject).to receive(:run_command!).with("chown newowner '/tmp/dir'")
35
- subject.chown("/tmp/dir", "newowner")
36
- end
37
- end
38
-
39
- context "#install_package" do
40
- context "when it receives an RPM package" do
41
- let(:expected_command) { "rpm -Uvh /my/package.rpm" }
42
- it "should run the correct rpm command" do
43
- expect(subject).to receive(:run_command!).with expected_command
44
- subject.install_package("/my/package.rpm")
45
-
46
- end
47
-
48
- end
49
- context "when it receives a DEB package" do
50
- let(:expected_command) { "dpkg -i /my/package.deb" }
51
- it "should run the correct dpkg command" do
52
- expect(subject).to receive(:run_command!).with expected_command
53
- subject.install_package("/my/package.deb")
54
- end
55
- end
56
- end
57
- end
@@ -1,43 +0,0 @@
1
-
2
- require "spec_helper"
3
- require "chef_apply/target_host"
4
- require "chef_apply/target_host/windows"
5
-
6
- RSpec.describe ChefApply::TargetHost::Windows do
7
- let(:host) { "mock://user@example.com" }
8
- let(:family) { "windows" }
9
- let(:name) { "windows" }
10
- let(:path) { "C:\\temp\\blah" }
11
-
12
- subject do
13
- ChefApply::TargetHost.mock_instance(host, family: family, name: name)
14
- end
15
-
16
- context "#make_temp_dir" do
17
- it "creates the temporary directory using the correct PowerShell command and returns the path" do
18
- expect(subject).to receive(:run_command!)
19
- .with(ChefApply::TargetHost::Windows::MKTEMP_COMMAND)
20
- .and_return(instance_double("result", stdout: path))
21
- expect(subject.make_temp_dir).to eq(path)
22
- end
23
- end
24
-
25
- context "#mkdir" do
26
- it "creates the directory using the correct command PowerShell command" do
27
- expect(subject).to receive(:run_command!).with("New-Item -ItemType Directory -Force -Path C:\\temp\\dir")
28
- subject.mkdir("C:\\temp\\dir")
29
- end
30
- end
31
-
32
- context "#chown" do
33
- xit "does nothing - this is not implemented on Windows until we need it"
34
- end
35
-
36
- context "#install_package" do
37
- it "runs the correct MSI package install command" do
38
- expected_command = "cmd /c msiexec /package C:\\My\\Package.msi /quiet"
39
- expect(subject).to receive(:run_command!).with(expected_command)
40
- subject.install_package("C:/My/Package.msi")
41
- end
42
- end
43
- end
@@ -1,297 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) 2018-2019 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "ostruct"
20
- require "chef_apply/target_host"
21
-
22
- RSpec.describe ChefApply::TargetHost do
23
- let(:host) { "mock://user@example.com" }
24
- let(:family) { "debian" }
25
- let(:name) { "ubuntu" }
26
-
27
- subject do
28
- ChefApply::TargetHost.mock_instance(host, family: family, name: name)
29
- end
30
-
31
- context "#base_os" do
32
- context "for a windows os" do
33
- let(:family) { "windows" }
34
- let(:name) { "windows" }
35
- it "reports :windows" do
36
- expect(subject.base_os).to eq :windows
37
- end
38
- end
39
-
40
- context "for a linux os" do
41
- let(:family) { "debian" }
42
- let(:name) { "ubuntu" }
43
- it "reports :linux" do
44
- expect(subject.base_os).to eq :linux
45
- end
46
- end
47
-
48
- context "for an unsupported OS" do
49
- let(:family) { "unknown" }
50
- let(:name) { "unknown" }
51
- it "reports :other" do
52
- expect(subject.base_os).to eq :other
53
- end
54
- end
55
- end
56
-
57
- context "#installed_chef_version" do
58
- context "when no version manifest is present" do
59
- it "raises ChefNotInstalled" do
60
- expect(subject).to receive(:read_chef_version_manifest).and_raise(ChefApply::TargetHost::ChefNotInstalled.new)
61
- expect { subject.installed_chef_version }.to raise_error(ChefApply::TargetHost::ChefNotInstalled)
62
- end
63
- end
64
-
65
- context "when version manifest is present" do
66
- let(:manifest) { { "build_version" => "14.0.1" } }
67
- it "reports version based on the build_version field" do
68
- expect(subject).to receive(:read_chef_version_manifest).and_return manifest
69
- expect(subject.installed_chef_version).to eq Gem::Version.new("14.0.1")
70
- end
71
- end
72
- end
73
-
74
- context "connect!" do
75
- # For all other tets, target_host is a mocked instance that is already connected
76
- # In this case, we want to build a new one that is not yet connected to test connect! itself.
77
- let(:target_host) { ChefApply::TargetHost.new(host, sudo: false) }
78
- let(:train_connection_mock) { double("train connection") }
79
- before do
80
- allow(target_host).to receive(:train_connection).and_return(train_connection_mock)
81
- end
82
- context "when an Train::UserError occurs" do
83
- it "raises a ConnectionFailure" do
84
- allow(train_connection_mock).to receive(:connection).and_raise Train::UserError
85
- expect { target_host.connect! }.to raise_error(ChefApply::TargetHost::ConnectionFailure)
86
- end
87
- end
88
- context "when a Train::Error occurs" do
89
- it "raises a ConnectionFailure" do
90
- allow(train_connection_mock).to receive(:connection).and_raise Train::Error
91
- expect { target_host.connect! }.to raise_error(ChefApply::TargetHost::ConnectionFailure)
92
- end
93
- end
94
- end
95
-
96
- context "#mix_in_target_platform!" do
97
- let(:base_os) { :none }
98
- before do
99
- allow(subject).to receive(:base_os).and_return base_os
100
- end
101
-
102
- context "when base_os is linux" do
103
- let(:base_os) { :linux }
104
- it "mixes in Linux support" do
105
- expect(subject.class).to receive(:include).with(ChefApply::TargetHost::Linux)
106
- subject.mix_in_target_platform!
107
- end
108
- end
109
-
110
- context "when base_os is windows" do
111
- let(:base_os) { :windows }
112
- it "mixes in Windows support" do
113
- expect(subject.class).to receive(:include).with(ChefApply::TargetHost::Windows)
114
- subject.mix_in_target_platform!
115
- end
116
- end
117
-
118
- context "when base_os is other" do
119
- let(:base_os) { :other }
120
- it "raises UnsupportedTargetOS" do
121
- expect { subject.mix_in_target_platform! }.to raise_error(ChefApply::TargetHost::UnsupportedTargetOS)
122
- end
123
-
124
- end
125
- context "after it connects" do
126
- context "to a Windows host" do
127
- it "includes the Windows TargetHost mixin" do
128
- end
129
-
130
- end
131
-
132
- context "and the platform is linux" do
133
- it "includes the Windows TargetHost mixin" do
134
- end
135
- end
136
-
137
- end
138
-
139
- end
140
-
141
- context "#user" do
142
- before do
143
- allow(subject).to receive(:config).and_return(user: user)
144
- end
145
- context "when a user has been configured" do
146
- let(:user) { "testuser" }
147
- it "returns that user" do
148
- expect(subject.user).to eq user
149
- end
150
- end
151
- context "when no user has been configured" do
152
- let(:user) { nil }
153
- it "returns the correct default from train" do
154
- expect(subject.user).to eq Train::Transports::SSH.default_options[:user][:default]
155
- end
156
- end
157
- end
158
-
159
- context "#run_command!" do
160
- let(:backend) { double("backend") }
161
- let(:exit_status) { 0 }
162
- let(:result) { RemoteExecResult.new(exit_status, "", "an error occurred") }
163
- let(:command) { "cmd" }
164
-
165
- before do
166
- allow(subject).to receive(:backend).and_return(backend)
167
- allow(backend).to receive(:run_command).with(command).and_return(result)
168
- end
169
-
170
- context "when no error occurs" do
171
- let(:exit_status) { 0 }
172
- it "returns the result" do
173
- expect(subject.run_command!(command)).to eq result
174
- end
175
- end
176
-
177
- context "when an error occurs" do
178
- let(:exit_status) { 1 }
179
- it "raises a RemoteExecutionFailed error" do
180
- expected_error = ChefApply::TargetHost::RemoteExecutionFailed
181
- expect { subject.run_command!(command) }.to raise_error(expected_error)
182
- end
183
- end
184
- end
185
-
186
- context "#read_chef_version_manifest" do
187
- let(:manifest_content) { '{"build_version" : "1.2.3"}' }
188
- before do
189
- allow(subject).to receive(:fetch_file_contents).and_return(manifest_content)
190
- allow(subject).to receive(:omnibus_manifest_path).and_return("/path/to/manifest.json")
191
- end
192
-
193
- context "when manifest is missing" do
194
- let(:manifest_content) { nil }
195
- it "raises ChefNotInstalled" do
196
- expect { subject.read_chef_version_manifest }.to raise_error(ChefApply::TargetHost::ChefNotInstalled)
197
- end
198
- end
199
-
200
- context "when manifest is present" do
201
- let(:manifest_content) { '{"build_version" : "1.2.3"}' }
202
- it "should return the parsed manifest" do
203
- expect(subject.read_chef_version_manifest).to eq({ "build_version" => "1.2.3" })
204
- end
205
- end
206
- end
207
-
208
- # What we test:
209
- # - file contents can be retrieved, and invalid conditions results in no content
210
- # What we mock:
211
- # - the train `backend`
212
- # - the backend `file` method
213
- # Why?
214
- # - in this unit test, we're not testing round-trip behavior of the train API, only
215
- # that we are invoking the API and interpreting its results correctly.
216
- context "#fetch_file_contents" do
217
- let(:path) { "/path/to/file" }
218
- let(:sample_content) { "content" }
219
- let(:backend_mock) { double("backend") }
220
- let(:path_exists) { true }
221
- let(:path_is_file) { true }
222
- let(:remote_file_mock) do
223
- double("remote_file", exist?: path_exists,
224
- file?: path_is_file, content: sample_content)
225
- end
226
- before do
227
- expect(subject).to receive(:backend).and_return backend_mock
228
- expect(backend_mock).to receive(:file).with(path).and_return remote_file_mock
229
- end
230
-
231
- context "when path exists" do
232
- let(:path_exists) { true }
233
- before do
234
- end
235
-
236
- context "but is not a file" do
237
- let(:path_is_file) { false }
238
- it "returns nil" do
239
- expect(subject.fetch_file_contents(path)).to be_nil
240
- end
241
- end
242
- context "and is a file" do
243
- it "returns the expected file contents" do
244
- expect(subject.fetch_file_contents(path)).to eq sample_content
245
- end
246
- end
247
- end
248
- context "when path does not exist" do
249
- let(:path_exists) { false }
250
- it "returns nil" do
251
- expect(subject.fetch_file_contents(path)).to be_nil
252
- end
253
- end
254
- end
255
-
256
- context "#apply_ssh_config" do
257
- let(:ssh_host_config) { { user: "testuser", port: 1000, proxy: double("Net:SSH::Proxy::Command") } }
258
- let(:connection_config) { { user: "user1", port: 8022, proxy: nil } }
259
- before do
260
- allow(subject).to receive(:ssh_config_for_host).and_return ssh_host_config
261
- end
262
-
263
- ChefApply::TargetHost::SSH_CONFIG_OVERRIDE_KEYS.each do |key|
264
- context "when a value is not explicitly provided in options" do
265
- it "replaces config config[:#{key}] with the ssh config value" do
266
- subject.apply_ssh_config(connection_config, key => nil)
267
- expect(connection_config[key]).to eq(ssh_host_config[key])
268
- end
269
- end
270
-
271
- context "when a value is explicitly provided in options" do
272
- it "the connection configuration isnot updated with a value from ssh config" do
273
- original_config = connection_config.clone
274
- subject.apply_ssh_config(connection_config, { key => "testvalue" } )
275
- expect(connection_config[key]).to eq original_config[key]
276
- end
277
- end
278
- end
279
- end
280
-
281
- context "#temp_dir" do
282
- it "creates the temp directory and changes ownership" do
283
- expect(subject).to receive(:make_temp_dir).and_return("/tmp/dir")
284
- expect(subject).to receive(:chown).with("/tmp/dir", subject.user)
285
- subject.temp_dir
286
- end
287
- end
288
-
289
- context "#make_directory" do
290
- it "creates the directory and sets ownership to connecting user" do
291
- expect(subject).to receive(:mkdir).with("/tmp/mkdir")
292
- expect(subject).to receive(:chown).with("/tmp/mkdir", subject.user)
293
- subject.make_directory("/tmp/mkdir")
294
- end
295
- end
296
-
297
- end
@@ -1,380 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) 2018 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "chef_apply/target_resolver"
20
-
21
- RSpec.describe ChefApply::TargetResolver do
22
- let(:target_string) { "" }
23
- let(:default_protocol) { "ssh" }
24
- let(:connection_options) { {} }
25
- subject { ChefApply::TargetResolver.new(target_string, default_protocol, connection_options) }
26
-
27
- context "#targets" do
28
- context "when no target is provided" do
29
- let(:target_string) { "" }
30
- it "returns an empty array" do
31
- expect(subject.targets).to eq []
32
- end
33
- end
34
-
35
- context "when a single target is provided" do
36
- let(:target_string) { "ssh://localhost" }
37
- it "returns any array with one target" do
38
- actual_targets = subject.targets
39
- expect(actual_targets[0].config[:host]).to eq "localhost"
40
- end
41
- end
42
-
43
- context "when a comma-separated list of targets is provided" do
44
- let(:target_string) { "ssh://node1.example.com,winrm://node2.example.com" }
45
- it "returns an array with correct TargetHost instances" do
46
- actual_targets = subject.targets
47
- expect(actual_targets[0].config[:host]).to eq "node1.example.com"
48
- expect(actual_targets[1].config[:host]).to eq "node2.example.com"
49
- end
50
- end
51
- context "when a comma-separated list of targets that include ranges is provided" do
52
- let(:target_string) { "ssh://node[0:1],ssh://machine[0:1]" }
53
- it "returns an array with correct TargetHost instances" do
54
- actual_targets = subject.targets
55
-
56
- expect(actual_targets[0].config[:host]).to eq "node0"
57
- expect(actual_targets[1].config[:host]).to eq "node1"
58
- expect(actual_targets[2].config[:host]).to eq "machine0"
59
- expect(actual_targets[3].config[:host]).to eq "machine1"
60
- end
61
- end
62
-
63
- context "when a mixed list of targets containing user prefix and not are included" do
64
-
65
- let(:target_string) { "test_user1@node1,node2,test_user2:password@node3" }
66
-
67
- context "and the :user option is provided" do
68
-
69
- let(:connection_options) { { user: "defaultuser" } }
70
- it "should default to the given :user only for the host that does not include name" do
71
- actual_targets = subject.targets
72
- tc = actual_targets[0].config
73
- expect(tc[:host]).to eq "node1"
74
- expect(tc[:user]).to eq "test_user1"
75
-
76
- tc = actual_targets[1].config
77
- expect(tc[:host]).to eq "node2"
78
- expect(tc[:user]).to eq "defaultuser"
79
-
80
- tc = actual_targets[2].config
81
- expect(tc[:host]).to eq "node3"
82
- expect(tc[:user]).to eq "test_user2"
83
- end
84
- end
85
- context "and the :user option is not provided" do
86
- let(:opts) { {} }
87
- it "should default to no user when user is not included with host" do
88
- actual_targets = subject.targets
89
- tc = actual_targets[0].config
90
- expect(tc[:host]).to eq "node1"
91
- expect(tc[:user]).to eq "test_user1"
92
-
93
- tc = actual_targets[1].config
94
- expect(tc[:host]).to eq "node2"
95
- expect(tc[:user]).to eq nil
96
-
97
- tc = actual_targets[2].config
98
- expect(tc[:host]).to eq "node3"
99
- expect(tc[:user]).to eq "test_user2"
100
- end
101
- end
102
-
103
- end
104
- end
105
-
106
- context "#expand_targets" do
107
- it "returns a single item when no expansion is required" do
108
- expect(subject.expand_targets("one")).to eq ["one"]
109
- end
110
-
111
- it "expands single alphabetic range" do
112
- expect(subject.expand_targets("host[a:h]")).to eq %w{
113
- hosta hostb hostc hostd hoste hostf hostg hosth
114
- }
115
- end
116
- it "expands single alphabetic range even if reverse ordering is given" do
117
- expect(subject.expand_targets("host[h:a]")).to eq %w{
118
- hosta hostb hostc hostd hoste hostf hostg hosth
119
- }
120
- end
121
-
122
- it "expands a range when the target name is qualified with credentials" do
123
- expect(subject.expand_targets("ssh://user:password@host[a:b]")).to eq %w{
124
- ssh://user:password@hosta
125
- ssh://user:password@hostb
126
- }
127
- end
128
-
129
- it "expands a numeric range correctly when start/stop string values ASCII-sort in reverse" do
130
- # eg: ["4", "10"].sort => ["10", "4"]
131
- expect(subject.expand_targets("[4:10]")).to eq %w{ 4 5 6 7 8 9 10 }
132
- end
133
-
134
- it "expands a numeric range correctly when stop is higher than start" do
135
- expect(subject.expand_targets("[10:8]")).to eq %w{ 8 9 10 }
136
- end
137
-
138
- it "expands a string range correctly when stop is higher than start" do
139
- expect(subject.expand_targets("[z:y]")).to eq %w{ y z }
140
- end
141
-
142
- it "expands single numeric range" do
143
- expect(subject.expand_targets("host[10:20]")).to eq %w{
144
- host10 host11 host12 host13 host14 host15 host16
145
- host17 host18 host19 host20
146
- }
147
- end
148
-
149
- it "expands two included ranges" do
150
- expect(subject.expand_targets("host[1:4].domain[a:c]").sort).to eq [
151
- "host1.domaina", "host1.domainb", "host1.domainc",
152
- "host2.domaina", "host2.domainb", "host2.domainc",
153
- "host3.domaina", "host3.domainb", "host3.domainc",
154
- "host4.domaina", "host4.domainb", "host4.domainc"
155
- ].sort
156
- end
157
-
158
- it "raises InvalidRange if a range mixes alpha and numeric" do
159
- expect { subject.expand_targets("host[a:9]") }.to raise_error(ChefApply::TargetResolver::InvalidRange)
160
- end
161
-
162
- it "raises TooManyRanges if more than two ranges are included" do
163
- expect { subject.expand_targets("[0:1][5:10][10:11]") }.to raise_error(ChefApply::TargetResolver::TooManyRanges)
164
- end
165
-
166
- context "when the target resolves to more than #{ChefApply::TargetResolver::MAX_EXPANDED_TARGETS} names" do
167
- it "raises TooManyTargets" do
168
- expect { subject.expand_targets("[0:99999]") }.to raise_error(ChefApply::TargetResolver::TooManyTargets)
169
- end
170
- end
171
- end
172
-
173
- context "#make_credentials" do
174
- let(:default_user) { nil }
175
- let(:default_password) { nil }
176
-
177
- let(:inline_user) { nil }
178
- let(:inline_password) { nil }
179
-
180
- subject do
181
- opts = {}
182
- opts[:user] = default_user unless default_user.nil?
183
- opts[:password] = default_password unless default_password.nil?
184
- resolver = ChefApply::TargetResolver.new("", default_protocol, opts)
185
- Proc.new { resolver.make_credentials(inline_user, inline_password) }
186
- end
187
-
188
- context "when no default user or password is given" do
189
- let(:default_user) { nil }
190
- let(:default_password) { nil }
191
-
192
- context "and only an inline user is provided" do
193
- let(:inline_user) { "aninlineuser" }
194
- let(:inline_password) { nil }
195
- it "returns the decorated inline user with nil password" do
196
- expect(subject.call).to eq [inline_user, nil]
197
- end
198
- end
199
-
200
- context "and only an inline password is provided" do
201
- let(:inline_user) { nil }
202
- let(:inline_password) { "inlinepassword4u" }
203
- it "returns the decorated inline password" do
204
- expect(subject.call).to eq [nil, inline_password]
205
- end
206
- end
207
-
208
- context "and neither inline user nor inline password is given" do
209
- let(:inline_user) { nil }
210
- let(:inline_password) { nil }
211
- it "returns an empty string" do
212
- expect(subject.call).to eq [nil, nil]
213
- end
214
- end
215
-
216
- context "and both inline user and inline password are given" do
217
- let(:inline_user) { "adefaultuser" }
218
- let(:inline_password) { "inlinepassword4u" }
219
- it "returns the decorated inline_user and inline password" do
220
- expect(subject.call).to eq [inline_user, inline_password]
221
- end
222
- end
223
- end
224
-
225
- context "when only a default user is given" do
226
- let(:default_user) { "defaultusername" }
227
- let(:default_password) { nil }
228
-
229
- context "and only an inline user is provided" do
230
- let(:inline_user) { "aninlineuser" }
231
- let(:inline_password) { nil }
232
- it "returns the inline user with no password" do
233
- expect(subject.call).to eq [inline_user, nil]
234
- end
235
- end
236
-
237
- context "and only an inline password is provided" do
238
- let(:inline_user) { nil }
239
- let(:inline_password) { "inlinepassword4u" }
240
- it "returns the default user and inline password" do
241
- expect(subject.call).to eq [default_user, inline_password]
242
- end
243
- end
244
-
245
- context "and neither inline user nor inline password is given" do
246
- let(:inline_user) { nil }
247
- let(:inline_password) { nil }
248
- it "returns the default user" do
249
- expect(subject.call).to eq [default_user, nil]
250
- end
251
- end
252
-
253
- context "and both inline user and inline password are given" do
254
- let(:inline_user) { "adefaultuser" }
255
- let(:inline_password) { "inlinepassword4u" }
256
- it "returns the decorated inline_user and inline password" do
257
- expect(subject.call).to eq [inline_user, inline_password]
258
- end
259
- end
260
- end
261
-
262
- context "when only a default password is given" do
263
- let(:default_user) { nil }
264
- let(:default_password) { "ihasdefaultpassword" }
265
-
266
- context "and only an inline user is provided" do
267
- let(:inline_user) { "aninlineuser" }
268
- let(:inline_password) { nil }
269
- it "returns the decorated inline user and default password" do
270
- expect(subject.call).to eq [inline_user, default_password]
271
- end
272
- end
273
-
274
- context "and only an inline password is provided" do
275
- let(:inline_user) { nil }
276
- let(:inline_password) { "inlinepassword4u" }
277
- it "returns nil user and inline password" do
278
- expect(subject.call).to eq [nil, inline_password]
279
- end
280
- end
281
-
282
- context "and neither inline user nor inline password is given" do
283
- let(:inline_user) { nil }
284
- let(:inline_password) { nil }
285
- it "returns the nil user and default password" do
286
- expect(subject.call).to eq [nil, default_password]
287
- end
288
- end
289
-
290
- context "and both inline user and inline password are given" do
291
- let(:inline_user) { "adefaultuser" }
292
- let(:inline_password) { "inlinepassword4u" }
293
- it "returns the inline_user and inline password" do
294
- expect(subject.call).to eq [inline_user, inline_password]
295
- end
296
- end
297
- end
298
-
299
- context "when defaults for both user and password are given" do
300
- let(:default_user) { "adefaultuser" }
301
- let(:default_password) { "ihasdefaultpassword" }
302
-
303
- context "and only an inline user is provided" do
304
- let(:inline_user) { "aninlineuser" }
305
- let(:inline_password) { nil }
306
- it "returns the decorated inline user and default password" do
307
- expect(subject.call).to eq [inline_user, default_password]
308
- end
309
- end
310
-
311
- context "and only an inline password is provided" do
312
- let(:inline_user) { nil }
313
- let(:inline_password) { "inlinepassword4u" }
314
- it "returns the decorated default user and inline password" do
315
- expect(subject.call).to eq [default_user, inline_password]
316
- end
317
- end
318
-
319
- context "and neither inline user nor inline password is given" do
320
- let(:inline_user) { nil }
321
- let(:inline_password) { nil }
322
- it "returns the decorated default user and default password" do
323
- expect(subject.call).to eq [default_user, default_password]
324
- end
325
- end
326
-
327
- context "and both inline user and inline password are given" do
328
- let(:inline_user) { "adefaultuser" }
329
- let(:inline_password) { "inlinepassword4u" }
330
- it "returns the decorated inline_user and inline password" do
331
- expect(subject.call).to eq [inline_user, inline_password]
332
- end
333
- end
334
- end
335
- end
336
-
337
- context "#config_for_target" do
338
- { "example.com" => { password: nil, url: "ssh://example.com", user: nil },
339
- "ssh://example.com" => { password: nil, url: "ssh://example.com", user: nil },
340
- "ssh://user@example.com" => { password: nil, url: "ssh://example.com", user: "user" },
341
- "ssh://user:password@example.com" => { password: "password", user: "user", url: "ssh://example.com" },
342
- "ssh://user:pas:sw:ord@example.com" => { password: "pas:sw:ord", user: "user", url: "ssh://example.com" },
343
- "ssh://user:!@#$%^&*()|\'\";:/?><.,{}[]+=`~@example.com" => { password: "!@#$%^&*()|\'\";:/?><.,{}[]+=`~", user: "user", url: "ssh://example.com" },
344
- }.each do |values|
345
- it "resolves #{values[0]} to #{values[1]}" do
346
- expect(subject.config_for_target(values[0])).to eq values[1]
347
- end
348
- end
349
-
350
- it "preserves range specifiers in the host portion while encoding in the password portion" do
351
- input = "user:pas[1:2]!^@ho[a:b]s[t:z].com"
352
- output = { password: "pas[1:2]!^", url: "ssh://ho[a:b]s[t:z].com", user: "user" }
353
- expect(subject.config_for_target(input)).to eq output
354
- end
355
- end
356
-
357
- context "#prefix_from_target" do
358
- context "when no protocol is provided" do
359
- let(:default_protocol) { "badproto" }
360
- it "uses the default from configuration" do
361
- expect(subject.prefix_from_target("host.com")).to eq %w{badproto:// host.com}
362
- end
363
- end
364
-
365
- context "when protocol is provided" do
366
- context "and it is valid" do
367
- it "keeps the protocol" do
368
- expect(subject.prefix_from_target("ssh://host.com")).to eq %w{ssh:// host.com}
369
- end
370
- end
371
- context "and it is not valid" do
372
- it "raises an error" do
373
- expect { subject.prefix_from_target("bad://host.com") }
374
- .to raise_error(ChefApply::TargetResolver::UnsupportedProtocol)
375
- end
376
- end
377
- end
378
- end
379
-
380
- end