knife-windows 1.9.6 → 3.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bf0c4e742d3b1f2c96348ae916c2c6521d61a41f316077c91a66639b1370279
4
- data.tar.gz: 11d10a40bb240102a06ae7fd8603afd3bb6bf231dd25e364b5126bd9046a6e2c
3
+ metadata.gz: 9df0cbd0a270e724605457a247247450e280c06fec21039fbf6f3a7603d96e88
4
+ data.tar.gz: 0010acbcbceb5b3a95366591aa79dcacc08eb47e7c3c40da236df7ca1dc61880
5
5
  SHA512:
6
- metadata.gz: f07208ca07546853389ab4c7646b4cfdaca43cfb39b90fe86cccc73d286a4b07a9e3015a89d2a734e25fec99c37122446c67519dc40cd806f05b4e11f7e15b3f
7
- data.tar.gz: 3d81398062e1f4393072f172f8cc7bdb44a92c7f2cbd4db72305cf74b1b38a14a3c4dc7f9b1b00a8173eb53612084d97f32b2cdecb58474cf0d22ce00e67eee9
6
+ metadata.gz: ed4db6cce0bb4db8ccac3c1c59bc611f2584f5db4751462c8560639889d22070f9f5bfde616cdcc8a3e985b96395c2039b1bd1890e4d2776717083ee1e439f03
7
+ data.tar.gz: da60e7d18999d01e07c6a9510abaf07a6c8b550eead498f4d760ab044bc93ab80e95696b86c38bc4348c242e4371b41d4841c4e0b3332d1b1138dd12e1a1d816
@@ -19,10 +19,8 @@
19
19
  require 'chef/knife'
20
20
  require 'chef/knife/bootstrap'
21
21
  require 'chef/encrypted_data_bag_item'
22
- require 'chef/knife/core/windows_bootstrap_context'
23
22
  require 'chef/knife/knife_windows_base'
24
- # Chef 11 PathHelper doesn't have #home
25
- #require 'chef/util/path_helper'
23
+ require 'chef/util/path_helper'
26
24
 
27
25
  class Chef
28
26
  class Knife
@@ -70,30 +68,11 @@ class Chef
70
68
  :description => "Custom command to install chef-client",
71
69
  :proc => Proc.new { |ic| Chef::Config[:knife][:bootstrap_install_command] = ic }
72
70
 
73
- # DEPR: Remove this option in Chef 13
74
- option :distro,
75
- :short => "-d DISTRO",
76
- :long => "--distro DISTRO",
77
- :description => "Bootstrap a distro using a template. [DEPRECATED] Use -t / --bootstrap-template option instead.",
78
- :proc => Proc.new { |v|
79
- Chef::Log.warn("[DEPRECATED] -d / --distro option is deprecated. Use --bootstrap-template option instead.")
80
- v
81
- }
82
-
83
71
  option :bootstrap_template,
84
72
  :short => "-t TEMPLATE",
85
73
  :long => "--bootstrap-template TEMPLATE",
86
74
  :description => "Bootstrap Chef using a built-in or custom template. Set to the full path of an erb template or use one of the built-in templates."
87
75
 
88
- # DEPR: Remove this option in Chef 13
89
- option :template_file,
90
- :long => "--template-file TEMPLATE",
91
- :description => "Full path to location of template to use. [DEPRECATED] Use -t / --bootstrap-template option instead.",
92
- :proc => Proc.new { |v|
93
- Chef::Log.warn("[DEPRECATED] --template-file option is deprecated. Use --bootstrap-template option instead.")
94
- v
95
- }
96
-
97
76
  option :run_list,
98
77
  :short => "-r RUN_LIST",
99
78
  :long => "--run-list RUN_LIST",
@@ -203,243 +182,6 @@ class Chef
203
182
  :default => []
204
183
  end
205
184
  end
