require "providers/provider_factory" require "fileutils" require "commands/status" require_relative "request_handler" module Devops module API2_0 module Handler class Script < RequestHandler def scripts res = [] Dir.foreach(DevopsConfig.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")} end def execute_command out, cmd, node_name user = @request.env['REMOTE_USER'] s = ::Devops::Db.connector.server_by_chef_node_name node_name ::Devops::Db.connector.check_project_auth s.project, s.deploy_env, user cert = ::Devops::Db.connector.key s.key addr = "#{s.remote_user}@#{s.public_ip || s.private_ip}" ssh_cmd = "ssh -i %s #{addr} '#{cmd}'" out << ssh_cmd % File.basename(cert.path) out << "\n" IO.popen((ssh_cmd % cert.path) + " 2>&1") do |so| while line = so.gets do out << line end end out << "\nDone" end def run_script out, file_name, nodes, script_params file = File.join(DevopsConfig.config[:scripts_dir], file_name) unless File.exists?(file) out << "File '#{file_name}' does not exist\n" return end servers = ::Devops::Db.connector.servers_by_names(nodes) if servers.empty? out << "No servers found for names '#{nodes.join("', '")}'\n" return end user = @request.env['REMOTE_USER'] servers.each do |s| ::Devops::Db.connector.check_project_auth s.project, s.deploy_env, user end status = [] servers.each do |s| cert = begin ::Devops::Db.connector.key s.key rescue out << "No key found for '#{s.chef_node_name}'" status.push 2 next end ssh_cmd = "ssh -i #{cert.path} #{s.remote_user}@#{s.public_ip || s.private_ip} 'bash -s' < %s" out << "\nRun script on '#{s.chef_node_name}'\n" unless script_params.nil? ssh_cmd += " " + script_params.join(" ") end out << (ssh_cmd % [file_name]) out << "\n" begin IO.popen( (ssh_cmd % [file]) + " 2>&1") do |so| while line = so.gets do out << line end so.close status.push $?.to_i end rescue IOError => e logger.error e.message out << e.message status.push 3 end end out << create_status(status) end def create_script file_name file = File.join(Devops::Api2.settings.scripts_dir, file_name) raise RecordNotFound.new("File '#{file_name}' already exist") if File.exists?(file) File.open(file, "w") {|f| f.write(@request.body.read)} end def delete_script file_name file = File.join(Devops::Api2.settings.scripts_dir, file_name) raise RecordNotFound.new("File '#{file_name}' does not exist", 404) unless File.exists?(file) FileUtils.rm(file) end end end end end