require "commands/deploy" require "commands/status" require "commands/server" require "db/mongo/models/project" require "workers/project_test_worker" require_relative "../helpers/version_2.rb" require_relative "request_handler" module Devops module API2_0 module Handler class Project < RequestHandler include Devops::API2_0::Helpers 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 # check if project exists Devops::Db.connector.project(id) Devops::Db.connector.servers(id, @params[:deploy_env]) end def project_stacks id # check if project exists Devops::Db.connector.project(id) options = {project: @params[:project]} options[:deploy_env] = @params[:deploy_env] if @params[:deploy_env] Devops::Db.connector.stacks(options) end # TODO: multi project def create_project body p = Devops::Model::Project.new(body) raise InvalidRecord.new("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, DevopsLogger.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, DevopsLogger.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) #DevopsLogger.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