206
-
207
- def default_bootstrap_template
208
- "windows-chef-client-msi"
209
- end
210
-
211
- def bootstrap_template
212
- # The order here is important. We want to check if we have the new Chef 12 option is set first.
213
- # Knife cloud plugins unfortunately all set a default option for the :distro so it should be at
214
- # the end.
215
- config[:bootstrap_template] || config[:template_file] || config[:distro] || default_bootstrap_template
216
- end
217
-
218
- # TODO: This should go away when CHEF-2193 is fixed
219
- def load_template(template=nil)
220
- # Are we bootstrapping using an already shipped template?
221
-
222
- template = bootstrap_template
223
-
224
- # Use the template directly if it's a path to an actual file
225
- if File.exists?(template)
226
- Chef::Log.debug("Using the specified bootstrap template: #{File.dirname(template)}")
227
- return IO.read(template).chomp
228
- end
229
-
230
- # Otherwise search the template directories until we find the right one
231
- bootstrap_files = []
232
- bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap/templates', "#{template}.erb")
233
- bootstrap_files << File.join(Knife.chef_config_dir, "bootstrap", "#{template}.erb") if Chef::Knife.chef_config_dir
234
- ::Knife::Windows::PathHelper.all_homes('.chef', 'bootstrap', "#{template}.erb") { |p| bootstrap_files << p }
235
- bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{template}.erb"))
236
- bootstrap_files.flatten!
237
-
238
- template = Array(bootstrap_files).find do |bootstrap_template|
239
- Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
240
- ::File.exists?(bootstrap_template)
241
- end
242
-
243
- unless template
244
- ui.info("Can not find bootstrap definition for #{config[:distro]}")
245
- raise Errno::ENOENT
246
- end
247
-
248
- Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
249
-
250
- IO.read(template).chomp
251
- end
252
-
253
- def bootstrap_context
254
- @bootstrap_context ||= Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config)
255
- end
256
-
257
- def load_correct_secret
258
- knife_secret_file = Chef::Config[:knife][:encrypted_data_bag_secret_file]
259
- knife_secret = Chef::Config[:knife][:encrypted_data_bag_secret]
260
- cli_secret_file = config[:encrypted_data_bag_secret_file]
261
- cli_secret = config[:encrypted_data_bag_secret]
262
-
263
- cli_secret_file = nil if cli_secret_file == knife_secret_file
264
- cli_secret = nil if cli_secret == knife_secret
265
-
266
- cli_secret_file = Chef::EncryptedDataBagItem.load_secret(cli_secret_file) if cli_secret_file != nil
267
- knife_secret_file = Chef::EncryptedDataBagItem.load_secret(knife_secret_file) if knife_secret_file != nil
268
-
269
- cli_secret_file || cli_secret || knife_secret_file || knife_secret
270
- end
271
-
272
- def first_boot_attributes
273
- config[:first_boot_attributes] || config[:first_boot_attributes_from_file] || {}
274
- end
275
-
276
- def render_template(template=nil)
277
- config[:first_boot_attributes] = first_boot_attributes
278
- config[:secret] = load_correct_secret
279
- Erubis::Eruby.new(template).evaluate(bootstrap_context)
280
- end
281
-
282
- def bootstrap(proto=nil)
283
- if Chef::Config[:knife][:encrypted_data_bag_secret_file] || Chef::Config[:knife][:encrypted_data_bag_secret]
284
- warn_chef_config_secret_key
285
- end
286
-
287
- set_target_architecture
288
-
289
- # adding respond_to? so this works with pre 12.4 chef clients
290
- validate_options! if respond_to?(:validate_options!)
291
-
292
- @node_name = Array(@name_args).first
293
- # back compat--templates may use this setting:
294
- config[:server_name] = @node_name
295
-
296
- STDOUT.sync = STDERR.sync = true
297
-
298
- if Chef::VERSION.split('.').first.to_i == 11 && Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key]))
299
- ui.error("Unable to find validation key. Please verify your configuration file for validation_key config value.")
300
- exit 1
301
- end
302
-
303
- if (defined?(chef_vault_handler) && chef_vault_handler.doing_chef_vault?) ||
304
- (Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key])))
305
-
306
- unless locate_config_value(:chef_node_name)
307
- ui.error("You must pass a node name with -N when bootstrapping with user credentials")
308
- exit 1
309
- end
310
-
311
- client_builder.run
312
-
313
- if client_builder.respond_to?(:client)
314
- chef_vault_handler.run(client_builder.client)
315
- else
316
- chef_vault_handler.run(node_name: config[:chef_node_name])
317
- end
318
-
319
- bootstrap_context.client_pem = client_builder.client_path
320
-
321
- else
322
- ui.info("Doing old-style registration with the validation key at #{Chef::Config[:validation_key]}...")
323
- ui.info("Delete your validation key in order to use your user credentials instead")
324
- ui.info("")
325
- end
326
-
327
- wait_for_remote_response( config[:auth_timeout].to_i )
328
-
329
- ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
330
- # create a bootstrap.bat file on the node
331
- # we have to run the remote commands in 2047 char chunks
332
- create_bootstrap_bat_command do |command_chunk|
333
- render_command_result = run_command(command_chunk)
334
- unless render_command_result == 0
335
- ui.error("Batch render command returned #{render_command_result}")
336
- exit render_command_result
337
- end
338
- end
339
-
340
- # execute the bootstrap.bat file
341
- bootstrap_command_result = run_command(bootstrap_command)
342
- unless bootstrap_command_result == 0
343
- ui.error("Bootstrap command returned #{bootstrap_command_result}")
344
- exit bootstrap_command_result
345
- end
346
-
347
- # exit 0
348
- 0
349
- end
350
-
351
- protected
352
-
353
- # Default implementation -- override only if required by the transport
354
- def wait_for_remote_response(wait_max_minutes)
355
- end
356
-
357
- def bootstrap_command
358
- @bootstrap_command ||= "cmd.exe /C #{bootstrap_bat_file}"
359
- end
360
-
361
- def bootstrap_render_banner_command(chunk_num)
362
- "cmd.exe /C echo Rendering #{bootstrap_bat_file} chunk #{chunk_num}"
363
- end
364
-
365
- def escape_windows_batch_characters(line)
366
- # TODO: The commands are going to get redirected - do we need to escape &?
367
- line.gsub!(/[(<|>)^]/).each{|m| "^#{m}"}
368
- end
369
-
370
- def create_bootstrap_bat_command()
371
- chunk_num = 0
372
- bootstrap_bat = ""
373
- banner = bootstrap_render_banner_command(chunk_num += 1)
374
- render_template(load_template(config[:bootstrap_template])).each_line do |line|
375
- escape_windows_batch_characters(line)
376
- # We are guaranteed to have a prefix "banner" command that echo's chunk number. We can
377
- # confidently prefix every actual command with &&.
378
- # TODO: Why does ^\n&& work directly through the commandline but not through SOAP?
379
- render_line = " && >> #{bootstrap_bat_file} (echo.#{line.chomp.strip})"
380
- # Windows commands are limited to 8191 characters for machines running XP or higher but
381
- # this includes the length of environment variables after they have been expanded.
382
- # Since we don't actually know how long %TEMP% (and it's used twice - once in the banner
383
- # and once in every command redirection), we simply guess and set the max to 5000.
384
- # TODO: When a more accurate method is available, fix this.
385
- if bootstrap_bat.length + render_line.length + banner.length > 5000
386
- # Can't fit it into this chunk? - flush (if necessary) and then try.
387
- # Do this first because banner.length might change (e.g. due to an extra digit) and
388
- # prevent a fit.
389
- unless bootstrap_bat.empty?
390
- yield banner + bootstrap_bat
391
- bootstrap_bat = ""
392
- banner = bootstrap_render_banner_command(chunk_num += 1)
393
- end
394
- # Will this ever fit?
395
- if render_line.length + banner.length > 5000
396
- raise "Command in bootstrap template too long by #{render_line.length + banner.length - 5000} characters : #{line}"
397
- end
398
- end
399
- bootstrap_bat << render_line
400
- end
401
- raise "Bootstrap template was empty! Check #{config[:bootstrap_template]}" if bootstrap_bat.empty?
402
- yield banner + bootstrap_bat
403
- end
404
-
405
- def bootstrap_bat_file
406
- @bootstrap_bat_file ||= "\"%TEMP%\\bootstrap-#{Process.pid}-#{Time.now.to_i}.bat\""
407
- end
408
-
409
- def warn_chef_config_secret_key
410
- ui.info "* " * 40
411
- ui.warn(<<-WARNING)
412
- \nSpecifying the encrypted data bag secret key using an 'encrypted_data_bag_secret'
413
- entry in 'knife.rb' is deprecated. Please use the '--secret' or '--secret-file'
414
- options of this command instead.
415
-
416
- #{ui.color('IMPORTANT:', :red, :bold)} In a future version of Chef, this
417
- behavior will be removed and any 'encrypted_data_bag_secret' entries in
418
- 'knife.rb' will be ignored completely.
419
- WARNING
420
- ui.info "* " * 40
421
- end
422
-
423
- # We allow the user to specify the desired architecture of Chef to install or we default
424
- # to whatever the target system is.
425
- # This is because a user might want to install a 32bit chef client on a 64bit machine
426
- def set_target_architecture
427
- if Chef::Config[:knife][:architecture]
428
- raise "Do not set :architecture in your knife config, use :bootstrap_architecture."
429
- end
430
-
431
- if Chef::Config[:knife][:bootstrap_architecture]
432
- bootstrap_architecture = Chef::Config[:knife][:bootstrap_architecture]
433
-
434
- if ![:x86_64, :i386].include?(bootstrap_architecture.to_sym)
435
- raise "Valid values for the knife config :bootstrap_architecture are i386 or x86_64. Supplied value is #{bootstrap_architecture}"
436
- end
437
-
438
- # The windows install script wants i686, not i386
439
- bootstrap_architecture = :i686 if bootstrap_architecture == :i386
440
- Chef::Config[:knife][:architecture] = bootstrap_architecture
441
- end
442
- end
443
185
  end
