models in Devops::Model module, auth
This commit is contained in:
parent
5ee2e2f714
commit
42f936f040
@ -1,8 +1,9 @@
|
||||
module Sinatra
|
||||
module Devops
|
||||
module DevopsAuth
|
||||
module Helpers
|
||||
def protect!
|
||||
return if auth_with_basic?
|
||||
headers['WWW-Authenticate'] = 'Basic realm="Restricted Area"'
|
||||
halt 401, "Not authorized\n"
|
||||
end
|
||||
|
||||
@ -23,10 +24,10 @@ module Sinatra
|
||||
end
|
||||
|
||||
def self.registered(app)
|
||||
app.helpers Devops::Helpers
|
||||
app.helpers Sinatra::DevopsAuth::Helpers
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
register Devops
|
||||
register Sinatra::DevopsAuth
|
||||
end
|
||||
|
||||
@ -182,7 +182,7 @@ module ServerCommands
|
||||
servers = []
|
||||
servers_info.each do |info|
|
||||
image = info[:image]
|
||||
s = Server.new
|
||||
s = Devops::Model::Server.new
|
||||
s.provider = provider.name
|
||||
s.project = project_name
|
||||
s.deploy_env = env_name
|
||||
|
||||
@ -20,7 +20,7 @@ module Connectors
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Image.build_from_bson(bson)
|
||||
Devops::Model::Image.build_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ module Connectors
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Key.build_from_bson(bson)
|
||||
Devops::Model::Key.build_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ module Connectors
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Project.build_from_bson(bson)
|
||||
Devops::Model::Project.build_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ module Connectors
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Report.new(bson)
|
||||
Devops::Model::Report.new(bson)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ module Connectors
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::Server.build_from_bson(bson)
|
||||
Devops::Model::Server.build_from_bson(bson)
|
||||
end
|
||||
|
||||
# couldn't be replaced with ShowCommand (_id doesn't neccesary appear in params)
|
||||
|
||||
@ -18,7 +18,7 @@ module Connectors
|
||||
|
||||
def model_from_bson(bson)
|
||||
provider = bson['provider']
|
||||
::StackFactory.get_class(provider).build_from_bson(bson)
|
||||
Devops::Model::StackFactory.get_class(provider).build_from_bson(bson)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -18,7 +18,7 @@ module Connectors
|
||||
|
||||
def model_from_bson(bson)
|
||||
provider = bson['provider']
|
||||
::StackTemplateFactory.get_class(provider).build_from_bson(bson)
|
||||
Devops::Model::StackTemplateFactory.get_class(provider).build_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ module Connectors
|
||||
def create_root_user
|
||||
u = user('root')
|
||||
rescue RecordNotFound => e
|
||||
root = ::User.create_root
|
||||
root = Devops::Model::User.create_root
|
||||
collection.insert(root.to_mongo_hash)
|
||||
end
|
||||
|
||||
@ -49,7 +49,7 @@ module Connectors
|
||||
private
|
||||
|
||||
def model_from_bson(bson)
|
||||
::User.build_from_bson(bson)
|
||||
Devops::Model::User.build_from_bson(bson)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -3,54 +3,58 @@ require "db/exceptions/invalid_record"
|
||||
require "providers/provider_factory"
|
||||
require "commands/deploy_env"
|
||||
|
||||
class DeployEnvBase < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class DeployEnvBase < MongoModel
|
||||
|
||||
include DeployEnvCommands
|
||||
include DeployEnvCommands
|
||||
|
||||
attr_accessor :identifier, :run_list, :expires, :provider, :users
|
||||
attr_accessor :identifier, :run_list, :expires, :provider, :users
|
||||
|
||||
def initialize d={}
|
||||
self.identifier = d["identifier"]
|
||||
b = d["run_list"] || []
|
||||
self.run_list = (b.is_a?(Array) ? b.uniq : b)
|
||||
self.expires = d["expires"]
|
||||
self.provider = d["provider"]
|
||||
b = d["users"] || []
|
||||
self.users = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
def initialize d={}
|
||||
self.identifier = d["identifier"]
|
||||
b = d["run_list"] || []
|
||||
self.run_list = (b.is_a?(Array) ? b.uniq : b)
|
||||
self.expires = d["expires"]
|
||||
self.provider = d["provider"]
|
||||
b = d["users"] || []
|
||||
self.users = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
"identifier" => self.identifier,
|
||||
"run_list" => self.run_list,
|
||||
"expires" => self.expires,
|
||||
"provider" => self.provider,
|
||||
"users" => self.users
|
||||
}
|
||||
end
|
||||
def to_hash
|
||||
{
|
||||
"identifier" => self.identifier,
|
||||
"run_list" => self.run_list,
|
||||
"expires" => self.expires,
|
||||
"provider" => self.provider,
|
||||
"users" => self.users
|
||||
}
|
||||
end
|
||||
|
||||
def provider_instance
|
||||
@provider_instance ||= ::Provider::ProviderFactory.get(self.provider)
|
||||
end
|
||||
def provider_instance
|
||||
@provider_instance ||= ::Provider::ProviderFactory.get(self.provider)
|
||||
end
|
||||
|
||||
def build_error_message(message)
|
||||
"Deploy environment '#{self.identifier}'. " + message
|
||||
end
|
||||
def build_error_message(message)
|
||||
"Deploy environment '#{self.identifier}'. " + message
|
||||
end
|
||||
|
||||
|
||||
# class methods
|
||||
class << self
|
||||
# class methods
|
||||
class << self
|
||||
|
||||
def validators
|
||||
@validators
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_validators(*validators)
|
||||
@validators = validators
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def validators
|
||||
@validators
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_validators(*validators)
|
||||
@validators = validators
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,63 +1,67 @@
|
||||
require "db/mongo/models/deploy_env/deploy_env_base"
|
||||
|
||||
class DeployEnvEc2 < DeployEnvBase
|
||||
module Devops
|
||||
module Model
|
||||
class DeployEnvEc2 < DeployEnvBase
|
||||
|
||||
attr_accessor :flavor, :image, :subnets, :groups
|
||||
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}
|
||||
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
|
||||
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 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 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
|
||||
def self.create hash
|
||||
DeployEnvEc2.new(hash)
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def subnets_filter
|
||||
networks = provider_instance.networks
|
||||
def subnets_filter
|
||||
networks = provider_instance.networks
|
||||
|
||||
unless self.subnets.empty?
|
||||
{"vpc-id" => networks.detect{|n| n["name"] == self.subnets[0]}["vpcId"] }
|
||||
end
|
||||
end
|
||||
|
||||
unless self.subnets.empty?
|
||||
{"vpc-id" => networks.detect{|n| n["name"] == self.subnets[0]}["vpcId"] }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,20 +2,24 @@ require_relative "deploy_env_static"
|
||||
require_relative "deploy_env_openstack"
|
||||
require_relative "deploy_env_ec2"
|
||||
|
||||
class DeployEnvFactory
|
||||
module Devops
|
||||
module Model
|
||||
class DeployEnvFactory
|
||||
|
||||
def self.create hash
|
||||
c = case(hash["provider"])
|
||||
when ::Provider::Static::PROVIDER
|
||||
DeployEnvStatic
|
||||
when ::Provider::Ec2::PROVIDER
|
||||
DeployEnvEc2
|
||||
when ::Provider::Openstack::PROVIDER
|
||||
DeployEnvOpenstack
|
||||
else
|
||||
raise InvalidRecord.new "Invalid provider '#{hash["provider"]}' for deploy envirenment '#{hash["identifier"]}'"
|
||||
end
|
||||
c.new(hash)
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
c = case(hash["provider"])
|
||||
when ::Provider::Static::PROVIDER
|
||||
DeployEnvStatic
|
||||
when ::Provider::Ec2::PROVIDER
|
||||
DeployEnvEc2
|
||||
when ::Provider::Openstack::PROVIDER
|
||||
DeployEnvOpenstack
|
||||
else
|
||||
raise InvalidRecord.new "Invalid provider '#{hash["provider"]}' for deploy envirenment '#{hash["identifier"]}'"
|
||||
end
|
||||
c.new(hash)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,117 +2,121 @@ require "db/mongo/models/mongo_model"
|
||||
require "db/exceptions/invalid_record"
|
||||
require "commands/deploy_env"
|
||||
|
||||
class DeployEnvMulti < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class DeployEnvMulti < MongoModel
|
||||
|
||||
include DeployEnvCommands
|
||||
include DeployEnvCommands
|
||||
|
||||
attr_accessor :identifier, :servers, :expires, :users
|
||||
attr_accessor :identifier, :servers, :expires, :users
|
||||
|
||||
types :identifier => {:type => String, :empty => false},
|
||||
:expires => {:type => String, :empty => false, :nil => true},
|
||||
:users => {:type => Array, :empty => true},
|
||||
:servers => {:type => Array, :empty => false, :value_type => Hash}
|
||||
types :identifier => {:type => String, :empty => false},
|
||||
:expires => {:type => String, :empty => false, :nil => true},
|
||||
:users => {:type => Array, :empty => true},
|
||||
:servers => {:type => Array, :empty => false, :value_type => Hash}
|
||||
|
||||
def initialize d={}
|
||||
self.identifier = d["identifier"]
|
||||
self.expires = d["expires"]
|
||||
self.servers = d["servers"]
|
||||
b = d["users"] || []
|
||||
self.users = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
e = []
|
||||
check_users!(self.users)
|
||||
unless self.expires.nil?
|
||||
check_expires!(self.expires)
|
||||
end
|
||||
self.servers.each_with_index do |server, i|
|
||||
begin
|
||||
if server["priority"].nil?
|
||||
server["priority"] = 100
|
||||
else
|
||||
begin
|
||||
Integer(server["priority"])
|
||||
rescue ArgumentError, TypeError
|
||||
raise InvalidRecord.new("Parameter 'priority' should be an integer")
|
||||
end
|
||||
end
|
||||
|
||||
if !server["subprojects"].is_a?(Array) or server["subprojects"].empty?
|
||||
raise InvalidRecord.new("Parameter 'subprojects' must be a not empty array")
|
||||
end
|
||||
if server["subprojects"].size > 1
|
||||
check_provider(server["provider"])
|
||||
# strings
|
||||
%w{image flavor provider}.each do |p|
|
||||
begin
|
||||
check_string!(server[p])
|
||||
rescue ArgumentError
|
||||
raise InvalidRecord.new("Parameter '#{p}' must be a not empty string")
|
||||
end
|
||||
end
|
||||
# arrays
|
||||
%w{subnets groups}.each do |p|
|
||||
begin
|
||||
raise ArgumentError if !server[p].is_a?(Array) or server[p].empty?
|
||||
server[p].each do |v|
|
||||
raise ArgumentError unless v.is_a?(String)
|
||||
end
|
||||
rescue ArgumentError
|
||||
raise InvalidRecord.new("Parameter '#{p}' must be a not empty array of strings")
|
||||
end
|
||||
end
|
||||
|
||||
p = ::Provider::ProviderFactory.get(server["provider"])
|
||||
check_flavor!(p, server["flavor"])
|
||||
check_image!(p, server["image"])
|
||||
check_subnets_and_groups!(p, server["subnets"], server["groups"])
|
||||
end
|
||||
names = {}
|
||||
server["subprojects"].each_with_index do |sp, spi|
|
||||
begin
|
||||
raise InvalidRecord.new("Parameter 'subprojects' must contains objects only") unless sp.is_a?(Hash)
|
||||
%w{name env}.each do |p|
|
||||
begin
|
||||
check_string!(sp[p])
|
||||
rescue ArgumentError
|
||||
raise InvalidRecord.new("Parameter '#{p}' must be a not empty string")
|
||||
end
|
||||
end
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new("Subproject '#{spi}'. #{e.message}")
|
||||
end
|
||||
end
|
||||
pdb = ::Devops::Db.connector.project_names_with_envs(server["subprojects"].map{|sp| sp["name"]})
|
||||
server["subprojects"].each_with_index do |sp, spi|
|
||||
raise InvalidRecord.new("Subproject '#{spi}'. Project '#{sp["name"]}' with env '#{sp["env"]}' does not exist") if pdb[sp["name"]].nil? or !pdb[sp["name"]].include?(sp["env"])
|
||||
end
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new("Server '#{i}'. #{e.message}")
|
||||
def initialize d={}
|
||||
self.identifier = d["identifier"]
|
||||
self.expires = d["expires"]
|
||||
self.servers = d["servers"]
|
||||
b = d["users"] || []
|
||||
self.users = (b.is_a?(Array) ? b.uniq : b)
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
e = []
|
||||
check_users!(self.users)
|
||||
unless self.expires.nil?
|
||||
check_expires!(self.expires)
|
||||
end
|
||||
self.servers.each_with_index do |server, i|
|
||||
begin
|
||||
if server["priority"].nil?
|
||||
server["priority"] = 100
|
||||
else
|
||||
begin
|
||||
Integer(server["priority"])
|
||||
rescue ArgumentError, TypeError
|
||||
raise InvalidRecord.new("Parameter 'priority' should be an integer")
|
||||
end
|
||||
end
|
||||
|
||||
if !server["subprojects"].is_a?(Array) or server["subprojects"].empty?
|
||||
raise InvalidRecord.new("Parameter 'subprojects' must be a not empty array")
|
||||
end
|
||||
if server["subprojects"].size > 1
|
||||
check_provider(server["provider"])
|
||||
# strings
|
||||
%w{image flavor provider}.each do |p|
|
||||
begin
|
||||
check_string!(server[p])
|
||||
rescue ArgumentError
|
||||
raise InvalidRecord.new("Parameter '#{p}' must be a not empty string")
|
||||
end
|
||||
end
|
||||
# arrays
|
||||
%w{subnets groups}.each do |p|
|
||||
begin
|
||||
raise ArgumentError if !server[p].is_a?(Array) or server[p].empty?
|
||||
server[p].each do |v|
|
||||
raise ArgumentError unless v.is_a?(String)
|
||||
end
|
||||
rescue ArgumentError
|
||||
raise InvalidRecord.new("Parameter '#{p}' must be a not empty array of strings")
|
||||
end
|
||||
end
|
||||
|
||||
p = ::Provider::ProviderFactory.get(server["provider"])
|
||||
check_flavor!(p, server["flavor"])
|
||||
check_image!(p, server["image"])
|
||||
check_subnets_and_groups!(p, server["subnets"], server["groups"])
|
||||
end
|
||||
names = {}
|
||||
server["subprojects"].each_with_index do |sp, spi|
|
||||
begin
|
||||
raise InvalidRecord.new("Parameter 'subprojects' must contains objects only") unless sp.is_a?(Hash)
|
||||
%w{name env}.each do |p|
|
||||
begin
|
||||
check_string!(sp[p])
|
||||
rescue ArgumentError
|
||||
raise InvalidRecord.new("Parameter '#{p}' must be a not empty string")
|
||||
end
|
||||
end
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new("Subproject '#{spi}'. #{e.message}")
|
||||
end
|
||||
end
|
||||
pdb = ::Devops::Db.connector.project_names_with_envs(server["subprojects"].map{|sp| sp["name"]})
|
||||
server["subprojects"].each_with_index do |sp, spi|
|
||||
raise InvalidRecord.new("Subproject '#{spi}'. Project '#{sp["name"]}' with env '#{sp["env"]}' does not exist") if pdb[sp["name"]].nil? or !pdb[sp["name"]].include?(sp["env"])
|
||||
end
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new("Server '#{i}'. #{e.message}")
|
||||
end
|
||||
end
|
||||
true
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new "Deploy environment '#{self.identifier}'. " + e.message
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
"identifier" => self.identifier,
|
||||
"expires" => self.expires,
|
||||
"users" => self.users,
|
||||
"servers" => self.servers
|
||||
}
|
||||
end
|
||||
|
||||
def self.build_from_bson d
|
||||
DeployEnvMulti.new(d)
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
DeployEnvMulti.new(hash)
|
||||
end
|
||||
|
||||
end
|
||||
true
|
||||
rescue InvalidRecord => e
|
||||
raise InvalidRecord.new "Deploy environment '#{self.identifier}'. " + e.message
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
"identifier" => self.identifier,
|
||||
"expires" => self.expires,
|
||||
"users" => self.users,
|
||||
"servers" => self.servers
|
||||
}
|
||||
end
|
||||
|
||||
def self.build_from_bson d
|
||||
DeployEnvMulti.new(d)
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
DeployEnvMulti.new(hash)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,57 +1,61 @@
|
||||
require "db/mongo/models/deploy_env/deploy_env_base"
|
||||
require "providers/provider_factory"
|
||||
|
||||
class DeployEnvOpenstack < DeployEnvBase
|
||||
module Devops
|
||||
module Model
|
||||
class DeployEnvOpenstack < DeployEnvBase
|
||||
|
||||
attr_accessor :flavor, :image, :subnets, :groups
|
||||
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}
|
||||
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::SubnetNotEmpty,
|
||||
::Validators::DeployEnv::SubnetBelongsToProvider,
|
||||
::Validators::DeployEnv::Groups
|
||||
set_validators ::Validators::DeployEnv::RunList,
|
||||
::Validators::DeployEnv::Expiration,
|
||||
::Validators::DeployEnv::Users,
|
||||
::Validators::DeployEnv::Flavor,
|
||||
::Validators::DeployEnv::Image,
|
||||
::Validators::DeployEnv::SubnetNotEmpty,
|
||||
::Validators::DeployEnv::SubnetBelongsToProvider,
|
||||
::Validators::DeployEnv::Groups
|
||||
|
||||
def initialize d={}
|
||||
super(d)
|
||||
self.flavor = d["flavor"]
|
||||
self.image = d["image"]
|
||||
b = d["subnets"] || []
|
||||
self.subnets = (b.is_a?(Array) ? b.uniq : b)
|
||||
b = d["groups"] || ["default"]
|
||||
self.groups = (b.is_a?(Array) ? b.uniq : b)
|
||||
def initialize d={}
|
||||
super(d)
|
||||
self.flavor = d["flavor"]
|
||||
self.image = d["image"]
|
||||
b = d["subnets"] || []
|
||||
self.subnets = (b.is_a?(Array) ? b.uniq : b)
|
||||
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
|
||||
DeployEnvOpenstack.new(hash)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def subnets_filter
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
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
|
||||
DeployEnvOpenstack.new(hash)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def subnets_filter
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,45 +1,31 @@
|
||||
require "db/mongo/models/deploy_env/deploy_env_base"
|
||||
|
||||
class DeployEnvStatic < DeployEnvBase
|
||||
module Devops
|
||||
module Model
|
||||
class DeployEnvStatic < DeployEnvBase
|
||||
|
||||
types :identifier => {: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}
|
||||
types :identifier => {: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}
|
||||
|
||||
set_validators ::Validators::DeployEnv::RunList,
|
||||
::Validators::DeployEnv::Expiration,
|
||||
::Validators::DeployEnv::Users
|
||||
set_validators ::Validators::DeployEnv::RunList,
|
||||
::Validators::DeployEnv::Expiration,
|
||||
::Validators::DeployEnv::Users
|
||||
|
||||
def initialize d={}
|
||||
super(d)
|
||||
=begin
|
||||
self.identifier = d["identifier"]
|
||||
b = d["run_list"] || []
|
||||
self.run_list = (b.is_a?(Array) ? b.uniq : b)
|
||||
self.expires = d["expires"]
|
||||
self.provider = d["provider"]
|
||||
b = d["users"] || []
|
||||
self.users = (b.is_a?(Array) ? b.uniq : b)
|
||||
=end
|
||||
def initialize d={}
|
||||
super(d)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
super
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
DeployEnvStatic.new(hash)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def to_hash
|
||||
super
|
||||
=begin
|
||||
{
|
||||
"identifier" => self.identifier,
|
||||
"run_list" => self.run_list,
|
||||
"expires" => self.expires,
|
||||
"provider" => self.provider,
|
||||
"users" => self.users
|
||||
}
|
||||
=end
|
||||
end
|
||||
|
||||
def self.create hash
|
||||
DeployEnvStatic.new(hash)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,43 +1,47 @@
|
||||
require "db/exceptions/invalid_record"
|
||||
require "db/mongo/models/mongo_model"
|
||||
|
||||
class Image < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class Image < MongoModel
|
||||
|
||||
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}
|
||||
set_validators ::Validators::Image::ImageInFilter,
|
||||
::Validators::Image::BootstrapTemplate
|
||||
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}
|
||||
set_validators ::Validators::Image::ImageInFilter,
|
||||
::Validators::Image::BootstrapTemplate
|
||||
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
self.provider = p["provider"]
|
||||
self.remote_user = p["remote_user"]
|
||||
self.name = p["name"] || ""
|
||||
self.bootstrap_template = p["bootstrap_template"]
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
self.provider = p["provider"]
|
||||
self.remote_user = p["remote_user"]
|
||||
self.name = p["name"] || ""
|
||||
self.bootstrap_template = p["bootstrap_template"]
|
||||
end
|
||||
|
||||
def self.build_from_bson args
|
||||
image = Image.new(args)
|
||||
image.id = args["_id"]
|
||||
image
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
o = {
|
||||
"provider" => self.provider,
|
||||
"name" => self.name,
|
||||
"remote_user" => self.remote_user
|
||||
}
|
||||
o["bootstrap_template"] = self.bootstrap_template
|
||||
o
|
||||
end
|
||||
|
||||
def self.create_from_json! json
|
||||
Image.new( JSON.parse(json) )
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_from_bson args
|
||||
image = Image.new(args)
|
||||
image.id = args["_id"]
|
||||
image
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
o = {
|
||||
"provider" => self.provider,
|
||||
"name" => self.name,
|
||||
"remote_user" => self.remote_user
|
||||
}
|
||||
o["bootstrap_template"] = self.bootstrap_template
|
||||
o
|
||||
end
|
||||
|
||||
def self.create_from_json! json
|
||||
Image.new( JSON.parse(json) )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,45 +2,49 @@ require "db/exceptions/invalid_record"
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "json"
|
||||
|
||||
class Key < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class Key < MongoModel
|
||||
|
||||
SYSTEM = "system"
|
||||
USER = "user"
|
||||
SYSTEM = "system"
|
||||
USER = "user"
|
||||
|
||||
attr_accessor :id, :path, :scope
|
||||
types :id => {:type => String, :empty => false},
|
||||
:path => {:type => String, :empty => false},
|
||||
:scope => {:type => String, :empty => false}
|
||||
attr_accessor :id, :path, :scope
|
||||
types :id => {:type => String, :empty => false},
|
||||
:path => {:type => String, :empty => false},
|
||||
:scope => {:type => String, :empty => false}
|
||||
|
||||
set_validators ::Validators::Key::FileExistence,
|
||||
::Validators::Key::Scope
|
||||
set_validators ::Validators::Key::FileExistence,
|
||||
::Validators::Key::Scope
|
||||
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
self.path = p["path"]
|
||||
self.scope = p["scope"] || USER
|
||||
def initialize p={}
|
||||
self.id = p["id"]
|
||||
self.path = p["path"]
|
||||
self.scope = p["scope"] || USER
|
||||
end
|
||||
|
||||
def self.build_from_bson s
|
||||
key = Key.new s
|
||||
key.id = s["_id"]
|
||||
key
|
||||
end
|
||||
|
||||
def self.create_from_json json
|
||||
Key.new( JSON.parse(json) )
|
||||
end
|
||||
|
||||
def filename
|
||||
File.basename(self.path)
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
o = {
|
||||
"path" => self.path,
|
||||
"scope" => self.scope
|
||||
}
|
||||
o
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_from_bson s
|
||||
key = Key.new s
|
||||
key.id = s["_id"]
|
||||
key
|
||||
end
|
||||
|
||||
def self.create_from_json json
|
||||
Key.new( JSON.parse(json) )
|
||||
end
|
||||
|
||||
def filename
|
||||
File.basename(self.path)
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
o = {
|
||||
"path" => self.path,
|
||||
"scope" => self.scope
|
||||
}
|
||||
o
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,145 +2,149 @@ require "providers/provider_factory"
|
||||
require "db/exceptions/invalid_record"
|
||||
require "json"
|
||||
|
||||
class MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class MongoModel
|
||||
|
||||
# multi_json sends argument to 'to_json' method
|
||||
def to_json arg=nil
|
||||
JSON.pretty_generate self.to_hash
|
||||
end
|
||||
# multi_json sends argument to 'to_json' method
|
||||
def to_json arg=nil
|
||||
JSON.pretty_generate self.to_hash
|
||||
end
|
||||
|
||||
def to_hash
|
||||
h = to_hash_without_id
|
||||
h["id"] = self.id
|
||||
h
|
||||
end
|
||||
def to_hash
|
||||
h = to_hash_without_id
|
||||
h["id"] = self.id
|
||||
h
|
||||
end
|
||||
|
||||
def to_mongo_hash
|
||||
h = to_hash_without_id
|
||||
h["_id"] = self.id
|
||||
h
|
||||
end
|
||||
def to_mongo_hash
|
||||
h = to_hash_without_id
|
||||
h["_id"] = self.id
|
||||
h
|
||||
end
|
||||
|
||||
def is_empty? val
|
||||
val.nil? or val.strip.empty?
|
||||
end
|
||||
def is_empty? val
|
||||
val.nil? or val.strip.empty?
|
||||
end
|
||||
|
||||
def check_string! val
|
||||
raise ArgumentError unless val.is_a?(String)
|
||||
val.strip!
|
||||
raise ArgumentError if val.empty?
|
||||
end
|
||||
def check_string! val
|
||||
raise ArgumentError unless val.is_a?(String)
|
||||
val.strip!
|
||||
raise ArgumentError if val.empty?
|
||||
end
|
||||
|
||||
def check_array! val, type, empty=false
|
||||
raise ArgumentError unless val.is_a?(Array)
|
||||
raise ArgumentError if !empty and val.empty?
|
||||
val.each do |v|
|
||||
raise ArgumentError unless v.is_a?(type)
|
||||
end
|
||||
end
|
||||
|
||||
def check_name_value val
|
||||
raise ArgumentError.new "Invalid name, it should contains 0-9, a-z, A-Z, _, - symbols only" if val.match(/^[0-9a-zA-Z_\-]+$/).nil?
|
||||
end
|
||||
|
||||
def check_provider provider=self.provider
|
||||
unless ::Provider::ProviderFactory.providers.include?(provider)
|
||||
raise InvalidRecord.new "Invalid provider '#{provider}'"
|
||||
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
|
||||
# :type - param type
|
||||
# :empty - can param be empty? (false)
|
||||
# :nil - can param be nil? (false)
|
||||
# :value_type - type of array element (String)
|
||||
def self.types types
|
||||
define_method :validate_fields_types do
|
||||
t = types.keys
|
||||
e = types.keys
|
||||
n = types.keys
|
||||
types.each do |name, value|
|
||||
if value[:nil]
|
||||
n.delete(name)
|
||||
if self.send(name).nil?
|
||||
e.delete(name)
|
||||
t.delete(name)
|
||||
next
|
||||
end
|
||||
else
|
||||
n.delete(name) unless self.send(name).nil?
|
||||
def check_array! val, type, empty=false
|
||||
raise ArgumentError unless val.is_a?(Array)
|
||||
raise ArgumentError if !empty and val.empty?
|
||||
val.each do |v|
|
||||
raise ArgumentError unless v.is_a?(type)
|
||||
end
|
||||
if self.send(name).is_a? value[:type]
|
||||
t.delete(name)
|
||||
self.send(name).strip! if value[:type] == String
|
||||
if value[:type] == Array
|
||||
unless value[:value_type] == false
|
||||
type = value[:value_type] || String
|
||||
self.send(name).each do |e|
|
||||
unless e.is_a?(type)
|
||||
t.push(name)
|
||||
break
|
||||
end
|
||||
|
||||
def check_name_value val
|
||||
raise ArgumentError.new "Invalid name, it should contains 0-9, a-z, A-Z, _, - symbols only" if val.match(/^[0-9a-zA-Z_\-]+$/).nil?
|
||||
end
|
||||
|
||||
def check_provider provider=self.provider
|
||||
unless ::Provider::ProviderFactory.providers.include?(provider)
|
||||
raise InvalidRecord.new "Invalid provider '#{provider}'"
|
||||
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
|
||||
# :type - param type
|
||||
# :empty - can param be empty? (false)
|
||||
# :nil - can param be nil? (false)
|
||||
# :value_type - type of array element (String)
|
||||
def self.types types
|
||||
define_method :validate_fields_types do
|
||||
t = types.keys
|
||||
e = types.keys
|
||||
n = types.keys
|
||||
types.each do |name, value|
|
||||
if value[:nil]
|
||||
n.delete(name)
|
||||
if self.send(name).nil?
|
||||
e.delete(name)
|
||||
t.delete(name)
|
||||
next
|
||||
end
|
||||
else
|
||||
n.delete(name) unless self.send(name).nil?
|
||||
end
|
||||
if self.send(name).is_a? value[:type]
|
||||
t.delete(name)
|
||||
self.send(name).strip! if value[:type] == String
|
||||
if value[:type] == Array
|
||||
unless value[:value_type] == false
|
||||
type = value[:value_type] || String
|
||||
self.send(name).each do |e|
|
||||
unless e.is_a?(type)
|
||||
t.push(name)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
e.delete(name) if value[:empty] or !self.send(name).empty?
|
||||
end
|
||||
end
|
||||
e.delete(name) if value[:empty] or !self.send(name).empty?
|
||||
raise InvalidRecord.new "Parameter(s) '#{n.join("', '")}' can not be undefined" unless n.empty?
|
||||
raise InvalidRecord.new "Parameter(s) '#{t.join("', '")}' have invalid type(s)" unless t.empty?
|
||||
raise InvalidRecord.new "Parameter(s) '#{e.join("', '")}' can not be empty" unless e.empty?
|
||||
if types.has_key? :provider
|
||||
self.send("check_provider")
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
raise InvalidRecord.new "Parameter(s) '#{n.join("', '")}' can not be undefined" unless n.empty?
|
||||
raise InvalidRecord.new "Parameter(s) '#{t.join("', '")}' have invalid type(s)" unless t.empty?
|
||||
raise InvalidRecord.new "Parameter(s) '#{e.join("', '")}' can not be empty" unless e.empty?
|
||||
if types.has_key? :provider
|
||||
self.send("check_provider")
|
||||
|
||||
def self.validators
|
||||
@validators || []
|
||||
end
|
||||
true
|
||||
|
||||
# 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
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
@ -6,134 +6,138 @@ require "db/mongo/models/deploy_env/deploy_env_multi"
|
||||
require "db/mongo/models/mongo_model"
|
||||
require "json"
|
||||
|
||||
class Project < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class Project < MongoModel
|
||||
|
||||
attr_accessor :id, :deploy_envs, :type, :archived, :description
|
||||
attr_accessor :id, :deploy_envs, :type, :archived, :description
|
||||
|
||||
types :id => {:type => String, :empty => false},
|
||||
:deploy_envs => {:type => Array, :value_type => false, :empty => false},
|
||||
:description => {:type => String, :empty => true, :nil => true}
|
||||
types :id => {:type => String, :empty => false},
|
||||
:deploy_envs => {:type => Array, :value_type => false, :empty => false},
|
||||
:description => {:type => String, :empty => true, :nil => true}
|
||||
|
||||
MULTI_TYPE = "multi"
|
||||
MULTI_TYPE = "multi"
|
||||
|
||||
def self.fields
|
||||
["deploy_envs", "type", "description"]
|
||||
end
|
||||
def self.fields
|
||||
["deploy_envs", "type", "description"]
|
||||
end
|
||||
|
||||
def initialize p={}
|
||||
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"]
|
||||
self.description = p["description"]
|
||||
self.archived = p["archived"] || false
|
||||
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)
|
||||
def initialize p={}
|
||||
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"]
|
||||
self.description = p["description"]
|
||||
self.archived = p["archived"] || false
|
||||
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_authorized_user user, env=nil
|
||||
return if user.nil?
|
||||
new_users = ( user.is_a?(Array) ? user : [ user ] )
|
||||
if env.nil?
|
||||
self.deploy_envs.each do |e|
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = (e.users + new_users).uniq
|
||||
end
|
||||
else
|
||||
e = self.deploy_env(env)
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = (e.users + new_users).uniq
|
||||
end
|
||||
end
|
||||
|
||||
def remove_authorized_user user, env=nil
|
||||
return if user.nil?
|
||||
users = ( user.is_a?(Array) ? user : [ user ] )
|
||||
if env.nil?
|
||||
self.deploy_envs.each do |e|
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = e.users - users
|
||||
end
|
||||
else
|
||||
e = self.deploy_env(env)
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = e.users - users
|
||||
end
|
||||
end
|
||||
|
||||
def check_authorization user_id, env
|
||||
e = self.deploy_env(env)
|
||||
return true if user_id == User::ROOT_USER_NAME
|
||||
return e.users.include? user_id
|
||||
rescue RecordNotFound => e
|
||||
return false
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
check_name_value(self.id)
|
||||
envs = self.deploy_envs.map {|d| d.identifier}
|
||||
non_uniq = envs.uniq.select{|u| envs.count(u) > 1}
|
||||
raise InvalidRecord.new "Deploy environment(s) '#{non_uniq.join("', '")}' is/are not unique" unless non_uniq.empty?
|
||||
self.deploy_envs.each do |d|
|
||||
d.validate!
|
||||
unless self.multi?
|
||||
rn = "#{self.id}#{DevopsConfig.config[:role_separator] || "_"}#{d.identifier}"
|
||||
role = "role[#{rn}]"
|
||||
d.run_list = d.run_list - [rn, role]
|
||||
d.run_list.unshift(role)
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
rescue InvalidRecord, ArgumentError => e
|
||||
raise InvalidRecord.new "Project '#{self.id}'. #{e.message}"
|
||||
end
|
||||
|
||||
def remove_env env
|
||||
self.deploy_envs.delete_if {|e| e.identifier == env}
|
||||
end
|
||||
|
||||
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
|
||||
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_authorized_user user, env=nil
|
||||
return if user.nil?
|
||||
new_users = ( user.is_a?(Array) ? user : [ user ] )
|
||||
if env.nil?
|
||||
self.deploy_envs.each do |e|
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = (e.users + new_users).uniq
|
||||
def to_hash
|
||||
h = self.to_hash_without_id
|
||||
h["name"] = self.id
|
||||
h
|
||||
end
|
||||
else
|
||||
e = self.deploy_env(env)
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = (e.users + new_users).uniq
|
||||
end
|
||||
end
|
||||
|
||||
def remove_authorized_user user, env=nil
|
||||
return if user.nil?
|
||||
users = ( user.is_a?(Array) ? user : [ user ] )
|
||||
if env.nil?
|
||||
self.deploy_envs.each do |e|
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = e.users - users
|
||||
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
|
||||
h["description"] = self.description
|
||||
if self.multi?
|
||||
h["type"] = MULTI_TYPE
|
||||
end
|
||||
h
|
||||
end
|
||||
else
|
||||
e = self.deploy_env(env)
|
||||
return unless e.users.is_a?(Array)
|
||||
e.users = e.users - users
|
||||
end
|
||||
end
|
||||
|
||||
def check_authorization user_id, env
|
||||
e = self.deploy_env(env)
|
||||
return true if user_id == User::ROOT_USER_NAME
|
||||
return e.users.include? user_id
|
||||
rescue RecordNotFound => e
|
||||
return false
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
check_name_value(self.id)
|
||||
envs = self.deploy_envs.map {|d| d.identifier}
|
||||
non_uniq = envs.uniq.select{|u| envs.count(u) > 1}
|
||||
raise InvalidRecord.new "Deploy environment(s) '#{non_uniq.join("', '")}' is/are not unique" unless non_uniq.empty?
|
||||
self.deploy_envs.each do |d|
|
||||
d.validate!
|
||||
unless self.multi?
|
||||
rn = "#{self.id}#{DevopsConfig.config[:role_separator] || "_"}#{d.identifier}"
|
||||
role = "role[#{rn}]"
|
||||
d.run_list = d.run_list - [rn, role]
|
||||
d.run_list.unshift(role)
|
||||
def multi?
|
||||
self.type == MULTI_TYPE
|
||||
end
|
||||
|
||||
def self.build_from_bson p
|
||||
p["name"] = p["_id"]
|
||||
Project.new p
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
true
|
||||
rescue InvalidRecord, ArgumentError => e
|
||||
raise InvalidRecord.new "Project '#{self.id}'. #{e.message}"
|
||||
end
|
||||
|
||||
def remove_env env
|
||||
self.deploy_envs.delete_if {|e| e.identifier == env}
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def to_hash
|
||||
h = self.to_hash_without_id
|
||||
h["name"] = self.id
|
||||
h
|
||||
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
|
||||
h["description"] = self.description
|
||||
if self.multi?
|
||||
h["type"] = MULTI_TYPE
|
||||
end
|
||||
h
|
||||
end
|
||||
|
||||
def multi?
|
||||
self.type == MULTI_TYPE
|
||||
end
|
||||
|
||||
def self.build_from_bson p
|
||||
p["name"] = p["_id"]
|
||||
Project.new p
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,34 +1,38 @@
|
||||
require "db/exceptions/invalid_record"
|
||||
require "db/mongo/models/mongo_model"
|
||||
|
||||
class Report < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class Report < MongoModel
|
||||
|
||||
DEPLOY_TYPE = 1
|
||||
SERVER_TYPE = 2
|
||||
BOOTSTRAP_TYPE = 3
|
||||
PROJECT_TEST_TYPE = 4
|
||||
DEPLOY_TYPE = 1
|
||||
SERVER_TYPE = 2
|
||||
BOOTSTRAP_TYPE = 3
|
||||
PROJECT_TEST_TYPE = 4
|
||||
|
||||
attr_accessor :id, :file, :created_at, :created_by, :project, :deploy_env, :type
|
||||
attr_accessor :id, :file, :created_at, :created_by, :project, :deploy_env, :type
|
||||
|
||||
def initialize r
|
||||
self.id = r["_id"]
|
||||
self.file = r["file"]
|
||||
self.created_by = r["created_by"]
|
||||
self.project = r["project"]
|
||||
self.deploy_env = r["deploy_env"]
|
||||
self.type = r["type"]
|
||||
self.created_at = r["created_at"]
|
||||
def initialize r
|
||||
self.id = r["_id"]
|
||||
self.file = r["file"]
|
||||
self.created_by = r["created_by"]
|
||||
self.project = r["project"]
|
||||
self.deploy_env = r["deploy_env"]
|
||||
self.type = r["type"]
|
||||
self.created_at = r["created_at"]
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
{
|
||||
"file" => self.file,
|
||||
"created_at" => self.created_at,
|
||||
"created_by" => self.created_by,
|
||||
"project" => self.project,
|
||||
"deploy_env" => self.deploy_env,
|
||||
"type" => self.type
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
{
|
||||
"file" => self.file,
|
||||
"created_at" => self.created_at,
|
||||
"created_by" => self.created_by,
|
||||
"project" => self.project,
|
||||
"deploy_env" => self.deploy_env,
|
||||
"type" => self.type
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,89 +1,93 @@
|
||||
require "db/exceptions/invalid_record"
|
||||
require "db/mongo/models/mongo_model"
|
||||
|
||||
class Server < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class Server < MongoModel
|
||||
|
||||
attr_accessor :provider, :chef_node_name, :id, :remote_user, :project, :deploy_env, :private_ip, :public_ip, :created_at, :without_bootstrap, :created_by, :reserved_by
|
||||
attr_accessor :options, :static, :key
|
||||
attr_accessor :provider, :chef_node_name, :id, :remote_user, :project, :deploy_env, :private_ip, :public_ip, :created_at, :without_bootstrap, :created_by, :reserved_by
|
||||
attr_accessor :options, :static, :key
|
||||
|
||||
types :id => {:type => String, :empty => false},
|
||||
:provider => {:type => String, :empty => false},
|
||||
:remote_user => {:type => String, :empty => false},
|
||||
:project => {:type => String, :empty => false},
|
||||
:deploy_env => {:type => String, :empty => false},
|
||||
:private_ip => {:type => String, :empty => false},
|
||||
:public_ip => {:type => String, :empty => true, :nil => true},
|
||||
:key => {:type => String, :empty => false},
|
||||
:created_by => {:type => String, :empty => false},
|
||||
:chef_node_name => {:type => String, :empty => true},
|
||||
:reserved_by => {:type => String, :empty => true}
|
||||
types :id => {:type => String, :empty => false},
|
||||
:provider => {:type => String, :empty => false},
|
||||
:remote_user => {:type => String, :empty => false},
|
||||
:project => {:type => String, :empty => false},
|
||||
:deploy_env => {:type => String, :empty => false},
|
||||
:private_ip => {:type => String, :empty => false},
|
||||
:public_ip => {:type => String, :empty => true, :nil => true},
|
||||
:key => {:type => String, :empty => false},
|
||||
:created_by => {:type => String, :empty => false},
|
||||
:chef_node_name => {:type => String, :empty => true},
|
||||
:reserved_by => {:type => String, :empty => true}
|
||||
|
||||
def self.fields
|
||||
["chef_node_name", "project", "deploy_env", "provider", "remote_user", "private_ip", "public_ip", "created_at", "created_by", "static", "key", "reserved_by"]
|
||||
def self.fields
|
||||
["chef_node_name", "project", "deploy_env", "provider", "remote_user", "private_ip", "public_ip", "created_at", "created_by", "static", "key", "reserved_by"]
|
||||
end
|
||||
|
||||
def initialize s={}
|
||||
self.provider = s["provider"]
|
||||
self.chef_node_name = s["chef_node_name"]
|
||||
self.id = s["_id"]
|
||||
self.remote_user = s["remote_user"]
|
||||
self.project = s["project"]
|
||||
self.deploy_env = s["deploy_env"]
|
||||
self.public_ip = s["public_ip"]
|
||||
self.private_ip = s["private_ip"]
|
||||
self.created_at = s["created_at"]
|
||||
self.created_by = s["created_by"]
|
||||
self.static = s["static"]
|
||||
self.key = s["key"]
|
||||
self.reserved_by = s["reserved_by"]
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
true
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
{
|
||||
"provider" => self.provider,
|
||||
"chef_node_name" => self.chef_node_name,
|
||||
"remote_user" => self.remote_user,
|
||||
"project" => self.project,
|
||||
"deploy_env" => self.deploy_env,
|
||||
"private_ip" => self.private_ip,
|
||||
"public_ip" => self.public_ip,
|
||||
"created_at" => self.created_at,
|
||||
"created_by" => self.created_by,
|
||||
"static" => self.static,
|
||||
"key" => self.key,
|
||||
"reserved_by" => self.reserved_by
|
||||
}.delete_if{|k,v| v.nil?}
|
||||
end
|
||||
|
||||
def to_list_hash
|
||||
{
|
||||
"id" => self.id,
|
||||
"chef_node_name" => self.chef_node_name
|
||||
}
|
||||
end
|
||||
|
||||
def self.build_from_bson s
|
||||
Server.new(s)
|
||||
end
|
||||
|
||||
def info
|
||||
str = "Instance Name: #{self.chef_node_name}\n"
|
||||
str << "Instance ID: #{self.id}\n"
|
||||
str << "Private IP: #{self.private_ip}\n"
|
||||
str << "Public IP: #{self.public_ip}\n" unless self.public_ip.nil?
|
||||
str << "Remote user: #{self.remote_user}\n"
|
||||
str << "Project: #{self.project} - #{self.deploy_env}\n"
|
||||
str << "Created by: #{self.created_by}"
|
||||
str
|
||||
end
|
||||
|
||||
def static?
|
||||
self.static || false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def initialize s={}
|
||||
self.provider = s["provider"]
|
||||
self.chef_node_name = s["chef_node_name"]
|
||||
self.id = s["_id"]
|
||||
self.remote_user = s["remote_user"]
|
||||
self.project = s["project"]
|
||||
self.deploy_env = s["deploy_env"]
|
||||
self.public_ip = s["public_ip"]
|
||||
self.private_ip = s["private_ip"]
|
||||
self.created_at = s["created_at"]
|
||||
self.created_by = s["created_by"]
|
||||
self.static = s["static"]
|
||||
self.key = s["key"]
|
||||
self.reserved_by = s["reserved_by"]
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
true
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
{
|
||||
"provider" => self.provider,
|
||||
"chef_node_name" => self.chef_node_name,
|
||||
"remote_user" => self.remote_user,
|
||||
"project" => self.project,
|
||||
"deploy_env" => self.deploy_env,
|
||||
"private_ip" => self.private_ip,
|
||||
"public_ip" => self.public_ip,
|
||||
"created_at" => self.created_at,
|
||||
"created_by" => self.created_by,
|
||||
"static" => self.static,
|
||||
"key" => self.key,
|
||||
"reserved_by" => self.reserved_by
|
||||
}.delete_if{|k,v| v.nil?}
|
||||
end
|
||||
|
||||
def to_list_hash
|
||||
{
|
||||
"id" => self.id,
|
||||
"chef_node_name" => self.chef_node_name
|
||||
}
|
||||
end
|
||||
|
||||
def self.build_from_bson s
|
||||
Server.new(s)
|
||||
end
|
||||
|
||||
def info
|
||||
str = "Instance Name: #{self.chef_node_name}\n"
|
||||
str << "Instance ID: #{self.id}\n"
|
||||
str << "Private IP: #{self.private_ip}\n"
|
||||
str << "Public IP: #{self.public_ip}\n" unless self.public_ip.nil?
|
||||
str << "Remote user: #{self.remote_user}\n"
|
||||
str << "Project: #{self.project} - #{self.deploy_env}\n"
|
||||
str << "Created by: #{self.created_by}"
|
||||
str
|
||||
end
|
||||
|
||||
def static?
|
||||
self.static || false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,52 +1,56 @@
|
||||
class StackBase < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class StackBase < MongoModel
|
||||
|
||||
attr_accessor :id, :project, :deploy_env, :stack_template, :cloud_stack_id, :provider
|
||||
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}
|
||||
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
|
||||
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.build_from_bson(attrs)
|
||||
attrs['id'] = attrs["_id"]
|
||||
self.new(attrs)
|
||||
end
|
||||
|
||||
def create_stack_in_cloud!
|
||||
raise 'override me'
|
||||
end
|
||||
|
||||
end
|
||||
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.build_from_bson(attrs)
|
||||
attrs['id'] = attrs["_id"]
|
||||
self.new(attrs)
|
||||
end
|
||||
|
||||
def create_stack_in_cloud!
|
||||
raise 'override me'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
class StackEc2 < StackBase
|
||||
module Devops
|
||||
module Model
|
||||
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'
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,25 +2,29 @@ require_relative "stack_base"
|
||||
require_relative "stack_openstack"
|
||||
require_relative "stack_ec2"
|
||||
|
||||
class StackFactory
|
||||
module Devops
|
||||
module Model
|
||||
class StackFactory
|
||||
|
||||
def self.create(provider, attrs)
|
||||
get_class(provider).create(attrs)
|
||||
end
|
||||
def self.create(provider, attrs)
|
||||
get_class(provider).create(attrs)
|
||||
end
|
||||
|
||||
def self.build_from_bson(provider, attrs)
|
||||
get_class(provider).build_from_bson(attrs)
|
||||
end
|
||||
def self.build_from_bson(provider, attrs)
|
||||
get_class(provider).build_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
|
||||
|
||||
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
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
class StackOpenstack < StackBase
|
||||
module Devops
|
||||
module Model
|
||||
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'
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,73 +1,77 @@
|
||||
require 'tempfile'
|
||||
require 'securerandom'
|
||||
|
||||
class StackTemplateBase < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class StackTemplateBase < MongoModel
|
||||
|
||||
attr_accessor :id, :template_url, :template_json, :provider
|
||||
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.
|
||||
# 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}
|
||||
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 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
|
||||
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
|
||||
# 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
|
||||
# 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.build_from_bson(attrs)
|
||||
attrs['id'] = attrs["_id"]
|
||||
self.new(attrs)
|
||||
end
|
||||
def self.build_from_bson(attrs)
|
||||
attrs['id'] = attrs["_id"]
|
||||
self.new(attrs)
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
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
|
||||
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
|
||||
|
||||
def upload_file_to_storage(filename, file_path)
|
||||
raise 'Override me'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
class StackTemplateEc2 < StackTemplateBase
|
||||
module Devops
|
||||
module Model
|
||||
class StackTemplateEc2 < StackTemplateBase
|
||||
|
||||
def delete_template_file_from_storage
|
||||
raise 'Implement me'
|
||||
end
|
||||
def delete_template_file_from_storage
|
||||
raise 'Implement me'
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
class << self
|
||||
private
|
||||
|
||||
def upload_file_to_storage(filename, path)
|
||||
"https://s3.amazonaws.com/#{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
def upload_file_to_storage(filename, path)
|
||||
"https://s3.amazonaws.com/#{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,25 +2,29 @@ require_relative "stack_template_base"
|
||||
require_relative "stack_template_openstack"
|
||||
require_relative "stack_template_ec2"
|
||||
|
||||
class StackTemplateFactory
|
||||
module Devops
|
||||
module Model
|
||||
class StackTemplateFactory
|
||||
|
||||
def self.create(provider, attrs)
|
||||
get_class(provider).create(attrs)
|
||||
end
|
||||
def self.create(provider, attrs)
|
||||
get_class(provider).create(attrs)
|
||||
end
|
||||
|
||||
def self.build_from_bson(provider, attrs)
|
||||
get_class(provider).build_from_bson(attrs)
|
||||
end
|
||||
def self.build_from_bson(provider, attrs)
|
||||
get_class(provider).build_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
|
||||
|
||||
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
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
class StackTemplateOpenstack < StackTemplateBase
|
||||
module Devops
|
||||
module Model
|
||||
class StackTemplateOpenstack < StackTemplateBase
|
||||
|
||||
def delete_template_file_from_storage
|
||||
raise 'Implement me'
|
||||
end
|
||||
def delete_template_file_from_storage
|
||||
raise 'Implement me'
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
class << self
|
||||
private
|
||||
|
||||
def upload_file_to_storage(filename, path)
|
||||
"https://openstack_host/v1/my_account/#{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
def upload_file_to_storage(filename, path)
|
||||
"https://openstack_host/v1/my_account/#{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -2,111 +2,115 @@ require "db/exceptions/invalid_record"
|
||||
require "exceptions/invalid_command"
|
||||
require "db/mongo/models/mongo_model"
|
||||
|
||||
class User < MongoModel
|
||||
module Devops
|
||||
module Model
|
||||
class User < MongoModel
|
||||
|
||||
ROOT_USER_NAME = 'root'
|
||||
ROOT_PASSWORD = ''
|
||||
ROOT_USER_NAME = 'root'
|
||||
ROOT_PASSWORD = ''
|
||||
|
||||
PRIVILEGES = ["r", "w", "x"]
|
||||
PRIVILEGES_REGEX = /^r?w?x?$/
|
||||
PRIVILEGES = ["r", "w", "x"]
|
||||
PRIVILEGES_REGEX = /^r?w?x?$/
|
||||
|
||||
attr_accessor :id, :password, :privileges, :email
|
||||
types :id => {:type => String, :empty => false},
|
||||
:email => {:type => String, :empty => false},
|
||||
:password => {:type => String, :empty => true}
|
||||
attr_accessor :id, :password, :privileges, :email
|
||||
types :id => {:type => String, :empty => false},
|
||||
:email => {:type => String, :empty => false},
|
||||
:password => {:type => String, :empty => true}
|
||||
|
||||
def initialize p={}
|
||||
self.id = p['username']
|
||||
self.email = p['email']
|
||||
self.password = p['password']
|
||||
self.privileges = p["privileges"] || self.default_privileges
|
||||
end
|
||||
|
||||
def all_privileges
|
||||
privileges_with_value("rwx")
|
||||
end
|
||||
|
||||
def default_privileges
|
||||
privileges_with_value("r", "user" => "")
|
||||
end
|
||||
|
||||
def grant cmd, priv=''
|
||||
if !priv.empty? and PRIVILEGES_REGEX.match(priv).to_s.empty?
|
||||
raise InvalidCommand.new "Invalid privileges '#{priv}'. Available values are '#{PRIVILEGES.join("', '")}'"
|
||||
end
|
||||
raise InvalidPrivileges.new "Can't grant privileges to root" if self.id == ROOT_USER_NAME
|
||||
|
||||
case cmd
|
||||
when "all"
|
||||
self.privileges.each_key do |key|
|
||||
self.privileges[key] = priv
|
||||
def initialize p={}
|
||||
self.id = p['username']
|
||||
self.email = p['email']
|
||||
self.password = p['password']
|
||||
self.privileges = p["privileges"] || self.default_privileges
|
||||
end
|
||||
when ""
|
||||
self.privileges = self.default_privileges
|
||||
else
|
||||
raise InvalidCommand.new "Unsupported command #{cmd}" unless self.all_privileges.include?(cmd)
|
||||
self.privileges[cmd] = priv
|
||||
|
||||
def all_privileges
|
||||
privileges_with_value("rwx")
|
||||
end
|
||||
|
||||
def default_privileges
|
||||
privileges_with_value("r", "user" => "")
|
||||
end
|
||||
|
||||
def grant cmd, priv=''
|
||||
if !priv.empty? and PRIVILEGES_REGEX.match(priv).to_s.empty?
|
||||
raise InvalidCommand.new "Invalid privileges '#{priv}'. Available values are '#{PRIVILEGES.join("', '")}'"
|
||||
end
|
||||
raise InvalidPrivileges.new "Can't grant privileges to root" if self.id == ROOT_USER_NAME
|
||||
|
||||
case cmd
|
||||
when "all"
|
||||
self.privileges.each_key do |key|
|
||||
self.privileges[key] = priv
|
||||
end
|
||||
when ""
|
||||
self.privileges = self.default_privileges
|
||||
else
|
||||
raise InvalidCommand.new "Unsupported command #{cmd}" unless self.all_privileges.include?(cmd)
|
||||
self.privileges[cmd] = priv
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_from_bson s
|
||||
user = User.new s
|
||||
user.id = s["_id"]
|
||||
user
|
||||
end
|
||||
|
||||
def self.create_from_json json
|
||||
User.new( JSON.parse(json) )
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
o = {
|
||||
"email" => self.email,
|
||||
"password" => self.password,
|
||||
"privileges" => self.privileges
|
||||
}
|
||||
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
|
||||
|
||||
def self.create_root
|
||||
root = User.new({'username' => ROOT_USER_NAME, 'password' => ROOT_PASSWORD})
|
||||
root.privileges = root.all_privileges
|
||||
root.email = "#{ROOT_USER_NAME}@host"
|
||||
root
|
||||
end
|
||||
|
||||
private
|
||||
def privileges_with_value value, 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
|
||||
end
|
||||
|
||||
def self.build_from_bson s
|
||||
user = User.new s
|
||||
user.id = s["_id"]
|
||||
user
|
||||
end
|
||||
|
||||
def self.create_from_json json
|
||||
User.new( JSON.parse(json) )
|
||||
end
|
||||
|
||||
def to_hash_without_id
|
||||
o = {
|
||||
"email" => self.email,
|
||||
"password" => self.password,
|
||||
"privileges" => self.privileges
|
||||
}
|
||||
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
|
||||
|
||||
def self.create_root
|
||||
root = User.new({'username' => ROOT_USER_NAME, 'password' => ROOT_PASSWORD})
|
||||
root.privileges = root.all_privileges
|
||||
root.email = "#{ROOT_USER_NAME}@host"
|
||||
root
|
||||
end
|
||||
|
||||
private
|
||||
def privileges_with_value value, 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
|
||||
|
||||
@ -37,6 +37,10 @@ class DevopsConfig
|
||||
@@config
|
||||
end
|
||||
|
||||
def [](key)
|
||||
@@config[key]
|
||||
end
|
||||
|
||||
def first_private_ipv4
|
||||
Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
|
||||
end
|
||||
|
||||
@ -102,6 +102,8 @@ module Devops
|
||||
helpers Sinatra::Streaming
|
||||
helpers Devops::Version2_0::Helpers
|
||||
|
||||
register Sinatra::DevopsAuth
|
||||
|
||||
=begin
|
||||
use Rack::Auth::Basic do |username, password|
|
||||
begin
|
||||
|
||||
@ -45,7 +45,7 @@ module Devops
|
||||
lambda {
|
||||
check_privileges("image", "w")
|
||||
settings.mongo.image params[:image_id]
|
||||
image = ::Image.new(create_object_from_json_body)
|
||||
image = Devops::Model::Image.new(create_object_from_json_body)
|
||||
image.id = params[:image_id]
|
||||
settings.mongo.image_update image
|
||||
create_response("Image '#{params[:image_id]}' has been updated")
|
||||
|
||||
@ -18,7 +18,7 @@ module Devops
|
||||
check_privileges("project", "r")
|
||||
fields = []
|
||||
if params.key?("fields") and params["fields"].is_a?(Array)
|
||||
::Project.fields.each do |k|
|
||||
Devops::Model::Project.fields.each do |k|
|
||||
fields.push k if params["fields"].include?(k)
|
||||
end
|
||||
end
|
||||
@ -49,7 +49,7 @@ module Devops
|
||||
body = create_object_from_json_body
|
||||
check_string(body["name"], "Parameter 'name' must be a not empty string")
|
||||
check_array(body["deploy_envs"], "Parameter 'deploy_envs' must be a not empty array of objects", Hash)
|
||||
p = ::Project.new(body)
|
||||
p = Devops::Model::Project.new(body)
|
||||
halt_response("Project '#{p.id}' already exist") if settings.mongo.is_project_exists?(p)
|
||||
p.add_authorized_user [request.env['REMOTE_USER']]
|
||||
settings.mongo.project_insert p
|
||||
@ -70,11 +70,11 @@ module Devops
|
||||
def self.update_project
|
||||
lambda {
|
||||
check_privileges("project", "w")
|
||||
project = ::Project.new(create_object_from_json_body)
|
||||
project = Devops::Model::Project.new(create_object_from_json_body)
|
||||
project.id = params[:project]
|
||||
old_project = settings.mongo.project params[:project]
|
||||
settings.mongo.project_update project
|
||||
roles = ::Project.create_new_roles(old_project, project, logger)
|
||||
roles = Devops::Model::Project.create_new_roles(old_project, project, logger)
|
||||
info = "Project '#{project.id}' has been updated." + Project.create_roles_response(roles)
|
||||
create_response(info)
|
||||
}
|
||||
@ -181,7 +181,7 @@ module Devops
|
||||
end
|
||||
end
|
||||
else
|
||||
dir = DevopsService.config[:report_dir_v2]
|
||||
dir = DevopsConfig[:report_dir_v2]
|
||||
files = []
|
||||
uri = URI.parse(request.url)
|
||||
servers.each do |s|
|
||||
@ -190,9 +190,9 @@ module Devops
|
||||
rescue InvalidPrivileges, RecordNotFound => e
|
||||
next
|
||||
end
|
||||
jid = DeployWorker.perform_async(dir, s.to_hash, [], DevopsService.config)
|
||||
jid = DeployWorker.perform_async(dir, s.to_hash, [], DevopsConfig.config)
|
||||
logger.info "Job '#{jid}' has been started"
|
||||
uri.path = "#{DevopsService.config[:url_prefix]}/v2.0/report/" + jid
|
||||
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
|
||||
files.push uri.to_s
|
||||
end
|
||||
json files
|
||||
@ -234,23 +234,23 @@ module Devops
|
||||
project = settings.mongo.project(params[:id])
|
||||
env = project.deploy_env params[: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}'"
|
||||
if env.provider == ::Provider::Static::PROVIDER
|
||||
msg = "Can not test environment with provider '#{::Provider::Static::PROVIDER}'"
|
||||
Logger.warn msg
|
||||
return [400, msg]
|
||||
end
|
||||
|
||||
dir = DevopsService.config[:report_dir_v2]
|
||||
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, DevopsService.config)
|
||||
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 = "#{DevopsService.config[:url_prefix]}/v2.0/report/" + jid
|
||||
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
|
||||
files = [uri.to_s]
|
||||
sleep 1
|
||||
json files
|
||||
@ -283,7 +283,7 @@ module Devops
|
||||
old_project.deploy_envs.each do |e|
|
||||
new_project.remove_env(e.identifier)
|
||||
end
|
||||
::Project.create_roles new_project.id, new_project.deploy_envs, logger
|
||||
Devops::Model::Project.create_roles new_project.id, new_project.deploy_envs, logger
|
||||
end
|
||||
|
||||
def self.create_roles_response roles
|
||||
|
||||
@ -29,7 +29,7 @@ module Devops
|
||||
check_privileges("server", "r")
|
||||
fields = []
|
||||
if params.key?("fields") and params["fields"].is_a?(Array)
|
||||
Server.fields.each do |k|
|
||||
Devops::Model::Server.fields.each do |k|
|
||||
fields.push k if params["fields"].include?(k)
|
||||
end
|
||||
end
|
||||
@ -113,16 +113,16 @@ module Devops
|
||||
end
|
||||
end
|
||||
else
|
||||
dir = DevopsService.config[:report_dir_v2]
|
||||
dir = DevopsConfig[:report_dir_v2]
|
||||
files = []
|
||||
uri = URI.parse(request.url)
|
||||
servers.each do |s|
|
||||
h = s.to_hash
|
||||
h["options"] = s.options
|
||||
jid = CreateServerWorker.perform_async(dir, env.provider, h, request.env['REMOTE_USER'], DevopsService.config)
|
||||
jid = CreateServerWorker.perform_async(dir, env.provider, h, request.env['REMOTE_USER'], DevopsConfig.config)
|
||||
Worker.set_status jid, Worker::STATUS::IN_QUEUE
|
||||
logger.info "Job '#{jid}' has been started"
|
||||
uri.path = "#{DevopsService.config[:url_prefix]}/v2.0/report/" + jid
|
||||
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
|
||||
files.push uri.to_s
|
||||
end
|
||||
sleep 1
|
||||
@ -254,16 +254,16 @@ module Devops
|
||||
end
|
||||
end
|
||||
else
|
||||
dir = DevopsService.config[:report_dir_v2]
|
||||
dir = DevopsConfig[:report_dir_v2]
|
||||
files = []
|
||||
uri = URI.parse(request.url)
|
||||
h = s.to_hash
|
||||
h["options"] = s.options
|
||||
h["_id"] = s.id
|
||||
jid = BootstrapWorker.perform_async(dir, d.provider, h, request.env['REMOTE_USER'], DevopsService.config)
|
||||
jid = BootstrapWorker.perform_async(dir, d.provider, h, request.env['REMOTE_USER'], DevopsConfig.config)
|
||||
Worker.set_status jid, Worker::STATUS::IN_QUEUE
|
||||
logger.info "Job '#{jid}' has been started"
|
||||
uri.path = "#{DevopsService.config[:url_prefix]}/v2.0/report/" + jid
|
||||
uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/" + jid
|
||||
uri.query = nil
|
||||
uri.fragment = nil
|
||||
files.push uri.to_s
|
||||
@ -289,7 +289,7 @@ module Devops
|
||||
|
||||
cert = settings.mongo.key(key)
|
||||
provider = ::Provider::ProviderFactory.get("static")
|
||||
s = Server.new
|
||||
s = Devops::Model::Server.new
|
||||
s.provider = provider.name
|
||||
s.project = project
|
||||
s.deploy_env = deploy_env
|
||||
|
||||
@ -22,7 +22,7 @@ module Devops
|
||||
["username", "password", "email"].each do |p|
|
||||
check_string(user[p], "Parameter '#{p}' must be a not empty string")
|
||||
end
|
||||
Devops::Db.connector.user_insert ::User.new(user)
|
||||
Devops::Db.connector.user_insert Devops::Model::User.new(user)
|
||||
create_response("Created", nil, 201)
|
||||
}
|
||||
end
|
||||
@ -66,7 +66,7 @@ module Devops
|
||||
check_privileges("user", "w")
|
||||
action = File.basename(request.path)
|
||||
u = File.basename(File.dirname(request.path))
|
||||
raise InvalidPrivileges.new("Access denied for '#{request.env['REMOTE_USER']}'") if u == ::User::ROOT_USER_NAME and request.env['REMOTE_USER'] != ::User::ROOT_USER_NAME
|
||||
raise InvalidPrivileges.new("Access denied for '#{request.env['REMOTE_USER']}'") if u == Devops::Model::User::ROOT_USER_NAME and request.env['REMOTE_USER'] != Devops::Model::User::ROOT_USER_NAME
|
||||
|
||||
check_privileges("user", "w") unless request.env['REMOTE_USER'] == u
|
||||
|
||||
|
||||
@ -2,12 +2,6 @@ require "sinatra/base"
|
||||
|
||||
module Sinatra
|
||||
|
||||
module HeadersHelpers
|
||||
|
||||
end
|
||||
|
||||
helpers HeadersHelpers
|
||||
|
||||
class Base
|
||||
class << self
|
||||
|
||||
@ -16,6 +10,7 @@ module Sinatra
|
||||
headers = opt.delete(:headers) || []
|
||||
before path do
|
||||
check_headers *headers
|
||||
protect!
|
||||
end
|
||||
|
||||
get path, opt, &block
|
||||
@ -25,6 +20,7 @@ module Sinatra
|
||||
headers = opt.delete(:headers) || []
|
||||
before path do
|
||||
check_headers *headers
|
||||
protect!
|
||||
end
|
||||
post_with_statistic path, opt, &block
|
||||
end
|
||||
@ -41,6 +37,7 @@ module Sinatra
|
||||
headers = opt.delete(:headers) || []
|
||||
before path do
|
||||
check_headers *headers
|
||||
protect!
|
||||
end
|
||||
|
||||
put path, opt, &block
|
||||
@ -54,6 +51,7 @@ module Sinatra
|
||||
headers = opt.delete(:headers) || []
|
||||
before path do
|
||||
check_headers *headers
|
||||
protect!
|
||||
end
|
||||
|
||||
delete path, opt, &block
|
||||
@ -71,6 +69,7 @@ module Sinatra
|
||||
else
|
||||
check_headers *headers
|
||||
end
|
||||
protect!
|
||||
end
|
||||
|
||||
hash.each do |method, block|
|
||||
|
||||
Loading…
Reference in New Issue
Block a user