merged with achuchkalov
This commit is contained in:
parent
a0dd907afc
commit
fa3450e03e
19
devops-service/db/mongo/connectors/base.rb
Normal file
19
devops-service/db/mongo/connectors/base.rb
Normal file
@ -0,0 +1,19 @@
|
||||
require "db/exceptions/record_not_found"
|
||||
require "db/exceptions/invalid_record"
|
||||
require "exceptions/invalid_command"
|
||||
require "exceptions/invalid_privileges"
|
||||
|
||||
module Connectors
|
||||
class Base
|
||||
# Yes, we can implement connectors without attr_accessor, storing collection directly
|
||||
# in instance variable like
|
||||
# @collection = db.collection('users')
|
||||
#
|
||||
# But with latter approach included modules should know about instance variables of
|
||||
# base classes.
|
||||
# Also, debugging "No method error" is simplier than seeking missing instance var.
|
||||
private
|
||||
|
||||
attr_accessor :collection
|
||||
end
|
||||
end
|
||||
38
devops-service/db/mongo/connectors/filter.rb
Normal file
38
devops-service/db/mongo/connectors/filter.rb
Normal file
@ -0,0 +1,38 @@
|
||||
module Connectors
|
||||
class Filter < Base
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('filters')
|
||||
end
|
||||
|
||||
def available_images provider
|
||||
f = collection.find('type' => 'image', 'provider' => provider).to_a.first
|
||||
return [] if f.nil?
|
||||
f['images']
|
||||
end
|
||||
|
||||
def add_available_images images, provider
|
||||
return unless images.is_a?(Array)
|
||||
f = collection.find('type' => 'image', 'provider' => provider).to_a.first
|
||||
if f.nil?
|
||||
collection.insert('type' => 'image', 'provider' => provider, 'images' => images)
|
||||
return images
|
||||
else
|
||||
f['images'] |= images
|
||||
collection.update({'_id' => f['_id']}, f)
|
||||
return f['images']
|
||||
end
|
||||
end
|
||||
|
||||
def delete_available_images images, provider
|
||||
return unless images.is_a?(Array)
|
||||
f = collection.find('type' => 'image', 'provider' => provider).to_a.first
|
||||
unless f.nil?
|
||||
f['images'] -= images
|
||||
collection.update({'_id' => f['_id']}, f)
|
||||
return f['images']
|
||||
end
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
26
devops-service/db/mongo/connectors/helpers/delete_command.rb
Normal file
26
devops-service/db/mongo/connectors/helpers/delete_command.rb
Normal file
@ -0,0 +1,26 @@
|
||||
require 'lib/string_helper'
|
||||
|
||||
module Connectors
|
||||
module Helpers
|
||||
module DeleteCommand
|
||||
|
||||
# when included, this module adds method #delete and alias for it.
|
||||
# Alias name depends on base class name.
|
||||
# We need this alias to forward methods from MongoConnector to resources connectors.
|
||||
|
||||
def self.included(base)
|
||||
resource_name = StringHelper.underscore_class(base)
|
||||
method_name = "#{resource_name}_delete".to_sym
|
||||
alias_method method_name, :delete
|
||||
end
|
||||
|
||||
def delete(id, options={})
|
||||
delete_query = {'_id' => id}.merge(options)
|
||||
r = collection.remove(delete_query)
|
||||
raise RecordNotFound.new("'#{id}' not found") if r['n'] == 0
|
||||
r
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
31
devops-service/db/mongo/connectors/helpers/insert_command.rb
Normal file
31
devops-service/db/mongo/connectors/helpers/insert_command.rb
Normal file
@ -0,0 +1,31 @@
|
||||
require 'lib/string_helper'
|
||||
|
||||
module Connectors
|
||||
module Helpers
|
||||
module InsertCommand
|
||||
|
||||
# when included, this module adds method #insert and alias for it.
|
||||
# Alias name depends on base class name.
|
||||
# We need this alias to forward methods from MongoConnector to resources connectors.
|
||||
|
||||
def self.included(base)
|
||||
resource_name = StringHelper.underscore_class(base)
|
||||
method_name = "#{resource_name}_insert".to_sym
|
||||
alias_method method_name, :insert
|
||||
end
|
||||
|
||||
def insert(record)
|
||||
begin
|
||||
record.validate!
|
||||
collection.insert(record.to_mongo_hash)
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
resource_name = StringHelper.underscore_class(record.class)
|
||||
raise InvalidRecord.new("Duplicate key error: #{resource_name} with id '#{record.id}'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
24
devops-service/db/mongo/connectors/helpers/list_command.rb
Normal file
24
devops-service/db/mongo/connectors/helpers/list_command.rb
Normal file
@ -0,0 +1,24 @@
|
||||
require 'lib/string_helper'
|
||||
|
||||
module Connectors
|
||||
module Helpers
|
||||
module ListCommand
|
||||
|
||||
# when included, this module adds method #list and alias for it.
|
||||
# Alias name depends on base class name.
|
||||
# We need this alias to forward methods from MongoConnector to resources connectors.
|
||||
|
||||
def self.included(base)
|
||||
resource_name = StringHelper.underscore_class(base).to_sym
|
||||
method_name = StringHelper.pluralize(resource_name)
|
||||
alias_method method_name, :list
|
||||
end
|
||||
|
||||
# query options is needed, for example, for fields limiting
|
||||
def list(query={}, query_options={})
|
||||
collection.find(query, query_options).to_a.map {|bson| model_from_bson(bson)}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
25
devops-service/db/mongo/connectors/helpers/show_command.rb
Normal file
25
devops-service/db/mongo/connectors/helpers/show_command.rb
Normal file
@ -0,0 +1,25 @@
|
||||
require 'lib/string_helper'
|
||||
|
||||
module Connectors
|
||||
module Helpers
|
||||
module ShowCommand
|
||||
|
||||
# when included, this module adds method #show and alias for it.
|
||||
# Alias name depends on base class name.
|
||||
# We need this alias to forward methods from MongoConnector to resources connectors.
|
||||
|
||||
def self.included(base)
|
||||
method_name = StringHelper.underscore_class(base).to_sym
|
||||
alias_method method_name, :show
|
||||
end
|
||||
|
||||
def show(id, options={})
|
||||
query = {'_id' => id}.merge(options)
|
||||
bson = collection.find(query).to_a.first
|
||||
raise RecordNotFound.new("'#{id}' not found") unless bson
|
||||
model_from_bson(bson)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
29
devops-service/db/mongo/connectors/helpers/update_command.rb
Normal file
29
devops-service/db/mongo/connectors/helpers/update_command.rb
Normal file
@ -0,0 +1,29 @@
|
||||
require 'lib/string_helper'
|
||||
|
||||
module Connectors
|
||||
module Helpers
|
||||
module UpdateCommand
|
||||
|
||||
# when included, this module adds method #update and alias for it.
|
||||
# Alias name depends on base class name.
|
||||
# We need this alias to forward methods from MongoConnector to resources connectors.
|
||||
|
||||
def self.included(base)
|
||||
resource_name = StringHelper.underscore_class(base)
|
||||
method_name = "#{resource_name}_update".to_sym
|
||||
alias_method method_name, :update
|
||||
end
|
||||
|
||||
def update(record)
|
||||
record.validate!
|
||||
collection.update({"_id" => record.id}, record.to_mongo_hash)
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
resource_name = StringHelper.underscore_class(record.class)
|
||||
raise InvalidRecord.new("Duplicate key error: #{resource_name} with id '#{record.id}'")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
25
devops-service/db/mongo/connectors/image.rb
Normal file
25
devops-service/db/mongo/connectors/image.rb
Normal file
@ -0,0 +1,25 @@
|
||||
module Connectors
|
||||
class Image < Base
|
||||
include Helpers::InsertCommand,
|
||||
Helpers::ShowCommand,
|
||||
Helpers::ListCommand,
|
||||
Helpers::DeleteCommand,
|
||||
Helpers::UpdateCommand
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('images')
|
||||
end
|
||||
|
||||
def images(provider=nil)
|
||||
query = (provider.nil? ? {} : {'provider' => provider})
|
||||
list(query)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Image.create_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
28
devops-service/db/mongo/connectors/key.rb
Normal file
28
devops-service/db/mongo/connectors/key.rb
Normal file
@ -0,0 +1,28 @@
|
||||
module Connectors
|
||||
class Key < Base
|
||||
include Helpers::InsertCommand,
|
||||
Helpers::ShowCommand,
|
||||
Helpers::ListCommand,
|
||||
Helpers::DeleteCommand
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('keys')
|
||||
end
|
||||
|
||||
def key(id, scope=nil)
|
||||
options = scope ? {'scope' => scope} : {}
|
||||
show(id, options)
|
||||
end
|
||||
|
||||
def key_delete id
|
||||
delete(id, 'scope' => ::Key::USER)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Key.create_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
90
devops-service/db/mongo/connectors/project.rb
Normal file
90
devops-service/db/mongo/connectors/project.rb
Normal file
@ -0,0 +1,90 @@
|
||||
module Connectors
|
||||
class Project < Base
|
||||
include Helpers::InsertCommand,
|
||||
Helpers::ShowCommand,
|
||||
Helpers::ListCommand,
|
||||
Helpers::DeleteCommand,
|
||||
Helpers::UpdateCommand
|
||||
|
||||
|
||||
def initialize(db)
|
||||
@collection = db.collection('projects')
|
||||
end
|
||||
|
||||
def is_project_exists?(project)
|
||||
self.project(project.id)
|
||||
return true
|
||||
rescue RecordNotFound => e
|
||||
return false
|
||||
end
|
||||
|
||||
def projects_all
|
||||
list
|
||||
end
|
||||
|
||||
def projects ids=nil, type=nil, fields=[]
|
||||
query = {}
|
||||
query['_id'] = {'$in' => ids} if ids
|
||||
query['type'] = 'multi' if type == :multi
|
||||
list(query, fields: fields)
|
||||
end
|
||||
|
||||
# names - array of project names
|
||||
def project_names_with_envs(names=nil)
|
||||
# db.projects.aggregate({$unwind:"$deploy_envs"}, {$project:{"deploy_envs.identifier":1}}, {$group:{_id:"$_id", envs: {$addToSet: "$deploy_envs.identifier"}}})
|
||||
q = []
|
||||
unless names.nil?
|
||||
q.push({
|
||||
'$match' => {
|
||||
'_id' => {
|
||||
'$in' => names
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
q.push({
|
||||
'$unwind' => '$deploy_envs'
|
||||
})
|
||||
q.push({
|
||||
'$project' => {
|
||||
'deploy_envs.identifier' => 1
|
||||
}
|
||||
})
|
||||
q.push({
|
||||
'$group' => {
|
||||
'_id' => '$_id',
|
||||
'envs' => {
|
||||
'$addToSet' => '$deploy_envs.identifier'
|
||||
}
|
||||
}
|
||||
})
|
||||
res = @collection.aggregate(q)
|
||||
r = {}
|
||||
res.each do |ar|
|
||||
r[ar['_id']] = ar['envs']
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
def projects_by_image(image)
|
||||
list('deploy_envs.image' => image)
|
||||
end
|
||||
|
||||
def projects_by_user(user)
|
||||
list('deploy_envs.users' => user)
|
||||
end
|
||||
|
||||
def check_project_auth(project_id, env, user_id)
|
||||
project = show(project_id)
|
||||
raise InvalidPrivileges.new("User '#{user_id}' unauthorized to work with project '#{project_id}'") unless project.check_authorization(user_id, env)
|
||||
project
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Project.create_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
48
devops-service/db/mongo/connectors/report.rb
Normal file
48
devops-service/db/mongo/connectors/report.rb
Normal file
@ -0,0 +1,48 @@
|
||||
require "date"
|
||||
|
||||
module Connectors
|
||||
class Report < Base
|
||||
include Helpers::ShowCommand,
|
||||
Helpers::ListCommand
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('reports')
|
||||
end
|
||||
|
||||
def save_report r
|
||||
r.created_at = Time.new
|
||||
collection.insert(r.to_mongo_hash)
|
||||
end
|
||||
|
||||
def reports options={}
|
||||
date = {}
|
||||
if options.has_key?("date_from") or options.has_key?("date_to")
|
||||
if options.has_key?("date_from")
|
||||
begin
|
||||
d = Date.parse(options["date_from"])
|
||||
date["$gte"] = d.to_time
|
||||
rescue ArgumentError
|
||||
end
|
||||
end
|
||||
if options.has_key?("date_to")
|
||||
begin
|
||||
d = Date.parse(options["date_to"])
|
||||
date["$lt"] = d.to_time
|
||||
rescue ArgumentError
|
||||
end
|
||||
end
|
||||
options.delete("date_from")
|
||||
options.delete("date_to")
|
||||
options["created_at"] = date unless date.empty?
|
||||
end
|
||||
list(options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Report.new(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
88
devops-service/db/mongo/connectors/server.rb
Normal file
88
devops-service/db/mongo/connectors/server.rb
Normal file
@ -0,0 +1,88 @@
|
||||
module Connectors
|
||||
class Server < Base
|
||||
include Helpers::DeleteCommand,
|
||||
Helpers::ListCommand
|
||||
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('servers')
|
||||
end
|
||||
|
||||
def servers_find(query, fields)
|
||||
query_options = fields.nil? ? {} : {fields: fields}
|
||||
list(query, query_options)
|
||||
end
|
||||
|
||||
def servers(p=nil, env=nil, names=nil, reserved=nil, fields=:all)
|
||||
q = {}
|
||||
q['project'] = p unless p.nil? or p.empty?
|
||||
q['deploy_env'] = env unless env.nil? or env.empty?
|
||||
q['chef_node_name'] = {'$in' => names} unless names.nil? or names.class != Array
|
||||
q['reserved_by'] = {'$ne' => nil} unless reserved.nil?
|
||||
f = nil
|
||||
unless fields == :all
|
||||
f = fields
|
||||
['_id', 'chef_node_name'].each do |k|
|
||||
f.push(k) unless f.include?(k)
|
||||
end
|
||||
end
|
||||
servers_find(q, f)
|
||||
end
|
||||
|
||||
def servers_by_names(names)
|
||||
query = {}
|
||||
query['chef_node_name'] = {'$in' => names} unless names.nil? or names.class != Array
|
||||
list(query)
|
||||
end
|
||||
|
||||
def server_by_instance_id(id)
|
||||
find_server('_id' => id)
|
||||
end
|
||||
|
||||
def server_by_chef_node_name(name)
|
||||
find_server('chef_node_name' => name)
|
||||
end
|
||||
|
||||
def servers_by_key(key_name)
|
||||
collection.find('key' => key_name).to_a.map { |bson| model_from_bson(bson) }
|
||||
end
|
||||
|
||||
def server_insert(server)
|
||||
#server.validate!
|
||||
server.created_at = Time.now
|
||||
collection.insert(server.to_mongo_hash)
|
||||
end
|
||||
|
||||
# somewhy servers are not validated in previous version of code. I leave this until I know, why.
|
||||
def server_update(server)
|
||||
collection.update({'_id' => server.id}, server.to_hash_without_id)
|
||||
end
|
||||
|
||||
# somewhy servers are not validated in previous version of code. I leave this until I know, why.
|
||||
def server_set_chef_node_name(server)
|
||||
collection.update({'_id' => server.id}, {'$set' => {'chef_node_name' => server.chef_node_name}})
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Server.create_from_bson(bson)
|
||||
end
|
||||
|
||||
# couldn't be replaced with ShowCommand (_id doesn't neccesary appear in params)
|
||||
def find_server(params)
|
||||
bson = collection.find(params).to_a.first
|
||||
if bson.nil?
|
||||
if params.has_key? "_id"
|
||||
raise RecordNotFound.new("No server by instance id '#{params["_id"]}' found")
|
||||
elsif params.has_key? "chef_node_name"
|
||||
raise RecordNotFound.new("No server by node name '#{params["chef_node_name"]}' found")
|
||||
else
|
||||
raise RecordNotFound.new('Invalid params')
|
||||
end
|
||||
end
|
||||
model_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
24
devops-service/db/mongo/connectors/stack.rb
Normal file
24
devops-service/db/mongo/connectors/stack.rb
Normal file
@ -0,0 +1,24 @@
|
||||
module Connectors
|
||||
class Stack < Base
|
||||
include Helpers::InsertCommand,
|
||||
Helpers::ShowCommand,
|
||||
Helpers::ListCommand,
|
||||
Helpers::DeleteCommand
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('stacks')
|
||||
end
|
||||
|
||||
def stacks(provider=nil)
|
||||
query = (provider.nil? ? {} : {'provider' => provider})
|
||||
list(query)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
provider = bson['provider']
|
||||
::StackFactory.get_class(provider).create_from_bson(bson)
|
||||
end
|
||||
end
|
||||
end
|
||||
25
devops-service/db/mongo/connectors/stack_template.rb
Normal file
25
devops-service/db/mongo/connectors/stack_template.rb
Normal file
@ -0,0 +1,25 @@
|
||||
module Connectors
|
||||
class StackTemplate < Base
|
||||
include Helpers::InsertCommand,
|
||||
Helpers::ShowCommand,
|
||||
Helpers::ListCommand,
|
||||
Helpers::DeleteCommand
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('stack_templates')
|
||||
end
|
||||
|
||||
def stack_templates(provider=nil)
|
||||
query = (provider.nil? ? {} : {'provider' => provider})
|
||||
list(query)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
provider = bson['provider']
|
||||
::StackTemplateFactory.get_class(provider).create_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
14
devops-service/db/mongo/connectors/statictic.rb
Normal file
14
devops-service/db/mongo/connectors/statictic.rb
Normal file
@ -0,0 +1,14 @@
|
||||
module Connectors
|
||||
class Statistic < Base
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('statistic')
|
||||
end
|
||||
|
||||
def statistic(user, path, method, body, response_code)
|
||||
collection.insert(user: user, path: path, method: method, body: body, response_code: response_code, date: Time.now)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
57
devops-service/db/mongo/connectors/user.rb
Normal file
57
devops-service/db/mongo/connectors/user.rb
Normal file
@ -0,0 +1,57 @@
|
||||
module Connectors
|
||||
class User < Base
|
||||
include Helpers::InsertCommand,
|
||||
Helpers::ShowCommand,
|
||||
Helpers::ListCommand,
|
||||
Helpers::DeleteCommand,
|
||||
Helpers::UpdateCommand
|
||||
|
||||
|
||||
def initialize(db)
|
||||
self.collection = db.collection('users')
|
||||
end
|
||||
|
||||
def user_auth user, password
|
||||
u = collection.find('_id' => user, 'password' => password).to_a.first
|
||||
raise RecordNotFound.new('Invalid username or password') if u.nil?
|
||||
end
|
||||
|
||||
def users(ids=nil)
|
||||
query = {}
|
||||
query['_id'] = {'$in' => ids} if ids.is_a?(Array)
|
||||
list(query)
|
||||
end
|
||||
|
||||
def users_names(ids=nil)
|
||||
users = self.users(ids)
|
||||
users.map(&:id)
|
||||
end
|
||||
|
||||
def create_root_user
|
||||
u = user('root')
|
||||
rescue RecordNotFound => e
|
||||
root = ::User.create_root
|
||||
collection.insert(root.to_mongo_hash)
|
||||
end
|
||||
|
||||
def check_user_privileges(id, cmd, required_privelege)
|
||||
user = show(id)
|
||||
|
||||
unless %w(r w x).include?(required_privelege)
|
||||
raise InvalidPrivileges.new("Access internal problem with privilege '#{required_privelege}'")
|
||||
end
|
||||
|
||||
unless user.can?(cmd, required_privelege)
|
||||
raise InvalidPrivileges.new("Access denied for '#{user.id}'")
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::User.create_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -1,5 +1,6 @@
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "db/exceptions/invalid_record"
|
||||
require "providers/provider_factory"
|
||||
require "commands/deploy_env"
|
||||
|
||||
class DeployEnvBase < MongoModel
|
||||
@ -18,18 +19,6 @@ class DeployEnvBase < MongoModel
|
||||
self.users = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
begin
|
||||
self.class.validators.each do |validator|
|
||||
validator.new(self).validate!
|
||||
end
|
||||
true
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new "Deploy environment '#{self.identifier}'. " + e.message
|
||||
end
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
"identifier" => self.identifier,
|
||||
@ -44,6 +33,10 @@ class DeployEnvBase < MongoModel
|
||||
@provider_instance ||= ::Provider::ProviderFactory.get(self.provider)
|
||||
end
|
||||
|
||||
def build_error_message(message)
|
||||
"Deploy environment '#{self.identifier}'. " + message
|
||||
end
|
||||
|
||||
|
||||
# class methods
|
||||
class << self
|
||||
@ -52,7 +45,7 @@ class DeployEnvBase < MongoModel
|
||||
@validators
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def set_validators(*validators)
|
||||
@validators = validators
|
||||
63
devops-service/db/mongo/models/deploy_env/deploy_env_ec2.rb
Normal file
63
devops-service/db/mongo/models/deploy_env/deploy_env_ec2.rb
Normal file
@ -0,0 +1,63 @@
|
||||
require "db/mongo/models/deploy_env/deploy_env_base"
|
||||
|
||||
class DeployEnvEc2 < DeployEnvBase
|
||||
|
||||
attr_accessor :flavor, :image, :subnets, :groups
|
||||
|
||||
types :identifier => {:type => String, :empty => false},
|
||||
:image => {:type => String, :empty => false},
|
||||
:flavor => {:type => String, :empty => false},
|
||||
:provider => {:type => String, :empty => false},
|
||||
:expires => {:type => String, :empty => false, :nil => true},
|
||||
:run_list => {:type => Array, :empty => true},
|
||||
:users => {:type => Array, :empty => true},
|
||||
:subnets => {:type => Array, :empty => true},
|
||||
:groups => {:type => Array, :empty => false}
|
||||
|
||||
set_validators ::Validators::DeployEnv::RunList,
|
||||
::Validators::DeployEnv::Expiration,
|
||||
::Validators::DeployEnv::Users,
|
||||
::Validators::DeployEnv::Flavor,
|
||||
::Validators::DeployEnv::Image,
|
||||
::Validators::DeployEnv::SubnetBelongsToProvider,
|
||||
::Validators::DeployEnv::Groups
|
||||
|
||||
def initialize d={}
|
||||
super(d)
|
||||
self.flavor = d["flavor"]
|
||||
self.image = d["image"]
|
||||
b = d["subnets"] || []
|
||||
self.subnets = if b.is_a?(Array)
|
||||
(b.size > 1 ? [ b[0] ] : b)
|
||||
else
|
||||
b
|
||||
end
|
||||
b = d["groups"] || ["default"]
|
||||
self.groups = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
h = super
|
||||
h.merge!({
|
||||
"flavor" => self.flavor,
|
||||
"image" => self.image,
|
||||
"subnets" => self.subnets,
|
||||
"groups" => self.groups
|
||||
})
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
DeployEnvEc2.new(hash)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def subnets_filter
|
||||
networks = provider_instance.networks
|
||||
|
||||
unless self.subnets.empty?
|
||||
{"vpc-id" => networks.detect{|n| n["name"] == self.subnets[0]}["vpcId"] }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -1,12 +1,8 @@
|
||||
require "db/exceptions/invalid_record"
|
||||
require "db/mongo/models/deploy_env_static"
|
||||
require "db/mongo/models/deploy_env_openstack"
|
||||
require "db/mongo/models/deploy_env_ec2"
|
||||
require "providers/static"
|
||||
require "providers/openstack"
|
||||
require "providers/ec2"
|
||||
require_relative "deploy_env_static"
|
||||
require_relative "deploy_env_openstack"
|
||||
require_relative "deploy_env_ec2"
|
||||
|
||||
class DeployEnv
|
||||
class DeployEnvFactory
|
||||
|
||||
def self.create hash
|
||||
c = case(hash["provider"])
|
||||
@ -1,64 +0,0 @@
|
||||
require "db/mongo/models/deploy_env_base"
|
||||
require "providers/provider_factory"
|
||||
|
||||
class DeployEnvEc2 < DeployEnvBase
|
||||
|
||||
attr_accessor :flavor, :image, :subnets, :groups
|
||||
|
||||
types :identifier => {:type => String, :empty => false},
|
||||
:image => {:type => String, :empty => false},
|
||||
:flavor => {:type => String, :empty => false},
|
||||
:provider => {:type => String, :empty => false},
|
||||
:expires => {:type => String, :empty => false, :nil => true},
|
||||
:run_list => {:type => Array, :empty => true},
|
||||
:users => {:type => Array, :empty => true},
|
||||
:subnets => {:type => Array, :empty => true},
|
||||
:groups => {:type => Array, :empty => false}
|
||||
|
||||
set_validators ::Validators::DeployEnv::RunList,
|
||||
::Validators::DeployEnv::Expiration,
|
||||
::Validators::DeployEnv::Users,
|
||||
::Validators::DeployEnv::Flavor,
|
||||
::Validators::DeployEnv::Image,
|
||||
::Validators::DeployEnv::SubnetBelongsToProvider,
|
||||
::Validators::DeployEnv::Groups
|
||||
|
||||
def initialize d={}
|
||||
super(d)
|
||||
self.flavor = d["flavor"]
|
||||
self.image = d["image"]
|
||||
b = d["subnets"] || []
|
||||
self.subnets = if b.is_a?(Array)
|
||||
(b.size > 1 ? [ b[0] ] : b)
|
||||
else
|
||||
b
|
||||
end
|
||||
b = d["groups"] || ["default"]
|
||||
self.groups = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
h = super
|
||||
h.merge!({
|
||||
"flavor" => self.flavor,
|
||||
"image" => self.image,
|
||||
"subnets" => self.subnets,
|
||||
"groups" => self.groups
|
||||
})
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
DeployEnvEc2.new(hash)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def subnets_filter
|
||||
networks = provider_instance.networks
|
||||
|
||||
unless self.subnets.empty?
|
||||
{"vpc-id" => networks.detect{|n| n["name"] == self.subnets[0]}["vpcId"] }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -1,30 +1,16 @@
|
||||
require "db/exceptions/invalid_record"
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "commands/image"
|
||||
require "commands/bootstrap_templates"
|
||||
|
||||
class Image < MongoModel
|
||||
|
||||
include ImageCommands
|
||||
include BootstrapTemplatesCommands
|
||||
|
||||
attr_accessor :id, :provider, :remote_user, :name, :bootstrap_template
|
||||
types :id => {:type => String, :empty => false},
|
||||
:provider => {:type => String, :empty => false},
|
||||
:remote_user => {:type => String, :empty => false},
|
||||
:name => {:type => String, :empty => true},
|
||||
:bootstrap_template => {:type => String, :empty => false, :nil => true}
|
||||
|
||||
def validate!
|
||||
super
|
||||
images = get_images(DevopsService.mongo, self.provider)
|
||||
raise InvalidRecord.new "Invalid image id '#{self.id}' for provider '#{self.provider}', please check image filters" unless images.map{|i| i["id"]}.include?(self.id)
|
||||
|
||||
if self.bootstrap_template
|
||||
templates = get_templates
|
||||
raise InvalidRecord.new "Invalid bootstrap template '#{self.bootstrap_template}' for image '#{self.id}'" unless templates.include?(self.bootstrap_template)
|
||||
end
|
||||
end
|
||||
set_validators ::Validators::Image::ImageInFilter,
|
||||
::Validators::Image::BootstrapTemplate
|
||||
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
|
||||
@ -12,6 +12,9 @@ class Key < MongoModel
|
||||
:path => {:type => String, :empty => false},
|
||||
:scope => {:type => String, :empty => false}
|
||||
|
||||
set_validators ::Validators::Key::FileExistence,
|
||||
::Validators::Key::Scope
|
||||
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
self.path = p["path"]
|
||||
@ -40,11 +43,4 @@ class Key < MongoModel
|
||||
o
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
raise InvalidRecord.new "File does not exist" unless File.exist?(self.path)
|
||||
raise InvalidRecord.new "Key parameter 'scope' is invalid" unless [SYSTEM, USER].include?(self.scope)
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -48,6 +48,22 @@ class MongoModel
|
||||
end
|
||||
end
|
||||
|
||||
def validate!
|
||||
begin
|
||||
self.validate_fields_types
|
||||
self.class.validate_model(self)
|
||||
true
|
||||
rescue InvalidRecord => e
|
||||
error_message = self.build_error_message(e.message)
|
||||
raise InvalidRecord.new(error_message)
|
||||
end
|
||||
end
|
||||
|
||||
def build_error_message(message)
|
||||
# overrided in descendants
|
||||
message
|
||||
end
|
||||
|
||||
# types - Hash
|
||||
# key - param name
|
||||
# value - Hash
|
||||
@ -56,7 +72,7 @@ class MongoModel
|
||||
# :nil - can param be nil? (false)
|
||||
# :value_type - type of array element (String)
|
||||
def self.types types
|
||||
define_method :validate do
|
||||
define_method :validate_fields_types do
|
||||
t = types.keys
|
||||
e = types.keys
|
||||
n = types.keys
|
||||
@ -98,8 +114,32 @@ class MongoModel
|
||||
end
|
||||
end
|
||||
|
||||
def validate!
|
||||
self.validate
|
||||
def self.validators
|
||||
@validators || []
|
||||
end
|
||||
|
||||
# all exceptions are handled in @validate! method
|
||||
def self.validate_model(model)
|
||||
validators.each do |validator|
|
||||
validator.new(model).validate!
|
||||
end
|
||||
end
|
||||
|
||||
# private class methods
|
||||
class << self
|
||||
|
||||
private
|
||||
|
||||
def set_validators(*validators_to_add)
|
||||
@validators ||= []
|
||||
@validators += validators_to_add
|
||||
end
|
||||
|
||||
def unset_validators(*validators_to_remove)
|
||||
@validators ||= []
|
||||
self.validators -= validators_to_remove
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
require "db/exceptions/invalid_record"
|
||||
require "db/exceptions/record_not_found"
|
||||
require "db/mongo/models/deploy_env"
|
||||
require "db/mongo/models/deploy_env/deploy_env_factory"
|
||||
require "db/mongo/models/user"
|
||||
require "db/mongo/models/deploy_env_multi"
|
||||
require "db/mongo/models/deploy_env/deploy_env_multi"
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "json"
|
||||
|
||||
@ -23,7 +23,7 @@ class Project < MongoModel
|
||||
self.id = p["name"]
|
||||
#raise InvalidRecord.new "No deploy envirenments for project #{self.id}" if p["deploy_envs"].nil? or p["deploy_envs"].empty?
|
||||
self.type = p["type"]
|
||||
env_class = ( self.multi? ? DeployEnvMulti : DeployEnv )
|
||||
env_class = ( self.multi? ? DeployEnvMulti : DeployEnvFactory )
|
||||
unless p["deploy_envs"].nil?
|
||||
self.deploy_envs = []
|
||||
p["deploy_envs"].each do |e|
|
||||
|
||||
52
devops-service/db/mongo/models/stack/stack_base.rb
Normal file
52
devops-service/db/mongo/models/stack/stack_base.rb
Normal file
@ -0,0 +1,52 @@
|
||||
class StackBase < MongoModel
|
||||
|
||||
attr_accessor :id, :project, :deploy_env, :stack_template, :cloud_stack_id, :provider
|
||||
|
||||
types id: {type: String, empty: false},
|
||||
provider: {type: String, empty: false},
|
||||
project: {type: String, empty: false},
|
||||
deploy_env: {type: String, empty: false},
|
||||
stack_template: {type: String, empty: false},
|
||||
cloud_stack_id: {type: String, empty: false}
|
||||
|
||||
def initialize attrs={}
|
||||
self.id = attrs['id']
|
||||
self.provider = attrs['provider']
|
||||
self.project = attrs['project']
|
||||
self.deploy_env = attrs['deploy_env']
|
||||
self.stack_template = attrs['stack_template']
|
||||
self.cloud_stack_id = attrs['cloud_stack_id']
|
||||
self
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
{
|
||||
provider: provider,
|
||||
project: self.project,
|
||||
deploy_env: self.deploy_env,
|
||||
stack_template: self.stack_template,
|
||||
cloud_stack_id: self.cloud_stack_id
|
||||
}
|
||||
end
|
||||
|
||||
# attrs should include:
|
||||
# - id (String)
|
||||
# - provider (String)
|
||||
# - deploy_env (String)
|
||||
# - stack_template (String)
|
||||
def self.create(attrs)
|
||||
model = new(attrs)
|
||||
model.create_stack_in_cloud!
|
||||
model
|
||||
end
|
||||
|
||||
def self.create_from_bson(attrs)
|
||||
attrs['id'] = attrs["_id"]
|
||||
self.new(attrs)
|
||||
end
|
||||
|
||||
def create_stack_in_cloud!
|
||||
raise 'override me'
|
||||
end
|
||||
|
||||
end
|
||||
8
devops-service/db/mongo/models/stack/stack_ec2.rb
Normal file
8
devops-service/db/mongo/models/stack/stack_ec2.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class StackEc2 < StackBase
|
||||
|
||||
def create_stack_in_cloud!
|
||||
# create stack in AWS
|
||||
self.cloud_stack_id = 'arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83'
|
||||
end
|
||||
|
||||
end
|
||||
26
devops-service/db/mongo/models/stack/stack_factory.rb
Normal file
26
devops-service/db/mongo/models/stack/stack_factory.rb
Normal file
@ -0,0 +1,26 @@
|
||||
require_relative "stack_base"
|
||||
require_relative "stack_openstack"
|
||||
require_relative "stack_ec2"
|
||||
|
||||
class StackFactory
|
||||
|
||||
def self.create(provider, attrs)
|
||||
get_class(provider).create(attrs)
|
||||
end
|
||||
|
||||
def self.create_from_bson(provider, attrs)
|
||||
get_class(provider).create_from_bson(attrs)
|
||||
end
|
||||
|
||||
def self.get_class(provider)
|
||||
case provider
|
||||
when ::Provider::Openstack::PROVIDER
|
||||
StackOpenstack
|
||||
when ::Provider::Ec2::PROVIDER
|
||||
StackEc2
|
||||
else
|
||||
raise InvalidRecord.new "Invalid provider: '#{provider}'"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
10
devops-service/db/mongo/models/stack/stack_openstack.rb
Normal file
10
devops-service/db/mongo/models/stack/stack_openstack.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class StackOpenstack < StackBase
|
||||
|
||||
def create_stack_in_cloud!
|
||||
provider = ::Provider::ProviderFactory.get('openstack')
|
||||
provider.create_stack(self)
|
||||
# # create stack in Openstack
|
||||
# self.cloud_stack_id = '4c712026-dcd5-4664-90b8-0915494c1332'
|
||||
end
|
||||
|
||||
end
|
||||
@ -0,0 +1,73 @@
|
||||
require 'tempfile'
|
||||
require 'securerandom'
|
||||
|
||||
class StackTemplateBase < MongoModel
|
||||
|
||||
attr_accessor :id, :template_url, :template_json, :provider
|
||||
|
||||
# Few words about template_url:
|
||||
# In Amazon Cloudformation the template file must be stored on an Amazon S3 bucket,
|
||||
# but for Openstack stacks it isn't neccessary (your may use local file).
|
||||
# I decided to enforce template_url strategy using in openstack to reach more common
|
||||
# interface between different providers' stack templates.
|
||||
|
||||
types id: {type: String, empty: false},
|
||||
provider: {type: String, empty: false},
|
||||
template_json: {type: String, empty: false},
|
||||
template_url: {type: String, empty: false}
|
||||
|
||||
def initialize(attrs)
|
||||
self.id = attrs['id']
|
||||
self.template_json = attrs['template_json'].to_s
|
||||
self.template_url = attrs['template_url']
|
||||
self.provider = attrs['provider']
|
||||
self
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
{
|
||||
provider: provider,
|
||||
template_json: template_json,
|
||||
template_url: template_url
|
||||
}
|
||||
end
|
||||
|
||||
# do not forget to destroy template files on template destroying
|
||||
def delete_template_file_from_storage
|
||||
raise 'Override me'
|
||||
end
|
||||
|
||||
# attrs should include:
|
||||
# - id (String)
|
||||
# - provider (String)
|
||||
# - template_json (String)
|
||||
def self.create(attrs)
|
||||
json = attrs['template_json']
|
||||
attrs['template_url'] = generate_template_file_and_upload_to_storage(attrs['id'], json)
|
||||
new(attrs)
|
||||
end
|
||||
|
||||
def self.create_from_bson(attrs)
|
||||
attrs['id'] = attrs["_id"]
|
||||
self.new(attrs)
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
def generate_template_file_and_upload_to_storage(id, json)
|
||||
tempfile = Tempfile.new('foo')
|
||||
tempfile.write(json)
|
||||
secure_filename = "#{id}-#{SecureRandom.hex}.template"
|
||||
upload_file_to_storage(secure_filename, tempfile.path)
|
||||
ensure
|
||||
tempfile.close
|
||||
tempfile.unlink
|
||||
end
|
||||
|
||||
def upload_file_to_storage(filename, file_path)
|
||||
raise 'Override me'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,15 @@
|
||||
class StackTemplateEc2 < StackTemplateBase
|
||||
|
||||
def delete_template_file_from_storage
|
||||
raise 'Implement me'
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
def upload_file_to_storage(filename, path)
|
||||
"https://s3.amazonaws.com/#{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -0,0 +1,26 @@
|
||||
require_relative "stack_template_base"
|
||||
require_relative "stack_template_openstack"
|
||||
require_relative "stack_template_ec2"
|
||||
|
||||
class StackTemplateFactory
|
||||
|
||||
def self.create(provider, attrs)
|
||||
get_class(provider).create(attrs)
|
||||
end
|
||||
|
||||
def self.create_from_bson(provider, attrs)
|
||||
get_class(provider).create_from_bson(attrs)
|
||||
end
|
||||
|
||||
def self.get_class(provider)
|
||||
case provider
|
||||
when ::Provider::Openstack::PROVIDER
|
||||
StackTemplateOpenstack
|
||||
when ::Provider::Ec2::PROVIDER
|
||||
StackTemplateEc2
|
||||
else
|
||||
raise InvalidRecord.new "Invalid provider: '#{provider}'"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -0,0 +1,15 @@
|
||||
class StackTemplateOpenstack < StackTemplateBase
|
||||
|
||||
def delete_template_file_from_storage
|
||||
raise 'Implement me'
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
def upload_file_to_storage(filename, path)
|
||||
"https://openstack_host/v1/my_account/#{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -2,8 +2,6 @@ require "db/exceptions/invalid_record"
|
||||
require "exceptions/invalid_command"
|
||||
require "db/mongo/models/mongo_model"
|
||||
|
||||
#require "common/fog"
|
||||
|
||||
class User < MongoModel
|
||||
|
||||
ROOT_USER_NAME = 'root'
|
||||
@ -70,28 +68,17 @@ class User < MongoModel
|
||||
o
|
||||
end
|
||||
|
||||
def can?(command, privilege)
|
||||
p = self.privileges[command] || []
|
||||
p.include?(privilege)
|
||||
end
|
||||
|
||||
def check_privilege cmd, priv
|
||||
p = self.privileges[cmd]
|
||||
return false if p.nil?
|
||||
return p.include?(priv)
|
||||
end
|
||||
|
||||
=begin
|
||||
def check_privilege_read cmd
|
||||
check_privilege_r_w cmd, "r"
|
||||
end
|
||||
|
||||
def check_privilege_write cmd
|
||||
check_privilege_r_w cmd, "w"
|
||||
end
|
||||
|
||||
def check_privilege_r_w cmd, flag
|
||||
p = self.privileges[cmd]
|
||||
return false if p.nil?
|
||||
return p == flag || p == 'rw'
|
||||
end
|
||||
=end
|
||||
|
||||
def self.create_root
|
||||
root = User.new({'username' => ROOT_USER_NAME, 'password' => ROOT_PASSWORD})
|
||||
root.privileges = root.all_privileges
|
||||
@ -101,20 +88,25 @@ class User < MongoModel
|
||||
|
||||
private
|
||||
def privileges_with_value v, options={}
|
||||
{
|
||||
"flavor" => v,
|
||||
"group" => v,
|
||||
"image" => v,
|
||||
"project" => v,
|
||||
"server" => v,
|
||||
"key" => v,
|
||||
"user" => v,
|
||||
"filter" => v,
|
||||
"network" => v,
|
||||
"provider" => v,
|
||||
"script" => v,
|
||||
"templates" => v
|
||||
}.merge(options)
|
||||
privileges = {}
|
||||
[
|
||||
'flavor',
|
||||
'group',
|
||||
'image',
|
||||
'project',
|
||||
'server',
|
||||
'key',
|
||||
'user',
|
||||
'filter',
|
||||
'network',
|
||||
'provider',
|
||||
'script',
|
||||
'templates',
|
||||
'stack_template',
|
||||
'stack'
|
||||
].each { |t| privileges.store(t, value) }
|
||||
|
||||
privileges.merge(options)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,438 +1,77 @@
|
||||
require "mongo"
|
||||
require "date"
|
||||
require "forwardable"
|
||||
|
||||
require "db/exceptions/record_not_found"
|
||||
require "db/exceptions/invalid_record"
|
||||
require "exceptions/invalid_privileges"
|
||||
|
||||
require "db/mongo/models/project"
|
||||
require "db/mongo/models/image"
|
||||
require "db/mongo/models/report"
|
||||
require "db/mongo/models/key"
|
||||
require "db/mongo/models/project"
|
||||
require "db/mongo/models/server"
|
||||
require "db/mongo/models/user"
|
||||
require "db/mongo/connectors/base"
|
||||
Dir["db/mongo/connectors/helpers/*.rb"].each {|file| require file }
|
||||
Dir["db/mongo/connectors/*.rb"].each {|file| require file }
|
||||
|
||||
include Mongo
|
||||
|
||||
class MongoConnector
|
||||
extend Forwardable
|
||||
|
||||
delegate(
|
||||
[:images, :image, :image_insert, :image_delete, :image_update] => :images_connector,
|
||||
[:stack_templates, :stack_template, :stack_template_insert, :stack_template_delete] => :stack_templates_connector,
|
||||
[:stacks, :stack, :stack_insert, :stack_delete] => :stacks_connector,
|
||||
[:available_images, :add_available_images, :delete_available_images] => :filters_connector,
|
||||
[:project, :projects_all, :projects, :project_names_with_envs,
|
||||
:projects_by_image, :projects_by_user, :project_insert, :project_update,
|
||||
:project_delete, :is_project_exists?, :check_project_auth] => :projects_connector,
|
||||
[:servers_find, :servers, :servers_by_names, :server_by_instance_id,
|
||||
:server_by_chef_node_name, :servers_by_key, :server_insert,
|
||||
:server_delete, :server_update, :server_set_chef_node_name] => :servers_connector,
|
||||
[:user_auth, :user, :users, :users_names, :user_insert, :user_delete,
|
||||
:user_update, :create_root_user, :check_user_privileges] => :users_connector,
|
||||
[:keys, :key, :key_insert, :key_delete] => :keys_connector,
|
||||
[:save_report, :report, :reports] => :reports_connector,
|
||||
[:statistic] => :statistics_connector
|
||||
)
|
||||
|
||||
def initialize(db, host, port=27017, user=nil, password=nil)
|
||||
@mongo_client = MongoClient.new(host, port)
|
||||
@db = @mongo_client.db(db)
|
||||
@db = MongoClient.new(host, port).db(db)
|
||||
@db.authenticate(user, password) unless user.nil? or password.nil?
|
||||
@projects = @db.collection("projects")
|
||||
@images = @db.collection("images")
|
||||
@servers = @db.collection("servers")
|
||||
@filters = @db.collection("filters")
|
||||
@keys = @db.collection("keys")
|
||||
@users = @db.collection("users")
|
||||
@statistic = @db.collection("statistic")
|
||||
@reports = @db.collection("reports")
|
||||
end
|
||||
|
||||
def images provider=nil
|
||||
q = (provider.nil? ? {} : {"provider" => provider})
|
||||
@images.find(q).to_a.map {|bi| Image.create_from_bson bi}
|
||||
private
|
||||
|
||||
def images_connector
|
||||
@image_connector ||= Connectors::Image.new(@db)
|
||||
end
|
||||
|
||||
def image id
|
||||
i = @images.find(create_query("_id" => id)).to_a[0]
|
||||
raise RecordNotFound.new("Image '#{id}' does not exist") if i.nil?
|
||||
Image.create_from_bson i
|
||||
def stack_templates_connector
|
||||
@stack_templates_connector ||= Connectors::StackTemplate.new(@db)
|
||||
end
|
||||
|
||||
def image_insert image
|
||||
image.validate!
|
||||
@images.insert(image.to_mongo_hash)
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: image with id '#{image.id}'")
|
||||
end
|
||||
def stacks_connector
|
||||
@stack_connector ||= Connectors::Stack.new(@db)
|
||||
end
|
||||
|
||||
def image_update image
|
||||
image.validate!
|
||||
@images.update(create_query({"_id" => image.id}), create_query(image.to_mongo_hash))
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: image with id '#{image.id}'")
|
||||
end
|
||||
def filters_connector
|
||||
@filter_connector ||= Connectors::Filter.new(@db)
|
||||
end
|
||||
|
||||
def image_delete id
|
||||
r = @images.remove(create_query("_id" => id))
|
||||
raise RecordNotFound.new("Image '#{id}' not found") if r["n"] == 0
|
||||
r
|
||||
def projects_connector
|
||||
@projects_connector ||= Connectors::Project.new(@db)
|
||||
end
|
||||
|
||||
def available_images provider
|
||||
f = @filters.find(create_query("type" => "image", "provider" => provider)).to_a[0]
|
||||
return [] if f.nil?
|
||||
f["images"]
|
||||
def servers_connector
|
||||
@servers_connector ||= Connectors::Server.new(@db)
|
||||
end
|
||||
|
||||
def add_available_images images, provider
|
||||
return unless images.is_a?(Array)
|
||||
f = @filters.find(create_query("type" => "image", "provider" => provider)).to_a[0]
|
||||
if f.nil?
|
||||
@filters.insert(create_query({"type" => "image", "provider" => provider, "images" => images}))
|
||||
return images
|
||||
else
|
||||
f["images"] |= images
|
||||
@filters.update({"_id" => f["_id"]}, f)
|
||||
return f["images"]
|
||||
end
|
||||
def users_connector
|
||||
@users_connector ||= Connectors::User.new(@db)
|
||||
end
|
||||
|
||||
def delete_available_images images, provider
|
||||
return unless images.is_a?(Array)
|
||||
f = @filters.find(create_query("type" => "image", "provider" => provider)).to_a[0]
|
||||
unless f.nil?
|
||||
f["images"] -= images
|
||||
@filters.update({"_id" => f["_id"]}, f)
|
||||
return f["images"]
|
||||
end
|
||||
[]
|
||||
def keys_connector
|
||||
@keys_connector ||= Connectors::Key.new(@db)
|
||||
end
|
||||
|
||||
def is_project_exists? project
|
||||
self.project project.id
|
||||
return true
|
||||
rescue RecordNotFound => e
|
||||
return false
|
||||
def reports_connector
|
||||
@reports_connector ||= Connectors::Report.new(@db)
|
||||
end
|
||||
|
||||
def project_insert project
|
||||
project.validate!
|
||||
@projects.insert(create_query(project.to_mongo_hash))
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: project with id '#{project.id}'")
|
||||
end
|
||||
end
|
||||
|
||||
def project name
|
||||
p = @projects.find(create_query("_id" => name)).to_a[0]
|
||||
raise RecordNotFound.new("Project '#{name}' does not exist") if p.nil?
|
||||
Project.create_from_bson p
|
||||
end
|
||||
|
||||
def projects_all
|
||||
p = @projects.find()
|
||||
p.to_a.map {|bp| Project.create_from_bson bp}
|
||||
end
|
||||
|
||||
def projects list=nil, type=nil, fields=[]
|
||||
q = (list.nil? ? {} : {"_id" => {"$in" => list}})
|
||||
case type
|
||||
when :multi
|
||||
q["type"] = "multi"
|
||||
#else
|
||||
# q["type"] = {"$exists" => false}
|
||||
end
|
||||
res = @projects.find(create_query(q), :fields => fields)
|
||||
a = res.to_a
|
||||
a.map {|bp| Project.create_from_bson bp}
|
||||
end
|
||||
|
||||
# names - array of project names
|
||||
def project_names_with_envs names=nil
|
||||
# db.projects.aggregate({$unwind:"$deploy_envs"}, {$project:{"deploy_envs.identifier":1}}, {$group:{_id:"$_id", envs: {$addToSet: "$deploy_envs.identifier"}}})
|
||||
q = []
|
||||
unless names.nil?
|
||||
q.push({
|
||||
"$match" => {
|
||||
"_id" => {
|
||||
"$in" => names
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
q.push({
|
||||
"$unwind" => "$deploy_envs"
|
||||
})
|
||||
q.push({
|
||||
"$project" => {
|
||||
"deploy_envs.identifier" => 1
|
||||
}
|
||||
})
|
||||
q.push({
|
||||
"$group" => {
|
||||
"_id" => "$_id",
|
||||
"envs" => {
|
||||
"$addToSet" => "$deploy_envs.identifier"
|
||||
}
|
||||
}
|
||||
})
|
||||
res = @projects.aggregate(q)
|
||||
r = {}
|
||||
res.each do |ar|
|
||||
r[ar["_id"]] = ar["envs"]
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
def projects_by_image image
|
||||
@projects.find(create_query("deploy_envs.image" => image)).to_a.map {|bp| Project.create_from_bson bp}
|
||||
end
|
||||
|
||||
def projects_by_user user
|
||||
@projects.find(create_query("deploy_envs.users" => user)).to_a.map {|bp| Project.create_from_bson bp}
|
||||
end
|
||||
|
||||
def project_delete name
|
||||
r = @projects.remove(create_query("_id" => name))
|
||||
raise RecordNotFound.new("Project '#{name}' not found") if r["n"] == 0
|
||||
end
|
||||
|
||||
def project_update project
|
||||
project.validate!
|
||||
@projects.update(create_query({"_id" => project.id}), project.to_mongo_hash)
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: project with id '#{project.id}'")
|
||||
end
|
||||
end
|
||||
|
||||
def servers_find q, fields
|
||||
s = if fields.nil?
|
||||
@servers.find(create_query(q))
|
||||
else
|
||||
@servers.find(create_query(q), :fields => fields)
|
||||
end
|
||||
s.to_a.map{|bs| Server.create_from_bson bs}
|
||||
end
|
||||
|
||||
def servers p=nil, env=nil, names=nil, reserved=nil, fields=:all
|
||||
q = {}
|
||||
q["project"] = p unless p.nil? or p.empty?
|
||||
q["deploy_env"] = env unless env.nil? or env.empty?
|
||||
q["chef_node_name"] = {"$in" => names} unless names.nil? or names.class != Array
|
||||
q["reserved_by"] = {"$ne" => nil} unless reserved.nil?
|
||||
f = nil
|
||||
unless fields == :all
|
||||
f = fields
|
||||
["_id", "chef_node_name"].each do |k|
|
||||
f.push(k) unless f.include?(k)
|
||||
end
|
||||
end
|
||||
servers_find(q, f)
|
||||
end
|
||||
|
||||
def servers_by_names names
|
||||
q = {}
|
||||
q["chef_node_name"] = {"$in" => names} unless names.nil? or names.class != Array
|
||||
@servers.find(create_query(q)).to_a.map{|bs| Server.create_from_bson bs}
|
||||
end
|
||||
|
||||
def server_by_instance_id id
|
||||
find_server "_id" => id
|
||||
end
|
||||
|
||||
def server_by_chef_node_name name
|
||||
find_server "chef_node_name" => name
|
||||
end
|
||||
|
||||
def servers_by_key key_name
|
||||
@servers.find(create_query("key" => key_name)).to_a.map {|bs| Server.create_from_bson bs}
|
||||
end
|
||||
|
||||
def server_insert s
|
||||
#s.validate!
|
||||
s.created_at = Time.now
|
||||
@servers.insert(create_query(s.to_mongo_hash))
|
||||
end
|
||||
|
||||
def server_delete id
|
||||
@servers.remove(create_query("_id" => id))
|
||||
end
|
||||
|
||||
def server_update server
|
||||
@servers.update({"_id" => server.id}, server.to_hash_without_id)
|
||||
end
|
||||
|
||||
def server_set_chef_node_name server
|
||||
@servers.update({"_id" => server.id}, {"$set" => {"chef_node_name" => server.chef_node_name}})
|
||||
end
|
||||
|
||||
def keys
|
||||
@keys.find(create_query).to_a.map {|bi| Key.create_from_bson bi}
|
||||
end
|
||||
|
||||
def key id, scope=nil
|
||||
q = {
|
||||
"_id" => id
|
||||
}
|
||||
q["scope"] = scope unless scope.nil?
|
||||
k = @keys.find(create_query(q)).to_a[0]
|
||||
raise RecordNotFound.new("Key '#{id}' does not exist") if k.nil?
|
||||
Key.create_from_bson k
|
||||
end
|
||||
|
||||
def key_insert key
|
||||
key.validate!
|
||||
@keys.insert(create_query(key.to_mongo_hash))
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: key with id '#{key.id}'")
|
||||
end
|
||||
end
|
||||
|
||||
def key_delete id
|
||||
r = @keys.remove(create_query("_id" => id, "scope" => Key::USER))
|
||||
raise RecordNotFound.new("Key '#{id}' not found") if r["n"] == 0
|
||||
r
|
||||
end
|
||||
|
||||
def user_auth user, password
|
||||
u = @users.find("_id" => user, "password" => password).to_a[0]
|
||||
raise RecordNotFound.new("Invalid username or password") if u.nil?
|
||||
end
|
||||
|
||||
def user id
|
||||
u = @users.find("_id" => id).to_a[0]
|
||||
raise RecordNotFound.new("User '#{id}' does not exist") if u.nil?
|
||||
User.create_from_bson u
|
||||
end
|
||||
|
||||
def users array=nil
|
||||
q = {}
|
||||
q["_id"] = {"$in" => array} if array.is_a?(Array)
|
||||
@users.find(q).to_a.map {|bi| User.create_from_bson bi}
|
||||
end
|
||||
|
||||
def users_names array=nil
|
||||
q = {}
|
||||
q["_id"] = {"$in" => array} if array.is_a?(Array)
|
||||
@users.find({}, :fields => ["_id"]).to_a.map{|u| u["_id"]}
|
||||
end
|
||||
|
||||
def user_insert user
|
||||
user.validate!
|
||||
@users.insert(user.to_mongo_hash)
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: user with id '#{user.id}'")
|
||||
end
|
||||
end
|
||||
|
||||
def user_delete id
|
||||
r = @users.remove("_id" => id)
|
||||
raise RecordNotFound.new("User '#{id}' not found") if r["n"] == 0
|
||||
r
|
||||
end
|
||||
|
||||
def user_update user
|
||||
user.validate!
|
||||
@users.update({"_id" => user.id}, user.to_mongo_hash)
|
||||
rescue Mongo::OperationFailure => e
|
||||
if e.message =~ /^11000/
|
||||
raise InvalidRecord.new("Duplicate key error: user with id '#{user.id}'")
|
||||
end
|
||||
end
|
||||
|
||||
def create_root_user
|
||||
begin
|
||||
u = user("root")
|
||||
rescue RecordNotFound => e
|
||||
root = User.create_root
|
||||
@users.insert(root.to_mongo_hash)
|
||||
end
|
||||
end
|
||||
|
||||
def check_user_privileges id, cmd, priv
|
||||
user = self.user(id)
|
||||
case priv
|
||||
when "r", "w", "x"
|
||||
raise InvalidPrivileges.new("Access denied for '#{user.id}'") unless user.check_privilege cmd, priv
|
||||
else
|
||||
raise InvalidPrivileges.new("Access internal problem with privilege '#{priv}'")
|
||||
end
|
||||
end
|
||||
|
||||
def check_project_auth project_id, env, user_id
|
||||
p = @projects.find(create_query("_id" => project_id)).to_a[0]
|
||||
raise RecordNotFound.new("Project '#{project_id}' does not exist") if p.nil?
|
||||
project = Project.create_from_bson p
|
||||
raise InvalidPrivileges.new("User '#{user_id}' unauthorized to work with project '#{project_id}'") unless project.check_authorization(user_id, env)
|
||||
project
|
||||
end
|
||||
|
||||
def statistic user, path, method, body, response_code
|
||||
@statistic.insert({:user => user, :path => path, :method => method, :body => body, :response_code => response_code, :date => Time.now})
|
||||
end
|
||||
|
||||
def save_report r
|
||||
r.created_at = Time.new
|
||||
@reports.insert(r.to_mongo_hash)
|
||||
end
|
||||
|
||||
def reports options={}
|
||||
date = {}
|
||||
if options.has_key?("date_from") or options.has_key?("date_to")
|
||||
if options.has_key?("date_from")
|
||||
begin
|
||||
d = Date.parse(options["date_from"])
|
||||
date["$gte"] = d.to_time
|
||||
rescue ArgumentError
|
||||
end
|
||||
end
|
||||
if options.has_key?("date_to")
|
||||
begin
|
||||
d = Date.parse(options["date_to"])
|
||||
date["$lt"] = d.to_time
|
||||
rescue ArgumentError
|
||||
end
|
||||
end
|
||||
options.delete("date_from")
|
||||
options.delete("date_to")
|
||||
options["created_at"] = date unless date.empty?
|
||||
end
|
||||
if options.has_key?("type")
|
||||
begin
|
||||
options["type"] = Integer(options["type"])
|
||||
rescue ArgumentError
|
||||
options.delete("type")
|
||||
end
|
||||
end
|
||||
sort = -1
|
||||
if options.has_key?("sort")
|
||||
sort = 1 if options["sort"] == "asc"
|
||||
options.delete("sort")
|
||||
end
|
||||
@reports.find(options).to_a.map{|e| Report.new(e)}
|
||||
end
|
||||
|
||||
def report id
|
||||
r = @reports.find({"_id" => id}).to_a[0]
|
||||
raise RecordNotFound.new("Report '#{id}' does not exist") if r.nil?
|
||||
Report.new(r)
|
||||
end
|
||||
|
||||
def set_report_status id, status
|
||||
@reports.update({"_id" => id}, {"$set" => {"status" => status, "updated_at" => Time.new}})
|
||||
end
|
||||
|
||||
private
|
||||
def find_server params
|
||||
s = @servers.find(create_query(params)).to_a[0]
|
||||
if s.nil?
|
||||
if params.has_key? "_id"
|
||||
raise RecordNotFound.new("No server by instance id '#{params["_id"]}' found")
|
||||
elsif params.has_key? "chef_node_name"
|
||||
raise RecordNotFound.new("No server by node name '#{params["chef_node_name"]}' found")
|
||||
end
|
||||
end
|
||||
Server.create_from_bson s
|
||||
end
|
||||
|
||||
def create_query q={}
|
||||
q
|
||||
end
|
||||
|
||||
def create_query_with_provider provider, q={}
|
||||
q["provider"] = provider
|
||||
q
|
||||
def statistics_connector
|
||||
@statistics_connector ||= Connectors::Statistic.new(@db)
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,8 +1,16 @@
|
||||
module Validators
|
||||
class Helpers; end
|
||||
class DeployEnv; end
|
||||
class Key; end
|
||||
class Image; end
|
||||
end
|
||||
|
||||
require "db/validators/base"
|
||||
Dir["db/validators/helpers/*.rb"].each {|file| require file }
|
||||
Dir["db/validators/deploy_env/*.rb"].each {|file| require file }
|
||||
[
|
||||
'db/validators/helpers/*.rb',
|
||||
'db/validators/deploy_env/*.rb',
|
||||
'db/validators/key/*.rb',
|
||||
'db/validators/image/*.rb'
|
||||
].each do |files_regexp|
|
||||
Dir[files_regexp].each {|file| require file }
|
||||
end
|
||||
|
||||
@ -16,4 +16,25 @@ class Validators::Base
|
||||
def message
|
||||
raise 'override me'
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
# this method delegates @valid? and @message methods to helper validator, passed as block
|
||||
def delegate_to_helper_validator(&block)
|
||||
|
||||
define_method :helper_validator do
|
||||
@helper_validator ||= self.instance_eval(&block)
|
||||
end
|
||||
|
||||
define_method :valid? do
|
||||
self.helper_validator.valid?
|
||||
end
|
||||
|
||||
define_method :message do
|
||||
self.helper_validator.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -4,17 +4,6 @@
|
||||
module Validators
|
||||
class DeployEnv::RunList < Base
|
||||
|
||||
def initialize(model)
|
||||
super(model)
|
||||
@helper_validator = Helpers::RunList.new(@model.run_list)
|
||||
end
|
||||
|
||||
def valid?
|
||||
@helper_validator.valid?
|
||||
end
|
||||
|
||||
def message
|
||||
@helper_validator.message
|
||||
end
|
||||
delegate_to_helper_validator { Helpers::RunList.new(@model.run_list) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
12
devops-service/db/validators/helpers/file_existence.rb
Normal file
12
devops-service/db/validators/helpers/file_existence.rb
Normal file
@ -0,0 +1,12 @@
|
||||
module Validators
|
||||
class Helpers::FileExistence < Base
|
||||
|
||||
def valid?
|
||||
File.exist?(@model)
|
||||
end
|
||||
|
||||
def message
|
||||
"File does not exist: '#{@model}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
20
devops-service/db/validators/image/bootstrap_template.rb
Normal file
20
devops-service/db/validators/image/bootstrap_template.rb
Normal file
@ -0,0 +1,20 @@
|
||||
require "commands/bootstrap_templates"
|
||||
module Validators
|
||||
class Image::BootstrapTemplate < Base
|
||||
|
||||
include BootstrapTemplatesCommands
|
||||
|
||||
def valid?
|
||||
if @model.bootstrap_template
|
||||
templates = get_templates
|
||||
templates.include?(@model.bootstrap_template)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid bootstrap template '#{@model.bootstrap_template}' for image '#{@model.id}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
16
devops-service/db/validators/image/image_in_filter.rb
Normal file
16
devops-service/db/validators/image/image_in_filter.rb
Normal file
@ -0,0 +1,16 @@
|
||||
require "commands/image"
|
||||
module Validators
|
||||
class Image::ImageInFilter < Base
|
||||
|
||||
include ImageCommands
|
||||
|
||||
def valid?
|
||||
images = get_images(DevopsService.mongo, @model.provider)
|
||||
images.map{|i| i["id"]}.include?(@model.id)
|
||||
end
|
||||
|
||||
def message
|
||||
"Invalid image id '#{@model.id}' for provider '#{@model.provider}', please check image filters"
|
||||
end
|
||||
end
|
||||
end
|
||||
7
devops-service/db/validators/key/file_existence.rb
Normal file
7
devops-service/db/validators/key/file_existence.rb
Normal file
@ -0,0 +1,7 @@
|
||||
module Validators
|
||||
class Key::FileExistence < Base
|
||||
|
||||
delegate_to_helper_validator { Helpers::FileExistence.new(@model.path) }
|
||||
|
||||
end
|
||||
end
|
||||
12
devops-service/db/validators/key/scope.rb
Normal file
12
devops-service/db/validators/key/scope.rb
Normal file
@ -0,0 +1,12 @@
|
||||
module Validators
|
||||
class Key::Scope < Base
|
||||
|
||||
def valid?
|
||||
[::Key::SYSTEM, ::Key::USER].include?(@model.scope)
|
||||
end
|
||||
|
||||
def message
|
||||
"Key parameter 'scope' is invalid"
|
||||
end
|
||||
end
|
||||
end
|
||||
35
devops-service/lib/string_helper.rb
Normal file
35
devops-service/lib/string_helper.rb
Normal file
@ -0,0 +1,35 @@
|
||||
module StringHelper
|
||||
extend self
|
||||
|
||||
# from Rails' ActiveSupport
|
||||
def underscore(string)
|
||||
string.gsub(/::/, '/').
|
||||
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
||||
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
||||
tr("-", "_").
|
||||
downcase
|
||||
end
|
||||
|
||||
def underscore_class(klass, without_ancestors=true)
|
||||
class_name = if without_ancestors
|
||||
klass.to_s.split('::').last
|
||||
else
|
||||
klass.to_s
|
||||
end
|
||||
StringHelper.underscore(class_name)
|
||||
end
|
||||
|
||||
# from Rails' ActiveSupport
|
||||
def camelize(term)
|
||||
string = term.to_s
|
||||
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
||||
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
||||
string.gsub!(/\//, '::')
|
||||
string
|
||||
end
|
||||
|
||||
# rough simplification
|
||||
def pluralize(string)
|
||||
"#{string}s"
|
||||
end
|
||||
end
|
||||
13
devops-service/providers/all.rb
Normal file
13
devops-service/providers/all.rb
Normal file
@ -0,0 +1,13 @@
|
||||
["ec2", "openstack", "static"].each do |provider|
|
||||
begin
|
||||
require_relative provider
|
||||
|
||||
provider_stub_path = File.expand_path("../#{provider}_stub.rb", __FILE__)
|
||||
|
||||
if DevopsService.debug? && File.exists?(provider_stub_path)
|
||||
require provider_stub_path
|
||||
end
|
||||
rescue LoadError => e
|
||||
puts "Can not load provider '#{provider}': " + e.message
|
||||
end
|
||||
end
|
||||
@ -190,6 +190,11 @@ module Provider
|
||||
def network
|
||||
connection_network(self.connection_options)
|
||||
end
|
||||
|
||||
def create_stack(stack)
|
||||
byebug
|
||||
result = orchestration.create_stack(stack.id, {template_url: stack.template_url})
|
||||
end
|
||||
private
|
||||
def convert_groups list
|
||||
res = {}
|
||||
@ -211,5 +216,9 @@ module Provider
|
||||
res
|
||||
end
|
||||
|
||||
def orchestration
|
||||
@connection ||= Fog::Orchestration::OpenStack.new(connection_options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@ -20,14 +20,12 @@ module Provider
|
||||
end
|
||||
|
||||
def self.init conf
|
||||
|
||||
# require providers here to get access to debug properties
|
||||
require 'providers/all'
|
||||
|
||||
["ec2", "openstack", "static"].each do |p|
|
||||
begin
|
||||
require "providers/#{p}"
|
||||
|
||||
if File.exist?("providers/#{p}_stub.rb")
|
||||
require "providers/#{p}_stub"
|
||||
end
|
||||
|
||||
o = Provider.const_get(p.capitalize).new(conf)
|
||||
if o.configured?
|
||||
@@providers[p] = o
|
||||
@ -36,9 +34,6 @@ module Provider
|
||||
rescue => e
|
||||
puts "Error while loading provider '#{p}': " + e.message
|
||||
next
|
||||
rescue LoadError => e
|
||||
puts "Can not load provider '#{p}': " + e.message
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user