knife-windows 1.0.0.rc.0 → 1.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|