From 53052646991e3c8dc1030269f4fedcddd82a3100 Mon Sep 17 00:00:00 2001 From: amartynov Date: Thu, 13 Aug 2015 15:49:37 +0300 Subject: [PATCH] stack_template for environment + validation feature --- devops-service/app/api2/handlers/project.rb | 10 ++-- devops-service/app/api2/routes/project.rb | 4 +- devops-service/app/api2/routes/v2.0.rb | 25 +++++--- .../models/deploy_env/cloud_deploy_env.rb | 60 +++++++++++++++++++ .../models/deploy_env/deploy_env_base.rb | 28 ++++----- .../mongo/models/deploy_env/deploy_env_ec2.rb | 42 ++++--------- .../models/deploy_env/deploy_env_openstack.rb | 57 +++++------------- .../models/deploy_env/deploy_env_static.rb | 4 -- devops-service/db/mongo/models/image.rb | 2 +- devops-service/db/mongo/models/mongo_model.rb | 35 ++++++----- devops-service/db/mongo/models/project.rb | 27 ++++----- .../db/validators/deploy_env/deploy_envs.rb | 21 +++++++ .../validators/deploy_env/stack_template.rb | 21 +++++++ .../lib/project/type/generic_type.rb | 2 +- 14 files changed, 196 insertions(+), 142 deletions(-) create mode 100644 devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb create mode 100644 devops-service/db/validators/deploy_env/deploy_envs.rb create mode 100644 devops-service/db/validators/deploy_env/stack_template.rb diff --git a/devops-service/app/api2/handlers/project.rb b/devops-service/app/api2/handlers/project.rb index 579240f..fcf54f4 100644 --- a/devops-service/app/api2/handlers/project.rb +++ b/devops-service/app/api2/handlers/project.rb @@ -54,8 +54,8 @@ module Devops if p.multi? "Project '#{p.id}' with type 'multi' created" else - roles = create_roles p.id, p.deploy_envs - "Project '#{p.id}' created. " + create_roles_response(roles) + #roles = create_roles p.id, p.deploy_envs + "Project '#{p.id}' created. "# + create_roles_response(roles) end end @@ -65,8 +65,8 @@ module Devops project.id = id old_project = Devops::Db.connector.project id Devops::Db.connector.project_update project - roles = create_new_roles(old_project, project) - create_roles_response(roles) +# roles = create_new_roles(old_project, project) +# create_roles_response(roles) end # TODO: multi project @@ -202,7 +202,7 @@ module Devops end 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? roles = {:new => [], :error => [], :exist => []} envs.each do |e| diff --git a/devops-service/app/api2/routes/project.rb b/devops-service/app/api2/routes/project.rb index ee4bee1..d166137 100644 --- a/devops-service/app/api2/routes/project.rb +++ b/devops-service/app/api2/routes/project.rb @@ -35,8 +35,10 @@ module Devops # {"name" : "project_1"} # ] app.get_with_headers "/projects", :headers => [:accept] do + puts env.inspect + puts env["app"].inspect 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 # Get project by id diff --git a/devops-service/app/api2/routes/v2.0.rb b/devops-service/app/api2/routes/v2.0.rb index ca25757..17751cb 100644 --- a/devops-service/app/api2/routes/v2.0.rb +++ b/devops-service/app/api2/routes/v2.0.rb @@ -23,33 +23,42 @@ module Devops register Sinatra::DevopsAuth + @@logger = nil + configure :production do config = DevopsConfig.config log_file = File.join(config[:log_dir], "devops-api2.log") - logger = DevopsLogger.create(log_file, Logger::DEBUG) - use Rack::CommonLogger, logger + @@logger = DevopsLogger.create(log_file, Logger::INFO) +# use Rack::CommonLogger, logger disable :dump_errors disable :show_exceptions - set :logging, Logger::INFO - puts "Production mode" + #set :logging, Logger::INFO + @@logger.info "Production mode" end configure :development do config = DevopsConfig.config - log_file = File.join(config[:log_dir], "devops-api2.log") - logger = DevopsLogger.create(log_file, Logger::DEBUG) - use Rack::CommonLogger, logger + 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) +# logger = Logger.new STDOUT +# use Rack::CommonLogger, logger disable :raise_errors #set :show_exceptions, :after_handler set :show_exceptions, false #set :dump_errors, false - logger.info "Development mode" + @@logger.info "Development mode" end not_found do "Not found" end + def call env + DevopsLogger.logger = @@logger + super(env) + end + error Devops::ValidationError do e = env["sinatra.error"] #logger.warn e.message diff --git a/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb b/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb new file mode 100644 index 0000000..dc7825e --- /dev/null +++ b/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb @@ -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 + diff --git a/devops-service/db/mongo/models/deploy_env/deploy_env_base.rb b/devops-service/db/mongo/models/deploy_env/deploy_env_base.rb index e57ecde..8f02d50 100644 --- a/devops-service/db/mongo/models/deploy_env/deploy_env_base.rb +++ b/devops-service/db/mongo/models/deploy_env/deploy_env_base.rb @@ -1,6 +1,9 @@ require "db/mongo/models/mongo_model" require "providers/provider_factory" 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 Model @@ -8,16 +11,20 @@ module Devops 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={} self.identifier = d["identifier"] b = d["run_list"] || [] - self.run_list = (b.is_a?(Array) ? b.uniq : b) + self.run_list = b.uniq self.expires = d["expires"] self.provider = d["provider"] b = d["users"] || [] - self.users = (b.is_a?(Array) ? b.uniq : b) + self.users = b.uniq end def to_hash @@ -34,21 +41,6 @@ module Devops "Deploy environment '#{self.identifier}'. " + message end - # class methods - class << self - - def validators - @validators - end - - private - - def set_validators(*validators) - @validators = validators - end - - end - end end end diff --git a/devops-service/db/mongo/models/deploy_env/deploy_env_ec2.rb b/devops-service/db/mongo/models/deploy_env/deploy_env_ec2.rb index 50b12cb..43f5a61 100644 --- a/devops-service/db/mongo/models/deploy_env/deploy_env_ec2.rb +++ b/devops-service/db/mongo/models/deploy_env/deploy_env_ec2.rb @@ -1,17 +1,8 @@ -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/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" +require "db/mongo/models/deploy_env/cloud_deploy_env" module Devops module Model - class DeployEnvEc2 < DeployEnvBase - - attr_accessor :flavor, :image, :subnets, :groups + class DeployEnvEc2 < CloudDeployEnv types :identifier => {:type => String, :empty => false}, :image => {:type => String, :empty => false}, @@ -21,38 +12,25 @@ module Devops :run_list => {:type => Array, :empty => true}, :users => {: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, ::Validators::DeployEnv::Expiration, ::Validators::DeployEnv::Users, ::Validators::DeployEnv::Flavor, ::Validators::DeployEnv::Image, ::Validators::DeployEnv::SubnetBelongsToProvider, - ::Validators::DeployEnv::Groups + ::Validators::DeployEnv::Groups, + ::Validators::DeployEnv::StackTemplate +=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 + if self.subnets.size > 1 + self.subnets = [ self.subnets[0] ] end - b = d["groups"] || ["default"] - self.groups = (b.is_a?(Array) ? b.uniq : b) - end - - def to_hash - h = super - h.merge!({ - "flavor" => self.flavor, - "image" => self.image, - "subnets" => self.subnets, - "groups" => self.groups - }) end def self.create hash diff --git a/devops-service/db/mongo/models/deploy_env/deploy_env_openstack.rb b/devops-service/db/mongo/models/deploy_env/deploy_env_openstack.rb index 263f7c8..85687ad 100644 --- a/devops-service/db/mongo/models/deploy_env/deploy_env_openstack.rb +++ b/devops-service/db/mongo/models/deploy_env/deploy_env_openstack.rb @@ -1,19 +1,8 @@ -require "db/mongo/models/deploy_env/deploy_env_base" -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" +require "db/mongo/models/deploy_env/cloud_deploy_env" module Devops module Model - class DeployEnvOpenstack < DeployEnvBase - - attr_accessor :flavor, :image, :subnets, :groups + class DeployEnvOpenstack < CloudDeployEnv types :identifier => {:type => String, :empty => false}, :image => {:type => String, :empty => false}, @@ -23,36 +12,20 @@ module Devops :run_list => {:type => Array, :empty => true}, :users => {: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, - ::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) - end - - def to_hash - h = super - h.merge!({ - "flavor" => self.flavor, - "image" => self.image, - "subnets" => self.subnets, - "groups" => self.groups - }) - end +=begin + 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, + ::Validators::DeployEnv::StackTemplate +=end def self.create hash DeployEnvOpenstack.new(hash) diff --git a/devops-service/db/mongo/models/deploy_env/deploy_env_static.rb b/devops-service/db/mongo/models/deploy_env/deploy_env_static.rb index 5df72e2..5635d4b 100644 --- a/devops-service/db/mongo/models/deploy_env/deploy_env_static.rb +++ b/devops-service/db/mongo/models/deploy_env/deploy_env_static.rb @@ -13,10 +13,6 @@ module Devops :run_list => {:type => Array, :empty => true}, :users => {:type => Array, :empty => true} - set_validators ::Validators::DeployEnv::RunList, - ::Validators::DeployEnv::Expiration, - ::Validators::DeployEnv::Users - def initialize d={} super(d) end diff --git a/devops-service/db/mongo/models/image.rb b/devops-service/db/mongo/models/image.rb index f537248..5f3364c 100644 --- a/devops-service/db/mongo/models/image.rb +++ b/devops-service/db/mongo/models/image.rb @@ -13,7 +13,7 @@ module Devops :name => {:type => String, :empty => true}, :bootstrap_template => {:type => String, :empty => false, :nil => true} set_validators ::Validators::Image::ImageInFilter, - ::Validators::Image::BootstrapTemplate + ::Validators::Image::BootstrapTemplate def initialize p={} self.id = p["id"] diff --git a/devops-service/db/mongo/models/mongo_model.rb b/devops-service/db/mongo/models/mongo_model.rb index cf37bf3..8b86ae5 100644 --- a/devops-service/db/mongo/models/mongo_model.rb +++ b/devops-service/db/mongo/models/mongo_model.rb @@ -54,6 +54,7 @@ module Devops def validate! begin + # TODO: we should validate type in request parser self.validate_fields_types self.class.validate_model(self) true @@ -118,29 +119,33 @@ module Devops 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 + @validators = [] 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 def set_validators(*validators_to_add) - @validators ||= [] - @validators += validators_to_add + self.validators += validators_to_add end def unset_validators(*validators_to_remove) - @validators ||= [] self.validators -= validators_to_remove end diff --git a/devops-service/db/mongo/models/project.rb b/devops-service/db/mongo/models/project.rb index 852a91b..4331ebc 100644 --- a/devops-service/db/mongo/models/project.rb +++ b/devops-service/db/mongo/models/project.rb @@ -5,6 +5,7 @@ require "db/mongo/models/mongo_model" require "json" require "hooks" require "lib/project/type/types_factory" +require "db/validators/deploy_env/deploy_envs" module Devops module Model @@ -27,7 +28,8 @@ module Devops MULTI_TYPE = "multi" - set_validators ::Validators::DeployEnv::RunList + set_validators ::Validators::DeployEnv::RunList, + ::Validators::DeployEnv::DeployEnvs def self.fields ["deploy_envs", "type", "description"] @@ -98,28 +100,16 @@ module Devops return false end +=begin 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! -=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 rescue InvalidRecord, ArgumentError => e raise InvalidRecord.new "Project '#{self.id}'. #{e.message}" end +=end def remove_env env self.deploy_envs.delete_if {|e| e.identifier == env} @@ -136,6 +126,13 @@ module Devops h end + def to_hash_list + { + name: self.id, + description: self.description + } + end + def deploy_info deploy_env, build_number {} end diff --git a/devops-service/db/validators/deploy_env/deploy_envs.rb b/devops-service/db/validators/deploy_env/deploy_envs.rb new file mode 100644 index 0000000..6ccceab --- /dev/null +++ b/devops-service/db/validators/deploy_env/deploy_envs.rb @@ -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 diff --git a/devops-service/db/validators/deploy_env/stack_template.rb b/devops-service/db/validators/deploy_env/stack_template.rb new file mode 100644 index 0000000..dfbe69b --- /dev/null +++ b/devops-service/db/validators/deploy_env/stack_template.rb @@ -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 diff --git a/devops-service/lib/project/type/generic_type.rb b/devops-service/lib/project/type/generic_type.rb index 24c6956..ae81da0 100644 --- a/devops-service/lib/project/type/generic_type.rb +++ b/devops-service/lib/project/type/generic_type.rb @@ -10,7 +10,7 @@ module Devops include ProjectType def prepare project - project.before_create create_roles + #project.before_create create_roles end def create_roles