#868: validation order

This commit is contained in:
amartynov 2015-11-19 14:09:38 +03:00
parent 17f7812d65
commit e6903adb92
13 changed files with 131 additions and 74 deletions

View File

@ -11,28 +11,28 @@ module Devops
module Model
class CloudDeployEnv < DeployEnvBase
attr_accessor :flavor, :image, :subnets, :groups, :stack_template
# attr_accessor :flavor, :image, :subnets, :groups, :stack_template
set_validators ::Validators::DeployEnv::Flavor,
::Validators::DeployEnv::Image,
::Validators::DeployEnv::Groups,
::Validators::DeployEnv::StackTemplate
# set_validators ::Validators::DeployEnv::CloudParameters
set_field_validators :flavor, ::Validators::FieldValidator::Nil,
set_field_validators :flavor, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Flavor
set_field_validators :image, ::Validators::FieldValidator::Nil,
::Validators::FieldValidator::Flavor], order: 2
set_field_validators :image, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Image
set_field_validators :subnets, ::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::Array
::Validators::FieldValidator::Image], order: 2
set_field_validators :subnets, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::Array], order: 4
# ::Validators::FieldValidator::Subnets.new
set_field_validators :groups, ::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::Array
set_field_validators :groups, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::Array], order: 4
# ::Validators::FieldValidator::Groups.new
set_field_validators :stack_template, ::Validators::FieldValidator::Nil,
set_field_validators :stack_template, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::NotEmpty], order: 2
# ::Validators::FieldValidator::StackTemplate.new
def initialize d={}

View File

@ -8,27 +8,27 @@ module Devops
include ModelWithProvider
attr_accessor :identifier, :run_list, :expires, :users
# attr_accessor :identifier, :run_list, :expires, :users
set_validators ::Validators::DeployEnv::RunList,
::Validators::DeployEnv::Expiration,
::Validators::DeployEnv::Users
set_field_validators :identifier, ::Validators::FieldValidator::NotNil,
set_field_validators :identifier, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::Name
::Validators::FieldValidator::Name]
set_field_validators :run_list, ::Validators::FieldValidator::NotNil,
set_field_validators :run_list, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Array,
::Validators::FieldValidator::RunList
::Validators::FieldValidator::RunList]
set_field_validators :users, ::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Array
set_field_validators :users, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Array]
set_field_validators :expires, ::Validators::FieldValidator::Nil,
set_field_validators :expires, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Expires
::Validators::FieldValidator::Expires]
def initialize d={}
self.identifier = d["identifier"]

View File

@ -4,11 +4,11 @@ module Devops
module Model
class DeployEnvEc2 < CloudDeployEnv
attr_accessor :vpc_id
# attr_accessor :vpc_id
set_field_validators :vpc_id, ::Validators::FieldValidator::Nil,
set_field_validators :vpc_id, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Vpc
::Validators::FieldValidator::Vpc], order: 3
=begin
@Deprecated
types :identifier => {:type => String, :empty => false},

View File

@ -8,7 +8,7 @@ module Devops
class Image < MongoModel
include ModelWithProvider
attr_accessor :id, :remote_user, :name, :bootstrap_template
# attr_accessor :id, :remote_user, :name, :bootstrap_template
=begin
types :id => {:type => String, :empty => false},
:provider => {:type => String, :empty => false},
@ -20,27 +20,27 @@ module Devops
# set_validators ::Validators::Image::ImageInFilter,
# ::Validators::Image::BootstrapTemplate
set_field_validators :id, ::Validators::FieldValidator::NotNil,
set_field_validators :id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::ImageName,
::Validators::Image::ImageInFilter
::Validators::Image::ImageInFilter]
set_field_validators :remote_user, ::Validators::FieldValidator::NotNil,
set_field_validators :remote_user, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::Name
::Validators::FieldValidator::Name]
set_field_validators :name, ::Validators::FieldValidator::NotNil,
set_field_validators :name, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::ImageName
::Validators::FieldValidator::ImageName]
set_field_validators :bootstrap_template, ::Validators::FieldValidator::Nil,
set_field_validators :bootstrap_template, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::Name,
::Validators::Image::BootstrapTemplate
::Validators::Image::BootstrapTemplate]
def validate!
validate_id!

View File

@ -4,14 +4,19 @@ module Devops
module Model
module ModelWithProvider
attr_accessor :provider, :provider_account
# attr_accessor :provider, :provider_account
def ModelWithProvider.included(mod)
mod.set_field_validators :provider, ::Validators::FieldValidator::NotNil,
mod.set_field_validators :provider, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::Provider
::Validators::FieldValidator::Provider]
mod.set_field_validators :provider_account, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::ProviderAccount], order: 1
end
def provider_instance