444
186
  end
445
187
  end
@@ -25,13 +25,13 @@ class Chef
25
25
  include Chef::Knife::BootstrapWindowsBase
26
26
 
27
27
  deps do
28
- require 'chef/knife/core/windows_bootstrap_context'
29
28
  require 'chef/json_compat'
30
29
  require 'tempfile'
31
30
  require 'highline'
32
31
  require 'net/ssh'
33
32
  require 'net/ssh/multi'
34
33
  Chef::Knife::Ssh.load_deps
34
+ Chef::Knife::Bootstrap.load_deps
35
35
  end
36
36
 
37
37
  banner "knife bootstrap windows ssh FQDN (options)"
@@ -74,17 +74,6 @@ class Chef
74
74
  :long => "--ssh-identity-file IDENTITY_FILE",
75
75
  :description => "The SSH identity file used for authentication"
76
76
 
77
- # DEPR: Remove this option for the next release.
78
- option :host_key_verification,
79
- :long => "--[no-]host-key-verify",
80
- :description => "Verify host key, enabled by default. [DEPRECATED] Use --host-key-verify option instead.",
81
- :boolean => true,
82
- :default => true,
83
- :proc => Proc.new { |key|
84
- Chef::Log.warn("[DEPRECATED] --host-key-verification option is deprecated. Use --host-key-verify option instead.")
85
- config[:host_key_verify] = key
86
- }
87
-
88
77
  option :host_key_verify,
