knife-windows 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,9 @@
1
+ Release Notes - Knife Windows Plugin - Version 0.5.4
2
+
3
+ ** Bug
4
+ * [KNIFE_WINDOWS-7] - Exception: NoMethodError: undefined method `env_namespace' for Savon:Module
5
+ * [KNIFE_WINDOWS-8] - winrm based bootstrap fails with 'Bad HTTP response returned from server (500)'
6
+
7
+
8
+ ** New Feature
9
+ * [KNIFE_WINDOWS-6] - default bootstrap template should support encrypted_data_bag_secret
data/README.rdoc CHANGED
@@ -90,6 +90,10 @@ The Chef and Ohai gem installations (that occur during bootstrap) take more memo
90
90
 
91
91
  C:\Users\Administrator> winrm set winrm/config/winrs @{MaxMemoryPerShellMB="300"}
92
92
 
93
+ Bootstrap commands can take longer than the WinRM default 60 seconds to complete, bump to 30 minutes:
94
+
95
+ C:\Users\Administrator> winrm set winrm/config @{MaxTimeoutms="1800000"}
96
+
93
97
  WinRM supports both the HTTP and HTTPS transports and the following authentication schemes: Kerberos, Digest, Certificate and Basic. The details of these authentication transports are outside of the scope of this README but details can be found on the {WinRM configuration guide}[http://msdn.microsoft.com/en-us/library/aa384372(v=vs.85).aspx]. Currently, this plugin support Kerberos and Basic authentication schemes.
94
98
 
95
99
  For development and testing purposes, unencrypted traffic with Basic authentication can make things easier:
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.description = s.summary
16
16
 
17
17
  s.required_ruby_version = ">= 1.9.1"
18
- s.add_dependency "em-winrm", "= 0.0.5"
18
+ s.add_dependency "em-winrm", "= 0.5.2"
19
19
 
20
20
  s.files = `git ls-files`.split("\n")
21
21
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -44,6 +44,12 @@ cmd.exe /C C:\ruby\bin\gem install chef --no-rdoc --no-ri --verbose <%= bootstra
44
44
  <%= validation_key %>
45
45
  )
46
46
 
47
+ <% if @config[:encrypted_data_bag_secret] -%>
48
+ > C:\chef\encrypted_data_bag_secret (
49
+ <%= encrypted_data_bag_secret %>
50
+ )
51
+ <% end -%>
52
+
47
53
  > C:\chef\client.rb (
48
54
  echo.require 'win32ole'
49
55
  echo.WIN32OLE.codepage = WIN32OLE::CP_UTF8
@@ -0,0 +1,175 @@
1
+ #
2
+ # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
+ # Copyright:: Copyright (c) 2011 Opscode, 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/encrypted_data_bag_item'
21
+
22
+ class Chef
23
+ class Knife
24
+ module BootstrapWindowsBase
25
+
26
+ # :nodoc:
27
+ # Would prefer to do this in a rational way, but can't be done b/c of
28
+ # Mixlib::CLI's design :(
29
+ def self.included(includer)
30
+ includer.class_eval do
31
+
32
+ deps do
33
+ require 'readline'
34
+ require 'chef/json_compat'
35
+ end
36
+
37
+ option :chef_node_name,
38
+ :short => "-N NAME",
39
+ :long => "--node-name NAME",
40
+ :description => "The Chef node name for your new node"
41
+
42
+ option :prerelease,
43
+ :long => "--prerelease",
44
+ :description => "Install the pre-release chef gems"
45
+
46
+ option :bootstrap_version,
47
+ :long => "--bootstrap-version VERSION",
48
+ :description => "The version of Chef to install",
49
+ :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
50
+
51
+ option :bootstrap_proxy,
52
+ :long => "--bootstrap-proxy PROXY_URL",
53
+ :description => "The proxy server for the node being bootstrapped",
54
+ :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
55
+
56
+ option :distro,
57
+ :short => "-d DISTRO",
58
+ :long => "--distro DISTRO",
59
+ :description => "Bootstrap a distro using a template",
60
+ :default => "windows-shell"
61
+
62
+ option :template_file,
63
+ :long => "--template-file TEMPLATE",
64
+ :description => "Full path to location of template to use",
65
+ :default => false
66
+
67
+ option :run_list,
68
+ :short => "-r RUN_LIST",
69
+ :long => "--run-list RUN_LIST",
70
+ :description => "Comma separated list of roles/recipes to apply",
71
+ :proc => lambda { |o| o.split(",") },
72
+ :default => []
73
+
74
+ option :encrypted_data_bag_secret,
75
+ :short => "-s SECRET",
76
+ :long => "--secret ",
77
+ :description => "The secret key to use to decrypt data bag item values. Will be rendered on the node at c:/chef/encrypted_data_bag_secret and set in the rendered client config.",
78
+ :default => false
79
+
80
+ option :encrypted_data_bag_secret_file,
81
+ :long => "--secret-file SECRET_FILE",
82
+ :description => "A file containing the secret key to use to encrypt data bag item values. Will be rendered on the node at c:/chef/encrypted_data_bag_secret and set in the rendered client config."
83
+
84
+ end
85
+ end
86
+
87
+ # TODO: This should go away when CHEF-2193 is fixed
88
+ def load_template(template=nil)
89
+ # Are we bootstrapping using an already shipped template?
90
+ if config[:template_file]
91
+ bootstrap_files = config[:template_file]
92
+ else
93
+ bootstrap_files = []
94
+ bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
95
+ bootstrap_files << File.join(Dir.pwd, ".chef", "bootstrap", "#{config[:distro]}.erb")
96
+ bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{config[:distro]}.erb")
97
+ bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
98
+ bootstrap_files.flatten!
99
+ end
100
+
101
+ template = Array(bootstrap_files).find do |bootstrap_template|
102
+ Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
103
+ ::File.exists?(bootstrap_template)
104
+ end
105
+
106
+ unless template
107
+ ui.info("Can not find bootstrap definition for #{config[:distro]}")
108
+ raise Errno::ENOENT
109
+ end
110
+
111
+ Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
112
+
113
+ IO.read(template).chomp
114
+ end
115
+
116
+ def render_template(template=nil)
117
+ if config[:encrypted_data_bag_secret_file]
118
+ config[:encrypted_data_bag_secret] = Chef::EncryptedDataBagItem.load_secret(config[:encrypted_data_bag_secret_file])
119
+ end
120
+ context = Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config)
121
+ Erubis::Eruby.new(template).evaluate(context)
122
+ end
123
+
124
+ def bootstrap(proto=nil)
125
+
126
+ validate_name_args!
127
+
128
+ @node_name = Array(@name_args).first
129
+ # back compat--templates may use this setting:
130
+ config[:server_name] = @node_name
131
+
132
+ STDOUT.sync = STDERR.sync = true
133
+
134
+ ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
135
+ # create a bootstrap.bat file on the node
136
+ # we have to run the remote commands in 2047 char chunks
137
+ create_bootstrap_bat_command do |command_chunk, chunk_num|
138
+ run_command("cmd.exe /C echo \"Rendering bootstrap.bat chunk #{chunk_num}\" && #{command_chunk}").run
139
+ end
140
+
141
+ # execute the bootstrap.bat file
142
+ run_command(bootstrap_command).run
143
+ end
144
+
145
+ def bootstrap_command
146
+ @bootstrap_command ||= "cmd.exe /C #{bootstrap_bat_file}"
147
+ end
148
+
149
+ def create_bootstrap_bat_command(&block)
150
+ bootstrap_bat = []
151
+ chunk_num = 0
152
+ render_template(load_template(config[:bootstrap_template])).each_line do |line|
153
+ # escape WIN BATCH special chars
154
+ line.gsub!(/[(<|>)^]/).each{|m| "^#{m}"}
155
+ # windows commands are limited to 2047 characters
156
+ if((bootstrap_bat + [line]).join(" && ").size > 2047 )
157
+ yield bootstrap_bat.join(" && "), chunk_num += 1
158
+ bootstrap_bat = []
159
+ end
160
+ bootstrap_bat << ">> #{bootstrap_bat_file} (echo.#{line.chomp.strip})"
161
+ end
162
+ yield bootstrap_bat.join(" && "), chunk_num += 1
163
+ end
164
+
165
+ def bootstrap_bat_file
166
+ "%TEMP%\\bootstrap.bat"
167
+ end
168
+
169
+ def locate_config_value(key)
170
+ key = key.to_sym
171
+ Chef::Config[:knife][key] || config[key]
172
+ end
173
+ end
174
+ end
175
+ end
@@ -16,13 +16,13 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require File.join(File.dirname(__FILE__), 'mixin/windows/bootstrap')
19
+ require 'chef/knife/bootstrap_windows_base'
20
20
 
21
21
  class Chef
22
22
  class Knife
23
23
  class BootstrapWindowsSsh < Bootstrap
24
24
 
25
- include Chef::Mixin::Bootstrap
25
+ include Chef::Knife::BootstrapWindowsBase
26
26
 
27
27
  deps do
28
28
  require 'chef/knife/core/windows_bootstrap_context'
@@ -59,43 +59,6 @@ class Chef
59
59
  :long => "--identity-file IDENTITY_FILE",
60
60
  :description => "The SSH identity file used for authentication"
61
61
 
62
- option :chef_node_name,
63
- :short => "-N NAME",
64
- :long => "--node-name NAME",
65
- :description => "The Chef node name for your new node"
66
-
67
- option :prerelease,
68
- :long => "--prerelease",
69
- :description => "Install the pre-release chef gems"
70
-
71
- option :bootstrap_version,
72
- :long => "--bootstrap-version VERSION",
73
- :description => "The version of Chef to install",
74
- :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
75
-
76
- option :bootstrap_proxy,
77
- :long => "--bootstrap-proxy PROXY_URL",
78
- :description => "The proxy server for the node being bootstrapped",
79
- :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
80
-
81
- option :distro,
82
- :short => "-d DISTRO",
83
- :long => "--distro DISTRO",
84
- :description => "Bootstrap a distro using a template",
85
- :default => "windows-shell"
86
-
87
- option :template_file,
88
- :long => "--template-file TEMPLATE",
89
- :description => "Full path to location of template to use",
90
- :default => false
91
-
92
- option :run_list,
93
- :short => "-r RUN_LIST",
94
- :long => "--run-list RUN_LIST",
95
- :description => "Comma separated list of roles/recipes to apply",
96
- :proc => lambda { |o| o.split(",") },
97
- :default => []
98
-
99
62
  option :no_host_key_verify,
100
63
  :long => "--no-host-key-verify",
101
64
  :description => "Disable host key verification",
@@ -16,13 +16,15 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require File.join(File.dirname(__FILE__), 'mixin/windows/bootstrap')
19
+ require 'chef/knife/bootstrap_windows_base'
20
+ require 'chef/knife/winrm_base'
20
21
 
21
22
  class Chef
22
23
  class Knife
23
24
  class BootstrapWindowsWinrm < Bootstrap
24
25
 
25
- include Chef::Mixin::Bootstrap
26
+ include Chef::Knife::BootstrapWindowsBase
27
+ include Chef::Knife::WinrmBase
26
28
 
27
29
  deps do
28
30
  require 'chef/knife/core/windows_bootstrap_context'
@@ -33,99 +35,6 @@ class Chef
33
35
 
34
36
  banner "knife bootstrap windows winrm FQDN (options)"
35
37
 
36
- option :winrm_user,
37
- :short => "-x USERNAME",
38
- :long => "--winrm-user USERNAME",
39
- :description => "The WinRM username",
40
- :default => "Administrator",
41
- :proc => Proc.new { |key| Chef::Config[:knife][:winrm_user] = key }
42
-
43
- option :winrm_password,
44
- :short => "-P PASSWORD",
45
- :long => "--winrm-password PASSWORD",
46
- :description => "The WinRM password",
47
- :proc => Proc.new { |key| Chef::Config[:knife][:winrm_password] = key }
48
-
49
- option :winrm_port,
50
- :short => "-p PORT",
51
- :long => "--winrm-port PORT",
52
- :description => "The WinRM port, by default this is 5985",
53
- :default => "5985",
54
- :proc => Proc.new { |key| Chef::Config[:knife][:winrm_port] = key }
55
-
56
- option :identity_file,
57
- :short => "-i IDENTITY_FILE",
58
- :long => "--identity-file IDENTITY_FILE",
59
- :description => "The SSH identity file used for authentication"
60
-
61
- option :winrm_transport,
62
- :short => "-t TRANSPORT",
63
- :long => "--winrm-transport TRANSPORT",
64
- :description => "The WinRM transport type. valid choices are [ssl, plaintext]",
65
- :default => 'plaintext',
66
- :proc => Proc.new { |transport| Chef::Config[:knife][:winrm_transport] = transport }
67
-
68
- option :keytab_file,
69
- :short => "-i KEYTAB_FILE",
70
- :long => "--keytab-file KEYTAB_FILE",
71
- :description => "The Kerberos keytab file used for authentication",
72
- :proc => Proc.new { |keytab| Chef::Config[:knife][:keytab_file] = keytab }
73
-
74
- option :kerberos_realm,
75
- :short => "-R KERBEROS_REALM",
76
- :long => "--kerberos-realm KERBEROS_REALM",
77
- :description => "The Kerberos realm used for authentication",
78
- :proc => Proc.new { |realm| Chef::Config[:knife][:kerberos_realm] = realm }
79
-
80
- option :kerberos_service,
81
- :short => "-S KERBEROS_SERVICE",
82
- :long => "--kerberos-service KERBEROS_SERVICE",
83
- :description => "The Kerberos service used for authentication",
84
- :proc => Proc.new { |service| Chef::Config[:knife][:kerberos_service] = service }
85
-
86
- option :ca_trust_file,
87
- :short => "-f CA_TRUST_FILE",
88
- :long => "--ca-trust-file CA_TRUST_FILE",
89
- :description => "The Certificate Authority (CA) trust file used for SSL transport",
90
- :proc => Proc.new { |trust| Chef::Config[:knife][:ca_trust_file] = trust }
91
-
92
- option :chef_node_name,
93
- :short => "-N NAME",
94
- :long => "--node-name NAME",
95
- :description => "The Chef node name for your new node"
96
-
97
- option :prerelease,
98
- :long => "--prerelease",
99
- :description => "Install the pre-release chef gems"
100
-
101
- option :bootstrap_version,
102
- :long => "--bootstrap-version VERSION",
103
- :description => "The version of Chef to install",
104
- :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
105
-
106
- option :bootstrap_proxy,
107
- :long => "--bootstrap-proxy PROXY_URL",
108
- :description => "The proxy server for the node being bootstrapped",
109
- :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
110
-
111
- option :distro,
112
- :short => "-d DISTRO",
113
- :long => "--distro DISTRO",
114
- :description => "Bootstrap a distro using a template",
115
- :default => "windows-shell"
116
-
117
- option :template_file,
118
- :long => "--template-file TEMPLATE",
119
- :description => "Full path to location of template to use",
120
- :default => false
121
-
122
- option :run_list,
123
- :short => "-r RUN_LIST",
124
- :long => "--run-list RUN_LIST",
125
- :description => "Comma separated list of roles/recipes to apply",
126
- :proc => lambda { |o| o.split(",") },
127
- :default => []
128
-
129
38
  def run
130
39
  bootstrap
131
40
  end
@@ -40,6 +40,10 @@ class Chef
40
40
  escape_and_echo(super)
41
41
  end
42
42
 
43
+ def encrypted_data_bag_secret
44
+ escape_and_echo(@config[:encrypted_data_bag_secret])
45
+ end
46
+
43
47
  def config_content
44
48
  client_rb = <<-CONFIG
45
49
  log_level :info
@@ -60,13 +64,17 @@ CONFIG
60
64
  else
61
65
  client_rb << "# Using default node name (fqdn)\n"
62
66
  end
63
-
67
+
64
68
  if knife_config[:bootstrap_proxy]
65
69
  client_rb << "\n"
66
70
  client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
67
71
  client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
68
72
  end
69
-
73
+
74
+ if @config[:encrypted_data_bag_secret]
75
+ client_rb << %Q{encrypted_data_bag_secret "c:/chef/encrypted_data_bag_secret"\n}
76
+ end
77
+
70
78
  escape_and_echo(client_rb)
71
79
  end
72
80
 
@@ -17,14 +17,18 @@
17
17
  #
18
18
 
19
19
  require 'chef/knife'
20
+ require 'chef/knife/winrm_base'
20
21
 
21
22
  class Chef
22
23
  class Knife
23
24
  class Winrm < Knife
24
25
 
26
+ include Chef::Knife::WinrmBase
27
+
25
28
  deps do
26
29
  require 'readline'
27
30
  require 'chef/search/query'
31
+ require 'em-winrm'
28
32
  end
29
33
 
30
34
  attr_writer :password
@@ -44,65 +48,7 @@ class Chef
44
48
  :description => "QUERY is a space separated list of servers",
45
49
  :default => false
46
50
 
47
- option :winrm_user,
48
- :short => "-x USERNAME",
49
- :long => "--winrm-user USERNAME",
50
- :description => "The WinRM username",
51
- :default => "Administrator",
52
- :proc => Proc.new { |key| Chef::Config[:knife][:winrm_user] = key }
53
-
54
- option :winrm_password,
55
- :short => "-P PASSWORD",
56
- :long => "--winrm-password PASSWORD",
57
- :description => "The WinRM password",
58
- :proc => Proc.new { |key| Chef::Config[:knife][:winrm_password] = key }
59
-
60
- option :winrm_port,
61
- :short => "-p PORT",
62
- :long => "--winrm-port PORT",
63
- :description => "The WinRM port",
64
- :default => "5985",
65
- :proc => Proc.new { |key| Chef::Config[:knife][:winrm_port] = key }
66
-
67
- option :winrm_transport,
68
- :short => "-t TRANSPORT",
69
- :long => "--winrm-transport TRANSPORT",
70
- :description => "The WinRM transport type: ssl, or plaintext",
71
- :default => 'plaintext',
72
- :proc => Proc.new { |transport| Chef::Config[:knife][:winrm_transport] = transport }
73
-
74
- option :kerberos_keytab_file,
75
- :short => "-i KEYTAB_FILE",
76
- :long => "--keytab-file KEYTAB_FILE",
77
- :description => "The Kerberos keytab file used for authentication",
78
- :proc => Proc.new { |keytab| Chef::Config[:knife][:kerberos_keytab_file] = keytab }
79
-
80
- option :kerberos_realm,
81
- :short => "-R KERBEROS_REALM",
82
- :long => "--kerberos-realm KERBEROS_REALM",
83
- :description => "The Kerberos realm used for authentication",
84
- :proc => Proc.new { |realm| Chef::Config[:knife][:kerberos_realm] = realm }
85
-
86
- option :kerberos_service,
87
- :short => "-S KERBEROS_SERVICE",
88
- :long => "--kerberos-service KERBEROS_SERVICE",
89
- :description => "The Kerberos service used for authentication",
90
- :proc => Proc.new { |service| Chef::Config[:knife][:kerberos_service] = service }
91
-
92
- option :keytab_file,
93
- :short => "-i KEYTAB_FILE",
94
- :long => "--keytab-file KEYTAB_FILE",
95
- :description => "The Kerberos keytab file used for authentication",
96
- :proc => Proc.new { |keytab| Chef::Config[:knife][:keytab_file] = keytab }
97
-
98
- option :ca_trust_file,
99
- :short => "-f CA_TRUST_FILE",
100
- :long => "--ca-trust-file CA_TRUST_FILE",
101
- :description => "The Certificate Authority (CA) trust file used for SSL transport",
102
- :proc => Proc.new { |trust| Chef::Config[:knife][:ca_trust_file] = trust }
103
-
104
51
  def session
105
- require 'em-winrm'
106
52
  session_opts = {}
107
53
  session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
108
54
  @session ||= begin
@@ -151,6 +97,7 @@ class Chef
151
97
  session_opts[:realm] = Chef::Config[:knife][:kerberos_realm] if Chef::Config[:knife][:kerberos_realm]
152
98
  session_opts[:service] = Chef::Config[:knife][:kerberos_service] if Chef::Config[:knife][:kerberos_service]
153
99
  session_opts[:ca_trust_path] = Chef::Config[:knife][:ca_trust_file] if Chef::Config[:knife][:ca_trust_file]
100
+ session_opts[:operation_timeout] = 1800 # 30 min OperationTimeout for long bootstraps fix for KNIFE_WINDOWS-8
154
101
 
155
102
  if config.keys.any? {|k| k.to_s =~ /kerberos/ }
156
103
  session_opts[:transport] = :kerberos
@@ -243,16 +190,28 @@ class Chef
243
190
  end
244
191
 
245
192
  def run
246
- @longest = 0
193
+ STDOUT.sync = STDERR.sync = true
247
194
 
248
- configure_session
195
+ begin
196
+ @longest = 0
249
197
 
250
- case @name_args[1]
251
- when "interactive"
252
- interactive
253
- else
254
- winrm_command(@name_args[1..-1].join(" "))
255
- session.close
198
+ configure_session
199
+
200
+ case @name_args[1]
201
+ when "interactive"
202
+ interactive
203
+ else
204
+ winrm_command(@name_args[1..-1].join(" "))
205
+ session.close
206
+ end
207
+ rescue WinRM::WinRMHTTPTransportError => e
208
+ case e.message
209
+ when /401/
210
+ ui.error "Failed to authenticate to #{@name_args[0].split(" ")} as #{config[:winrm_user]}"
211
+ ui.info "Response: #{e.message}"
212
+ else
213
+ raise e
214
+ end
256
215
  end
257
216
  end
258
217
 
@@ -0,0 +1,98 @@
1
+ #
2
+ # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
+ # Copyright:: Copyright (c) 2011 Opscode, 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/encrypted_data_bag_item'
21
+
22
+ class Chef
23
+ class Knife
24
+ module WinrmBase
25
+
26
+ # :nodoc:
27
+ # Would prefer to do this in a rational way, but can't be done b/c of
28
+ # Mixlib::CLI's design :(
29
+ def self.included(includer)
30
+ includer.class_eval do
31
+
32
+ deps do
33
+ require 'readline'
34
+ require 'chef/json_compat'
35
+ end
36
+
37
+ option :winrm_user,
38
+ :short => "-x USERNAME",
39
+ :long => "--winrm-user USERNAME",
40
+ :description => "The WinRM username",
41
+ :default => "Administrator",
42
+ :proc => Proc.new { |key| Chef::Config[:knife][:winrm_user] = key }
43
+
44
+ option :winrm_password,
45
+ :short => "-P PASSWORD",
46
+ :long => "--winrm-password PASSWORD",
47
+ :description => "The WinRM password",
48
+ :proc => Proc.new { |key| Chef::Config[:knife][:winrm_password] = key }
49
+
50
+ option :winrm_port,
51
+ :short => "-p PORT",
52
+ :long => "--winrm-port PORT",
53
+ :description => "The WinRM port, by default this is 5985",
54
+ :default => "5985",
55
+ :proc => Proc.new { |key| Chef::Config[:knife][:winrm_port] = key }
56
+
57
+ option :identity_file,
58
+ :short => "-i IDENTITY_FILE",
59
+ :long => "--identity-file IDENTITY_FILE",
60
+ :description => "The SSH identity file used for authentication"
61
+
62
+ option :winrm_transport,
63
+ :short => "-t TRANSPORT",
64
+ :long => "--winrm-transport TRANSPORT",
65
+ :description => "The WinRM transport type. valid choices are [ssl, plaintext]",
66
+ :default => 'plaintext',
67
+ :proc => Proc.new { |transport| Chef::Config[:knife][:winrm_transport] = transport }
68
+
69
+ option :kerberos_keytab_file,
70
+ :short => "-i KEYTAB_FILE",
71
+ :long => "--keytab-file KEYTAB_FILE",
72
+ :description => "The Kerberos keytab file used for authentication",
73
+ :proc => Proc.new { |keytab| Chef::Config[:knife][:kerberos_keytab_file] = keytab }
74
+
75
+ option :kerberos_realm,
76
+ :short => "-R KERBEROS_REALM",
77
+ :long => "--kerberos-realm KERBEROS_REALM",
78
+ :description => "The Kerberos realm used for authentication",
79
+ :proc => Proc.new { |realm| Chef::Config[:knife][:kerberos_realm] = realm }
80
+
81
+ option :kerberos_service,
82
+ :short => "-S KERBEROS_SERVICE",
83
+ :long => "--kerberos-service KERBEROS_SERVICE",
84
+ :description => "The Kerberos service used for authentication",
85
+ :proc => Proc.new { |service| Chef::Config[:knife][:kerberos_service] = service }
86
+
87
+ option :ca_trust_file,
88
+ :short => "-f CA_TRUST_FILE",
89
+ :long => "--ca-trust-file CA_TRUST_FILE",
90
+ :description => "The Certificate Authority (CA) trust file used for SSL transport",
91
+ :proc => Proc.new { |trust| Chef::Config[:knife][:ca_trust_file] = trust }
92
+
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Windows
3
- VERSION = "0.5.3"
3
+ VERSION = "0.5.4"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  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.5.3
5
+ version: 0.5.4
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-05-13 00:00:00 -07:00
13
+ date: 2011-08-12 00:00:00 -04: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.0.5
24
+ version: 0.5.2
25
25
  type: :runtime
26
26
  version_requirements: *id001
27
27
  description: Plugin that adds functionality to Chef's Knife CLI for configuring/interacting with nodes running Microsoft Windows
@@ -36,17 +36,19 @@ extra_rdoc_files:
36
36
  - LICENSE
37
37
  files:
38
38
  - .gitignore
39
+ - CHANGELOG
39
40
  - Gemfile
40
41
  - LICENSE
41
42
  - README.rdoc
42
43
  - Rakefile
43
44
  - knife-windows.gemspec
44
45
  - lib/chef/knife/bootstrap/windows-shell.erb
46
+ - lib/chef/knife/bootstrap_windows_base.rb
45
47
  - lib/chef/knife/bootstrap_windows_ssh.rb
46
48
  - lib/chef/knife/bootstrap_windows_winrm.rb
47
49
  - lib/chef/knife/core/windows_bootstrap_context.rb
48
- - lib/chef/knife/mixin/windows/bootstrap.rb
49
50
  - lib/chef/knife/winrm.rb
51
+ - lib/chef/knife/winrm_base.rb
50
52
  - lib/knife-windows/version.rb
51
53
  has_rdoc: true
52
54
  homepage: https://github.com/opscode/knife-windows
@@ -1,94 +0,0 @@
1
- require 'chef/knife'
2
- require 'erubis'
3
-
4
- class Chef
5
- module Mixin
6
- module Bootstrap
7
-
8
- # TODO: This should go away when CHEF-2193 is fixed
9
- def load_template(template=nil)
10
- # Are we bootstrapping using an already shipped template?
11
- if config[:template_file]
12
- bootstrap_files = config[:template_file]
13
- else
14
- bootstrap_files = []
15
- bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
16
- bootstrap_files << File.join(Dir.pwd, ".chef", "bootstrap", "#{config[:distro]}.erb")
17
- bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{config[:distro]}.erb")
18
- bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
19
- bootstrap_files.flatten!
20
- end
21
-
22
- template = Array(bootstrap_files).find do |bootstrap_template|
23
- Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
24
- ::File.exists?(bootstrap_template)
25
- end
26
-
27
- unless template
28
- ui.info("Can not find bootstrap definition for #{config[:distro]}")
29
- raise Errno::ENOENT
30
- end
31
-
32
- Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
33
-
34
- IO.read(template).chomp
35
- end
36
-
37
- def render_template(template=nil)
38
- context = Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config)
39
- Erubis::Eruby.new(template).evaluate(context)
40
- end
41
-
42
- def bootstrap(proto=nil)
43
-
44
- validate_name_args!
45
-
46
- @node_name = Array(@name_args).first
47
- # back compat--templates may use this setting:
48
- config[:server_name] = @node_name
49
-
50
- $stdout.sync = true
51
-
52
- ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
53
- # create a bootstrap.bat file on the node
54
- # we have to run the remote commands in 2047 char chunks
55
- create_bootstrap_bat_command do |command_chunk, chunk_num|
56
- run_command("cmd.exe /C echo \"Rendering bootstrap.bat chunk #{chunk_num}\" && #{command_chunk}").run
57
- end
58
-
59
- # execute the bootstrap.bat file
60
- run_command(bootstrap_command).run
61
- end
62
-
63
- def bootstrap_command
64
- @bootstrap_command ||= "cmd.exe /C #{bootstrap_bat_file}"
65
- end
66
-
67
- def create_bootstrap_bat_command(&block)
68
- bootstrap_bat = []
69
- chunk_num = 0
70
- render_template(load_template(config[:bootstrap_template])).each_line do |line|
71
- # escape WIN BATCH special chars
72
- line.gsub!(/[(<|>)^]/).each{|m| "^#{m}"}
73
- # windows commands are limited to 2047 characters
74
- if((bootstrap_bat + [line]).join(" && ").size > 2047 )
75
- yield bootstrap_bat.join(" && "), chunk_num += 1
76
- bootstrap_bat = []
77
- end
78
- bootstrap_bat << ">> #{bootstrap_bat_file} (echo.#{line.chomp.strip})"
79
- end
80
- yield bootstrap_bat.join(" && "), chunk_num += 1
81
- end
82
-
83
- def bootstrap_bat_file
84
- "%TEMP%\\bootstrap.bat"
85
- end
86
-
87
- def locate_config_value(key)
88
- key = key.to_sym
89
- Chef::Config[:knife][key] || config[key]
90
- end
91
-
92
- end
93
- end
94
- end