240 lines
8.9 KiB
Ruby
240 lines
8.9 KiB
Ruby
require "db/mongo/models/environment/environment"
|
|
require "db/mongo/models/user"
|
|
require "db/mongo/models/environment/environments_array"
|
|
require "json"
|
|
require "hooks"
|
|
require "lib/project/type/types_factory"
|
|
require "exceptions/invalid_record"
|
|
require "exceptions/record_not_found"
|
|
#require "db/validators/environment/environments"
|
|
require "db/validators/project/named_tasks"
|
|
|
|
module Devops
|
|
module Model
|
|
class Project
|
|
|
|
include Hooks
|
|
include Hooks::InstanceHooks
|
|
define_hook :before_create
|
|
define_hook :after_create
|
|
|
|
define_hook :before_delete
|
|
define_hook :after_delete
|
|
|
|
include ::Mongoid::Document
|
|
include ::Mongoid::Timestamps::CreatedInt
|
|
include ::ActiveModel::Validations
|
|
|
|
#attr_accessor :components
|
|
store_in collection: "projects"
|
|
|
|
field :_id, as: :'id', overwrite: true, type: String
|
|
field :environments, type: EnvironmentsArray, default: ->{ [] }
|
|
field :type, type: String
|
|
field :owner, type: String
|
|
field :project_users, type: Array, default: ->{ [] }
|
|
field :archived, type: Boolean
|
|
field :description, type: String
|
|
field :run_list, type: Array, default: ->{ [] }
|
|
field :named_tasks, type: Array, default: ->{ [] }
|
|
|
|
MAX_ID_LEN = 100
|
|
ID_REGEX = /\A[\w\-\.]{1,#{MAX_ID_LEN}}\z/
|
|
|
|
validates_presence_of :id, message: "'id' is undefined"
|
|
validates_length_of :id, minimum: 1, maximum: MAX_ID_LEN
|
|
validates_format_of :id, with: ID_REGEX, message: "invalid id, it should contains 'a-zA-Z0-9-.' symbols"
|
|
validates_uniqueness_of :id, on: :create
|
|
|
|
validates_length_of :description, maximum: 500
|
|
|
|
validates_presence_of :owner, message: "'owner' is undefined"
|
|
validates :named_tasks, proper_named_tasks_format: true
|
|
|
|
|
|
=begin
|
|
TODO:
|
|
|
|
set_field_validators :named_tasks, [::Validators::FieldValidator::Nil,
|
|
::Validators::FieldValidator::FieldType::Array,
|
|
::Validators::FieldValidator::NamedTasks]
|
|
|
|
set_validators ::Validators::DeployEnv::RunList,
|
|
::Validators::DeployEnv::DeployEnvs
|
|
=end
|
|
validates_length_of :description, maximum: 500
|
|
|
|
#TODO: self.named_tasks = p["named_tasks"] || []
|
|
def initialize hash
|
|
raise InvalidRecord.new("Parameter 'id' is not a string") unless hash["id"].is_a?(String)
|
|
raise InvalidRecord.new("Parameter 'environments' is not an array") unless hash["environments"].is_a?(Array) or hash["environments"].nil?
|
|
raise InvalidRecord.new("Parameter 'run_list' is not an array") unless hash["run_list"].is_a?(Array) or hash["run_list"].nil?
|
|
raise InvalidRecord.new("Parameter 'project_users' is not an array") unless hash["project_users"].is_a?(Array) or hash["project_users"].nil?
|
|
super(hash)
|
|
end
|
|
|
|
def self.find_with_environment id, environment
|
|
Project.find_by({_id: id, environments:{'$elemMatch' => {id: environment}}})
|
|
end
|
|
|
|
def self.find_with_category id, environment, category
|
|
Project.find_by(
|
|
_id: id,
|
|
environments: {
|
|
'$elemMatch' => {
|
|
id: environment,
|
|
categories: {'$elemMatch' => {id: category}}
|
|
}
|
|
}
|
|
)
|
|
end
|
|
|
|
# TODO: extract to handler or parser
|
|
def self.list_fields
|
|
['deploy_envs', 'type', 'description', 'named_tasks']
|
|
end
|
|
|
|
def self.check_user_authorization project_id, env, user_id
|
|
# find({'_id' => project_id}).projection({environments:{'$elemMatch' => {id:env}}})
|
|
project = find(project_id)
|
|
if !project.check_authorization(user_id, env)
|
|
raise Devops::Exception::Unauthorized.new("User '#{user_id}' is unauthorized to work with project '#{project_id}' and environment '#{env}'")
|
|
end
|
|
project
|
|
rescue Mongoid::Errors::DocumentNotFound
|
|
raise Devops::Exception::RecordNotFound.new("Project with id '#{project_id}' not found")
|
|
end
|
|
|
|
def environment env
|
|
de = self.environments.detect {|e| e.id == env}
|
|
raise Devops::Exception::RecordNotFound.new("Project '#{self.id}' does not have deploy environment '#{env}'") if de.nil?
|
|
de
|
|
end
|
|
|
|
def add_environment environment
|
|
self.push(environments: environment.to_hash)
|
|
DevopsLogger.logger.info("Added environment '#{environment.id}' to project '#{self.id}'")
|
|
DevopsLogger.logger.debug("Added environment: #{environment.to_hash.inspect}")
|
|
end
|
|
|
|
def add_category env, category
|
|
env.categories.push category
|
|
category_hash = category.to_hash
|
|
Project.where('_id' => self.id, 'environments.id' => env.id).push('environments.$.categories' => category_hash)
|
|
DevopsLogger.logger.debug("Added category '#{category.id}' to project '#{self.id}' and environment '#{env.id}'")
|
|
DevopsLogger.logger.debug("Added category: #{category_hash.inspect}")
|
|
category
|
|
end
|
|
|
|
def delete_category env, category_id
|
|
bsize = env.categories.size
|
|
env.categories.delete_if{|c| c.id == category_id}
|
|
if bsize == env.categories.size
|
|
raise Devops::Exception::RecordNotFound.new("Category '#{category_id}' in project '#{id}' and deploy environment '#{env}' does not exist")
|
|
else
|
|
Project.where({'_id' => self.id, 'environments.id' => env.id}).pull('environments.$.categories' => {'id' => category_id})
|
|
DevopsLogger.logger.info("Category '#{category_id}' removed from project '#{self.id}' and environment '#{env.id}'")
|
|
end
|
|
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.environments : [ self.environment(env) ]
|
|
environments.each do |e|
|
|
e.add_users new_users
|
|
Devops::Db.connector.set_project_environment_field(self.id, e.id, {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.environments : [ self.environment(env) ]
|
|
environments.each do |e|
|
|
e.users = e.users - users
|
|
Devops::Db.connector.set_project_environment_field(self.id, e.id, {users: e.users})
|
|
end
|
|
end
|
|
|
|
def check_authorization user_id, env
|
|
return true if user_id == self.owner or user_id == User::ROOT_USER_NAME
|
|
return true if is_sandbox?
|
|
e = self.environment(env)
|
|
return e.users.include? user_id
|
|
rescue Devops::Exception::RecordNotFound => e
|
|
return false
|
|
end
|
|
|
|
def is_sandbox?
|
|
id.start_with?('sandbox-')
|
|
end
|
|
|
|
def delete_environment env
|
|
self.environments.delete_if {|e| e.id == env}
|
|
Project.where('_id' => self.id).pull('environments' => {'id' => env})
|
|
end
|
|
|
|
def to_hash
|
|
hash = self.attributes.clone
|
|
hash["id"] = hash.delete("_id")
|
|
hash.delete('archived') unless hash['archived']
|
|
hash
|
|
end
|
|
|
|
# TODO: why symbols here?
|
|
def to_hash_list
|
|
{
|
|
id: self.id,
|
|
description: self.description,
|
|
owner: self.owner,
|
|
run_list: self.run_list,
|
|
project_users: self.project_users,
|
|
created_at: self.created_at
|
|
}
|
|
end
|
|
|
|
def deploy_info environment, build_number=nil
|
|
{
|
|
"use_json_file" => false,
|
|
# "run_list" => Set.new.merge(self.run_list).merge(environment.run_list).to_a,
|
|
"project" => self.id,
|
|
"project_info" => {
|
|
"project" => self.id,
|
|
"environment" => environment.id,
|
|
"deployers" => environment.users
|
|
}
|
|
}
|
|
end
|
|
|
|
=begin
|
|
def extract_servers env, params
|
|
@handler.extract_servers(self, env, params)
|
|
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 'fileid'" unless c.key?("fileid")
|
|
end
|
|
end
|
|
=end
|
|
|
|
# def self.create_roles_response roles
|
|
# return "error in creating roles" unless roles
|
|
# 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
|