knife-windows 0.0.2 → 0.5.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.
- data/README.rdoc +1 -7
- data/knife-windows.gemspec +3 -3
- data/lib/chef/knife/bootstrap/windows-shell.erb +9 -0
- data/lib/chef/knife/winrm.rb +34 -42
- data/lib/chef/knife/winrm_bootstrap.rb +51 -28
- data/lib/knife-windows/version.rb +1 -1
- metadata +6 -6
data/README.rdoc
CHANGED
@@ -63,13 +63,7 @@ This is the default bootstrap template used by the +winrm+ +bootstrap+ subcomman
|
|
63
63
|
|
64
64
|
== Chef Version
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
cd YOUR_CHEF_REPO
|
69
|
-
curl https://gist.github.com/raw/f33e15bac2820dd572d4/cb6ab81023440235868e83b96fa0ae527d37e2d7/knife >> knife
|
70
|
-
chmod 744 knife
|
71
|
-
|
72
|
-
More details about Knife plugins can be {found on the Chef wiki}[http://wiki.opscode.com/display/chef/Knife+Plugins].
|
66
|
+
Knife plugins require >= Chef 0.10. More details about Knife plugins can be {found on the Chef wiki}[http://wiki.opscode.com/display/chef/Knife+Plugins].
|
73
67
|
|
74
68
|
== Nodes
|
75
69
|
|
data/knife-windows.gemspec
CHANGED
@@ -14,9 +14,9 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.summary = %q{Plugin that adds functionality to Chef's Knife CLI for configuring/interacting with nodes running Microsoft Windows}
|
15
15
|
s.description = s.summary
|
16
16
|
|
17
|
-
s.required_ruby_version =
|
18
|
-
s.add_dependency "chef", ">= 0.
|
19
|
-
s.add_dependency "em-winrm", "
|
17
|
+
s.required_ruby_version = ">= 1.9.1"
|
18
|
+
s.add_dependency "chef", ">= 0.10.0.beta.5"
|
19
|
+
s.add_dependency "em-winrm", "= 0.0.4"
|
20
20
|
|
21
21
|
s.files = `git ls-files`.split("\n")
|
22
22
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -42,6 +42,15 @@ mkdir C:\chef
|
|
42
42
|
|
43
43
|
cscript /nologo C:\chef\wget.vbs http://files.rubyforge.vm.bytemark.co.uk/rubyinstaller/rubyinstaller-1.8.7-p334.exe %TEMP%\rubyinstaller.exe
|
44
44
|
%TEMP%\rubyinstaller.exe /verysilent /dir="C:\ruby" /tasks="assocfiles,modpath"
|
45
|
+
|
46
|
+
@rem Install the Ruby Dev Kit so we compile us some native gems
|
47
|
+
cscript /nologo C:\chef\wget.vbs http://cloud.github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.1-20101214-1400-sfx.exe %TEMP%\rubydevkit.exe
|
48
|
+
mkdir C:\DevKit
|
49
|
+
copy %TEMP%\rubydevkit.exe C:\DevKit
|
50
|
+
cmd.exe /C C:\DevKit\rubydevkit.exe -y
|
51
|
+
cmd.exe /C C:\ruby\bin\ruby c:/DevKit/dk.rb init
|
52
|
+
cmd.exe /C C:\ruby\bin\ruby c:/DevKit/dk.rb install
|
53
|
+
|
45
54
|
cmd.exe /C C:\ruby\bin\gem install win32-open3 ruby-wmi windows-api windows-pr --no-rdoc --no-ri --verbose
|
46
55
|
|
47
56
|
@rem Install Chef gems separately to prevent 'failed to allocate memory' errors
|
data/lib/chef/knife/winrm.rb
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -17,17 +17,16 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
|
-
require 'chef/data_bag_item'
|
21
|
-
|
22
|
-
begin
|
23
|
-
gem "em-winrm"
|
24
|
-
rescue LoadError
|
25
|
-
end
|
26
20
|
|
27
21
|
class Chef
|
28
22
|
class Knife
|
29
23
|
class Winrm < Knife
|
30
24
|
|
25
|
+
deps do
|
26
|
+
require 'readline'
|
27
|
+
require 'chef/search/query'
|
28
|
+
end
|
29
|
+
|
31
30
|
attr_writer :password
|
32
31
|
|
33
32
|
banner "knife winrm QUERY COMMAND (options)"
|
@@ -36,7 +35,7 @@ class Chef
|
|
36
35
|
:short => "-a ATTR",
|
37
36
|
:long => "--attribute ATTR",
|
38
37
|
:description => "The attribute to use for opening the connection - default is fqdn",
|
39
|
-
:default => "fqdn"
|
38
|
+
:default => "fqdn"
|
40
39
|
|
41
40
|
option :manual,
|
42
41
|
:short => "-m",
|
@@ -48,18 +47,21 @@ class Chef
|
|
48
47
|
option :winrm_user,
|
49
48
|
:short => "-x USERNAME",
|
50
49
|
:long => "--winrm-user USERNAME",
|
51
|
-
:description => "The WinRM username"
|
50
|
+
:description => "The WinRM username",
|
51
|
+
:default => "Administrator",
|
52
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_user] = key }
|
52
53
|
|
53
54
|
option :winrm_password,
|
54
55
|
:short => "-P PASSWORD",
|
55
56
|
:long => "--winrm-password PASSWORD",
|
56
|
-
:description => "The WinRM password"
|
57
|
+
:description => "The WinRM password",
|
58
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_password] = key }
|
57
59
|
|
58
60
|
option :winrm_port,
|
59
61
|
:short => "-p PORT",
|
60
62
|
:long => "--winrm-port PORT",
|
61
63
|
:description => "The WinRM port",
|
62
|
-
:default => "
|
64
|
+
:default => "5985",
|
63
65
|
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_port] = key }
|
64
66
|
|
65
67
|
option :winrm_transport,
|
@@ -100,6 +102,7 @@ class Chef
|
|
100
102
|
:proc => Proc.new { |trust| Chef::Config[:knife][:ca_trust_file] = trust }
|
101
103
|
|
102
104
|
def session
|
105
|
+
require 'em-winrm'
|
103
106
|
session_opts = {}
|
104
107
|
session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
|
105
108
|
@session ||= begin
|
@@ -119,10 +122,6 @@ class Chef
|
|
119
122
|
|
120
123
|
end
|
121
124
|
|
122
|
-
def h
|
123
|
-
@highline ||= HighLine.new
|
124
|
-
end
|
125
|
-
|
126
125
|
def configure_session
|
127
126
|
list = case config[:manual]
|
128
127
|
when true
|
@@ -137,27 +136,28 @@ class Chef
|
|
137
136
|
end
|
138
137
|
r
|
139
138
|
end
|
140
|
-
(
|
139
|
+
(ui.fatal("No nodes returned from search!"); exit 10) if list.length == 0
|
141
140
|
session_from_list(list)
|
142
141
|
end
|
143
142
|
|
144
143
|
def session_from_list(list)
|
145
144
|
list.each do |item|
|
146
145
|
Chef::Log.debug("Adding #{item}")
|
147
|
-
|
148
146
|
session_opts = {}
|
149
|
-
session_opts[:user] =
|
150
|
-
session_opts[:password] =
|
151
|
-
session_opts[:port] = config[:winrm_port]
|
152
|
-
session_opts[:keytab] =
|
153
|
-
session_opts[:realm] =
|
154
|
-
session_opts[:service] =
|
155
|
-
session_opts[:ca_trust_path] =
|
156
|
-
|
147
|
+
session_opts[:user] = Chef::Config[:knife][:winrm_user] || config[:winrm_user]
|
148
|
+
session_opts[:password] = Chef::Config[:knife][:winrm_password] if config[:winrm_password]
|
149
|
+
session_opts[:port] = Chef::Config[:knife][:winrm_port] || config[:winrm_port]
|
150
|
+
session_opts[:keytab] = Chef::Config[:knife][:kerberos_keytab_file] if Chef::Config[:knife][:kerberos_keytab_file]
|
151
|
+
session_opts[:realm] = Chef::Config[:knife][:kerberos_realm] if Chef::Config[:knife][:kerberos_realm]
|
152
|
+
session_opts[:service] = Chef::Config[:knife][:kerberos_service] if Chef::Config[:knife][:kerberos_service]
|
153
|
+
session_opts[:ca_trust_path] = Chef::Config[:knife][:ca_trust_file] if Chef::Config[:knife][:ca_trust_file]
|
154
|
+
|
157
155
|
if config.keys.any? {|k| k.to_s =~ /kerberos/ }
|
158
156
|
session_opts[:transport] = :kerberos
|
157
|
+
session_opts[:basic_auth_only] = false
|
159
158
|
else
|
160
|
-
session_opts[:transport] = config[:winrm_transport].to_sym
|
159
|
+
session_opts[:transport] = (Chef::Config[:knife][:winrm_transport] || config[:winrm_transport]).to_sym
|
160
|
+
session_opts[:basic_auth_only] = true
|
161
161
|
end
|
162
162
|
|
163
163
|
session.use(item, session_opts)
|
@@ -172,7 +172,7 @@ class Chef
|
|
172
172
|
data.split(/\n/).each { |d| print_data(host, d, color) }
|
173
173
|
else
|
174
174
|
padding = @longest - host.length
|
175
|
-
print
|
175
|
+
print ui.color(host, color)
|
176
176
|
padding.downto(0) { print " " }
|
177
177
|
puts data.chomp
|
178
178
|
end
|
@@ -184,7 +184,7 @@ class Chef
|
|
184
184
|
end
|
185
185
|
|
186
186
|
def get_password
|
187
|
-
@password ||=
|
187
|
+
@password ||= ui.ask("Enter your password: ") { |q| q.echo = false }
|
188
188
|
end
|
189
189
|
|
190
190
|
# Present the prompt and read a single line from the console. It also
|
@@ -193,7 +193,7 @@ class Chef
|
|
193
193
|
# line is input.
|
194
194
|
def read_line
|
195
195
|
loop do
|
196
|
-
command = reader.readline("#{
|
196
|
+
command = reader.readline("#{ui.color('knife-winrm>', :bold)} ", true)
|
197
197
|
|
198
198
|
if command.nil?
|
199
199
|
command = "exit"
|
@@ -213,7 +213,7 @@ class Chef
|
|
213
213
|
end
|
214
214
|
|
215
215
|
def interactive
|
216
|
-
puts "Connected to #{
|
216
|
+
puts "Connected to #{ui.list(session.servers.collect { |s| ui.color(s.host, :cyan) }, :inline, " and ")}"
|
217
217
|
puts
|
218
218
|
puts "To run a command on a list of servers, do:"
|
219
219
|
puts " on SERVER1 SERVER2 SERVER3; COMMAND"
|
@@ -232,7 +232,7 @@ class Chef
|
|
232
232
|
raw_list = $1.split(" ")
|
233
233
|
server_list = Array.new
|
234
234
|
session.servers.each do |session_server|
|
235
|
-
server_list << session_server if raw_list.include?(session_server.host)
|
235
|
+
server_list << session_server if raw_list.include?(session_server.host)
|
236
236
|
end
|
237
237
|
command = $2
|
238
238
|
winrm_command(command, session.on(*server_list))
|
@@ -242,28 +242,20 @@ class Chef
|
|
242
242
|
end
|
243
243
|
end
|
244
244
|
|
245
|
-
def run
|
245
|
+
def run
|
246
246
|
@longest = 0
|
247
|
-
load_late_dependencies
|
248
247
|
|
249
248
|
configure_session
|
250
249
|
|
251
250
|
case @name_args[1]
|
252
251
|
when "interactive"
|
253
|
-
interactive
|
252
|
+
interactive
|
254
253
|
else
|
255
254
|
winrm_command(@name_args[1..-1].join(" "))
|
256
255
|
session.close
|
257
256
|
end
|
258
257
|
end
|
259
258
|
|
260
|
-
def load_late_dependencies
|
261
|
-
require 'readline'
|
262
|
-
%w[em-winrm highline].each do |dep|
|
263
|
-
load_late_dependency dep
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
259
|
end
|
268
260
|
end
|
269
261
|
end
|
@@ -6,9 +6,9 @@
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -16,29 +16,38 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'chef/knife
|
19
|
+
require 'chef/knife'
|
20
20
|
|
21
21
|
class Chef
|
22
22
|
class Knife
|
23
|
-
class WinrmBootstrap <
|
23
|
+
class WinrmBootstrap < Knife
|
24
|
+
|
25
|
+
deps do
|
26
|
+
require 'chef/json_compat'
|
27
|
+
require 'tempfile'
|
28
|
+
require 'erubis'
|
29
|
+
end
|
24
30
|
|
25
31
|
banner "knife winrm bootstrap FQDN [RUN LIST...] (options)"
|
26
32
|
|
27
33
|
option :winrm_user,
|
28
34
|
:short => "-x USERNAME",
|
29
35
|
:long => "--winrm-user USERNAME",
|
30
|
-
:description => "The WinRM username"
|
36
|
+
:description => "The WinRM username",
|
37
|
+
:default => "Administrator",
|
38
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_user] = key }
|
31
39
|
|
32
40
|
option :winrm_password,
|
33
41
|
:short => "-P PASSWORD",
|
34
42
|
:long => "--winrm-password PASSWORD",
|
35
|
-
:description => "The WinRM password"
|
43
|
+
:description => "The WinRM password",
|
44
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_password] = key }
|
36
45
|
|
37
46
|
option :winrm_port,
|
38
47
|
:short => "-p PORT",
|
39
48
|
:long => "--winrm-port PORT",
|
40
49
|
:description => "The WinRM port",
|
41
|
-
:default => "
|
50
|
+
:default => "5985",
|
42
51
|
:proc => Proc.new { |key| Chef::Config[:knife][:winrm_port] = key }
|
43
52
|
|
44
53
|
option :winrm_transport,
|
@@ -108,7 +117,7 @@ class Chef
|
|
108
117
|
bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
|
109
118
|
bootstrap_files << File.join(Dir.pwd, ".chef", "bootstrap", "#{config[:distro]}.erb")
|
110
119
|
bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{config[:distro]}.erb")
|
111
|
-
bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
|
120
|
+
bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
|
112
121
|
end
|
113
122
|
|
114
123
|
template = Array(bootstrap_files).find do |bootstrap_template|
|
@@ -117,26 +126,33 @@ class Chef
|
|
117
126
|
end
|
118
127
|
|
119
128
|
unless template
|
120
|
-
|
129
|
+
ui.info("Can not find bootstrap definition for #{config[:distro]}")
|
121
130
|
raise Errno::ENOENT
|
122
131
|
end
|
123
132
|
|
124
133
|
Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
|
125
|
-
|
134
|
+
|
126
135
|
IO.read(template).chomp
|
127
136
|
end
|
128
137
|
|
129
|
-
def
|
130
|
-
|
138
|
+
def render_template(template=nil)
|
139
|
+
context = {}
|
140
|
+
context[:run_list] = config[:run_list]
|
141
|
+
context[:config] = config
|
142
|
+
Erubis::Eruby.new(template).evaluate(context)
|
143
|
+
end
|
131
144
|
|
132
|
-
|
145
|
+
def run
|
133
146
|
|
134
|
-
|
147
|
+
validate_name_args!
|
135
148
|
|
136
|
-
|
149
|
+
@node_name = Array(@name_args).first
|
150
|
+
# back compat--templates may use this setting:
|
151
|
+
config[:server_name] = @node_name
|
137
152
|
|
138
|
-
|
153
|
+
$stdout.sync = true
|
139
154
|
|
155
|
+
ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
|
140
156
|
# create a bootstrap.bat file on the node
|
141
157
|
# we have to run the remote commands in 2047 char chunks
|
142
158
|
create_bootstrap_bat_command do |command_chunk, chunk_num|
|
@@ -147,17 +163,29 @@ class Chef
|
|
147
163
|
knife_winrm(bootstrap_command).run
|
148
164
|
end
|
149
165
|
|
166
|
+
def validate_name_args!
|
167
|
+
if Array(@name_args).first.nil?
|
168
|
+
ui.error("Must pass an FQDN or ip to bootstrap")
|
169
|
+
exit 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def server_name
|
174
|
+
Array(@name_args).first
|
175
|
+
end
|
176
|
+
|
150
177
|
def knife_winrm(command = '')
|
151
178
|
winrm = Chef::Knife::Winrm.new
|
152
179
|
winrm.name_args = [ server_name, command ]
|
153
|
-
winrm.config[:winrm_user] = config[:winrm_user]
|
154
|
-
winrm.config[:winrm_password] = config[:winrm_password]
|
155
|
-
winrm.config[:winrm_transport] = config[:winrm_transport]
|
156
|
-
winrm.config[:kerberos_keytab_file] =
|
157
|
-
winrm.config[:kerberos_realm] =
|
158
|
-
winrm.config[:kerberos_service] =
|
159
|
-
winrm.config[:ca_trust_file] =
|
180
|
+
winrm.config[:winrm_user] = Chef::Config[:knife][:winrm_user] || config[:winrm_user]
|
181
|
+
winrm.config[:winrm_password] = Chef::Config[:knife][:winrm_password] if config[:winrm_password]
|
182
|
+
winrm.config[:winrm_transport] = Chef::Config[:knife][:winrm_transport] || config[:winrm_transport]
|
183
|
+
winrm.config[:kerberos_keytab_file] = Chef::Config[:knife][:kerberos_keytab_file] if Chef::Config[:knife][:kerberos_keytab_file]
|
184
|
+
winrm.config[:kerberos_realm] = Chef::Config[:knife][:kerberos_realm] if Chef::Config[:knife][:kerberos_realm]
|
185
|
+
winrm.config[:kerberos_service] = Chef::Config[:knife][:kerberos_service] if Chef::Config[:knife][:kerberos_service]
|
186
|
+
winrm.config[:ca_trust_file] = Chef::Config[:knife][:ca_trust_file] if Chef::Config[:knife][:ca_trust_file]
|
160
187
|
winrm.config[:manual] = true
|
188
|
+
winrm.config[:winrm_port] = Chef::Config[:knife][:winrm_port]
|
161
189
|
winrm
|
162
190
|
end
|
163
191
|
|
@@ -184,11 +212,6 @@ class Chef
|
|
184
212
|
def bootstrap_bat_file
|
185
213
|
"%TEMP%\\bootstrap.bat"
|
186
214
|
end
|
187
|
-
|
188
|
-
def load_late_dependencies
|
189
|
-
super
|
190
|
-
require 'chef/knife/winrm'
|
191
|
-
end
|
192
215
|
end
|
193
216
|
end
|
194
217
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: knife-windows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0
|
5
|
+
version: 0.5.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Seth Chisamore
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-31 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ">="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.
|
24
|
+
version: 0.10.0.beta.5
|
25
25
|
type: :runtime
|
26
26
|
version_requirements: *id001
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -30,9 +30,9 @@ dependencies:
|
|
30
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
|
-
- - "
|
33
|
+
- - "="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 0.0.
|
35
|
+
version: 0.0.4
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id002
|
38
38
|
description: Plugin that adds functionality to Chef's Knife CLI for configuring/interacting with nodes running Microsoft Windows
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
requirements: []
|
81
81
|
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.
|
83
|
+
rubygems_version: 1.6.2
|
84
84
|
signing_key:
|
85
85
|
specification_version: 3
|
86
86
|
summary: Plugin that adds functionality to Chef's Knife CLI for configuring/interacting with nodes running Microsoft Windows
|