Class: Chef::Knife::Bootstrap

Inherits:
Chef::Knife show all
Defined in:
lib/chef/knife/bootstrap.rb

Instance Attribute Summary

Attributes inherited from Chef::Knife

#name_args, #ui

Instance Method Summary collapse

Methods inherited from Chef::Knife

#api_key, #apply_computed_config, category, common_name, config_fetcher, #config_file_settings, #configure_chef, #create_object, #delete_object, dependency_loaders, deps, #format_rest_error, guess_category, #highlight_config_error, #humanize_exception, #humanize_http_exception, inherited, #initialize, list_commands, load_commands, load_deps, locate_config_file, #merge_configs, msg, #noauth_rest, #parse_options, #read_config, reset_subcommands!, #rest, run, #run_with_pretty_exceptions, #server_url, #show_usage, snake_case_name, subcommand_category, subcommand_class_from, subcommand_loader, subcommands, subcommands_by_category, ui, unnamed?, use_separate_defaults?, #username

Methods included from Mixin::ConvertToClassName

#convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #snake_case_basename

Methods included from Mixin::PathSanity

#enforce_path_sanity

Constructor Details

This class inherits a constructor from Chef::Knife

Instance Method Details

#find_template(template = nil) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/chef/knife/bootstrap.rb', line 157

def find_template(template=nil)
  # Are we bootstrapping using an already shipped template?
  if config[:template_file]
    bootstrap_files = config[:template_file]
  else
    bootstrap_files = []
    bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
    bootstrap_files << File.join(Knife.chef_config_dir, "bootstrap", "#{config[:distro]}.erb") if Knife.chef_config_dir
    bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{config[:distro]}.erb") if ENV['HOME']
    bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{config[:distro]}.erb"))
    bootstrap_files.flatten!
  end

  template = 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
    ui.info("Can not find bootstrap definition for #{config[:distro]}")
    raise Errno::ENOENT
  end

  Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")

  template
end

#knife_sshObject



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/chef/knife/bootstrap.rb', line 227

def knife_ssh
  ssh = Chef::Knife::Ssh.new
  ssh.ui = ui
  ssh.name_args = [ server_name, ssh_command ]
  ssh.config[:ssh_user] = Chef::Config[:knife][:ssh_user] || config[:ssh_user]
  ssh.config[:ssh_password] = config[:ssh_password]
  ssh.config[:ssh_port] = Chef::Config[:knife][:ssh_port] || config[:ssh_port]
  ssh.config[:ssh_gateway] = Chef::Config[:knife][:ssh_gateway] || config[:ssh_gateway]
  ssh.config[:forward_agent] = Chef::Config[:knife][:forward_agent] || config[:forward_agent]
  ssh.config[:identity_file] = Chef::Config[:knife][:identity_file] || config[:identity_file]
  ssh.config[:manual] = true
  ssh.config[:host_key_verify] = Chef::Config[:knife][:host_key_verify] || config[:host_key_verify]
  ssh.config[:on_error] = :raise
  ssh
end

#knife_ssh_with_password_authObject



243
244
245
246
247
248
# File 'lib/chef/knife/bootstrap.rb', line 243

def knife_ssh_with_password_auth
  ssh = knife_ssh
  ssh.config[:identity_file] = nil
  ssh.config[:ssh_password] = ssh.get_password
  ssh
end

#read_templateObject



190
191
192
# File 'lib/chef/knife/bootstrap.rb', line 190

def read_template
  IO.read(@template_file).chomp
end

#render_template(template = nil) ⇒ Object



185
186
187
188
# File 'lib/chef/knife/bootstrap.rb', line 185

def render_template(template=nil)
  context = Knife::Core::BootstrapContext.new(config, config[:run_list], Chef::Config)
  Erubis::Eruby.new(template).evaluate(context)
end

#runObject



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/chef/knife/bootstrap.rb', line 194

def run
  validate_name_args!
  warn_chef_config_secret_key
  @template_file = find_template(config[:bootstrap_template])
  @node_name = Array(@name_args).first
  # back compat--templates may use this setting:
  config[:server_name] = @node_name

  $stdout.sync = true

  ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")

  begin
    knife_ssh.run
  rescue Net::SSH::AuthenticationFailed
    unless config[:ssh_password]
      ui.info("Failed to authenticate #{config[:ssh_user]} - trying password auth")
      knife_ssh_with_password_auth.run
    end
  end
end

#server_nameObject



223
224
225
# File 'lib/chef/knife/bootstrap.rb', line 223

def server_name
  Array(@name_args).first
end

#ssh_commandObject



250
251
252
253
254
255
256
257
258
# File 'lib/chef/knife/bootstrap.rb', line 250

def ssh_command
  command = render_template(read_template)

  if config[:use_sudo]
    command = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -S #{command}" : "sudo #{command}"
  end

  command
end

#validate_name_args!Object



216
217
218
219
220
221
# File 'lib/chef/knife/bootstrap.rb', line 216

def validate_name_args!
  if Array(@name_args).first.nil?
    ui.error("Must pass an FQDN or ip to bootstrap")
    exit 1
  end
end

#warn_chef_config_secret_keyObject



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/chef/knife/bootstrap.rb', line 260

def warn_chef_config_secret_key
  unless Chef::Config[:encrypted_data_bag_secret].nil?
    ui.warn "* " * 40
    ui.warn("Specifying the encrypted data bag secret key using an 'encrypted_data_bag_secret'\nentry in 'knife.rb' is deprecated. Please see CHEF-4011 for more details. You\ncan supress this warning and still distribute the secret key to all bootstrapped\nmachines by adding the following to your 'knife.rb' file:\n\n  knife[:secret_file] = \"/path/to/your/secret\"\n\nIf you would like to selectively distribute a secret key during bootstrap\nplease use the '--secret' or '--secret-file' options of this command instead.\n\n\#{ui.color('IMPORTANT:', :red, :bold)} In a future version of Chef, this\nbehavior will be removed and any 'encrypted_data_bag_secret' entries in\n'knife.rb' will be ignored completely.\n")
    ui.warn "* " * 40
  end
end