knife-windows 1.0.0.rc.0 → 1.0.0.rc.1
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/CHANGELOG.md +1 -0
- data/README.md +2 -2
- data/lib/chef/knife/bootstrap_windows_base.rb +27 -5
- data/lib/chef/knife/bootstrap_windows_ssh.rb +21 -4
- data/lib/chef/knife/bootstrap_windows_winrm.rb +5 -1
- data/lib/chef/knife/windows_cert_install.rb +23 -17
- data/lib/chef/knife/windows_listener_create.rb +33 -26
- data/lib/chef/knife/winrm_knife_base.rb +2 -2
- data/lib/knife-windows/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/knife/bootstrap_options_spec.rb +146 -0
- data/spec/unit/knife/bootstrap_template_spec.rb +4 -4
- data/spec/unit/knife/bootstrap_windows_winrm_spec.rb +11 -0
- data/spec/unit/knife/windows_cert_install_spec.rb +25 -9
- data/spec/unit/knife/windows_listener_create_spec.rb +51 -36
- data/spec/unit/knife/winrm_spec.rb +48 -57
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c29e2359b9d358c5351eed09ce0cd3012f6252c
|
4
|
+
data.tar.gz: 86e873abc6246ca156e557dfa087e170d4ce53b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01daeb2230c7290c573a2401906a02929b54f82e3447289fe2bcd1bf0649133ebe41ff9830e7a5cc49f5c5b4b8b5b7deae3eb05a727419f97488b45298fa1398
|
7
|
+
data.tar.gz: 586c6301b29e79aec969a5b6aab3bf6cc45c90cdb0e38be7449a56148d7b98db1ee0f9cce1c1a0de1e49a4d82eed891dfff805f6a5b70afc688fabac9374b96a
|
data/CHANGELOG.md
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
* [knife-windows #125](https://github.com/opscode/knife-windows/issues/125) knife-windows should use PowerShell first before cscript to download the Chef Client msi
|
23
23
|
* [knife-windows #92](https://github.com/opscode/knife-windows/issues/92) EventMachine issue: knife bootstrap windows winrm error
|
24
24
|
* [knife-windows #94](https://github.com/opscode/knife-windows/issues/94) Remove Eventmachine dependency
|
25
|
+
* [knife-windows #252](https://github.com/chef/knife-windows/pull/252) Fail early on ECONNREFUSED, Closes #244.
|
25
26
|
|
26
27
|
## Release: 0.8.5
|
27
28
|
* [knife-windows #228](https://github.com/chef/knife-windows/pull/228) make winrm-s dep more strict on knife-windows 0.8.x
|
data/README.md
CHANGED
@@ -103,7 +103,7 @@ The *.b64 is Base64 PKCS12 key pair. Contains both the public and private keys,
|
|
103
103
|
The *.pem is Base64 encoded public certificate only. Required by the client to connect to the server.
|
104
104
|
This command also displays the thumbprint of the generated certificate.
|
105
105
|
|
106
|
-
knife windows cert generate --cert-passphrase "strong_passphrase" --
|
106
|
+
knife windows cert generate --cert-passphrase "strong_passphrase" --hostname "cloudapp.net" --output-file "~/server_cert.pfx"
|
107
107
|
# This command will generate certificates at user's home directory with names server_cert.b64, server_cert.pfx and server_cert.pem.
|
108
108
|
|
109
109
|
### knife windows cert install
|
@@ -140,7 +140,7 @@ This bootstrap template does the following:
|
|
140
140
|
* Writes a default config file for Chef (`C:\chef\client.rb`) using values from the `knife.rb`.
|
141
141
|
* Creates a JSON attributes file containing the specified run list and run Chef.
|
142
142
|
|
143
|
-
This is the default bootstrap template used by both of the `windows bootstrap` subcommands.
|
143
|
+
This is the default bootstrap template used by both of the `knife windows bootstrap winrm` and `knife windows bootstrap ssh` subcommands.
|
144
144
|
|
145
145
|
## REQUIREMENTS/SETUP:
|
146
146
|
|
@@ -58,28 +58,29 @@ class Chef
|
|
58
58
|
:proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
|
59
59
|
|
60
60
|
option :bootstrap_no_proxy,
|
61
|
-
:long => "--bootstrap-no-proxy ",
|
62
|
-
:description => "
|
61
|
+
:long => "--bootstrap-no-proxy [NO_PROXY_URL|NO_PROXY_IP]",
|
62
|
+
:description => "Do not proxy locations for the node being bootstrapped; this option is used internally by Opscode",
|
63
63
|
:proc => Proc.new { |np| Chef::Config[:knife][:bootstrap_no_proxy] = np }
|
64
64
|
|
65
65
|
# DEPR: Remove this option in Chef 13
|
66
66
|
option :distro,
|
67
67
|
:short => "-d DISTRO",
|
68
68
|
:long => "--distro DISTRO",
|
69
|
-
:description => "Bootstrap a distro using a template. [DEPRECATED] Use --bootstrap-template option instead.",
|
69
|
+
:description => "Bootstrap a distro using a template. [DEPRECATED] Use -t / --bootstrap-template option instead.",
|
70
70
|
:proc => Proc.new { |v|
|
71
71
|
Chef::Log.warn("[DEPRECATED] -d / --distro option is deprecated. Use --bootstrap-template option instead.")
|
72
72
|
v
|
73
73
|
}
|
74
74
|
|
75
75
|
option :bootstrap_template,
|
76
|
+
:short => "-t TEMPLATE",
|
76
77
|
:long => "--bootstrap-template TEMPLATE",
|
77
78
|
:description => "Bootstrap Chef using a built-in or custom template. Set to the full path of an erb template or use one of the built-in templates."
|
78
79
|
|
79
80
|
# DEPR: Remove this option in Chef 13
|
80
81
|
option :template_file,
|
81
82
|
:long => "--template-file TEMPLATE",
|
82
|
-
:description => "Full path to location of template to use. [DEPRECATED] Use --bootstrap-template option instead.",
|
83
|
+
:description => "Full path to location of template to use. [DEPRECATED] Use -t / --bootstrap-template option instead.",
|
83
84
|
:proc => Proc.new { |v|
|
84
85
|
Chef::Log.warn("[DEPRECATED] --template-file option is deprecated. Use --bootstrap-template option instead.")
|
85
86
|
v
|
@@ -142,7 +143,7 @@ class Chef
|
|
142
143
|
|
143
144
|
option :msi_url,
|
144
145
|
:short => "-u URL",
|
145
|
-
:long => "--
|
146
|
+
:long => "--msi-url URL",
|
146
147
|
:description => "Location of the Chef Client MSI. The default templates will prefer to download from this location. The MSI will be downloaded from chef.io if not provided.",
|
147
148
|
:default => ''
|
148
149
|
|
@@ -150,6 +151,25 @@ class Chef
|
|
150
151
|
:long => "--install-as-service",
|
151
152
|
:description => "Install chef-client as service in windows machine",
|
152
153
|
:default => false
|
154
|
+
|
155
|
+
option :bootstrap_vault_file,
|
156
|
+
:long => '--bootstrap-vault-file VAULT_FILE',
|
157
|
+
:description => 'A JSON file with a list of vault(s) and item(s) to be updated'
|
158
|
+
|
159
|
+
option :bootstrap_vault_json,
|
160
|
+
:long => '--bootstrap-vault-json VAULT_JSON',
|
161
|
+
:description => 'A JSON string with the vault(s) and item(s) to be updated'
|
162
|
+
|
163
|
+
option :bootstrap_vault_item,
|
164
|
+
:long => '--bootstrap-vault-item VAULT_ITEM',
|
165
|
+
:description => 'A single vault and item to update as "vault:item"',
|
166
|
+
:proc => Proc.new { |i|
|
167
|
+
(vault, item) = i.split(/:/)
|
168
|
+
Chef::Config[:knife][:bootstrap_vault_item] ||= {}
|
169
|
+
Chef::Config[:knife][:bootstrap_vault_item][vault] ||= []
|
170
|
+
Chef::Config[:knife][:bootstrap_vault_item][vault].push(item)
|
171
|
+
Chef::Config[:knife][:bootstrap_vault_item]
|
172
|
+
}
|
153
173
|
end
|
154
174
|
end
|
155
175
|
|
@@ -236,6 +256,8 @@ class Chef
|
|
236
256
|
exit 1
|
237
257
|
end
|
238
258
|
|
259
|
+
chef_vault_handler.run(node_name: config[:chef_node_name]) if chef_vault_handler.doing_chef_vault?
|
260
|
+
|
239
261
|
client_builder.run
|
240
262
|
bootstrap_context.client_pem = client_builder.client_path
|
241
263
|
else
|
@@ -51,8 +51,7 @@ class Chef
|
|
51
51
|
:short => "-p PORT",
|
52
52
|
:long => "--ssh-port PORT",
|
53
53
|
:description => "The ssh port",
|
54
|
-
:
|
55
|
-
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
|
54
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key.strip }
|
56
55
|
|
57
56
|
option :ssh_gateway,
|
58
57
|
:short => "-G GATEWAY",
|
@@ -60,14 +59,31 @@ class Chef
|
|
60
59
|
:description => "The ssh gateway",
|
61
60
|
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
|
62
61
|
|
62
|
+
option :forward_agent,
|
63
|
+
:short => "-A",
|
64
|
+
:long => "--forward-agent",
|
65
|
+
:description => "Enable SSH agent forwarding",
|
66
|
+
:boolean => true
|
67
|
+
|
63
68
|
option :identity_file,
|
64
69
|
:short => "-i IDENTITY_FILE",
|
65
70
|
:long => "--identity-file IDENTITY_FILE",
|
66
71
|
:description => "The SSH identity file used for authentication"
|
67
72
|
|
73
|
+
# DEPR: Remove this option for the next release.
|
68
74
|
option :host_key_verification,
|
69
|
-
:long => "--[no-]host-key-
|
70
|
-
:description => "
|
75
|
+
:long => "--[no-]host-key-verify",
|
76
|
+
:description => "Verify host key, enabled by default. [DEPRECATED] Use --host-key-verify option instead.",
|
77
|
+
:boolean => true,
|
78
|
+
:default => true,
|
79
|
+
:proc => Proc.new { |key|
|
80
|
+
Chef::Log.warn("[DEPRECATED] --host-key-verification option is deprecated. Use --host-key-verify option instead.")
|
81
|
+
config[:host_key_verify] = key
|
82
|
+
}
|
83
|
+
|
84
|
+
option :host_key_verify,
|
85
|
+
:long => "--[no-]host-key-verify",
|
86
|
+
:description => "Verify host key, enabled by default.",
|
71
87
|
:boolean => true,
|
72
88
|
:default => true
|
73
89
|
|
@@ -83,6 +99,7 @@ class Chef
|
|
83
99
|
ssh.config[:ssh_port] = locate_config_value(:ssh_port)
|
84
100
|
ssh.config[:ssh_gateway] = locate_config_value(:ssh_gateway)
|
85
101
|
ssh.config[:identity_file] = config[:identity_file]
|
102
|
+
ssh.config[:forward_agent] = config[:forward_agent]
|
86
103
|
ssh.config[:manual] = true
|
87
104
|
ssh.config[:host_key_verify] = config[:host_key_verify]
|
88
105
|
ssh.run
|
@@ -89,10 +89,14 @@ class Chef
|
|
89
89
|
raise RuntimeError, 'Command execution failed.' if status != 0
|
90
90
|
ui.info(ui.color("Remote node responded after #{elapsed_time_in_minutes(wait_start_time)} minutes.", :magenta))
|
91
91
|
return
|
92
|
-
rescue
|
92
|
+
rescue Errno::ECONNREFUSED => e
|
93
|
+
ui.error("Connection refused connecting to #{locate_config_value(:server_name)}:#{locate_config_value(:winrm_port)}.")
|
94
|
+
raise
|
95
|
+
rescue Exception => e
|
93
96
|
retries_left -= 1
|
94
97
|
if retries_left <= 0 || (elapsed_time_in_minutes(wait_start_time) > wait_max_minutes)
|
95
98
|
ui.error("No response received from remote node after #{elapsed_time_in_minutes(wait_start_time)} minutes, giving up.")
|
99
|
+
ui.error("Exception: #{e.message}")
|
96
100
|
raise
|
97
101
|
end
|
98
102
|
print '.'
|
@@ -37,24 +37,30 @@ class Chef
|
|
37
37
|
|
38
38
|
def run
|
39
39
|
STDOUT.sync = STDERR.sync = true
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
config[:cert_passphrase] = get_cert_passphrase unless config[:cert_passphrase]
|
46
|
-
|
47
|
-
begin
|
48
|
-
ui.info "Adding certificate to the Windows Certificate Store..."
|
49
|
-
result = %x{powershell.exe -Command " '#{config[:cert_passphrase]}' | certutil -importPFX '#{file_path}' AT_KEYEXCHANGE"}
|
50
|
-
if $?.exitstatus == 0
|
51
|
-
ui.info "Certificate added to Certificate Store"
|
52
|
-
else
|
53
|
-
ui.info "Error adding the certificate. Use -VV option for details"
|
40
|
+
|
41
|
+
if Chef::Platform.windows?
|
42
|
+
if @name_args.empty?
|
43
|
+
ui.error "Please specify the certificate path. e.g- 'knife windows cert install <path>"
|
44
|
+
exit 1
|
54
45
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
46
|
+
file_path = @name_args.first
|
47
|
+
config[:cert_passphrase] = get_cert_passphrase unless config[:cert_passphrase]
|
48
|
+
|
49
|
+
begin
|
50
|
+
ui.info "Adding certificate to the Windows Certificate Store..."
|
51
|
+
result = %x{powershell.exe -Command " '#{config[:cert_passphrase]}' | certutil -importPFX '#{file_path}' AT_KEYEXCHANGE"}
|
52
|
+
if $?.exitstatus == 0
|
53
|
+
ui.info "Certificate added to Certificate Store"
|
54
|
+
else
|
55
|
+
ui.info "Error adding the certificate. Use -VV option for details"
|
56
|
+
end
|
57
|
+
Chef::Log.debug "#{result}"
|
58
|
+
rescue => e
|
59
|
+
puts "ERROR: + #{e}"
|
60
|
+
end
|
61
|
+
else
|
62
|
+
ui.error "Certificate can be installed on Windows system only"
|
63
|
+
exit 1
|
58
64
|
end
|
59
65
|
end
|
60
66
|
end
|
@@ -61,40 +61,47 @@ class Chef
|
|
61
61
|
def run
|
62
62
|
STDOUT.sync = STDERR.sync = true
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
if Chef::Platform.windows?
|
65
|
+
begin
|
66
|
+
if config[:cert_install]
|
67
|
+
config[:cert_passphrase] = get_cert_passphrase unless config[:cert_passphrase]
|
68
|
+
result = %x{powershell.exe -Command " '#{config[:cert_passphrase]}' | certutil -importPFX '#{config[:cert_install]}' AT_KEYEXCHANGE"}
|
69
|
+
if $?.exitstatus
|
70
|
+
ui.info "Certificate installed to Certificate Store"
|
71
|
+
result = %x{powershell.exe -Command " echo (Get-PfxCertificate #{config[:cert_install]}).thumbprint "}
|
72
|
+
ui.info "Certificate Thumbprint: #{result}"
|
73
|
+
config[:cert_thumbprint] = result.strip
|
74
|
+
else
|
75
|
+
ui.error "Error installing certificate to Certificate Store"
|
76
|
+
ui.error result
|
77
|
+
exit 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
unless config[:cert_thumbprint]
|
82
|
+
ui.error "Please specify the --cert-thumbprint"
|
76
83
|
exit 1
|
77
84
|
end
|
78
|
-
end
|
79
85
|
|
80
|
-
|
81
|
-
|
82
|
-
exit 1
|
83
|
-
end
|
86
|
+
result = %x{winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="#{config[:hostname]}";CertificateThumbprint="#{config[:cert_thumbprint]}";Port="#{config[:port]}"}}
|
87
|
+
Chef::Log.debug result
|
84
88
|
|
85
|
-
|
86
|
-
|
89
|
+
if ($?.exitstatus == 0)
|
90
|
+
ui.info "WinRM listener created with Port: #{config[:port]} and CertificateThumbprint: #{config[:cert_thumbprint]}"
|
91
|
+
else
|
92
|
+
ui.error "Error creating WinRM listener. use -VV for more details."
|
93
|
+
exit 1
|
94
|
+
end
|
87
95
|
|
88
|
-
|
89
|
-
|
90
|
-
else
|
91
|
-
ui.error "Error creating WinRM listener. use -VV for more details."
|
96
|
+
rescue => e
|
97
|
+
puts "ERROR: + #{e}"
|
92
98
|
end
|
93
|
-
|
94
|
-
|
95
|
-
|
99
|
+
else
|
100
|
+
ui.error "WinRM listener can be created on Windows system only"
|
101
|
+
exit 1
|
96
102
|
end
|
97
103
|
end
|
104
|
+
|
98
105
|
end
|
99
106
|
end
|
100
107
|
end
|
@@ -125,8 +125,8 @@ class Chef
|
|
125
125
|
@session_opts[:transport] = :sspinegotiate
|
126
126
|
@session_opts[:disable_sspi] = false
|
127
127
|
elsif negotiate_auth? && !Chef::Platform.windows?
|
128
|
-
ui.warn "
|
129
|
-
ui.
|
128
|
+
ui.warn "\nUsing '--winrm-authentication-protocol negotiate' with '--winrm-transport plaintext' is only supported when this tool is invoked from a Windows system."
|
129
|
+
ui.warn "Switch to either '--winrm-transport ssl' or '--winrm-authentication-protocol basic'."
|
130
130
|
exit 1
|
131
131
|
end
|
132
132
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,6 +23,7 @@ end
|
|
23
23
|
|
24
24
|
require_relative '../lib/chef/knife/core/windows_bootstrap_context'
|
25
25
|
require_relative '../lib/chef/knife/bootstrap_windows_winrm'
|
26
|
+
require_relative '../lib/chef/knife/bootstrap_windows_ssh'
|
26
27
|
require_relative '../lib/chef/knife/wsman_test'
|
27
28
|
|
28
29
|
if windows?
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kartik Null Cating-Subramanian(<ksubramanian@chef.io>)
|
3
|
+
# Copyright:: Copyright (c) 2015 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
|
+
describe Chef::Knife::Bootstrap, :chef_gte_12_only do
|
22
|
+
before(:all) do
|
23
|
+
Chef::Config.reset
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:bootstrap) { Chef::Knife::Bootstrap.new }
|
27
|
+
let(:win_bootstrap) { nil }
|
28
|
+
let(:opt_map) { {} }
|
29
|
+
let(:ref_ignore) { [] }
|
30
|
+
let(:win_ignore) { [] }
|
31
|
+
|
32
|
+
def compare_property(sym)
|
33
|
+
win_bootstrap.options.each do |win_key, win_val|
|
34
|
+
unless win_ignore.include?(win_key) || opt_map.include?(win_key) then
|
35
|
+
actual = win_val[sym]
|
36
|
+
expected = bootstrap.options[win_key][sym]
|
37
|
+
expect(actual).to eq(expected),
|
38
|
+
"#{win_key} flag's #{sym} property doesn't match
|
39
|
+
|
40
|
+
expected: #{expected}
|
41
|
+
got: #{actual}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
shared_examples 'compare_options' do
|
47
|
+
it 'contains the option flags' do
|
48
|
+
opt_map.default_proc = proc { |map, key| key }
|
49
|
+
filtered_keys = (win_bootstrap.options.keys - win_ignore).map! { |key| opt_map[key] }
|
50
|
+
|
51
|
+
expect(filtered_keys).to match_array(bootstrap.options.keys - ref_ignore)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'uses the same long-name' do
|
55
|
+
compare_property(:long)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'uses the same short-name' do
|
59
|
+
compare_property(:short)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'uses the same description' do
|
63
|
+
compare_property(:description)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'uses the same default value' do
|
67
|
+
compare_property(:default)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when compared to BootstrapWindowsWinrm' do
|
72
|
+
let(:win_bootstrap) { Chef::Knife::BootstrapWindowsWinrm.new }
|
73
|
+
|
74
|
+
# opt_map: Hash of symbols in windows mapping to symbols in core. Name checks are
|
75
|
+
# ignored for these.
|
76
|
+
let(:opt_map) { {
|
77
|
+
:msi_url => :bootstrap_url,
|
78
|
+
:encrypted_data_bag_secret => :secret,
|
79
|
+
:encrypted_data_bag_secret_file => :secret_file,
|
80
|
+
:winrm_user => :ssh_user,
|
81
|
+
:winrm_password => :ssh_password,
|
82
|
+
:winrm_port => :ssh_port,
|
83
|
+
:winrm_ssl_verify_mode => :host_key_verify,
|
84
|
+
}}
|
85
|
+
|
86
|
+
# ref_ignore: Options in core that are not implemented here.
|
87
|
+
let(:ref_ignore) { [
|
88
|
+
# These are irrelevant to WinRM.
|
89
|
+
:bootstrap_curl_options,
|
90
|
+
:bootstrap_install_command,
|
91
|
+
:bootstrap_wget_options,
|
92
|
+
:forward_agent,
|
93
|
+
:ssh_gateway,
|
94
|
+
:use_sudo,
|
95
|
+
:use_sudo_password,
|
96
|
+
:encrypt, # irrelevant during bootstrap
|
97
|
+
]}
|
98
|
+
|
99
|
+
# win_ignore: Options in windows that aren't relevant to core.
|
100
|
+
let(:win_ignore) { [
|
101
|
+
:attribute,
|
102
|
+
:auth_timeout,
|
103
|
+
:ca_trust_file,
|
104
|
+
:install_as_service,
|
105
|
+
:kerberos_keytab_file,
|
106
|
+
:kerberos_realm,
|
107
|
+
:kerberos_service,
|
108
|
+
:manual,
|
109
|
+
:session_timeout,
|
110
|
+
:winrm_authentication_protocol,
|
111
|
+
:winrm_transport,
|
112
|
+
] }
|
113
|
+
|
114
|
+
include_examples 'compare_options'
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when compared to BootstrapWindowsSsh' do
|
118
|
+
let(:win_bootstrap) { Chef::Knife::BootstrapWindowsSsh.new }
|
119
|
+
|
120
|
+
# opt_map: Hash of symbols in windows mapping to symbols in core. Name checks are
|
121
|
+
# ignored for these.
|
122
|
+
let(:opt_map) { {
|
123
|
+
:msi_url => :bootstrap_url,
|
124
|
+
:encrypted_data_bag_secret => :secret,
|
125
|
+
:encrypted_data_bag_secret_file => :secret_file,
|
126
|
+
}}
|
127
|
+
# ref_ignore: Options in core that are not implemented here.
|
128
|
+
let(:ref_ignore) { [
|
129
|
+
:bootstrap_curl_options,
|
130
|
+
:bootstrap_install_command,
|
131
|
+
:bootstrap_wget_options,
|
132
|
+
:use_sudo,
|
133
|
+
:use_sudo_password,
|
134
|
+
:encrypt, # irrelevant during bootstrap
|
135
|
+
]}
|
136
|
+
# win_ignore: Options in windows that aren't relevant to core.
|
137
|
+
let(:win_ignore) { [
|
138
|
+
:auth_timeout,
|
139
|
+
:install_as_service,
|
140
|
+
:host_key_verification, # Deprecated - remove this when the flag is removed.
|
141
|
+
] }
|
142
|
+
|
143
|
+
include_examples 'compare_options'
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -73,17 +73,17 @@ describe Chef::Knife::BootstrapWindowsWinrm do
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
describe "specifying
|
76
|
+
describe "specifying --msi-url" do
|
77
77
|
subject(:knife) { described_class.new }
|
78
78
|
|
79
|
-
context "with explicitly provided
|
80
|
-
let(:options) { ["--
|
79
|
+
context "with explicitly provided --msi-url" do
|
80
|
+
let(:options) { ["--msi-url", "file:///something.msi"] }
|
81
81
|
|
82
82
|
it "bootstrap batch file must fetch from provided url" do
|
83
83
|
expect(rendered_template).to match(%r{.*REMOTE_SOURCE_MSI_URL=file:///something\.msi.*})
|
84
84
|
end
|
85
85
|
end
|
86
|
-
context "with no provided
|
86
|
+
context "with no provided --msi-url" do
|
87
87
|
it "bootstrap batch file must fetch from provided url" do
|
88
88
|
expect(rendered_template).to match(%r{.*REMOTE_SOURCE_MSI_URL=https://www\.chef\.io/.*})
|
89
89
|
end
|
@@ -84,6 +84,17 @@ describe Chef::Knife::BootstrapWindowsWinrm do
|
|
84
84
|
expect { bootstrap.bootstrap }.to raise_error(SystemExit)
|
85
85
|
end
|
86
86
|
|
87
|
+
it 'should not a wait for timeout on Errno::ECONNREFUSED' do
|
88
|
+
allow(bootstrap).to receive(:run_command).and_raise(Errno::ECONNREFUSED.new)
|
89
|
+
allow(bootstrap.ui).to receive(:info)
|
90
|
+
bootstrap.config[:auth_timeout] = bootstrap.options[:auth_timeout][:default]
|
91
|
+
expect(bootstrap.ui).to receive(:error).with("Connection refused connecting to localhost:5985.")
|
92
|
+
|
93
|
+
# wait_for_remote_response is protected method, So define singleton test method to call it.
|
94
|
+
bootstrap.define_singleton_method(:test_wait_for_remote_response){wait_for_remote_response(bootstrap.options[:auth_timeout][:default])}
|
95
|
+
expect { bootstrap.test_wait_for_remote_response }.to raise_error(Errno::ECONNREFUSED)
|
96
|
+
end
|
97
|
+
|
87
98
|
it "should exit bootstrap with non-zero status if the bootstrap fails" do
|
88
99
|
command_status = 1
|
89
100
|
|
@@ -20,16 +20,32 @@ require 'spec_helper'
|
|
20
20
|
require 'chef/knife/windows_cert_install'
|
21
21
|
|
22
22
|
describe Chef::Knife::WindowsCertInstall do
|
23
|
-
|
24
|
-
|
23
|
+
context "on Windows" do
|
24
|
+
before do
|
25
|
+
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
26
|
+
@certinstall = Chef::Knife::WindowsCertInstall.new
|
27
|
+
end
|
28
|
+
|
29
|
+
it "installs certificate" do
|
30
|
+
@certinstall.name_args = ["test-path"]
|
31
|
+
@certinstall.config[:cert_passphrase] = "your-secret!"
|
32
|
+
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
33
|
+
expect(@certinstall).to receive(:`).with("powershell.exe -Command \" 'your-secret!' | certutil -importPFX 'test-path' AT_KEYEXCHANGE\"")
|
34
|
+
expect(@certinstall.ui).to receive(:info).with("Certificate added to Certificate Store")
|
35
|
+
expect(@certinstall.ui).to receive(:info).with("Adding certificate to the Windows Certificate Store...")
|
36
|
+
@certinstall.run
|
37
|
+
end
|
25
38
|
end
|
26
39
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
40
|
+
context "not on Windows" do
|
41
|
+
before do
|
42
|
+
allow(Chef::Platform).to receive(:windows?).and_return(false)
|
43
|
+
@listener = Chef::Knife::WindowsListenerCreate.new
|
44
|
+
end
|
45
|
+
|
46
|
+
it "exits with an error" do
|
47
|
+
expect(@listener.ui).to receive(:error)
|
48
|
+
expect { @listener.run }.to raise_error(SystemExit)
|
49
|
+
end
|
34
50
|
end
|
35
51
|
end
|
@@ -19,43 +19,58 @@
|
|
19
19
|
require 'spec_helper'
|
20
20
|
require 'chef/knife/windows_listener_create'
|
21
21
|
|
22
|
-
describe Chef::Knife::WindowsListenerCreate
|
23
|
-
|
24
|
-
|
22
|
+
describe Chef::Knife::WindowsListenerCreate do
|
23
|
+
context "on Windows" do
|
24
|
+
before do
|
25
|
+
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
26
|
+
@listener = Chef::Knife::WindowsListenerCreate.new
|
27
|
+
end
|
28
|
+
|
29
|
+
it "creates winrm listener" do
|
30
|
+
@listener.config[:hostname] = "host"
|
31
|
+
@listener.config[:cert_thumbprint] = "CERT-THUMBPRINT"
|
32
|
+
@listener.config[:port] = "5986"
|
33
|
+
expect(@listener).to receive(:`).with("winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=\"host\";CertificateThumbprint=\"CERT-THUMBPRINT\";Port=\"5986\"}")
|
34
|
+
expect(@listener.ui).to receive(:info).with("WinRM listener created with Port: 5986 and CertificateThumbprint: CERT-THUMBPRINT")
|
35
|
+
@listener.run
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raise an error on command failure" do
|
39
|
+
@listener.config[:hostname] = "host"
|
40
|
+
@listener.config[:cert_thumbprint] = "CERT-THUMBPRINT"
|
41
|
+
@listener.config[:port] = "5986"
|
42
|
+
@listener.config[:basic_auth] = true
|
43
|
+
expect(@listener).to receive(:`).with("winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=\"host\";CertificateThumbprint=\"CERT-THUMBPRINT\";Port=\"5986\"}")
|
44
|
+
expect($?).to receive(:exitstatus).and_return(100)
|
45
|
+
expect(@listener.ui).to receive(:error).with("Error creating WinRM listener. use -VV for more details.")
|
46
|
+
expect(@listener.ui).to_not receive(:info).with("WinRM listener created with Port: 5986 and CertificateThumbprint: CERT-THUMBPRINT")
|
47
|
+
expect { @listener.run }.to raise_error(SystemExit)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "creates winrm listener with cert install option" do
|
51
|
+
@listener.config[:hostname] = "host"
|
52
|
+
@listener.config[:cert_thumbprint] = "CERT-THUMBPRINT"
|
53
|
+
@listener.config[:port] = "5986"
|
54
|
+
@listener.config[:cert_install] = true
|
55
|
+
allow(@listener).to receive(:get_cert_passphrase).and_return("your-secret!")
|
56
|
+
expect(@listener).to receive(:`).with("powershell.exe -Command \" 'your-secret!' | certutil -importPFX 'true' AT_KEYEXCHANGE\"")
|
57
|
+
expect(@listener).to receive(:`).with("powershell.exe -Command \" echo (Get-PfxCertificate true).thumbprint \"")
|
58
|
+
expect(@listener.ui).to receive(:info).with("Certificate installed to Certificate Store")
|
59
|
+
expect(@listener.ui).to receive(:info).with("Certificate Thumbprint: ")
|
60
|
+
allow(@listener).to receive(:puts)
|
61
|
+
@listener.run
|
62
|
+
end
|
25
63
|
end
|
26
64
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
expect(@listener.ui).to receive(:info).with("WinRM listener created with Port: 5986 and CertificateThumbprint: CERT-THUMBPRINT")
|
33
|
-
@listener.run
|
34
|
-
end
|
35
|
-
|
36
|
-
it "raise an error on command failure" do
|
37
|
-
@listener.config[:hostname] = "host"
|
38
|
-
@listener.config[:cert_thumbprint] = "CERT-THUMBPRINT"
|
39
|
-
@listener.config[:port] = "5986"
|
40
|
-
@listener.config[:basic_auth] = true
|
41
|
-
expect(@listener).to receive(:`).with("winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=\"host\";CertificateThumbprint=\"CERT-THUMBPRINT\";Port=\"5986\"}")
|
42
|
-
expect($?).to receive(:exitstatus).and_return(100)
|
43
|
-
expect(@listener.ui).to receive(:error).with("Error creating WinRM listener. use -VV for more details.")
|
44
|
-
expect(@listener.ui).to_not receive(:info).with("WinRM listener created with Port: 5986 and CertificateThumbprint: CERT-THUMBPRINT")
|
45
|
-
@listener.run
|
46
|
-
end
|
65
|
+
context "not on Windows" do
|
66
|
+
before do
|
67
|
+
allow(Chef::Platform).to receive(:windows?).and_return(false)
|
68
|
+
@listener = Chef::Knife::WindowsListenerCreate.new
|
69
|
+
end
|
47
70
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@listener.config[:cert_install] = true
|
53
|
-
allow(@listener).to receive(:get_cert_passphrase).and_return("your-secret!")
|
54
|
-
expect(@listener).to receive(:`).with("powershell.exe -Command \" 'your-secret!' | certutil -importPFX 'true' AT_KEYEXCHANGE\"")
|
55
|
-
expect(@listener).to receive(:`).with("powershell.exe -Command \" echo (Get-PfxCertificate true).thumbprint \"")
|
56
|
-
expect(@listener.ui).to receive(:info).with("Certificate installed to Certificate Store")
|
57
|
-
expect(@listener.ui).to receive(:info).with("Certificate Thumbprint: ")
|
58
|
-
allow(@listener).to receive(:puts)
|
59
|
-
@listener.run
|
71
|
+
it "exits with an error" do
|
72
|
+
expect(@listener.ui).to receive(:error)
|
73
|
+
expect { @listener.run }.to raise_error(SystemExit)
|
74
|
+
end
|
60
75
|
end
|
61
|
-
end
|
76
|
+
end
|
@@ -58,7 +58,7 @@ describe Chef::Knife::Winrm do
|
|
58
58
|
allow(Chef::Search::Query).to receive(:new).and_return(@query)
|
59
59
|
end
|
60
60
|
|
61
|
-
it "
|
61
|
+
it "raises a specific error (KNIFE-222)" do
|
62
62
|
expect(@knife.ui).to receive(:fatal).with(/does not have the required attribute/)
|
63
63
|
expect(@knife).to receive(:exit).with(10)
|
64
64
|
@knife.configure_chef
|
@@ -74,7 +74,7 @@ describe Chef::Knife::Winrm do
|
|
74
74
|
allow(Chef::Search::Query).to receive(:new).and_return(@query)
|
75
75
|
end
|
76
76
|
|
77
|
-
it "
|
77
|
+
it "uses the nested attributes (KNIFE-276)" do
|
78
78
|
@knife.config[:attribute] = "ec2.public_hostname"
|
79
79
|
@knife.configure_chef
|
80
80
|
@knife.resolve_target_nodes
|
@@ -94,7 +94,7 @@ describe Chef::Knife::Winrm do
|
|
94
94
|
|
95
95
|
context "on windows workstations" do
|
96
96
|
let(:winrm_command_windows_http) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', 'echo helloworld']) }
|
97
|
-
it "
|
97
|
+
it "defaults to negotiate when on a Windows host" do
|
98
98
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
99
99
|
expect(winrm_command_windows_http).to receive(:load_windows_specific_gems)
|
100
100
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :sspinegotiate)).and_call_original
|
@@ -109,15 +109,16 @@ describe Chef::Knife::Winrm do
|
|
109
109
|
allow(Chef::Platform).to receive(:windows?).and_return(false)
|
110
110
|
end
|
111
111
|
|
112
|
-
let(:winrm_command_http) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '-t', 'plaintext', '--winrm-authentication-protocol', 'basic', 'echo helloworld'])
|
113
|
-
|
112
|
+
let(:winrm_command_http) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '-t', 'plaintext', '--winrm-authentication-protocol', 'basic', 'echo helloworld']) }
|
113
|
+
|
114
|
+
it "defaults to the http uri scheme" do
|
114
115
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :plaintext)).and_call_original
|
115
116
|
expect(WinRM::WinRMWebService).to receive(:new).with('http://localhost:5985/wsman', anything, anything).and_return(@winrm_session)
|
116
117
|
winrm_command_http.configure_chef
|
117
118
|
winrm_command_http.configure_session
|
118
119
|
end
|
119
120
|
|
120
|
-
it "
|
121
|
+
it "sets the operation timeout and verifes default" do
|
121
122
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :plaintext)).and_call_original
|
122
123
|
expect(WinRM::WinRMWebService).to receive(:new).with('http://localhost:5985/wsman', anything, anything).and_return(@winrm_session)
|
123
124
|
expect(@winrm_session).to receive(:set_timeout).with(1800)
|
@@ -125,7 +126,7 @@ describe Chef::Knife::Winrm do
|
|
125
126
|
winrm_command_http.configure_session
|
126
127
|
end
|
127
128
|
|
128
|
-
it "
|
129
|
+
it "sets the user specified winrm port" do
|
129
130
|
Chef::Config[:knife] = {winrm_port: "5988"}
|
130
131
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :plaintext)).and_call_original
|
131
132
|
expect(WinRM::WinRMWebService).to receive(:new).with('http://localhost:5988/wsman', anything, anything).and_return(@winrm_session)
|
@@ -133,9 +134,9 @@ describe Chef::Knife::Winrm do
|
|
133
134
|
winrm_command_http.configure_session
|
134
135
|
end
|
135
136
|
|
136
|
-
let(:winrm_command_timeout) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-authentication-protocol', 'basic', '--session-timeout', '10', 'echo helloworld'])
|
137
|
+
let(:winrm_command_timeout) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-authentication-protocol', 'basic', '--session-timeout', '10', 'echo helloworld']) }
|
137
138
|
|
138
|
-
it "
|
139
|
+
it "sets operation timeout and verify 10 Minute timeout" do
|
139
140
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :plaintext)).and_call_original
|
140
141
|
expect(WinRM::WinRMWebService).to receive(:new).with('http://localhost:5985/wsman', anything, anything).and_return(@winrm_session)
|
141
142
|
expect(@winrm_session).to receive(:set_timeout).with(600)
|
@@ -143,9 +144,9 @@ describe Chef::Knife::Winrm do
|
|
143
144
|
winrm_command_timeout.configure_session
|
144
145
|
end
|
145
146
|
|
146
|
-
let(:winrm_command_https) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-transport', 'ssl', 'echo helloworld'])
|
147
|
+
let(:winrm_command_https) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-transport', 'ssl', 'echo helloworld']) }
|
147
148
|
|
148
|
-
it "
|
149
|
+
it "uses the https uri scheme if the ssl transport is specified" do
|
149
150
|
Chef::Config[:knife] = {:winrm_transport => 'ssl'}
|
150
151
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
151
152
|
expect(WinRM::WinRMWebService).to receive(:new).with('https://localhost:5986/wsman', anything, anything).and_return(@winrm_session)
|
@@ -153,7 +154,7 @@ describe Chef::Knife::Winrm do
|
|
153
154
|
winrm_command_https.configure_session
|
154
155
|
end
|
155
156
|
|
156
|
-
it "
|
157
|
+
it "uses the winrm port '5986' by default for ssl transport" do
|
157
158
|
Chef::Config[:knife] = {:winrm_transport => 'ssl'}
|
158
159
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
159
160
|
expect(WinRM::WinRMWebService).to receive(:new).with('https://localhost:5986/wsman', anything, anything).and_return(@winrm_session)
|
@@ -161,7 +162,7 @@ describe Chef::Knife::Winrm do
|
|
161
162
|
winrm_command_https.configure_session
|
162
163
|
end
|
163
164
|
|
164
|
-
it "
|
165
|
+
it "defaults to validating the server when the ssl transport is used" do
|
165
166
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
166
167
|
expect(WinRM::WinRMWebService).to receive(:new).with(anything, anything, hash_including(:no_ssl_peer_verification => false)).and_return(@winrm_session)
|
167
168
|
winrm_command_https.configure_chef
|
@@ -169,7 +170,8 @@ describe Chef::Knife::Winrm do
|
|
169
170
|
end
|
170
171
|
|
171
172
|
let(:winrm_command_verify_peer) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-transport', 'ssl', '--winrm-ssl-verify-mode', 'verify_peer', 'echo helloworld'])}
|
172
|
-
|
173
|
+
|
174
|
+
it "validates the server when the ssl transport is used and the :winrm_ssl_verify_mode option is not configured to :verify_none" do
|
173
175
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
174
176
|
expect(WinRM::WinRMWebService).to receive(:new).with(anything, anything, hash_including(:no_ssl_peer_verification => false)).and_return(@winrm_session)
|
175
177
|
winrm_command_verify_peer.configure_chef
|
@@ -178,14 +180,14 @@ describe Chef::Knife::Winrm do
|
|
178
180
|
|
179
181
|
let(:winrm_command_no_verify) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-transport', 'ssl', '--winrm-ssl-verify-mode', 'verify_none', 'echo helloworld'])}
|
180
182
|
|
181
|
-
it "
|
183
|
+
it "does not validate the server when the ssl transport is used and the :winrm_ssl_verify_mode option is set to :verify_none" do
|
182
184
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
183
185
|
expect(WinRM::WinRMWebService).to receive(:new).with(anything, anything, hash_including(:no_ssl_peer_verification => true)).and_return(@winrm_session)
|
184
186
|
winrm_command_no_verify.configure_chef
|
185
187
|
winrm_command_no_verify.configure_session
|
186
188
|
end
|
187
189
|
|
188
|
-
it "
|
190
|
+
it "prints warning output when the :winrm_ssl_verify_mode set to :verify_none to disable server validation" do
|
189
191
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
190
192
|
expect(WinRM::WinRMWebService).to receive(:new).with(anything, anything, hash_including(:no_ssl_peer_verification => true)).and_return(@winrm_session)
|
191
193
|
expect(winrm_command_no_verify).to receive(:warn_no_ssl_peer_verification)
|
@@ -196,7 +198,7 @@ describe Chef::Knife::Winrm do
|
|
196
198
|
|
197
199
|
let(:winrm_command_ca_trust) { Chef::Knife::Winrm.new(['-m', 'localhost', '-x', 'testuser', '-P', 'testpassword', '--winrm-transport', 'ssl', '--ca-trust-file', '~/catrustroot', '--winrm-ssl-verify-mode', 'verify_none', 'echo helloworld'])}
|
198
200
|
|
199
|
-
it "
|
201
|
+
it "validates the server when the ssl transport is used and the :ca_trust_file option is specified even if the :winrm_ssl_verify_mode option is set to :verify_none" do
|
200
202
|
expect(Chef::Knife::WinrmSession).to receive(:new).with(hash_including(:transport => :ssl)).and_call_original
|
201
203
|
expect(WinRM::WinRMWebService).to receive(:new).with(anything, anything, hash_including(:no_ssl_peer_verification => false)).and_return(@winrm_session)
|
202
204
|
winrm_command_ca_trust.configure_chef
|
@@ -216,14 +218,13 @@ describe Chef::Knife::Winrm do
|
|
216
218
|
Chef::Config[:knife] = @original_knife_config if @original_knife_config
|
217
219
|
end
|
218
220
|
|
219
|
-
it "
|
220
|
-
allow(@winrm).to receive(:exit)
|
221
|
+
it "returns with 0 if the command succeeds" do
|
221
222
|
allow(@winrm).to receive(:relay_winrm_command).and_return(0)
|
222
|
-
|
223
|
-
expect(
|
223
|
+
return_code = @winrm.run
|
224
|
+
expect(return_code).to be_zero
|
224
225
|
end
|
225
226
|
|
226
|
-
it "
|
227
|
+
it "exits with exact exit status if the command fails and returns config is set to 0" do
|
227
228
|
command_status = 510
|
228
229
|
session_mock = Chef::Knife::WinrmSession.new({:transport => :plaintext, :host => 'localhost', :port => '5985'})
|
229
230
|
|
@@ -237,7 +238,7 @@ describe Chef::Knife::Winrm do
|
|
237
238
|
expect { @winrm.run_with_pretty_exceptions }.to raise_error(SystemExit) { |e| expect(e.status).to eq(command_status) }
|
238
239
|
end
|
239
240
|
|
240
|
-
it "
|
241
|
+
it "exits with non-zero status if the command fails and returns config is set to 0" do
|
241
242
|
command_status = 1
|
242
243
|
@winrm.config[:returns] = "0,53"
|
243
244
|
Chef::Config[:knife][:returns] = [0,53]
|
@@ -249,7 +250,7 @@ describe Chef::Knife::Winrm do
|
|
249
250
|
expect { @winrm.run_with_pretty_exceptions }.to raise_error(SystemExit) { |e| expect(e.status).to eq(command_status) }
|
250
251
|
end
|
251
252
|
|
252
|
-
it "
|
253
|
+
it "exits with a zero status if the command returns an expected non-zero status" do
|
253
254
|
command_status = 53
|
254
255
|
Chef::Config[:knife][:returns] = [0,53]
|
255
256
|
allow(@winrm).to receive(:relay_winrm_command).and_return(command_status)
|
@@ -260,7 +261,7 @@ describe Chef::Knife::Winrm do
|
|
260
261
|
expect(exit_code).to be_zero
|
261
262
|
end
|
262
263
|
|
263
|
-
it "
|
264
|
+
it "exits with a zero status if the command returns an expected non-zero status" do
|
264
265
|
command_status = 53
|
265
266
|
@winrm.config[:returns] = '0,53'
|
266
267
|
allow(@winrm).to receive(:relay_winrm_command).and_return(command_status)
|
@@ -271,20 +272,20 @@ describe Chef::Knife::Winrm do
|
|
271
272
|
expect(exit_code).to be_zero
|
272
273
|
end
|
273
274
|
|
274
|
-
it "
|
275
|
+
it "exits with 100 if command execution raises an exception other than 401" do
|
275
276
|
allow(@winrm).to receive(:relay_winrm_command).and_raise(WinRM::WinRMHTTPTransportError.new('', '500'))
|
276
277
|
allow(@winrm.ui).to receive(:error)
|
277
278
|
expect { @winrm.run_with_pretty_exceptions }.to raise_error(SystemExit) { |e| expect(e.status).to eq(100) }
|
278
279
|
end
|
279
280
|
|
280
|
-
it "
|
281
|
+
it "exits with 100 if command execution raises a 401" do
|
281
282
|
allow(@winrm).to receive(:relay_winrm_command).and_raise(WinRM::WinRMHTTPTransportError.new('', '401'))
|
282
283
|
allow(@winrm.ui).to receive(:info)
|
283
284
|
allow(@winrm.ui).to receive(:error)
|
284
285
|
expect { @winrm.run_with_pretty_exceptions }.to raise_error(SystemExit) { |e| expect(e.status).to eq(100) }
|
285
286
|
end
|
286
287
|
|
287
|
-
it "
|
288
|
+
it "exits with 0 if command execution raises a 401 and suppress_auth_failure is set to true" do
|
288
289
|
@winrm.config[:suppress_auth_failure] = true
|
289
290
|
allow(@winrm).to receive(:relay_winrm_command).and_raise(WinRM::WinRMHTTPTransportError.new('', '401'))
|
290
291
|
exit_code = @winrm.run_with_pretty_exceptions
|
@@ -297,16 +298,15 @@ describe Chef::Knife::Winrm do
|
|
297
298
|
allow(@winrm).to receive(:relay_winrm_command).and_return(0)
|
298
299
|
end
|
299
300
|
|
300
|
-
it "
|
301
|
+
it "sets sspinegotiate transport on windows for 'negotiate' authentication" do
|
301
302
|
@winrm.config[:winrm_authentication_protocol] = "negotiate"
|
302
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
303
303
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
304
304
|
allow(@winrm).to receive(:require).with('winrm-s').and_return(true)
|
305
|
-
expect(@winrm).to receive(:create_winrm_session).with({:user=>"
|
305
|
+
expect(@winrm).to receive(:create_winrm_session).with({:user=>"testuser", :password=>"testpassword", :port=>"5985", :no_ssl_peer_verification => false, :basic_auth_only=>false, :operation_timeout=>1800, :transport=>:sspinegotiate, :disable_sspi=>false, :host=>"localhost"})
|
306
306
|
exit_code = @winrm.run
|
307
307
|
end
|
308
308
|
|
309
|
-
it "
|
309
|
+
it "does not have winrm opts transport set to sspinegotiate for unix" do
|
310
310
|
@winrm.config[:winrm_authentication_protocol] = "negotiate"
|
311
311
|
allow(Chef::Platform).to receive(:windows?).and_return(false)
|
312
312
|
allow(@winrm).to receive(:exit)
|
@@ -314,69 +314,60 @@ describe Chef::Knife::Winrm do
|
|
314
314
|
exit_code = @winrm.run
|
315
315
|
end
|
316
316
|
|
317
|
-
it "
|
317
|
+
it "applies winrm monkey patch on windows if 'negotiate' authentication and 'plaintext' transport is specified", :windows_only => true do
|
318
318
|
@winrm.config[:winrm_authentication_protocol] = "negotiate"
|
319
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
320
319
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
321
320
|
allow(@winrm.ui).to receive(:warn)
|
322
321
|
expect(@winrm).to receive(:require).with('winrm-s').and_call_original
|
323
|
-
|
322
|
+
@winrm.run
|
324
323
|
end
|
325
324
|
|
326
|
-
it "
|
325
|
+
it "raises an error if value is other than [basic, negotiate, kerberos]" do
|
327
326
|
@winrm.config[:winrm_authentication_protocol] = "invalid"
|
328
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
329
327
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
330
328
|
expect(@winrm.ui).to receive(:error)
|
331
|
-
expect
|
332
|
-
exit_code = @winrm.run
|
329
|
+
expect { @winrm.run }.to raise_error(SystemExit)
|
333
330
|
end
|
334
331
|
|
335
|
-
it "
|
332
|
+
it "skips the winrm monkey patch for 'basic' authentication" do
|
336
333
|
@winrm.config[:winrm_authentication_protocol] = "basic"
|
337
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
338
334
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
339
335
|
expect(@winrm).to_not receive(:require).with('winrm-s')
|
340
|
-
|
336
|
+
@winrm.run
|
341
337
|
end
|
342
338
|
|
343
|
-
it "
|
339
|
+
it "skips the winrm monkey patch for 'kerberos' authentication" do
|
344
340
|
@winrm.config[:winrm_authentication_protocol] = "kerberos"
|
345
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
346
341
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
347
342
|
expect(@winrm).to_not receive(:require).with('winrm-s')
|
348
|
-
|
343
|
+
@winrm.run
|
349
344
|
end
|
350
345
|
|
351
|
-
it "
|
346
|
+
it "skips the winrm monkey patch for 'ssl' transport and 'negotiate' authentication" do
|
352
347
|
@winrm.config[:winrm_authentication_protocol] = "negotiate"
|
353
348
|
@winrm.config[:winrm_transport] = "ssl"
|
354
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
355
349
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
356
350
|
expect(@winrm).to_not receive(:require).with('winrm-s')
|
357
|
-
|
351
|
+
@winrm.run
|
358
352
|
end
|
359
353
|
|
360
|
-
it "
|
354
|
+
it "disables sspi and skips the winrm monkey patch for 'ssl' transport and 'basic' authentication" do
|
361
355
|
@winrm.config[:winrm_authentication_protocol] = "basic"
|
362
356
|
@winrm.config[:winrm_transport] = "ssl"
|
363
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
364
357
|
@winrm.config[:winrm_port] = "5986"
|
365
358
|
allow(Chef::Platform).to receive(:windows?).and_return(true)
|
366
|
-
expect(@winrm).to receive(:create_winrm_session).with({:user=>"
|
359
|
+
expect(@winrm).to receive(:create_winrm_session).with({:user=>"testuser", :password=>"testpassword", :port=>"5986", :no_ssl_peer_verification=>false, :basic_auth_only=>true, :operation_timeout=>1800, :transport=>:ssl, :disable_sspi=>true, :host=>"localhost"})
|
367
360
|
expect(@winrm).to_not receive(:require).with('winrm-s')
|
368
|
-
|
361
|
+
@winrm.run
|
369
362
|
end
|
370
363
|
|
371
|
-
it "
|
364
|
+
it "prints a warning and exits on linux for unencrypted negotiate authentication" do
|
372
365
|
@winrm.config[:winrm_authentication_protocol] = "negotiate"
|
373
366
|
@winrm.config[:winrm_transport] = "plaintext"
|
374
|
-
@winrm.config[:winrm_user] = "domain\\testuser"
|
375
|
-
allow(@winrm).to receive(:exit)
|
376
367
|
allow(Chef::Platform).to receive(:windows?).and_return(false)
|
377
368
|
expect(@winrm).to_not receive(:require).with('winrm-s')
|
378
|
-
expect(@winrm.ui).to receive(:warn)
|
379
|
-
|
369
|
+
expect(@winrm.ui).to receive(:warn).twice
|
370
|
+
expect { @winrm.run }.to raise_error(SystemExit)
|
380
371
|
end
|
381
372
|
end
|
382
373
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-windows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.rc.
|
4
|
+
version: 1.0.0.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seth Chisamore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: winrm
|
@@ -109,6 +109,7 @@ files:
|
|
109
109
|
- lib/knife-windows/version.rb
|
110
110
|
- spec/functional/bootstrap_download_spec.rb
|
111
111
|
- spec/spec_helper.rb
|
112
|
+
- spec/unit/knife/bootstrap_options_spec.rb
|
112
113
|
- spec/unit/knife/bootstrap_template_spec.rb
|
113
114
|
- spec/unit/knife/bootstrap_windows_winrm_spec.rb
|
114
115
|
- spec/unit/knife/core/windows_bootstrap_context_spec.rb
|