fluke/devops-service/app/api2/handlers/project.rb
2015-07-27 15:40:10 +03:00

232 lines
8.5 KiB
Ruby

require "commands/deploy"
require "commands/status"
require "commands/server"
require "db/mongo/models/project"
require "workers/project_test_worker"
require_relative "request_handler"
module Devops
module API2_0
module Handler
class Project < RequestHandler
extend DeployCommands
extend StatusCommands
extend ServerCommands
def projects
fields = []
if @params.key?("fields") and @params["fields"].is_a?(Array)
Devops::Model::Project.fields.each do |k|
fields.push k if @params["fields"].include?(k)
end
end
archived = @params.include?("archived")
Devops::Db.connector.projects(nil, nil, fields, archived)
end
def project id
Devops::Db.connector.project(id)
end
def project_servers id
Devops::Db.connector.project(id)
Devops::Db.connector.servers(id, @params[:deploy_env])
end
# TODO: multi project
def create_project body
p = Devops::Model::Project.new(body)
halt_response("Project '#{p.id}' already exist") if Devops::Db.connector.is_project_exists?(p)
p.add_authorized_user [@request.env['REMOTE_USER']]
p.create
if p.multi?
"Project '#{p.id}' with type 'multi' created"
else
roles = create_roles p.id, p.deploy_envs, logger
"Project '#{p.id}' created. " + create_roles_response(roles)
end
end
# TODO: multi project
def update_project id, body
project = Devops::Model::Project.new(body)
project.id = id
old_project = Devops::Db.connector.project id
Devops::Db.connector.project_update project
roles = create_new_roles(old_project, project, logger)
create_roles_response(roles)
end
# TODO: multi project
def update_project_users id, deploy_env, users
project = Devops::Db.connector.project(id)
dbusers = Devops::Db.connector.users(users).map{|u| u.id}
buf = dbusers - users
project.add_authorized_user users, deploy_env
Devops::Db.connector.project_update(project)
info = "Users '#{dbusers.join("', '")}' has been added to '#{id}' project's authorized users"
info << ", invalid users: '#{buf.join("', '")}'" unless buf.empty?
info
end
# TODO: multi project
def delete_project_users id, deploy_env, users
project = Devops::Db.connector.project(id)
project.remove_authorized_user users, deploy_env
Devops::Db.connector.project_update project
"Users '#{users.join("', '")}' have been removed from '#{id}' project's authorized users"
end
# TODO: multi project
def set_project_env_run_list id, deploy_env, list
project = Devops::Db.connector.project(id)
env = project.deploy_env deploy_env
env.run_list = list
Devops::Db.connector.project_update project
"Updated environment '#{env.identifier}' with run_list '#{env.run_list.inspect}' in project '#{project.id}'"
end
def delete_project id, deploy_env
servers = Devops::Db.connector.servers id
raise DependencyError.new "Deleting #{id} is forbidden: Project has servers" if !servers.empty?
project = Devops::Db.connector.project(id)
info = if deploy_env.nil?
project.delete
"Project '#{id}' is deleted"
else
project.remove_env deploy_env
Devops::Db.connector.project_update project
"Project '#{id}'. Deploy environment '#{deploy_env}' has been deleted"
end
end
def deploy_project_stream out, id, deploy_env, servers, body
keys = {}
dbserver = servers(id, deploy_env, servers)
out << (dbservers.empty? ? "No reserved servers to deploy\n" : "Deploy servers: '#{dbservers.map{|s| s.chef_node_name}.join("', '")}'\n")
status = []
servers.each do |s|
begin
Devops::Db.connector.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 = Devops::Db.connector.key s.key
keys[s.key] = k.path
end
status.push(deploy_server(out, s, keys[s.key]))
end
status
end
def deploy_project id, deploy_env, servers, body
dir = DevopsConfig[:report_dir_v2]
files = []
uri = URI.parse(request.url)
servers(id, deploy_env, servers).each do |s|
project = begin
Devops::Db.connector.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, [], DevopsConfig.config)
#logger.info "Job '#{jid}' has been started"
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
files.push uri.to_s
end
files
end
def servers project_id, deploy_env, servers
project = Devops::Db.connector.project(project_id)
dbservers = Devops::Db.connector.servers(project_id, deploy_env, servers, true)
end
def archive_project id
project = Devops::Db.connector.project(id)
Devops::Db.connector.archive_project(id)
"Project '#{id}' has been archived"
end
def unarchive_project id
project = Devops::Db.connector.project(id)
Devops::Db.connector.unarchive_project(id)
"Project '#{id}' has been unarchived"
end
def test_project id, deploy_env
project = Devops::Db.connector.project(id)
env = project.deploy_env deploy_env
#logger.info "Test project '#{project.id}' and environment '#{env.identifier}'"
if env.provider == ::Provider::Static::PROVIDER
msg = "Can not test environment with provider '#{::Provider::Static::PROVIDER}'"
Logger.warn msg
raise InvalidRecord.new(msg)
end
dir = DevopsConfig[: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, DevopsConfig.config)
Worker.set_status jid, Worker::STATUS::IN_QUEUE
#logger.info "Job '#{jid}' has been created"
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
sleep 1
return [uri.to_s]
end
def 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 create_new_roles old_project, new_project, logger
old_project.deploy_envs.each do |e|
new_project.remove_env(e.identifier)
end
create_roles new_project.id, new_project.deploy_envs, logger
end
def 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