89
78
  :long => "--[no-]host-key-verify",
90
79
  :description => "Verify host key, enabled by default.",
@@ -92,23 +81,15 @@ class Chef
92
81
  :default => true
93
82
 
94
83
  def run
95
- validate_name_args!
96
- bootstrap
97
- end
98
-
99
- def run_command(command = '')
100
- ssh = Chef::Knife::Ssh.new
101
- ssh.name_args = [ server_name, command ]
102
- ssh.config[:ssh_user] = locate_config_value(:ssh_user)
103
- ssh.config[:ssh_password] = locate_config_value(:ssh_password)
104
- ssh.config[:ssh_port] = locate_config_value(:ssh_port)
105
- ssh.config[:ssh_gateway] = locate_config_value(:ssh_gateway)
106
- ssh.config[:identity_file] = config[:identity_file]
107
- ssh.config[:ssh_identity_file] = config[:ssh_identity_file] || config[:identity_file]
108
- ssh.config[:forward_agent] = config[:forward_agent]
109
- ssh.config[:manual] = true
110
- ssh.config[:host_key_verify] = config[:host_key_verify]
111
- ssh.run
84
+ Chef::Application.fatal!(<<~EOM
85
+ *knife windows bootstrap ssh*
86
+ Core Chef now supports bootstrapping Windows systems without a knife plugin
87
+
88
+ Use 'knife bootstrap -o ssh' instead.
89
+
90
+ For more detail https://github.com/chef/chef/blob/master/RELEASE_NOTES.md#knife-bootstrap
91
+ EOM
92
+ )
112
93
  end
