diff options
author | Vivek Singh <vivek.singh@msystechnologies.com> | 2020-09-10 16:54:39 +0530 |
---|---|---|
committer | Vivek Singh <vivek.singh@msystechnologies.com> | 2020-09-17 09:21:43 +0530 |
commit | 8d2a18d850f8faa2845941d3a8928a9f1d738742 (patch) | |
tree | 8c3b34344147fc8f851ee5a9450d23b2ba4e01a7 /lib/chef/knife/bootstrap.rb | |
parent | ebcf51824dd3e5521901ca946abb4b64b278e36d (diff) | |
download | chef-8d2a18d850f8faa2845941d3a8928a9f1d738742.tar.gz |
handles su - USER sesssion to perform bootstrap
Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
Diffstat (limited to 'lib/chef/knife/bootstrap.rb')
-rw-r--r-- | lib/chef/knife/bootstrap.rb | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb index efd969210b..31ce53601c 100644 --- a/lib/chef/knife/bootstrap.rb +++ b/lib/chef/knife/bootstrap.rb @@ -217,6 +217,16 @@ class Chef description: "Execute the bootstrap via sudo with password.", boolean: false + # runtime - su user + option :su_user, + long: "--su-user NAME", + description: "The su - USER name to perform bootstrap command using a non-root user." + + # runtime - su user password + option :su_password, + long: "--su-password PASSWORD", + description: "The su USER password for authentication." + # runtime - client_builder option :chef_node_name, short: "-N NAME", @@ -590,13 +600,30 @@ class Chef def perform_bootstrap(remote_bootstrap_script_path) ui.info("Bootstrapping #{ui.color(server_name, :bold)}") cmd = bootstrap_command(remote_bootstrap_script_path) + bootstrap_run_command(cmd) + end + + # Actual bootstrap command to perform on the node. + # Handles recursive calls if su USER failed to authenticate. + def bootstrap_run_command(cmd) r = connection.run_command(cmd) do |data| ui.msg("#{ui.color(" [#{connection.hostname}]", :cyan)} #{data}") end if r.exit_status != 0 - ui.error("The following error occurred on #{server_name}:") - ui.error(r.stderr) - exit 1 + stderr = (r.stderr + r.stdout).strip + + if stderr.match?("su: Authentication failure") + ui.warn("Failed to authenticate su - #{config[:su_user]} to #{server_name}") + password = ui.ask("Enter password for su - #{config[:su_user]}@#{server_name}:", echo: false) + + set_transport_options(su_password: password) + + bootstrap_run_command(cmd) + else + ui.error("The following error occurred on #{server_name}:") + ui.error(stderr) + exit(r.exit_status) + end end end @@ -880,6 +907,7 @@ class Chef @connection_opts.merge! winrm_opts @connection_opts.merge! ssh_opts @connection_opts.merge! ssh_identity_opts + @connection_opts.merge! su_user_opts @connection_opts end @@ -1045,6 +1073,15 @@ class Chef } end + def su_user_opts + opts = {} + return opts if winrm? || !config.key?(:su_user) + + opts[:su_user] = config[:su_user] + opts[:su_password] = config[:su_password] || config[:connection_password] + opts + end + # This is for deprecating config options. The fallback_key can be used # to pull an old knife config option out of the config file when the # cli value has been renamed. This is different from the deprecated @@ -1081,7 +1118,17 @@ class Chef if connection.windows? "cmd.exe /C #{remote_path}" else - "sh #{remote_path}" + cmd = "sh #{remote_path}" + + if config[:su_user] + # su - USER is subject to required an interactive console + # Otherwise, it will raise: su: must be run from a terminal + set_transport_options(pty: true) + cmd = "su - #{config[:su_user]} -c '#{cmd}'" + cmd = "sudo " << cmd if config[:use_sudo] + end + + cmd end end @@ -1136,6 +1183,18 @@ class Chef timeout.to_i end + + # Train::Transports::SSH::Connection#transport_options + # Append the options to connection transport_options + # + # @param opts [Hash] the opts to be added to connection transport_options. + # @return [Hash] transport_options if the opts contains any option to be set. + # + def set_transport_options(opts) + return unless opts.is_a?(Hash) || !opts.empty? + + connection&.connection&.transport_options&.merge! opts + end end end end |