fluke/devops-service/routes/v2.0/handlers/script.rb

128 lines
4.8 KiB
Ruby
Raw Normal View History

2014-12-22 14:22:04 +03:00
require "providers/provider_factory"
require "fileutils"
require "commands/status"
module Devops
module Version2_0
module Handler
class Script
def self.get_scripts
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("script", "r")
2014-12-22 14:22:04 +03:00
res = []
Dir.foreach(DevopsService.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")}
json res
}
end
def self.execute_command
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("script", "x")
2014-12-22 14:22:04 +03:00
user = request.env['REMOTE_USER']
2015-02-18 11:08:44 +03:00
s = ::Devops::Db.connector.server_by_chef_node_name params[:node_name]
::Devops::Db.connector.check_project_auth s.project, s.deploy_env, user
cert = ::Devops::Db.connector.key s.key
2014-12-22 14:22:04 +03:00
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 {
2015-02-19 11:27:56 +03:00
check_privileges("script", "x")
2014-12-22 14:22:04 +03:00
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)
2015-02-18 11:08:44 +03:00
servers = ::Devops::Db.connector.servers_by_names(nodes)
2014-12-22 14:22:04 +03:00
return [404, "No servers found for names '#{nodes.join("', '")}'"] if servers.empty?
user = request.env['REMOTE_USER']
servers.each do |s|
2015-02-18 11:08:44 +03:00
::Devops::Db.connector.check_project_auth s.project, s.deploy_env, user
2014-12-22 14:22:04 +03:00
end
stream() do |out|
begin
status = []
servers.each do |s|
cert = begin
2015-02-18 11:08:44 +03:00
::Devops::Db.connector.key s.key
2014-12-22 14:22:04 +03:00
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 {
2015-02-19 11:27:56 +03:00
check_privileges("script", "w")
file_name = params[:script_name]
2015-07-06 17:00:45 +03:00
file = File.join(settings.scripts_dir, check_filename(file_name, "Parameter 'script_name' must be a not empty string"))
2015-02-19 11:27:56 +03:00
halt_response("File '#{file_name}' already exist") if File.exists?(file)
File.open(file, "w") {|f| f.write(request.body.read)}
2014-12-22 14:22:04 +03:00
create_response("File '#{params[:script_name]}' created", nil, 201)
}
end
def self.delete_script
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("script", "w")
file_name = params[:script_name]
2015-07-06 17:00:45 +03:00
file = File.join(settings.scripts_dir, check_filename(file_name, "Parameter 'script_name' must be a not empty string"))
2015-02-19 11:27:56 +03:00
halt_response("File '#{file_name}' does not exist", 404) unless File.exists?(file)
FileUtils.rm(file)
2014-12-22 14:22:04 +03:00
create_response("File '#{params[:script_name]}' deleted")
}
end
end
end
end
end