117 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			117 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|   | require "providers/provider_factory" | ||
|  | require "fileutils" | ||
|  | require "commands/status" | ||
|  | 
 | ||
|  | module Devops | ||
|  |   module Version2_0 | ||
|  |     module Handler | ||
|  |       class Script | ||
|  | 
 | ||
|  |         def self.get_scripts | ||
|  |           lambda { | ||
|  |             res = [] | ||
|  |             Dir.foreach(DevopsService.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")} | ||
|  |             json res | ||
|  |           } | ||
|  |         end | ||
|  | 
 | ||
|  |         def self.execute_command | ||
|  |           lambda { | ||
|  |             user = request.env['REMOTE_USER'] | ||
|  |             s = BaseRoutes.mongo.server_by_chef_node_name params[:node_name] | ||
|  |             BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user | ||
|  |             cert = BaseRoutes.mongo.key s.key | ||
|  |             cmd = request.body.read | ||
|  |             addr = "#{s.remote_user}@#{s.public_ip || s.private_ip}" | ||
|  |             ssh_cmd = "ssh -i %s #{addr} '#{cmd}'" | ||
|  |             stream() do |out| | ||
|  |               begin | ||
|  |                 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" | ||
|  |               rescue IOError => e | ||
|  |                 logger.error e.message | ||
|  |               end | ||
|  |             end | ||
|  |           } | ||
|  |         end | ||
|  | 
 | ||
|  |         def self.run_script | ||
|  |           lambda { | ||
|  |             file_name = params[:script_name] | ||
|  |             @file = File.join(DevopsService.config[:scripts_dir], check_filename(file_name, "Parameter 'script_name' must be a not empty string", false)) | ||
|  |             halt(404, "File '#{file_name}' does not exist") unless File.exists?(@file) | ||
|  |             body = create_object_from_json_body | ||
|  |             nodes = check_array(body["nodes"], "Parameter 'nodes' must be a not empty array of strings") | ||
|  |             p = check_array(body["params"], "Parameter 'params' should be a not empty array of strings", String, true) | ||
|  |             servers = BaseRoutes.mongo.servers_by_names(nodes) | ||
|  |             return [404, "No servers found for names '#{nodes.join("', '")}'"] if servers.empty? | ||
|  |             user = request.env['REMOTE_USER'] | ||
|  |             servers.each do |s| | ||
|  |               BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user | ||
|  |             end | ||
|  |             stream() do |out| | ||
|  |               begin | ||
|  |                 status = [] | ||
|  |                 servers.each do |s| | ||
|  |                   cert = begin | ||
|  |                     BaseRoutes.mongo.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 p.nil? | ||
|  |                     ssh_cmd += " " + p.join(" ") | ||
|  |                   end | ||
|  |                   out << (ssh_cmd % [params[:script_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) | ||
|  |               rescue IOError => e | ||
|  |                 logger.error e.message | ||
|  |               end | ||
|  |             end | ||
|  |           } | ||
|  |         end | ||
|  | 
 | ||
|  |         def self.create_script | ||
|  |           lambda { | ||
|  |             File.open(@file, "w") {|f| f.write(request.body.read)} | ||
|  |             create_response("File '#{params[:script_name]}' created", nil, 201) | ||
|  |           } | ||
|  |         end | ||
|  | 
 | ||
|  |         def self.delete_script | ||
|  |           lambda { | ||
|  |             FileUtils.rm(@file) | ||
|  |             create_response("File '#{params[:script_name]}' deleted") | ||
|  |           } | ||
|  |         end | ||
|  |       end | ||
|  |     end | ||
|  |   end | ||
|  | end | ||
|  | 
 |