104 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require "providers/provider_factory"
 | |
| require "fileutils"
 | |
| require "commands/status"
 | |
| require "app/api2/parsers/script"
 | |
| require_relative "request_handler"
 | |
| 
 | |
| module Devops
 | |
|   module API2_0
 | |
|     module Handler
 | |
|       class Script < RequestHandler
 | |
| 
 | |
|         set_parser Devops::API2_0::Parser::ScriptParser
 | |
| 
 | |
|         def scripts
 | |
|           res = []
 | |
|           Dir.foreach(DevopsConfig.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")}
 | |
|         end
 | |
| 
 | |
|         def execute_command out, node_name
 | |
|           cmd = parse.execute_command
 | |
|           user = parser.current_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, script_name
 | |
|           nodes, script_params = parser.run_script
 | |
|           file = File.join(DevopsConfig.config[:scripts_dir], script_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
 | |
|           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(parser.create_script)}
 | |
|         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") unless File.exists?(file)
 | |
|           FileUtils.rm(file)
 | |
|         end
 | |
| 
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | |
| 
 | 
