Class: Chef::Knife::Bootstrap
Defined Under Namespace
Classes: ChefVaultHandler, ClientBuilder
Constant Summary
Constants inherited
from Chef::Knife
OFFICIAL_PLUGINS
Instance Attribute Summary collapse
Attributes inherited from Chef::Knife
#name_args, #ui
Instance Method Summary
collapse
#encryption_secret_provided?, #encryption_secret_provided_ignore_encrypt_flag?, included, #read_secret, #validate_secrets
#encrypted?
Methods inherited from Chef::Knife
#api_key, #apply_computed_config, category, chef_config_dir, #cli_keys, common_name, #config_file_settings, config_loader, #configure_chef, #create_object, #delete_object, dependency_loaders, deps, #format_rest_error, guess_category, #humanize_exception, #humanize_http_exception, inherited, list_commands, load_commands, load_config, load_deps, #maybe_setup_fips, #merge_configs, msg, #noauth_rest, #parse_options, reset_config_loader!, reset_subcommands!, #rest, run, #run_with_pretty_exceptions, #server_url, #show_usage, snake_case_name, subcommand_category, subcommand_class_from, subcommand_files, subcommand_loader, subcommands, subcommands_by_category, #test_mandatory_field, ui, unnamed?, use_separate_defaults?, #username
#constantize, #convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #normalize_snake_case_name, #snake_case_basename
#enforce_path_sanity, #sanitized_path
Constructor Details
#initialize(argv = []) ⇒ Bootstrap
Returns a new instance of Bootstrap.
267
268
269
270
271
272
273
274
275
276
277
278
|
# File 'lib/chef/knife/bootstrap.rb', line 267
def initialize(argv = [])
super
@client_builder = Chef::Knife::Bootstrap::ClientBuilder.new(
chef_config: Chef::Config,
knife_config: config,
ui: ui
)
@chef_vault_handler = Chef::Knife::Bootstrap::ChefVaultHandler.new(
knife_config: config,
ui: ui
)
end
|
Instance Attribute Details
#chef_vault_handler ⇒ Object
Returns the value of attribute chef_vault_handler.
32
33
34
|
# File 'lib/chef/knife/bootstrap.rb', line 32
def chef_vault_handler
@chef_vault_handler
end
|
#client_builder ⇒ Object
Returns the value of attribute client_builder.
31
32
33
|
# File 'lib/chef/knife/bootstrap.rb', line 31
def client_builder
@client_builder
end
|
Instance Method Details
#bootstrap_context ⇒ Object
352
353
354
355
356
357
358
359
|
# File 'lib/chef/knife/bootstrap.rb', line 352
def bootstrap_context
@bootstrap_context ||= Knife::Core::BootstrapContext.new(
config,
config[:run_list],
Chef::Config,
secret
)
end
|
#bootstrap_template ⇒ Object
309
310
311
312
313
314
|
# File 'lib/chef/knife/bootstrap.rb', line 309
def bootstrap_template
config[:bootstrap_template] || config[:template_file] || config[:distro] || default_bootstrap_template
end
|
#default_bootstrap_template ⇒ String
The default bootstrap template to use to bootstrap a server This is a public API hook which knife plugins use or inherit and override.
284
285
286
|
# File 'lib/chef/knife/bootstrap.rb', line 284
def default_bootstrap_template
"chef-full"
end
|
#find_template ⇒ Object
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
|
# File 'lib/chef/knife/bootstrap.rb', line 316
def find_template
template = bootstrap_template
if File.exists?(template)
Chef::Log.debug("Using the specified bootstrap template: #{File.dirname(template)}")
return template
end
bootstrap_files = []
bootstrap_files << File.join(File.dirname(__FILE__), "bootstrap/templates", "#{template}.erb")
bootstrap_files << File.join(Knife.chef_config_dir, "bootstrap", "#{template}.erb") if Chef::Knife.chef_config_dir
Chef::Util::PathHelper.home(".chef", "bootstrap", "#{template}.erb") { |p| bootstrap_files << p }
bootstrap_files << Gem.find_files(File.join("chef", "knife", "bootstrap", "#{template}.erb"))
bootstrap_files.flatten!
template_file = Array(bootstrap_files).find do |bootstrap_template|
Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
File.exists?(bootstrap_template)
end
unless template_file
ui.info("Can not find bootstrap definition for #{template}")
raise Errno::ENOENT
end
Chef::Log.debug("Found bootstrap template in #{File.dirname(template_file)}")
template_file
end
|
#first_boot_attributes ⇒ Object
361
362
363
|
# File 'lib/chef/knife/bootstrap.rb', line 361
def first_boot_attributes
@config[:first_boot_attributes] || @config[:first_boot_attributes_from_file] || {}
end
|
#host_descriptor ⇒ Object
288
289
290
|
# File 'lib/chef/knife/bootstrap.rb', line 288
def host_descriptor
Array(@name_args).first
end
|
#knife_ssh ⇒ Object
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
|
# File 'lib/chef/knife/bootstrap.rb', line 438
def knife_ssh
ssh = Chef::Knife::Ssh.new
ssh.ui = ui
ssh.name_args = [ server_name, ssh_command ]
ssh.config[:ssh_user] = user_name || config[:ssh_user]
ssh.config[:ssh_password] = config[:ssh_password]
ssh.config[:ssh_port] = config[:ssh_port]
ssh.config[:ssh_gateway] = config[:ssh_gateway]
ssh.config[:ssh_gateway_identity] = config[:ssh_gateway_identity]
ssh.config[:forward_agent] = config[:forward_agent]
ssh.config[:ssh_identity_file] = config[:ssh_identity_file] || config[:identity_file]
ssh.config[:manual] = true
ssh.config[:host_key_verify] = config[:host_key_verify]
ssh.config[:on_error] = true
ssh
end
|
#knife_ssh_with_password_auth ⇒ Object
455
456
457
458
459
460
|
# File 'lib/chef/knife/bootstrap.rb', line 455
def knife_ssh_with_password_auth
ssh = knife_ssh
ssh.config[:ssh_identity_file] = nil
ssh.config[:ssh_password] = ssh.get_password
ssh
end
|
#render_template ⇒ Object
365
366
367
368
369
370
|
# File 'lib/chef/knife/bootstrap.rb', line 365
def render_template
@config[:first_boot_attributes] = first_boot_attributes
template_file = find_template
template = IO.read(template_file).chomp
Erubis::Eruby.new(template).evaluate(bootstrap_context)
end
|
#run ⇒ Object
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
|
# File 'lib/chef/knife/bootstrap.rb', line 372
def run
if @config[:first_boot_attributes] && @config[:first_boot_attributes_from_file]
raise Chef::Exceptions::BootstrapCommandInputError
end
validate_name_args!
validate_options!
$stdout.sync = true
if chef_vault_handler.doing_chef_vault? ||
(Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key])))
unless config[:chef_node_name]
ui.error("You must pass a node name with -N when bootstrapping with user credentials")
exit 1
end
client_builder.run
chef_vault_handler.run(client_builder.client)
bootstrap_context.client_pem = client_builder.client_path
else
ui.info("Doing old-style registration with the validation key at #{Chef::Config[:validation_key]}...")
ui.info("Delete your validation key in order to use your user credentials instead")
ui.info("")
end
ui.info("Connecting to #{ui.color(server_name, :bold)}")
begin
knife_ssh.run
rescue Net::SSH::AuthenticationFailed
if config[:ssh_password]
raise
else
ui.info("Failed to authenticate #{knife_ssh.config[:ssh_user]} - trying password auth")
knife_ssh_with_password_auth.run
end
end
end
|
#secret ⇒ Object
348
349
350
|
# File 'lib/chef/knife/bootstrap.rb', line 348
def secret
@secret ||= encryption_secret_provided_ignore_encrypt_flag? ? read_secret : nil
end
|
#server_name ⇒ String
The server_name is the DNS or IP we are going to connect to, it is not necessarily the node name, the fqdn, or the hostname of the server. This is a public API hook which knife plugins use or inherit and override.
297
298
299
300
301
|
# File 'lib/chef/knife/bootstrap.rb', line 297
def server_name
if host_descriptor
@server_name ||= host_descriptor.split("@").reverse[0]
end
end
|
#ssh_command ⇒ Object
462
463
464
465
466
467
468
469
470
471
|
# File 'lib/chef/knife/bootstrap.rb', line 462
def ssh_command
command = render_template
if config[:use_sudo]
sudo_prefix = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -S " : "sudo "
command = config[:preserve_home] ? "#{sudo_prefix} #{command}" : "#{sudo_prefix} -H #{command}"
end
command
end
|
#user_name ⇒ Object
303
304
305
306
307
|
# File 'lib/chef/knife/bootstrap.rb', line 303
def user_name
if host_descriptor
@user_name ||= host_descriptor.split("@").reverse[1]
end
end
|
#validate_name_args! ⇒ Object
417
418
419
420
421
422
423
424
425
|
# File 'lib/chef/knife/bootstrap.rb', line 417
def validate_name_args!
if server_name.nil?
ui.error("Must pass an FQDN or ip to bootstrap")
exit 1
elsif server_name == "windows"
ui.warn("Hostname containing 'windows' specified. Please install 'knife-windows' if you are attempting to bootstrap a Windows node via WinRM.")
end
end
|
#validate_options! ⇒ Object
427
428
429
430
431
432
433
434
435
436
|
# File 'lib/chef/knife/bootstrap.rb', line 427
def validate_options!
if incomplete_policyfile_options?
ui.error("--policy-name and --policy-group must be specified together")
exit 1
elsif policyfile_and_run_list_given?
ui.error("Policyfile options and --run-list are exclusive")
exit 1
end
true
end
|