258 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			258 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require "commands/deploy"
 | |
| require "commands/status"
 | |
| require "commands/server"
 | |
| require "db/mongo/models/project"
 | |
| require "workers/project_test_worker"
 | |
| require "app/api2/parsers/project"
 | |
| require "lib/project/type/types_factory"
 | |
| require_relative "../helpers/version_2.rb"
 | |
| require_relative "request_handler"
 | |
| 
 | |
| module Devops
 | |
|   module API2_0
 | |
|     module Handler
 | |
|       class Project < RequestHandler
 | |
| 
 | |
|         set_parser Devops::API2_0::Parser::ProjectParser
 | |
| 
 | |
|         include Devops::API2_0::Helpers
 | |
| 
 | |
|         extend DeployCommands
 | |
|         extend StatusCommands
 | |
|         extend ServerCommands
 | |
| 
 | |
|         def project_types
 | |
|           Devops::TypesFactory.types_names
 | |
|         end
 | |
| 
 | |
|         def projects
 | |
|           Devops::Db.connector.projects(nil, nil, parser.projects, parser.archived_projects)
 | |
|         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, parser.project_servers)
 | |
|         end
 | |
| 
 | |
|         def project_stacks id
 | |
|           # check if project exists
 | |
|           Devops::Db.connector.project(id)
 | |
|           options = {project: id}
 | |
|           deploy_env = parser.project_stacks
 | |
|           options[:deploy_env] = deploy_env if deploy_env
 | |
|           Devops::Db.connector.stacks(options)
 | |
|         end
 | |
| 
 | |
|         # TODO: multi project
 | |
|         def create_project
 | |
|           p = parser.create_project
 | |
|           raise InvalidRecord.new("Project '#{p.id}' already exist") if Devops::Db.connector.is_project_exists?(p)
 | |
| 
 | |
|           p.add_authorized_user [parser.current_user]
 | |
|           p.create
 | |
|           if p.multi?
 | |
|             "Project '#{p.id}' with type 'multi' created"
 | |
|           else
 | |
|             roles = create_roles p.id, p.deploy_envs
 | |
|             "Project '#{p.id}' created. " + create_roles_response(roles)
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         # TODO: multi project
 | |
|         def update_project id
 | |
|           project = parser.update
 | |
|           project.id = id
 | |
|           old_project = Devops::Db.connector.project id
 | |
|           Devops::Db.connector.project_update project
 | |
|           roles = create_new_roles(old_project, project)
 | |
|           create_roles_response(roles)
 | |
|         end
 | |
| 
 | |
|         # TODO: multi project
 | |
|         def update_project_users id
 | |
|           deploy_env, users = parser.project_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 = parser.project_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
 | |
| 
 | |
|         def set_project_run_list id
 | |
|           list = parser.run_list
 | |
|           project = Devops::Db.connector.project(id)
 | |
|           Devops::Db.connector.set_project_run_list id, list
 | |
|           "Updated project with run_list '#{list.inspect}'"
 | |
|         end
 | |
| 
 | |
|         def set_project_env_run_list id, deploy_env
 | |
|           list = parser.run_list
 | |
|           project = Devops::Db.connector.project(id)
 | |
|           env = project.deploy_env deploy_env
 | |
|           Devops::Db.connector.set_project_env_run_list id, deploy_env, list
 | |
|           "Updated environment '#{env.identifier}' with run_list '#{list.inspect}' in project '#{project.id}'"
 | |
|         end
 | |
| 
 | |
|         def delete_project id
 | |
|           deploy_env = parser.delete
 | |
|           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 = parser.deploy
 | |
|           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 = parser.deploy
 | |
|           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
 | |
|           DevopsLogger.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
 | |
|           DevopsLogger.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
 | |
|           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
 | |
|                 DevopsLogger.logger.info "Role '#{role_name}' created"
 | |
|               end
 | |
|             rescue => er
 | |
|               roles[:error].push role_name
 | |
|               DevopsLogger.logger.error "Role '#{role_name}' can not be created: #{er.message}"
 | |
|             end
 | |
|           end
 | |
|           roles
 | |
|         end
 | |
| 
 | |
|         def create_new_roles old_project, new_project
 | |
|           old_project.deploy_envs.each do |e|
 | |
|             new_project.remove_env(e.identifier)
 | |
|           end
 | |
|           create_roles new_project.id, new_project.deploy_envs
 | |
|         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
 | |
| 
 | 
