#789: validation
This commit is contained in:
parent
57f545d109
commit
5549b028c4
@ -17,7 +17,7 @@ module Devops
|
|||||||
end
|
end
|
||||||
|
|
||||||
def accounts provider
|
def accounts provider
|
||||||
::Provider::ProviderFactory.get(provider).accounts
|
::Provider::ProviderFactory.get_accounts_factory(provider).accounts
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_fields provider
|
def account_fields provider
|
||||||
@ -25,8 +25,8 @@ module Devops
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_account provider
|
def add_account provider
|
||||||
account = ::Provider::ProviderFactory.get(provider).create_account(parser.account)
|
account = ::Provider::ProviderFactory.get_accounts_factory(provider).create_account(parser.account)
|
||||||
key = Devops::Db.connector.key account.ssh_key
|
account.validate_fields!
|
||||||
Devops::Db.connector.provider_accounts_insert(account)
|
Devops::Db.connector.provider_accounts_insert(account)
|
||||||
::Provider::ProviderFactory.add_account(provider, account)
|
::Provider::ProviderFactory.add_account(provider, account)
|
||||||
account.to_hash
|
account.to_hash
|
||||||
@ -35,6 +35,7 @@ module Devops
|
|||||||
def delete_account name, provider
|
def delete_account name, provider
|
||||||
account = Devops::Db.connector.provider_accounts_show(name)
|
account = Devops::Db.connector.provider_accounts_show(name)
|
||||||
Devops::Db.connector.provider_accounts_delete(name)
|
Devops::Db.connector.provider_accounts_delete(name)
|
||||||
|
::Provider::ProviderFactory.delete_account(provider, account)
|
||||||
account.to_hash
|
account.to_hash
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ module Devops
|
|||||||
|
|
||||||
def check_provider provider
|
def check_provider provider
|
||||||
list = ::Provider::ProviderFactory.providers
|
list = ::Provider::ProviderFactory.providers
|
||||||
halt_response("Invalid provider '#{provider}', available providers: '#{list.join("', '")}'", 404) unless list.include?(provider)
|
halt_response("Invalid provider '#{provider}', available providers: '#{list.join("', '")}'", 400) unless list.include?(provider)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Save information about requests with methods POST, PUT, DELETE
|
# Save information about requests with methods POST, PUT, DELETE
|
||||||
|
|||||||
@ -61,13 +61,23 @@ module Devops
|
|||||||
DevopsLogger.logger = @@logger
|
DevopsLogger.logger = @@logger
|
||||||
begin
|
begin
|
||||||
res = super(env)
|
res = super(env)
|
||||||
rescue DevopsError => e
|
rescue ::Devops::Exception::DevopsError => e
|
||||||
|
return [e.code, {}, e.message]
|
||||||
|
rescue InvalidRecord => e
|
||||||
return [e.code, {}, e.message]
|
return [e.code, {}, e.message]
|
||||||
end
|
end
|
||||||
@@access_logger.info(env["REQUEST_METHOD"] + " " + env["REQUEST_URI"] + " - from #{env["HTTP_USER_AGENT"]} (#{env["REMOTE_USER"]}) / #{res[0]}")
|
@@access_logger.info(env["REQUEST_METHOD"] + " " + env["REQUEST_URI"] + " - from #{env["HTTP_USER_AGENT"]} (#{env["REMOTE_USER"]}) / #{res[0]}")
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_exception!(boom)
|
||||||
|
if boom.is_a?(::Devops::Exception::DevopsError)
|
||||||
|
boom.http_response
|
||||||
|
else
|
||||||
|
super(boom)
|
||||||
|
end
|
||||||
|
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
|
||||||
@ -92,12 +102,14 @@ module Devops
|
|||||||
halt_response(e.message, 404)
|
halt_response(e.message, 404)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
error InvalidRecord do
|
error InvalidRecord do
|
||||||
e = env["sinatra.error"]
|
e = env["sinatra.error"]
|
||||||
logger.warn e.message
|
logger.warn e.message
|
||||||
logger.warn "Request body: #{request.body.read}"
|
logger.warn "Request body: #{request.body.read}"
|
||||||
halt_response(e.message, 400)
|
halt_response(e.message, 400)
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
|
|
||||||
error InvalidCommand do
|
error InvalidCommand do
|
||||||
e = env["sinatra.error"]
|
e = env["sinatra.error"]
|
||||||
|
|||||||
@ -78,7 +78,7 @@ module Devops
|
|||||||
Devops::Api2.register r
|
Devops::Api2.register r
|
||||||
end
|
end
|
||||||
Routes.route "/v2.0", Devops::Api2
|
Routes.route "/v2.0", Devops::Api2
|
||||||
Devops::Api2.routes_list
|
#Devops::Api2.routes_list
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@ -66,6 +66,21 @@ module Devops
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_fields!
|
||||||
|
result = []
|
||||||
|
self.class.field_validators.each do |field, validation_method|
|
||||||
|
begin
|
||||||
|
self.send(validation_method)
|
||||||
|
rescue InvalidRecord => e
|
||||||
|
result << {key: field, message: e.message}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
unless result.empty?
|
||||||
|
raise InvalidRecord.new(error_data: result)
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
def build_error_message(message)
|
def build_error_message(message)
|
||||||
# overrided in descendants
|
# overrided in descendants
|
||||||
message
|
message
|
||||||
@ -123,17 +138,16 @@ module Devops
|
|||||||
end
|
end
|
||||||
|
|
||||||
@validators = []
|
@validators = []
|
||||||
# @field_validators = []
|
@field_validators = {}
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
attr_accessor :validators
|
attr_accessor :validators
|
||||||
# attr_accessor :field_validators
|
attr_accessor :field_validators
|
||||||
|
|
||||||
def inherited(subclass)
|
def inherited(subclass)
|
||||||
subclass.validators = []
|
subclass.validators = []
|
||||||
subclass.validators += self.validators
|
subclass.validators += self.validators
|
||||||
# subclass.field_validators = []
|
subclass.field_validators = self.field_validators.clone
|
||||||
# subclass.field_validators += self.field_validators
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# all exceptions are handled in @validate! method
|
# all exceptions are handled in @validate! method
|
||||||
@ -146,11 +160,13 @@ module Devops
|
|||||||
# validate field value
|
# validate field value
|
||||||
# if method validate! returns false, then stop validation without error
|
# if method validate! returns false, then stop validation without error
|
||||||
def set_field_validators field, *validators
|
def set_field_validators field, *validators
|
||||||
define_method("validate_" + field.to_s + "!") do
|
method_name = "validate_" + field.to_s + "!"
|
||||||
|
define_method(method_name) do
|
||||||
validators.each do |validator|
|
validators.each do |validator|
|
||||||
break unless validator.new(self, send(field)).validate!
|
break unless validator.new(self, send(field)).validate!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self.field_validators[field] = method_name
|
||||||
end
|
end
|
||||||
|
|
||||||
# private class methods
|
# private class methods
|
||||||
|
|||||||
@ -6,6 +6,13 @@ module Devops
|
|||||||
|
|
||||||
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,
|
||||||
|
::Validators::FieldValidator::FieldType::String,
|
||||||
|
::Validators::FieldValidator::NotEmpty
|
||||||
|
|
||||||
|
set_field_validators :secret_access_key, ::Validators::FieldValidator::NotNil,
|
||||||
|
::Validators::FieldValidator::FieldType::String,
|
||||||
|
::Validators::FieldValidator::NotEmpty
|
||||||
def initialize a={}
|
def initialize a={}
|
||||||
super(a)
|
super(a)
|
||||||
self.provider = Provider::Ec2::PROVIDER
|
self.provider = Provider::Ec2::PROVIDER
|
||||||
|
|||||||
@ -9,6 +9,21 @@ module Devops
|
|||||||
|
|
||||||
attr_accessor :account_name, :description, :ssh_key
|
attr_accessor :account_name, :description, :ssh_key
|
||||||
|
|
||||||
|
set_field_validators :account_name, ::Validators::FieldValidator::NotNil,
|
||||||
|
::Validators::FieldValidator::FieldType::String,
|
||||||
|
::Validators::FieldValidator::NotEmpty,
|
||||||
|
::Validators::FieldValidator::Name
|
||||||
|
|
||||||
|
set_field_validators :description, ::Validators::FieldValidator::Nil,
|
||||||
|
::Validators::FieldValidator::FieldType::String,
|
||||||
|
::Validators::FieldValidator::NotEmpty,
|
||||||
|
::Validators::FieldValidator::Description
|
||||||
|
|
||||||
|
set_field_validators :ssh_key, ::Validators::FieldValidator::NotNil,
|
||||||
|
::Validators::FieldValidator::FieldType::String,
|
||||||
|
::Validators::FieldValidator::NotEmpty,
|
||||||
|
::Validators::FieldValidator::SshKey
|
||||||
|
|
||||||
ACCOUNT_FIELDS = {
|
ACCOUNT_FIELDS = {
|
||||||
account_name: "Account name (id)",
|
account_name: "Account name (id)",
|
||||||
description: "Account description",
|
description: "Account description",
|
||||||
|
|||||||
17
devops-service/db/validators/field_validators/description.rb
Normal file
17
devops-service/db/validators/field_validators/description.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
require_relative "base"
|
||||||
|
module Validators
|
||||||
|
module FieldValidator
|
||||||
|
class Description < Base
|
||||||
|
|
||||||
|
MAX_LEN = 500
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
@value.size <= 500
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
"Invalid value '#{@value}': it should be less or equals then #{MAX_LEN} symbols"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -11,7 +11,7 @@ module Validators
|
|||||||
end
|
end
|
||||||
|
|
||||||
def message
|
def message
|
||||||
"Invalid value '#{@value}': it should contains symbols 'a-zA-Z0-9_' and length should be more then 1 and less or equals then #{MAX_NAME_LEN}"
|
"Invalid value '#{@value}': it should contains symbols 'a-zA-Z0-9_' and length should be more then 1 and less or equals then #{MAX_NAME_LEN} symbols"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
20
devops-service/db/validators/field_validators/ssh_key.rb
Normal file
20
devops-service/db/validators/field_validators/ssh_key.rb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
require_relative "base"
|
||||||
|
module Validators
|
||||||
|
module FieldValidator
|
||||||
|
class SshKey < Base
|
||||||
|
|
||||||
|
MAX_LEN = 500
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
Devops::Db.connector.key @value
|
||||||
|
true
|
||||||
|
rescue RecordNotFound
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
"Invalid value '#{@value}': ssh key '#{@value}' not found"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,12 +1,25 @@
|
|||||||
|
require "json"
|
||||||
module Devops
|
module Devops
|
||||||
module Exception
|
module Exception
|
||||||
|
|
||||||
class DevopsError < StandardError
|
class DevopsError < StandardError
|
||||||
|
|
||||||
def code
|
def http_status
|
||||||
500
|
500
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def http_response
|
||||||
|
[self.http_status, self.http_headers, self.http_body]
|
||||||
|
end
|
||||||
|
|
||||||
|
def http_body
|
||||||
|
JSON.pretty_generate(message: self.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def http_headers
|
||||||
|
{"Content-Type" => "application/json"}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,3 +1,23 @@
|
|||||||
class InvalidRecord < StandardError
|
require_relative "devops_error"
|
||||||
|
class InvalidRecord < ::Devops::Exception::DevopsError
|
||||||
|
|
||||||
|
def initialize msg
|
||||||
|
if msg.is_a?(String)
|
||||||
|
super(msg)
|
||||||
|
else
|
||||||
|
@object = msg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def http_status
|
||||||
|
400
|
||||||
|
end
|
||||||
|
|
||||||
|
def http_body
|
||||||
|
if @object.nil?
|
||||||
|
super
|
||||||
|
else
|
||||||
|
JSON.pretty_generate(@object)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,8 +14,20 @@ module Provider
|
|||||||
@connections[name] = conn
|
@connections[name] = conn
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete_connection name
|
||||||
|
@connections.delete(name)
|
||||||
|
end
|
||||||
|
|
||||||
def create_connection_from_account config, account
|
def create_connection_from_account config, account
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def accounts
|
||||||
|
Devops::Db.connector.provider_accounts(provider_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_account hash
|
||||||
|
raise "override me"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -6,14 +6,6 @@ module Provider
|
|||||||
|
|
||||||
attr_accessor :ssh_key, :certificate_path, :connection_options, :run_list
|
attr_accessor :ssh_key, :certificate_path, :connection_options, :run_list
|
||||||
|
|
||||||
def accounts
|
|
||||||
Devops::Db.connector.provider_accounts(self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_account hash
|
|
||||||
raise "override me"
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_default_chef_node_name s
|
def create_default_chef_node_name s
|
||||||
"#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}"
|
"#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -35,10 +35,6 @@ module Provider
|
|||||||
super and !(empty_param?(o[:aws_access_key_id]) or empty_param?(o[:aws_secret_access_key]))
|
super and !(empty_param?(o[:aws_access_key_id]) or empty_param?(o[:aws_secret_access_key]))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_account hash
|
|
||||||
Devops::Model::Ec2ProviderAccount.new(hash)
|
|
||||||
end
|
|
||||||
|
|
||||||
def name
|
def name
|
||||||
PROVIDER
|
PROVIDER
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,13 +4,17 @@ module Provider
|
|||||||
|
|
||||||
def init config
|
def init config
|
||||||
@connections = {}
|
@connections = {}
|
||||||
Devops::Db.connector.provider_accounts(Ec2::PROVIDER).each do |account|
|
accounts.each do |account|
|
||||||
create_connection_from_account(config, account)
|
create_connection_from_account(config, account)
|
||||||
puts "\tFound ec2 account '#{account.account_name}'"
|
puts "\tFound ec2 account '#{account.account_name}'"
|
||||||
end
|
end
|
||||||
ProviderFactory.add_provider Ec2::PROVIDER unless @connections.empty?
|
ProviderFactory.add_provider Ec2::PROVIDER unless @connections.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def provider_name
|
||||||
|
Ec2::PROVIDER
|
||||||
|
end
|
||||||
|
|
||||||
def create_connection_from_account config, account
|
def create_connection_from_account config, account
|
||||||
options = {
|
options = {
|
||||||
aws_ssh_key: account.ssh_key,
|
aws_ssh_key: account.ssh_key,
|
||||||
@ -25,5 +29,9 @@ module Provider
|
|||||||
add_connection(account.account_name, Ec2.new(options))
|
add_connection(account.account_name, Ec2.new(options))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_account hash
|
||||||
|
Devops::Model::Ec2ProviderAccount.new(hash)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -50,6 +50,7 @@ module Provider
|
|||||||
next
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
puts "Available providers: #{@@available_providers}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.add_account provider, account
|
def self.add_account provider, account
|
||||||
@ -58,6 +59,12 @@ module Provider
|
|||||||
DevopsLogger.logger.info("Added #{provider} account '#{account.account_name}'")
|
DevopsLogger.logger.info("Added #{provider} account '#{account.account_name}'")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.delete_account provider, account
|
||||||
|
factory = @@providers_with_accounts_factories[provider]
|
||||||
|
factory.delete_connection(account.account_name)
|
||||||
|
DevopsLogger.logger.info("Removed #{provider} account '#{account.account_name}'")
|
||||||
|
end
|
||||||
|
|
||||||
def self.require_all
|
def self.require_all
|
||||||
["ec2", "openstack", "static"].each do |provider|
|
["ec2", "openstack", "static"].each do |provider|
|
||||||
begin
|
begin
|
||||||
@ -69,6 +76,10 @@ module Provider
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.get_accounts_factory provider
|
||||||
|
@@providers_with_accounts_factories[provider]
|
||||||
|
end
|
||||||
|
|
||||||
def self.get_account_class provider
|
def self.get_account_class provider
|
||||||
case(provider)
|
case(provider)
|
||||||
when ::Provider::Static::PROVIDER
|
when ::Provider::Static::PROVIDER
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user