knife-windows 1.5.0 → 1.6.0
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/.travis.yml +26 -26
- data/CHANGELOG.md +131 -121
- data/DOC_CHANGES.md +22 -14
- data/Gemfile +14 -13
- data/README.md +400 -392
- data/RELEASE_NOTES.md +2 -26
- data/appveyor.yml +39 -39
- data/ci.gemfile +16 -16
- data/knife-windows.gemspec +25 -25
- data/lib/chef/knife/bootstrap/windows-chef-client-msi.erb +246 -233
- data/lib/chef/knife/bootstrap_windows_base.rb +443 -454
- data/lib/chef/knife/bootstrap_windows_ssh.rb +116 -115
- data/lib/chef/knife/bootstrap_windows_winrm.rb +102 -95
- data/lib/chef/knife/core/windows_bootstrap_context.rb +378 -378
- data/lib/chef/knife/knife_windows_base.rb +33 -33
- data/lib/chef/knife/windows_cert_generate.rb +155 -155
- data/lib/chef/knife/windows_cert_install.rb +68 -68
- data/lib/chef/knife/windows_helper.rb +36 -36
- data/lib/chef/knife/windows_listener_create.rb +107 -107
- data/lib/chef/knife/winrm.rb +122 -122
- data/lib/chef/knife/winrm_base.rb +123 -117
- data/lib/chef/knife/winrm_knife_base.rb +306 -305
- data/lib/chef/knife/winrm_session.rb +97 -91
- data/lib/chef/knife/winrm_shared_options.rb +47 -47
- data/lib/chef/knife/wsman_endpoint.rb +44 -44
- data/lib/chef/knife/wsman_test.rb +118 -118
- data/lib/knife-windows/path_helper.rb +234 -234
- data/lib/knife-windows/version.rb +6 -6
- data/spec/assets/win_template_rendered_with_bootstrap_install_command.txt +223 -223
- data/spec/assets/win_template_rendered_with_bootstrap_install_command_on_12_5_client.txt +223 -223
- data/spec/assets/win_template_rendered_without_bootstrap_install_command.txt +335 -335
- data/spec/assets/win_template_rendered_without_bootstrap_install_command_on_12_5_client.txt +335 -335
- data/spec/dummy_winrm_connection.rb +21 -0
- data/spec/functional/bootstrap_download_spec.rb +236 -241
- data/spec/spec_helper.rb +94 -94
- data/spec/unit/knife/bootstrap_options_spec.rb +157 -155
- data/spec/unit/knife/bootstrap_template_spec.rb +98 -98
- data/spec/unit/knife/bootstrap_windows_winrm_spec.rb +423 -426
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +177 -177
- data/spec/unit/knife/windows_cert_generate_spec.rb +90 -90
- data/spec/unit/knife/windows_cert_install_spec.rb +51 -51
- data/spec/unit/knife/windows_listener_create_spec.rb +76 -76
- data/spec/unit/knife/winrm_session_spec.rb +71 -76
- data/spec/unit/knife/winrm_spec.rb +500 -508
- data/spec/unit/knife/wsman_test_spec.rb +209 -209
- metadata +16 -17
- data/spec/dummy_winrm_service.rb +0 -24
@@ -1,36 +1,36 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Chirag Jog (<chirag@clogeny.com>)
|
3
|
-
# Copyright:: Copyright (c) 2013-2016 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 'chef/knife'
|
20
|
-
require 'chef/knife/winrm'
|
21
|
-
require 'chef/knife/bootstrap_windows_ssh'
|
22
|
-
require 'chef/knife/bootstrap_windows_winrm'
|
23
|
-
require 'chef/knife/wsman_test'
|
24
|
-
|
25
|
-
class Chef
|
26
|
-
class Knife
|
27
|
-
class WindowsHelper < Knife
|
28
|
-
|
29
|
-
banner "#{BootstrapWindowsWinrm.banner}\n" +
|
30
|
-
"#{BootstrapWindowsSsh.banner}\n" +
|
31
|
-
"#{Winrm.banner}\n" +
|
32
|
-
"#{WsmanTest.banner}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
1
|
+
#
|
2
|
+
# Author:: Chirag Jog (<chirag@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013-2016 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 'chef/knife'
|
20
|
+
require 'chef/knife/winrm'
|
21
|
+
require 'chef/knife/bootstrap_windows_ssh'
|
22
|
+
require 'chef/knife/bootstrap_windows_winrm'
|
23
|
+
require 'chef/knife/wsman_test'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Knife
|
27
|
+
class WindowsHelper < Knife
|
28
|
+
|
29
|
+
banner "#{BootstrapWindowsWinrm.banner}\n" +
|
30
|
+
"#{BootstrapWindowsSsh.banner}\n" +
|
31
|
+
"#{Winrm.banner}\n" +
|
32
|
+
"#{WsmanTest.banner}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -1,107 +1,107 @@
|
|
1
|
-
# Author:: Mukta Aphale (<mukta.aphale@clogeny.com>)
|
2
|
-
# Copyright:: Copyright (c) 2014-2016 Chef Software, Inc.
|
3
|
-
# License:: Apache License, Version 2.0
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
#
|
17
|
-
|
18
|
-
require 'chef/knife'
|
19
|
-
require 'chef/knife/winrm_base'
|
20
|
-
require 'openssl'
|
21
|
-
|
22
|
-
class Chef
|
23
|
-
class Knife
|
24
|
-
class WindowsListenerCreate < Knife
|
25
|
-
|
26
|
-
banner "knife windows listener create (options)"
|
27
|
-
|
28
|
-
option :cert_install,
|
29
|
-
:short => "-c CERT_PATH",
|
30
|
-
:long => "--cert-install CERT_PATH",
|
31
|
-
:description => "Adds specified certificate to the Windows Certificate Store's Local Machine personal store before creating listener."
|
32
|
-
|
33
|
-
option :port,
|
34
|
-
:short => "-p PORT",
|
35
|
-
:long => "--port PORT",
|
36
|
-
:description => "Specify port. Default is 5986",
|
37
|
-
:default => "5986"
|
38
|
-
|
39
|
-
option :hostname,
|
40
|
-
:short => "-h HOSTNAME",
|
41
|
-
:long => "--hostname HOSTNAME",
|
42
|
-
:description => "Hostname on the listener. Default is blank",
|
43
|
-
:default => ""
|
44
|
-
|
45
|
-
option :cert_thumbprint,
|
46
|
-
:short => "-t THUMBPRINT",
|
47
|
-
:long => "--cert-thumbprint THUMBPRINT",
|
48
|
-
:description => "Thumbprint of the certificate. Required only if --cert-install option is not used."
|
49
|
-
|
50
|
-
option :cert_passphrase,
|
51
|
-
:short => "-cp PASSWORD",
|
52
|
-
:long => "--cert-passphrase PASSWORD",
|
53
|
-
:description => "Password for certificate."
|
54
|
-
|
55
|
-
def get_cert_passphrase
|
56
|
-
print "Enter given certificate's passphrase (empty for no passphrase):"
|
57
|
-
passphrase = STDIN.gets
|
58
|
-
passphrase.strip
|
59
|
-
end
|
60
|
-
|
61
|
-
def run
|
62
|
-
STDOUT.sync = STDERR.sync = true
|
63
|
-
|
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"
|
83
|
-
exit 1
|
84
|
-
end
|
85
|
-
|
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
|
88
|
-
|
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
|
95
|
-
|
96
|
-
rescue => e
|
97
|
-
puts "ERROR: + #{e}"
|
98
|
-
end
|
99
|
-
else
|
100
|
-
ui.error "WinRM listener can be created on Windows system only"
|
101
|
-
exit 1
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
1
|
+
# Author:: Mukta Aphale (<mukta.aphale@clogeny.com>)
|
2
|
+
# Copyright:: Copyright (c) 2014-2016 Chef Software, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef/knife'
|
19
|
+
require 'chef/knife/winrm_base'
|
20
|
+
require 'openssl'
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class Knife
|
24
|
+
class WindowsListenerCreate < Knife
|
25
|
+
|
26
|
+
banner "knife windows listener create (options)"
|
27
|
+
|
28
|
+
option :cert_install,
|
29
|
+
:short => "-c CERT_PATH",
|
30
|
+
:long => "--cert-install CERT_PATH",
|
31
|
+
:description => "Adds specified certificate to the Windows Certificate Store's Local Machine personal store before creating listener."
|
32
|
+
|
33
|
+
option :port,
|
34
|
+
:short => "-p PORT",
|
35
|
+
:long => "--port PORT",
|
36
|
+
:description => "Specify port. Default is 5986",
|
37
|
+
:default => "5986"
|
38
|
+
|
39
|
+
option :hostname,
|
40
|
+
:short => "-h HOSTNAME",
|
41
|
+
:long => "--hostname HOSTNAME",
|
42
|
+
:description => "Hostname on the listener. Default is blank",
|
43
|
+
:default => ""
|
44
|
+
|
45
|
+
option :cert_thumbprint,
|
46
|
+
:short => "-t THUMBPRINT",
|
47
|
+
:long => "--cert-thumbprint THUMBPRINT",
|
48
|
+
:description => "Thumbprint of the certificate. Required only if --cert-install option is not used."
|
49
|
+
|
50
|
+
option :cert_passphrase,
|
51
|
+
:short => "-cp PASSWORD",
|
52
|
+
:long => "--cert-passphrase PASSWORD",
|
53
|
+
:description => "Password for certificate."
|
54
|
+
|
55
|
+
def get_cert_passphrase
|
56
|
+
print "Enter given certificate's passphrase (empty for no passphrase):"
|
57
|
+
passphrase = STDIN.gets
|
58
|
+
passphrase.strip
|
59
|
+
end
|
60
|
+
|
61
|
+
def run
|
62
|
+
STDOUT.sync = STDERR.sync = true
|
63
|
+
|
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"
|
83
|
+
exit 1
|
84
|
+
end
|
85
|
+
|
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
|
88
|
+
|
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
|
95
|
+
|
96
|
+
rescue => e
|
97
|
+
puts "ERROR: + #{e}"
|
98
|
+
end
|
99
|
+
else
|
100
|
+
ui.error "WinRM listener can be created on Windows system only"
|
101
|
+
exit 1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/chef/knife/winrm.rb
CHANGED
@@ -1,122 +1,122 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
-
# Copyright:: Copyright (c) 2011-2016 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 'chef/knife'
|
20
|
-
require 'chef/knife/winrm_knife_base'
|
21
|
-
require 'chef/knife/windows_cert_generate'
|
22
|
-
require 'chef/knife/windows_cert_install'
|
23
|
-
require 'chef/knife/windows_listener_create'
|
24
|
-
require 'chef/knife/winrm_session'
|
25
|
-
require 'chef/knife/knife_windows_base'
|
26
|
-
|
27
|
-
class Chef
|
28
|
-
class Knife
|
29
|
-
class Winrm < Knife
|
30
|
-
|
31
|
-
include Chef::Knife::WinrmCommandSharedFunctions
|
32
|
-
include Chef::Knife::KnifeWindowsBase
|
33
|
-
|
34
|
-
deps do
|
35
|
-
require 'readline'
|
36
|
-
require 'chef/search/query'
|
37
|
-
end
|
38
|
-
|
39
|
-
attr_writer :password
|
40
|
-
|
41
|
-
banner "knife winrm QUERY COMMAND (options)"
|
42
|
-
|
43
|
-
option :returns,
|
44
|
-
:long => "--returns CODES",
|
45
|
-
:description => "A comma delimited list of return codes which indicate success",
|
46
|
-
:default => "0"
|
47
|
-
|
48
|
-
def run
|
49
|
-
STDOUT.sync = STDERR.sync = true
|
50
|
-
|
51
|
-
configure_session
|
52
|
-
execute_remote_command
|
53
|
-
end
|
54
|
-
|
55
|
-
def execute_remote_command
|
56
|
-
case @name_args[1]
|
57
|
-
when "interactive"
|
58
|
-
interactive
|
59
|
-
else
|
60
|
-
run_command(@name_args[1..-1].join(" "))
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def interactive
|
67
|
-
puts "WARN: Deprecated functionality. This will not be supported in future knife-windows releases."
|
68
|
-
puts "Connected to #{ui.list(session.servers.collect { |s| ui.color(s.host, :cyan) }, :inline, " and ")}"
|
69
|
-
puts
|
70
|
-
puts "To run a command on a list of servers, do:"
|
71
|
-
puts " on SERVER1 SERVER2 SERVER3; COMMAND"
|
72
|
-
puts " Example: on latte foamy; echo foobar"
|
73
|
-
puts
|
74
|
-
puts "To exit interactive mode, use 'quit!'"
|
75
|
-
puts
|
76
|
-
while 1
|
77
|
-
command = read_line
|
78
|
-
case command
|
79
|
-
when 'quit!'
|
80
|
-
puts 'Bye!'
|
81
|
-
break
|
82
|
-
when /^on (.+?); (.+)$/
|
83
|
-
raw_list = $1.split(" ")
|
84
|
-
server_list = Array.new
|
85
|
-
@winrm_sessions.each do |session_server|
|
86
|
-
server_list << session_server if raw_list.include?(session_server.host)
|
87
|
-
end
|
88
|
-
command = $2
|
89
|
-
relay_winrm_command(command, server_list)
|
90
|
-
else
|
91
|
-
relay_winrm_command(command)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Present the prompt and read a single line from the console. It also
|
97
|
-
# detects ^D and returns "exit" in that case. Adds the input to the
|
98
|
-
# history, unless the input is empty. Loops repeatedly until a non-empty
|
99
|
-
# line is input.
|
100
|
-
def read_line
|
101
|
-
loop do
|
102
|
-
command = reader.readline("#{ui.color('knife-winrm>', :bold)} ", true)
|
103
|
-
|
104
|
-
if command.nil?
|
105
|
-
command = "exit"
|
106
|
-
puts(command)
|
107
|
-
else
|
108
|
-
command.strip!
|
109
|
-
end
|
110
|
-
|
111
|
-
unless command.empty?
|
112
|
-
return command
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def reader
|
118
|
-
Readline
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
1
|
+
#
|
2
|
+
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
+
# Copyright:: Copyright (c) 2011-2016 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 'chef/knife'
|
20
|
+
require 'chef/knife/winrm_knife_base'
|
21
|
+
require 'chef/knife/windows_cert_generate'
|
22
|
+
require 'chef/knife/windows_cert_install'
|
23
|
+
require 'chef/knife/windows_listener_create'
|
24
|
+
require 'chef/knife/winrm_session'
|
25
|
+
require 'chef/knife/knife_windows_base'
|
26
|
+
|
27
|
+
class Chef
|
28
|
+
class Knife
|
29
|
+
class Winrm < Knife
|
30
|
+
|
31
|
+
include Chef::Knife::WinrmCommandSharedFunctions
|
32
|
+
include Chef::Knife::KnifeWindowsBase
|
33
|
+
|
34
|
+
deps do
|
35
|
+
require 'readline'
|
36
|
+
require 'chef/search/query'
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_writer :password
|
40
|
+
|
41
|
+
banner "knife winrm QUERY COMMAND (options)"
|
42
|
+
|
43
|
+
option :returns,
|
44
|
+
:long => "--returns CODES",
|
45
|
+
:description => "A comma delimited list of return codes which indicate success",
|
46
|
+
:default => "0"
|
47
|
+
|
48
|
+
def run
|
49
|
+
STDOUT.sync = STDERR.sync = true
|
50
|
+
|
51
|
+
configure_session
|
52
|
+
execute_remote_command
|
53
|
+
end
|
54
|
+
|
55
|
+
def execute_remote_command
|
56
|
+
case @name_args[1]
|
57
|
+
when "interactive"
|
58
|
+
interactive
|
59
|
+
else
|
60
|
+
run_command(@name_args[1..-1].join(" "))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def interactive
|
67
|
+
puts "WARN: Deprecated functionality. This will not be supported in future knife-windows releases."
|
68
|
+
puts "Connected to #{ui.list(session.servers.collect { |s| ui.color(s.host, :cyan) }, :inline, " and ")}"
|
69
|
+
puts
|
70
|
+
puts "To run a command on a list of servers, do:"
|
71
|
+
puts " on SERVER1 SERVER2 SERVER3; COMMAND"
|
72
|
+
puts " Example: on latte foamy; echo foobar"
|
73
|
+
puts
|
74
|
+
puts "To exit interactive mode, use 'quit!'"
|
75
|
+
puts
|
76
|
+
while 1
|
77
|
+
command = read_line
|
78
|
+
case command
|
79
|
+
when 'quit!'
|
80
|
+
puts 'Bye!'
|
81
|
+
break
|
82
|
+
when /^on (.+?); (.+)$/
|
83
|
+
raw_list = $1.split(" ")
|
84
|
+
server_list = Array.new
|
85
|
+
@winrm_sessions.each do |session_server|
|
86
|
+
server_list << session_server if raw_list.include?(session_server.host)
|
87
|
+
end
|
88
|
+
command = $2
|
89
|
+
relay_winrm_command(command, server_list)
|
90
|
+
else
|
91
|
+
relay_winrm_command(command)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Present the prompt and read a single line from the console. It also
|
97
|
+
# detects ^D and returns "exit" in that case. Adds the input to the
|
98
|
+
# history, unless the input is empty. Loops repeatedly until a non-empty
|
99
|
+
# line is input.
|
100
|
+
def read_line
|
101
|
+
loop do
|
102
|
+
command = reader.readline("#{ui.color('knife-winrm>', :bold)} ", true)
|
103
|
+
|
104
|
+
if command.nil?
|
105
|
+
command = "exit"
|
106
|
+
puts(command)
|
107
|
+
else
|
108
|
+
command.strip!
|
109
|
+
end
|
110
|
+
|
111
|
+
unless command.empty?
|
112
|
+
return command
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def reader
|
118
|
+
Readline
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|