stack_template for environment + validation feature

This commit is contained in:
amartynov 2015-08-13 15:49:37 +03:00
parent 2073e54ec4
commit 5305264699
14 changed files with 196 additions and 142 deletions

View File

@ -54,8 +54,8 @@ module Devops
if p.multi? if p.multi?
"Project '#{p.id}' with type 'multi' created" "Project '#{p.id}' with type 'multi' created"
else else
roles = create_roles p.id, p.deploy_envs #roles = create_roles p.id, p.deploy_envs
"Project '#{p.id}' created. " + create_roles_response(roles) "Project '#{p.id}' created. "# + create_roles_response(roles)
end end
end end
@ -65,8 +65,8 @@ module Devops
project.id = id project.id = id
old_project = Devops::Db.connector.project id old_project = Devops::Db.connector.project id
Devops::Db.connector.project_update project Devops::Db.connector.project_update project
roles = create_new_roles(old_project, project) # roles = create_new_roles(old_project, project)
create_roles_response(roles) # create_roles_response(roles)
end end
# TODO: multi project # TODO: multi project
@ -202,7 +202,7 @@ module Devops
end end
def create_roles project_id, envs def create_roles project_id, envs
all_roles = KnifeCommands.roles all_roles = KnifeFactory.instance.roles
return " Can't get roles list" if all_roles.nil? return " Can't get roles list" if all_roles.nil?
roles = {:new => [], :error => [], :exist => []} roles = {:new => [], :error => [], :exist => []}
envs.each do |e| envs.each do |e|

View File

@ -35,8 +35,10 @@ module Devops
# {"name" : "project_1"} # {"name" : "project_1"}
# ] # ]
app.get_with_headers "/projects", :headers => [:accept] do app.get_with_headers "/projects", :headers => [:accept] do
puts env.inspect
puts env["app"].inspect
check_privileges("project", "r") check_privileges("project", "r")
json Devops::API2_0::Handler::Project.new(request).projects.map(&:to_hash) json Devops::API2_0::Handler::Project.new(request).projects.map(&:to_hash_list)
end end
# Get project by id # Get project by id

View File

@ -23,33 +23,42 @@ module Devops
register Sinatra::DevopsAuth register Sinatra::DevopsAuth
@@logger = nil
configure :production do configure :production do
config = DevopsConfig.config config = DevopsConfig.config
log_file = File.join(config[:log_dir], "devops-api2.log") log_file = File.join(config[:log_dir], "devops-api2.log")
logger = DevopsLogger.create(log_file, Logger::DEBUG) @@logger = DevopsLogger.create(log_file, Logger::INFO)
use Rack::CommonLogger, logger # use Rack::CommonLogger, logger
disable :dump_errors disable :dump_errors
disable :show_exceptions disable :show_exceptions
set :logging, Logger::INFO #set :logging, Logger::INFO
puts "Production mode" @@logger.info "Production mode"
end end
configure :development do configure :development do
config = DevopsConfig.config config = DevopsConfig.config
log_file = File.join(config[:log_dir], "devops-api2.log") log_file = File.join(config[:log_dir], "devops-api2.dev.log")
logger = DevopsLogger.create(log_file, Logger::DEBUG) @@logger = DevopsLogger.create(log_file, Logger::DEBUG)
use Rack::CommonLogger, logger # logger = DevopsLogger.create(log_file, Logger::DEBUG)
# logger = Logger.new STDOUT
# use Rack::CommonLogger, logger
disable :raise_errors disable :raise_errors
#set :show_exceptions, :after_handler #set :show_exceptions, :after_handler
set :show_exceptions, false set :show_exceptions, false
#set :dump_errors, false #set :dump_errors, false
logger.info "Development mode" @@logger.info "Development mode"
end end
not_found do not_found do
"Not found" "Not found"
end end
def call env
DevopsLogger.logger = @@logger
super(env)
end
error Devops::ValidationError do error Devops::ValidationError do
e = env["sinatra.error"] e = env["sinatra.error"]
#logger.warn e.message #logger.warn e.message

View File

