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

271 lines
11 KiB
Ruby
Raw Normal View History

2014-12-22 14:22:04 +03:00
require "commands/deploy"
require "commands/status"
require "commands/server"
require "db/mongo/models/project"
require "workers/project_test_worker"
module Devops
module Version2_0
module Handler
class Project
extend DeployCommands
extend StatusCommands
extend ServerCommands
def self.get_projects
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "r")
2014-12-22 14:22:04 +03:00
fields = []
if params.key?("fields") and params["fields"].is_a?(Array)
2015-02-19 14:16:07 +03:00
::Project.fields.each do |k|
2014-12-22 14:22:04 +03:00
fields.push k if params["fields"].include?(k)
end
end
json settings.mongo.projects(nil, nil, fields).map {|p| p.to_hash}
}
end
def self.get_project
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "r")
2014-12-22 14:22:04 +03:00
json settings.mongo.project(params[:project])
}
end
def self.get_project_servers
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "r")
2014-12-22 14:22:04 +03:00
settings.mongo.project(params[:project])
json settings.mongo.servers(params[:project], params[:deploy_env]).map{|s| s.to_hash}
}
end
# TODO: multi project
def self.create_project
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "w")
2014-12-22 14:22:04 +03:00
body = create_object_from_json_body
check_string(body["name"], "Parameter 'name' must be a not empty string")
check_array(body["deploy_envs"], "Parameter 'deploy_envs' must be a not empty array of objects", Hash)
2015-02-19 14:16:07 +03:00
p = ::Project.new(body)
2014-12-22 14:22:04 +03:00
halt_response("Project '#{p.id}' already exist") if settings.mongo.is_project_exists?(p)
p.add_authorized_user [request.env['REMOTE_USER']]
settings.mongo.project_insert p
roles_res = ""
if p.multi?
logger.info "Project '#{p.id}' with type 'multi' created"
else
logger.info "Project '#{p.id}' created"
roles = Project.create_roles p.id, p.deploy_envs, logger
roles_res = ". " + Project.create_roles_response(roles)
end
res = "Created" + roles_res
create_response(res, nil, 201)
}
end
# TODO: multi project
def self.update_project
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "w")
2015-02-19 14:16:07 +03:00
project = ::Project.new(create_object_from_json_body)
project.id = params[:project]
old_project = settings.mongo.project params[:project]
2014-12-22 14:22:04 +03:00
settings.mongo.project_update project
2015-02-19 14:16:07 +03:00
roles = ::Project.create_new_roles(old_project, project, logger)
2014-12-22 14:22:04 +03:00
info = "Project '#{project.id}' has been updated." + Project.create_roles_response(roles)
create_response(info)
}
end
# TODO: multi project
def self.update_project_users
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "w")
body = create_object_from_json_body
users = check_array(body["users"], "Parameter 'users' must be a not empty array of strings")
deploy_env = check_string(body["deploy_env"], "Parameter 'deploy_env' must be a not empty string", true)
project = settings.mongo.project(params[:id])
users = settings.mongo.users(users).map{|u| u.id}
buf = users - users
project.add_authorized_user users, deploy_env
settings.mongo.project_update(project)
2014-12-22 14:22:04 +03:00
info = "Users '#{users.join("', '")}' have been added to '#{params[:id]}' project's authorized users"
info << ", invalid users: '#{buf.join("', '")}'" unless buf.empty?
create_response(info)
}
end
# TODO: multi project
def self.delete_project_users
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "w")
2014-12-22 14:22:04 +03:00
@project.remove_authorized_user @users, @deploy_env
settings.mongo.project_update @project
info = "Users '#{@users.join("', '")}' have been removed from '#{params[:id]}' project's authorized users"
create_response(info)
}
end
# TODO: multi project
def self.set_project_env_run_list
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "w")
2014-12-22 14:22:04 +03:00
list = create_object_from_json_body(Array)
check_array(list, "Body must contains not empty array of strings")
project = settings.mongo.project(params[:id])
env = project.deploy_env params[:env]
env.run_list = list
settings.mongo.project_update project
create_response("Updated environment '#{env.identifier}' with run_list '#{env.run_list.inspect}' in project '#{project.id}'")
}
end
def self.delete_project
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "w")
2015-02-19 14:16:07 +03:00
servers = settings.mongo.servers params[:project]
raise DependencyError.new "Deleting #{params[:project]} is forbidden: Project has servers" if !servers.empty?
2014-12-22 14:22:04 +03:00
body = create_object_from_json_body(Hash, true)
deploy_env = unless body.nil?
check_string(body["deploy_env"], "Parameter 'deploy_env' should be a not empty string", true)
end
info = if deploy_env.nil?
2015-02-19 14:16:07 +03:00
settings.mongo.project_delete(params[:project])
"Project '#{params[:project]}' is deleted"
2014-12-22 14:22:04 +03:00
else
2015-02-19 14:16:07 +03:00
project = settings.mongo.project(params[:project])
2014-12-22 14:22:04 +03:00
project.remove_env params[:deploy_env]
settings.mongo.project_update project
2015-02-19 14:16:07 +03:00
"Project '#{params[:project]}'. Deploy environment '#{params[:deploy_env]}' has been deleted"
2014-12-22 14:22:04 +03:00
end
create_response(info)
}
end
def self.deploy_project
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "x")
2014-12-22 14:22:04 +03:00
obj = create_object_from_json_body
check_string(obj["deploy_env"], "Parameter 'deploy_env' should be a not empty string", true)
check_array(obj["servers"], "Parameter 'servers' should be a not empty array of strings", String, true)
project = settings.mongo.project(params[:id])
servers = settings.mongo.servers(params[:id], obj["deploy_env"], obj["servers"], true)
keys = {}
if obj.key?("trace")
stream() do |out|
begin
out << (servers.empty? ? "No reserved servers to deploy\n" : "Deploy servers: '#{servers.map{|s| s.chef_node_name}.join("', '")}'\n")
status = []
servers.each do |s|
logger.debug "Deploy server: #{s.inspect}"
begin
settings.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER']
rescue InvalidPrivileges, RecordNotFound => e
out << e.message + "\n"
status.push 2
next
end
unless keys.key? s.key
k = settings.mongo.key s.key
keys[s.key] = k.path
end
status.push(deploy_server(out, s, keys[s.key]))
end
out << create_status(status)
rescue IOError => e
logger.error e.message
end
end
else
dir = DevopsService.config[:report_dir_v2]
files = []
uri = URI.parse(request.url)
servers.each do |s|
project = begin
settings.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER']
rescue InvalidPrivileges, RecordNotFound => e
next
end
jid = DeployWorker.perform_async(dir, s.to_hash, [], DevopsService.config)
logger.info "Job '#{jid}' has been started"
uri.path = "#{DevopsService.config[:url_prefix]}/v2.0/report/" + jid
files.push uri.to_s
end
json files
end
}
end
def self.test_project
lambda {
2015-02-19 11:27:56 +03:00
check_privileges("project", "r")
2014-12-22 14:22:04 +03:00
project = settings.mongo.project(params[:id])
env = project.deploy_env params[:env]
logger.info "Test project '#{project.id}' and environment '#{env.identifier}'"
dir = DevopsService.config[:report_dir_v2]
uri = URI.parse(request.url)
p = {
:project => project.id,
:env => env.identifier,
:user => request.env['REMOTE_USER']
}
jid = ProjectTestWorker.perform_async(dir, p, DevopsService.config)
logger.info "Job '#{jid}' has been created"
uri.path = "#{DevopsService.config[:url_prefix]}/v2.0/report/" + jid
files = [uri.to_s]
sleep 1
json files
}
end
def self.create_roles project_id, envs, logger
all_roles = KnifeCommands.roles
return " Can't get roles list" if all_roles.nil?
roles = {:new => [], :error => [], :exist => []}
envs.each do |e|
role_name = KnifeCommands.role_name(project_id, e.identifier)
begin
if all_roles.include? role_name
roles[:exist].push role_name
else
KnifeCommands.create_role role_name, project_id, e.identifier
roles[:new].push role_name
logger.info "Role '#{role_name}' created"
end
rescue => er
roles[:error].push role_name
logger.error "Role '#{role_name}' can not be created: #{er.message}"
end
end
roles
end
def self.create_new_roles old_project, new_project, logger
old_project.deploy_envs.each do |e|
new_project.remove_env(e.identifier)
end
2015-02-19 14:16:07 +03:00
::Project.create_roles new_project.id, new_project.deploy_envs, logger
2014-12-22 14:22:04 +03:00
end
def self.create_roles_response roles
if roles.is_a?(String)
roles
else
info = ""
info += " Project roles '#{roles[:new].join("', '")}' have been automaticaly created" unless roles[:new].empty?
info += " Project roles '#{roles[:exist].join("', '")}' weren't created because they exist" unless roles[:exist].empty?
info += " Project roles '#{roles[:error].join("', '")}' weren't created because of internal error" unless roles[:error].empty?
info
end
end
end
end
end
end