250 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require "db/mongo/models/deploy_env/deploy_env_factory"
 | |
| require "db/mongo/models/user"
 | |
| require "db/mongo/models/deploy_env/deploy_env_multi"
 | |
| require "db/mongo/models/mongo_model"
 | |
| require "json"
 | |
| require "hooks"
 | |
| require "lib/project/type/types_factory"
 | |
| require "db/validators/deploy_env/deploy_envs"
 | |
| 
 | |
| module Devops
 | |
|   module Model
 | |
|     class Project < MongoModel
 | |
| 
 | |
|       include Hooks
 | |
|       include Hooks::InstanceHooks
 | |
|       define_hook :before_create
 | |
|       define_hook :after_create
 | |
| 
 | |
|       define_hook :before_delete
 | |
|       define_hook :after_delete
 | |
| 
 | |
|       #define_hook :after_add_deploy_env
 | |
| 
 | |
|       attr_accessor :id, :deploy_envs, :type, :archived, :description, :run_list
 | |
|       attr_accessor :components
 | |
| 
 | |
|       MULTI_TYPE = "multi"
 | |
| 
 | |
|       set_field_validators :id, [::Validators::FieldValidator::NotNil,
 | |
|                                     ::Validators::FieldValidator::FieldType::String,
 | |
|                                     ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :deploy_envs, [::Validators::FieldValidator::NotNil,
 | |
|                                     ::Validators::FieldValidator::FieldType::Array,
 | |
|                                     ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :description, [::Validators::FieldValidator::Nil,
 | |
|                                     ::Validators::FieldValidator::FieldType::String]
 | |
| 
 | |
|       set_field_validators :run_list, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::Array,
 | |
|                                       ::Validators::FieldValidator::RunList]
 | |
| 
 | |
|       # should be an array of hashes like:
 | |
|       # {
 | |
|       #   'name' => 'restart',
 | |
|       #   'run_list' => [
 | |
|       #     'role[restart_service]'
 | |
|       #   ]
 | |
|       # }
 | |
|       set_field_validators :named_tasks, [::Validators::FieldValidator::Nil,
 | |
|                                     ::Validators::FieldValidator::FieldType::Array,
 | |
|                                     ::Validators::FieldValidator::NamedTasks]
 | |
| 
 | |
|       set_validators ::Validators::DeployEnv::RunList,
 | |
|                      ::Validators::DeployEnv::DeployEnvs
 | |
| 
 | |
| 
 | |
|       def self.fields
 | |
|         ["deploy_envs", "type", "description", "named_tasks"]
 | |
|       end
 | |
| 
 | |
|       def initialize p={}
 | |
|         self.id = p["name"]
 | |
|         #raise InvalidRecord.new "No deploy environments for project #{self.id}" if p["deploy_envs"].nil? or p["deploy_envs"].empty?
 | |
|         self.type = p["type"] || Devops::GenericType.name
 | |
|         self.description = p["description"]
 | |
|         self.archived = p["archived"] || false
 | |
|         self.run_list = p["run_list"] || []
 | |
|         self.named_tasks = p["named_tasks"] || []
 | |
| 
 | |
|         @handler = Devops::TypesFactory.type self.type
 | |
|         @handler.prepare(self)
 | |
| 
 | |
|         env_class = ( self.multi? ? DeployEnvMulti : DeployEnvFactory )
 | |
|         unless p["deploy_envs"].nil?
 | |
|           self.deploy_envs = []
 | |
|           p["deploy_envs"].each do |e|
 | |
|             env = env_class.create(e)
 | |
|             self.deploy_envs.push env
 | |
|           end
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def deploy_env env
 | |
|         de = self.deploy_envs.detect {|e| e.identifier == env}
 | |
|         raise RecordNotFound.new("Project '#{self.id}' does not have deploy environment '#{env}'") if de.nil?
 | |
|         de
 | |
|       end
 | |
| 
 | |
|       def add_deploy_env deploy_env
 | |
|         res = deploy_env.create_role(self.id)
 | |
|         Devops::Db.connector.add_deploy_env_to_project self.id, deploy_env
 | |
|         Project.create_roles_response(res)
 | |
|       end
 | |
| 
 | |
|       # user could be a String or an Array of strings.
 | |
|       # if env is nil, add given user(s) to all project's envs,
 | |
|       # otherwise only to specified one.
 | |
|       def add_authorized_user user, env=nil
 | |
|         return if user.nil?
 | |
|         new_users = ( user.is_a?(Array) ? user : [ user ] )
 | |
|         environments = env.nil? ? self.deploy_envs : [ self.deploy_env(env) ]
 | |
|         environments.each do |e|
 | |
|           e.add_users new_users
 | |
|           Devops::Db.connector.set_project_deploy_env_field(self.id, e.identifier, {users: e.users})
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def remove_authorized_user user, env=nil
 | |
|         return if user.nil?
 | |
|         users = ( user.is_a?(Array) ? user : [ user ] )
 | |
|         environments = env.nil? ? self.deploy_envs : [ self.deploy_env(env) ]
 | |
|         environments.each do |e|
 | |
|           e.users = e.users - users
 | |
|           Devops::Db.connector.set_project_deploy_env_field(self.id, e.identifier, {users: e.users})
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def check_authorization user_id, env
 | |
|         e = self.deploy_env(env)
 | |
|         return true if user_id == User::ROOT_USER_NAME
 | |
|         return true if is_sandbox?
 | |
|         return e.users.include? user_id
 | |
|       rescue RecordNotFound => e
 | |
|         return false
 | |
|       end
 | |
| 
 | |
|       def is_sandbox?
 | |
|         id.start_with?('sandbox-')
 | |
|       end
 | |
| 
 | |
| =begin
 | |
|       def validate!
 | |
|         super
 | |
|         check_name_value(self.id)
 | |
| 
 | |
|         true
 | |
|       rescue InvalidRecord, ArgumentError => e
 | |
|         raise InvalidRecord.new "Project '#{self.id}'. #{e.message}"
 | |
|       end
 | |
| =end
 | |
| 
 | |
|       def delete_deploy_env env
 | |
|         self.deploy_envs.delete_if {|e| e.identifier == env}
 | |
|         Devops::Db.connector.remove_deploy_env_from_project self.id, env
 | |
|       end
 | |
| 
 | |
| =begin
 | |
|       def add_env env
 | |
|         raise InvalidRecord.new "Deploy environment '#{env.identifier}' for project '#{self.id}' already exist" unless self.deploy_env(env.identifier).nil?
 | |
|         self.deploy_envs.push env
 | |
|       end
 | |
| =end
 | |
| 
 | |
|       def to_hash
 | |
|         h = self.to_hash_without_id
 | |
|         h["name"] = self.id
 | |
|         h
 | |
|       end
 | |
| 
 | |
|       # TODO: why symbols here?
 | |
|       def to_hash_list
 | |
|         {
 | |
|           name: self.id,
 | |
|           description: self.description
 | |
|         }
 | |
|       end
 | |
| 
 | |
|       def deploy_info deploy_env, build_number=nil
 | |
|         {
 | |
|           "use_json_file" => true,
 | |
| #          "run_list" => Set.new.merge(self.run_list).merge(deploy_env.run_list).to_a,
 | |
|           "project" => self.id,
 | |
|           "project_info" => {
 | |
|             "project" => self.id,
 | |
|             "deploy_env" => deploy_env.identifier,
 | |
|             "deployers" => deploy_env.users
 | |
|           }
 | |
|         }
 | |
|       end
 | |
| 
 | |
|       def to_hash_without_id
 | |
|         h = {}
 | |
|         h["deploy_envs"] = self.deploy_envs.map {|e| e.to_hash} unless self.deploy_envs.nil?
 | |
|         h["archived"] = self.archived if self.archived
 | |
|         h["description"] = self.description
 | |
|         h["run_list"] = self.run_list
 | |
|         h["named_tasks"] = self.named_tasks
 | |
|         if self.multi?
 | |
|           h["type"] = MULTI_TYPE
 | |
|         end
 | |
|         h
 | |
|       end
 | |
| 
 | |
|       def multi?
 | |
|         self.type == MULTI_TYPE
 | |
|       end
 | |
| 
 | |
|       def create
 | |
|         res = {}
 | |
|         res[:before] = self.run_hook :before_create
 | |
|         Devops::Db.connector.project_insert self
 | |
|         res[:after] = self.run_hook :after_create
 | |
|         res
 | |
|       end
 | |
| 
 | |
|       def delete
 | |
|         res = {}
 | |
|         res[:before] = self.run_hook :before_delete
 | |
|         Devops::Db.connector.project_delete self.id
 | |
|         res[:after] = self.run_hook :after_delete
 | |
|         res
 | |
|       end
 | |
| 
 | |
|       def extract_servers env, params
 | |
|         @handler.extract_servers(self, env, params)
 | |
|       end
 | |
| 
 | |
|       def self.build_from_bson p
 | |
|         p["name"] = p["_id"]
 | |
|         Project.new p
 | |
|       end
 | |
| 
 | |
|       # maybe it worth to move components functionality to devops-nibr?
 | |
|       #TODO: create validator
 | |
|       def validate_components
 | |
|         raise InvalidRecord.new "Components is not a hash" unless self.components.is_a?(Hash)
 | |
|         self.components.each do |id, c|
 | |
|           raise InvalidRecord.new "Component '#{id}' has no attribute 'filename'" unless c.key?("filename")
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def self.create_roles_response roles
 | |
|         return "error in creating roles" unless roles
 | |
|         if roles.is_a?(String)
 | |
|           roles
 | |
|         else
 | |
|           info = ""
 | |
|           info += " Project roles '#{roles[:new].join("', '")}' have been automaticaly created" unless roles[:new].nil?
 | |
|           info += " Project roles '#{roles[:exist].join("', '")}' weren't created because they exist" unless roles[:exist].nil?
 | |
|           info += " Project roles '#{roles[:error].join("', '")}' weren't created because of internal error" unless roles[:error].nil?
 | |
|           info
 | |
|         end
 | |
|       end
 | |
| 
 | |
|     end
 | |
|   end
 | |
| end
 | 