@ -0,0 +1,60 @@
require "db/mongo/models/deploy_env/deploy_env_base"
require "db/validators/deploy_env/run_list"
require "db/validators/deploy_env/expiration"
require "db/validators/deploy_env/flavor"
require "db/validators/deploy_env/image"
require "db/validators/deploy_env/subnet_not_empty"
require "db/validators/deploy_env/subnet_belongs_to_provider"
require "db/validators/deploy_env/groups"
require "db/validators/deploy_env/stack_template"
module Devops
module Model
class CloudDeployEnv < DeployEnvBase
attr_accessor :flavor, :image, :subnets, :groups, :stack_template
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},
:stack_template => {:type => String, :empty => false, :nil => true}
set_validators ::Validators::DeployEnv::Flavor,
::Validators::DeployEnv::Image,
::Validators::DeployEnv::SubnetNotEmpty,
::Validators::DeployEnv::SubnetBelongsToProvider,
::Validators::DeployEnv::Groups,
::Validators::DeployEnv::StackTemplate
def initialize d={}
super(d)
self.flavor = d["flavor"]
self.image = d["image"]
self.stack_template = d["stack_template"]
b = d["subnets"] || []
self.subnets = b.uniq
b = d["groups"] || ["default"]
self.groups = b.uniq
end
def to_hash
h = super
h.merge!({
"flavor" => self.flavor,
"image" => self.image,
"subnets" => self.subnets,
"groups" => self.groups,
"stack_template" => self.stack_template
})
end
end
end
end

View File

@ -1,6 +1,9 @@
require "db/mongo/models/mongo_model" require "db/mongo/models/mongo_model"
require "providers/provider_factory" require "providers/provider_factory"
require "db/mongo/models/model_with_provider" require "db/mongo/models/model_with_provider"
require "db/validators/deploy_env/run_list"
require "db/validators/deploy_env/expiration"
require "db/validators/deploy_env/users"
module Devops module Devops
module Model module Model
@ -8,16 +11,20 @@ module Devops
include ModelWithProvider include ModelWithProvider
attr_accessor :identifier, :run_list, :expires, :users, :chef_env attr_accessor :identifier, :run_list, :expires, :users
set_validators ::Validators::DeployEnv::RunList,
::Validators::DeployEnv::Expiration,
::Validators::DeployEnv::Users
def initialize d={} def initialize d={}
self.identifier = d["identifier"] self.identifier = d["identifier"]
b = d["run_list"] || [] b = d["run_list"] || []
self.run_list = (b.is_a?(Array) ? b.uniq : b) self.run_list = b.uniq
self.expires = d["expires"] self.expires = d["expires"]
self.provider = d["provider"] self.provider = d["provider"]
b = d["users"] || [] b = d["users"] || []
self.users = (b.is_a?(Array) ? b.uniq : b) self.users = b.uniq
end end
def to_hash def to_hash
@ -34,21 +41,6 @@ module Devops
"Deploy environment '#{self.identifier}'. " + message "Deploy environment '#{self.identifier}'. " + message
end end
# class methods
class << self
def validators
@validators
end
private
def set_validators(*validators)
@validators = validators
end
end
end end
end end
end end

View File