View File

@ -68,7 +68,11 @@ module Devops
def validate_fields!
result = []
self.class.field_validators.each do |field, validation_method|
orders = self.class.field_validators.keys.sort
orders.each do |order|
self.class.field_validators[order].each do |elem|
field = elem[:field]
validation_method = elem[:method]
begin
self.send(validation_method)
rescue InvalidRecord => e
@ -78,6 +82,7 @@ module Devops
unless result.empty?
raise InvalidRecord.new(error_data: result)
end
end
true
end
@ -142,6 +147,12 @@ module Devops
class << self
attr_accessor :validators
# hash:
# key - (integer) validators order
# value - (hash) validator params:
# field: (string) field name
# method: (string) field validator method
attr_accessor :field_validators
def inherited(subclass)
@ -159,14 +170,29 @@ module Devops
# validate field value
# if method validate! returns false, then stop validation without error
def set_field_validators field, *validators
#
# field - (string) field name to validate
# validators - (array) validators list
# options - (hash) options for validator
# order: integer - run validator in order with index order:
def set_field_validators field, validators, options={}
attr_accessor field
method_name = "validate_" + field.to_s + "!"
define_method(method_name) do
validators.each do |validator|
break unless validator.new(self, send(field)).validate!
break unless validator.new(self, field).validate!
end
end
self.field_validators[field] = method_name
order = options[:order] || 0
obj = {
field: field,
method: method_name
}
unless self.field_validators[order]
self.field_validators[order] = [obj]
else
self.field_validators[order] << obj
end
end
# private class methods

View File

@ -4,15 +4,15 @@ module Devops
module Model
class Ec2ProviderAccount < ProviderAccount
attr_accessor :access_key_id, :availability_zone, :secret_access_key
# attr_accessor :access_key_id, :availability_zone, :secret_access_key
set_field_validators :access_key_id, ::Validators::FieldValidator::NotNil,
set_field_validators :access_key_id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty
::Validators::FieldValidator::NotEmpty]
set_field_validators :secret_access_key, ::Validators::FieldValidator::NotNil,
set_field_validators :secret_access_key, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty
::Validators::FieldValidator::NotEmpty]
def initialize a={}
super(a)
self.provider = Provider::Ec2::PROVIDER

View File

@ -7,22 +7,22 @@ module Devops
include ModelWithProvider
attr_accessor :account_name, :description, :ssh_key
# attr_accessor :account_name, :description, :ssh_key
set_field_validators :account_name, ::Validators::FieldValidator::NotNil,
set_field_validators :account_name, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::Name
::Validators::FieldValidator::Name]
set_field_validators :description, ::Validators::FieldValidator::Nil,
set_field_validators :description, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::Description
::Validators::FieldValidator::Description]
set_field_validators :ssh_key, ::Validators::FieldValidator::NotNil,
set_field_validators :ssh_key, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::SshKey
::Validators::FieldValidator::SshKey]
ACCOUNT_FIELDS = {
account_name: "Account name (id)",

View File

@ -12,20 +12,20 @@ module Devops
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}
set_field_validators :id, ::Validators::FieldValidator::NotNil,
set_field_validators :id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Name
set_field_validators :password, ::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String
set_field_validators :email, ::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String
set_field_validators :privileges, ::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Hash
::Validators::FieldValidator::Name]
set_field_validators :password, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String]
set_field_validators :email, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String]
set_field_validators :privileges, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Hash]
def initialize p={}
self.id = p['username']
self.email = p['email']

View File

@ -2,9 +2,10 @@ module Validators
module FieldValidator
class Base
def initialize model, value
def initialize model, field
@model = model
@value = value
@field = field
@value = model.send(field)
end
def validate!

View File

@ -0,0 +1,17 @@
require_relative "base"
module Validators
module FieldValidator
class ProviderAccount < Base
def valid?
accounts = AccountsFactory.accounts(@model.provider)
accounts.map{|a| a.account_name}.include?(@value)
end
def message
"Account '#{@value}' for provider '#{@model.provider}' does not exist"
end
end
end
end

View File

@ -1,6 +1,14 @@
module Provider
class AccountsFactory
class << self
def accounts provider_name
Devops::Db.connector.provider_accounts(provider_name)
end
end
def init config
end
@ -22,7 +30,7 @@ module Provider
end
def accounts
Devops::Db.connector.provider_accounts(provider_name)
AccountsFactory.accounts(provider_name)
end
def create_account hash