knife-windows 0.5.3 → 0.5.4

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/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