@ -1,17 +1,8 @@
require "db/mongo/models/deploy_env/deploy_env_base" require "db/mongo/models/deploy_env/cloud_deploy_env"
require "db/validators/deploy_env/run_list"
require "db/validators/deploy_env/expiration"
require "db/validators/deploy_env/users"
require "db/validators/deploy_env/flavor"
require "db/validators/deploy_env/image"
require "db/validators/deploy_env/subnet_belongs_to_provider"
require "db/validators/deploy_env/groups"
module Devops module Devops
module Model module Model
class DeployEnvEc2 < DeployEnvBase class DeployEnvEc2 < CloudDeployEnv
attr_accessor :flavor, :image, :subnets, :groups
types :identifier => {:type => String, :empty => false}, types :identifier => {:type => String, :empty => false},
:image => {:type => String, :empty => false}, :image => {:type => String, :empty => false},
@ -21,38 +12,25 @@ module Devops
:run_list => {:type => Array, :empty => true}, :run_list => {:type => Array, :empty => true},
:users => {:type => Array, :empty => true}, :users => {:type => Array, :empty => true},
:subnets => {:type => Array, :empty => true}, :subnets => {:type => Array, :empty => true},
:groups => {:type => Array, :empty => false} :groups => {:type => Array, :empty => false},
:stack_template => {:type => String, :empty => false, :nil => true}
=begin
set_validators ::Validators::DeployEnv::RunList, set_validators ::Validators::DeployEnv::RunList,
::Validators::DeployEnv::Expiration, ::Validators::DeployEnv::Expiration,
::Validators::DeployEnv::Users, ::Validators::DeployEnv::Users,
::Validators::DeployEnv::Flavor, ::Validators::DeployEnv::Flavor,
::Validators::DeployEnv::Image, ::Validators::DeployEnv::Image,
::Validators::DeployEnv::SubnetBelongsToProvider, ::Validators::DeployEnv::SubnetBelongsToProvider,
::Validators::DeployEnv::Groups ::Validators::DeployEnv::Groups,
::Validators::DeployEnv::StackTemplate
=end
def initialize d={} def initialize d={}
super(d) super(d)
self.flavor = d["flavor"] if self.subnets.size > 1
self.image = d["image"] self.subnets = [ self.subnets[0] ]
b = d["subnets"] || []
self.subnets = if b.is_a?(Array)
(b.size > 1 ? [ b[0] ] : b)
else
b
end 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 end
def self.create hash def self.create hash

View File

@ -1,19 +1,8 @@
require "db/mongo/models/deploy_env/deploy_env_base" require "db/mongo/models/deploy_env/cloud_deploy_env"
require "providers/provider_factory"
require "db/validators/deploy_env/run_list"
require "db/validators/deploy_env/expiration"
require "db/validators/deploy_env/users"
require "db/validators/deploy_env/flavor"
require "db/validators/deploy_env/image"
require "db/validators/deploy_env/subnet_not_empty"
require "db/validators/deploy_env/subnet_belongs_to_provider"
require "db/validators/deploy_env/groups"
module Devops module Devops
module Model module Model
class DeployEnvOpenstack < DeployEnvBase class DeployEnvOpenstack < CloudDeployEnv
attr_accessor :flavor, :image, :subnets, :groups
types :identifier => {:type => String, :empty => false}, types :identifier => {:type => String, :empty => false},
:image => {:type => String, :empty => false}, :image => {:type => String, :empty => false},
@ -23,36 +12,20 @@ module Devops
:run_list => {:type => Array, :empty => true}, :run_list => {:type => Array, :empty => true},
:users => {:type => Array, :empty => true}, :users => {:type => Array, :empty => true},
:subnets => {:type => Array, :empty => true}, :subnets => {:type => Array, :empty => true},
:groups => {:type => Array, :empty => false} :groups => {:type => Array, :empty => false},
:stack_template => {:type => String, :empty => false, :nil => true}
set_validators ::Validators::DeployEnv::RunList, =begin
::Validators::DeployEnv::Expiration, set_validators ::Validators::DeployEnv::RunList,
::Validators::DeployEnv::Users, ::Validators::DeployEnv::Expiration,
::Validators::DeployEnv::Flavor, ::Validators::DeployEnv::Users,
::Validators::DeployEnv::Image, ::Validators::DeployEnv::Flavor,
::Validators::DeployEnv::SubnetNotEmpty, ::Validators::DeployEnv::Image,
::Validators::DeployEnv::SubnetBelongsToProvider, ::Validators::DeployEnv::SubnetNotEmpty,
::Validators::DeployEnv::Groups ::Validators::DeployEnv::SubnetBelongsToProvider,
::Validators::DeployEnv::Groups,
def initialize d={} ::Validators::DeployEnv::StackTemplate
super(d) =end
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 def self.create hash
DeployEnvOpenstack.new(hash) DeployEnvOpenstack.new(hash)

View File

@ -13,10 +13,6 @@ module Devops
:run_list => {:type => Array, :empty => true}, :run_list => {:type => Array, :empty => true},
:users => {:type => Array, :empty => true} :users => {:type => Array, :empty => true}
set_validators ::Validators::DeployEnv::RunList,
::Validators::DeployEnv::Expiration,
::Validators::DeployEnv::Users
def initialize d={} def initialize d={}
super(d) super(d)
end end