113
94
 
114
95
  end
@@ -31,72 +31,26 @@ class Chef
31
31
  include Chef::Knife::WinrmCommandSharedFunctions
32
32
 
33
33
  deps do
34
- require 'chef/knife/core/windows_bootstrap_context'
35
34
  require 'chef/json_compat'
36
35
  require 'tempfile'
37
36
  Chef::Knife::Winrm.load_deps
37
+ Chef::Knife::Bootstrap.load_deps
38
38
  end
39
39
 
40
40
  banner 'knife bootstrap windows winrm FQDN (options)'
41
41
 
42
42
  def run
43
- validate_name_args!
44
-
45
- if (Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key])))
46
- if !negotiate_auth? && !(locate_config_value(:winrm_transport) == 'ssl')
47
- ui.error('Validatorless bootstrap over unsecure winrm channels could expose your key to network sniffing')
48
- exit 1
49
- end
50
- end
51
-
52
- unless locate_config_value(:winrm_shell) == :cmd
53
- ui.warn("The cmd shell is the only valid winrm-shell for 'knife bootstrap windows winrm'. Switching to the cmd shell.")
54
- config[:winrm_shell] = :cmd
55
- end
56
-
57
- config[:manual] = true
58
- configure_session
59
-
60
- bootstrap
43
+ Chef::Application.fatal!(<<~EOM
44
+ *knife windows bootstrap winrm*
45
+ Core Chef now supports bootstrapping Windows systems without a knife plugin
46
+
47
+ Use 'knife bootstrap -o winrm' instead.
48
+
49
+ For more detail https://github.com/chef/chef/blob/master/RELEASE_NOTES.md#knife-bootstrap
50
+ EOM
51
+ )
61
52
  end
62
53
 
63
- protected
64
-
65
- def wait_for_remote_response(wait_max_minutes)
66
- wait_max_seconds = wait_max_minutes * 60
67
- retry_interval_seconds = 10
68
- retries_left = wait_max_seconds / retry_interval_seconds
69
- print(ui.color("\nWaiting for remote response before bootstrap", :magenta))
70
- wait_start_time = Time.now
71
- begin
72
- print(".")
73
- # Return status of the command is non-zero, typically nil,
74
- # for our simple echo command in cases where run_command
75
- # swallows the exception, such as 401's. Treat such cases
76
- # the same as the case where we encounter an exception.
77
- status = run_command("echo . & echo Response received.")
78
- raise RuntimeError, 'Command execution failed.' if status != 0
79
- ui.info(ui.color("Remote node responded after #{elapsed_time_in_minutes(wait_start_time)} minutes.", :magenta))
80
- return
81
- rescue Errno::ECONNREFUSED => e
82
- ui.error("Connection refused connecting to #{locate_config_value(:server_name)}:#{locate_config_value(:winrm_port)}.")
83
- raise
84
- rescue Exception => e
85
- retries_left -= 1
86
- if retries_left <= 0 || (elapsed_time_in_minutes(wait_start_time) > wait_max_minutes)
87
- ui.error("No response received from remote node after #{elapsed_time_in_minutes(wait_start_time)} minutes, giving up.")
88
- ui.error("Exception: #{e.message}")
89
- raise
90
- end
91
- print '.'
92
- sleep retry_interval_seconds
93
- retry
94
- end
95
- end
96
-
97
- def elapsed_time_in_minutes(start_time)
98
- ((Time.now - start_time) / 60).round(2)
99
- end
100
54
  end
101
55
  end
102
56
  end
@@ -33,4 +33,3 @@ class Chef
33
33
  end
34
34
  end
35
35
  end
36
-