View File

@ -13,7 +13,7 @@ module Devops
:name => {:type => String, :empty => true}, :name => {:type => String, :empty => true},
:bootstrap_template => {:type => String, :empty => false, :nil => true} :bootstrap_template => {:type => String, :empty => false, :nil => true}
set_validators ::Validators::Image::ImageInFilter, set_validators ::Validators::Image::ImageInFilter,
::Validators::Image::BootstrapTemplate ::Validators::Image::BootstrapTemplate
def initialize p={} def initialize p={}
self.id = p["id"] self.id = p["id"]

View File

@ -54,6 +54,7 @@ module Devops
def validate! def validate!
begin begin
# TODO: we should validate type in request parser
self.validate_fields_types self.validate_fields_types
self.class.validate_model(self) self.class.validate_model(self)
true true
@ -118,29 +119,33 @@ module Devops
end end
end end
def self.validators @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 class << self
attr_accessor :validators
def inherited(subclass)
subclass.validators = []
subclass.validators += self.validators
end
# all exceptions are handled in @validate! method
def validate_model(model)
DevopsLogger.logger.debug validators.inspect
puts validators.inspect
validators.each do |validator|
validator.new(model).validate!
end
end
# private class methods
private private
def set_validators(*validators_to_add) def set_validators(*validators_to_add)
@validators ||= [] self.validators += validators_to_add
@validators += validators_to_add
end end
def unset_validators(*validators_to_remove) def unset_validators(*validators_to_remove)
@validators ||= []
self.validators -= validators_to_remove self.validators -= validators_to_remove
end end

View File

@ -5,6 +5,7 @@ require "db/mongo/models/mongo_model"
require "json" require "json"
require "hooks" require "hooks"
require "lib/project/type/types_factory" require "lib/project/type/types_factory"
require "db/validators/deploy_env/deploy_envs"
module Devops module Devops
module Model module Model
@ -27,7 +28,8 @@ module Devops
MULTI_TYPE = "multi" MULTI_TYPE = "multi"
set_validators ::Validators::DeployEnv::RunList set_validators ::Validators::DeployEnv::RunList,
::Validators::DeployEnv::DeployEnvs
def self.fields def self.fields
["deploy_envs", "type", "description"] ["deploy_envs", "type", "description"]
@ -98,28 +100,16 @@ module Devops
return false return false
end end
=begin
def validate! def validate!
super super
check_name_value(self.id) 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!
=begin
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
end
true true
rescue InvalidRecord, ArgumentError => e rescue InvalidRecord, ArgumentError => e
raise InvalidRecord.new "Project '#{self.id}'. #{e.message}" raise InvalidRecord.new "Project '#{self.id}'. #{e.message}"
end end
=end
def remove_env env def remove_env env
self.deploy_envs.delete_if {|e| e.identifier == env} self.deploy_envs.delete_if {|e| e.identifier == env}
@ -136,6 +126,13 @@ module Devops
h h
end end
def to_hash_list
{
name: self.id,
description: self.description
}
end
def deploy_info deploy_env, build_number def deploy_info deploy_env, build_number
{} {}
end end

View File

@ -0,0 +1,21 @@
module Validators
class DeployEnv::DeployEnvs < Base
def valid?
envs = @model.deploy_envs.map {|d| d.identifier}
non_uniq = envs.uniq.select{|u| envs.count(u) > 1}
unless non_uniq.empty?
@msg = "Deploy environment(s) '#{non_uniq.join("', '")}' is/are not unique"
return false
end
@model.deploy_envs.each do |d|
d.validate!
end
true
end
def message
"Invalid project: #{@msg}."
end
end
end

View File

@ -0,0 +1,21 @@
module Validators
class DeployEnv::StackTemplate < Base
def valid?
if @model.stack_template
begin
Devops::Db.connector.stack_template(@model.stack_template)
true
rescue RecordNotFound => e
false
end
else
true
end
end
def message
"Invalid stack template '#{@model.stack_template}'."
end
end
end

View File

@ -10,7 +10,7 @@ module Devops
include ProjectType include ProjectType
def prepare project def prepare project
project.before_create create_roles #project.before_create create_roles
end end
def create_roles def create_roles