Merge branch 'qa' into cid-36

This commit is contained in:
amartynov 2015-12-07 14:15:41 +03:00
commit cc8b436c3d
38 changed files with 321 additions and 147 deletions

View File

@ -13,7 +13,6 @@ gem "chef", ">=12"
gem "mongo" gem "mongo"
gem "bson_ext" gem "bson_ext"
gem "multi_json", "1.7.8" gem "multi_json", "1.7.8"
# gem "rufus-scheduler", "2.0.24"
gem "sidekiq", "3.2.6" gem "sidekiq", "3.2.6"
gem 'wisper' gem 'wisper'
gem 'rake', '10.2.0' gem 'rake', '10.2.0'
@ -31,6 +30,7 @@ group :test do
gem 'rspec', '~>3.3' gem 'rspec', '~>3.3'
gem 'factory_girl', '~>4.5' gem 'factory_girl', '~>4.5'
gem 'activesupport' gem 'activesupport'
gem 'rspec_junit_formatter'
end end
group :devepoment do group :devepoment do

View File

@ -350,6 +350,7 @@ DEPENDENCIES
rack-accept-media-types rack-accept-media-types
rake (= 10.2.0) rake (= 10.2.0)
rspec (~> 3.3) rspec (~> 3.3)
rspec_junit_formatter
sidekiq (= 3.2.6) sidekiq (= 3.2.6)
sinatra (= 1.4.5) sinatra (= 1.4.5)
sinatra-contrib sinatra-contrib
@ -357,6 +358,3 @@ DEPENDENCIES
test-unit test-unit
thin (~> 1.5.1) thin (~> 1.5.1)
wisper wisper
BUNDLED WITH
1.10.5

View File

@ -1,3 +1,4 @@
require "app/api2/parsers/security_groups"
require "providers/provider_factory" require "providers/provider_factory"
require_relative "request_handler" require_relative "request_handler"
@ -6,13 +7,15 @@ module Devops
module Handler module Handler
class Group < RequestHandler class Group < RequestHandler
# TODO: vpc support for ec2 set_parser Devops::API2_0::Parser::SecurityGroupsParser
def groups provider def groups provider
groups_with_account(provider, nil) groups_with_account(provider, nil)
end end
def groups_with_account provider, account def groups_with_account provider, account
::Provider::ProviderFactory.get(provider, account).groups()#params available_keys = ["vpc-id"]
::Provider::ProviderFactory.get(provider, account).groups(parser.security_groups.select{|k,v| available_keys.include?(k)})
end end
end end
end end

View File

@ -1,3 +1,4 @@
require "app/api2/parsers/network"
require "providers/provider_factory" require "providers/provider_factory"
require_relative "request_handler" require_relative "request_handler"
@ -6,13 +7,16 @@ module Devops
module Handler module Handler
class Network < RequestHandler class Network < RequestHandler
set_parser Devops::API2_0::Parser::NetworkParser
def networks provider def networks provider
networks_with_account provider, nil networks_with_account provider, nil
end end
def networks_with_account provider, account def networks_with_account provider, account
p = ::Provider::ProviderFactory.get(provider, account) p = ::Provider::ProviderFactory.get(provider, account)
p.networks_detail available_keys = ["vpc-id"]
p.networks_detail(parser.networks.select{|k,v| available_keys.include?(k)})
end end
end end
end end

View File

@ -33,12 +33,17 @@ module Devops
end end
def delete_account name, provider def delete_account name, provider
account = Devops::Db.connector.provider_accounts_show(name) account = Devops::Db.connector.provider_account(provider, name)
Devops::Db.connector.provider_accounts_delete(name) Devops::Db.connector.provider_accounts_delete(name)
::Provider::ProviderFactory.delete_account(provider, account) ::Provider::ProviderFactory.delete_account(provider, account)
account.to_hash account.to_hash
end end
def account_vpcs provider, name
Devops::Db.connector.provider_account(provider, name)
::Provider::ProviderFactory.get(provider, name).describe_vpcs
end
end end
end end
end end

View File

@ -0,0 +1,15 @@
require_relative "request_parser"
module Devops
module API2_0
module Parser
class NetworkParser < RequestParser
def networks
@params
end
end
end
end
end

View File

@ -0,0 +1,15 @@
require_relative "request_parser"
module Devops
module API2_0
module Parser
class SecurityGroupsParser < RequestParser
def security_groups
@params
end
end
end
end
end

View File

@ -13,6 +13,9 @@ module Devops
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# #
# * Params:
# vpc-id - string
#
# * *Returns* : # * *Returns* :
# - ec2: # - ec2:
# { # {
@ -43,7 +46,6 @@ module Devops
# ] # ]
# } # }
# } # }
# TODO: vpc support for ec2
app.get_with_headers "/groups/:provider", :headers => [:accept] do |provider| app.get_with_headers "/groups/:provider", :headers => [:accept] do |provider|
check_privileges("group", "r") check_privileges("group", "r")
check_provider(provider) check_provider(provider)

View File

@ -13,6 +13,9 @@ module Devops
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# #
# * Params:
# vpc-id - string
#
# * *Returns* : array of strings # * *Returns* : array of strings
# - ec2: # - ec2:
# [ # [

View File

@ -175,7 +175,7 @@ module Devops
# Deletes project servers # Deletes project servers
# #
# * *Request* # * *Request*
# - method : PATCH # - method : DELETE
# - headers : # - headers :
# - Accept: application/json # - Accept: application/json
# - Content-Type: application/json # - Content-Type: application/json

View File

@ -115,7 +115,23 @@ module Devops
app.delete_with_headers "/provider/:provider/account/:account_name", :headers => [:accept, :content_type] do |provider, account_name| app.delete_with_headers "/provider/:provider/account/:account_name", :headers => [:accept, :content_type] do |provider, account_name|
check_privileges("provider", "w") check_privileges("provider", "w")
check_provider(provider) check_provider(provider)
create_response("Deleted", {:account => Devops::API2_0::Handler::Provider.new(request).delete_account(provider)}) create_response("Deleted", {:account => Devops::API2_0::Handler::Provider.new(request).delete_account(account_name, provider)})
end
# Describe vpc for account with name :account_name for provider ec2
#
# * *Request*
# - method : GET
# - headers :
# - Accept: application/json
# - Content-Type: application/json
#
# * *Returns* : 200
app.get_with_headers "/provider/ec2/account/:account_name/vpcs", :headers => [:accept, :content_type] do |account_name|
provider = "ec2"
check_privileges("provider", "r")
check_provider(provider)
json Devops::API2_0::Handler::Provider.new(request).account_vpcs(provider, account_name)
end end
puts "Provider routes initialized" puts "Provider routes initialized"

View File

@ -13,6 +13,13 @@ module Connectors
collection.find({provider: provider}).to_a.map{|bson| c.build_from_bson(bson)} collection.find({provider: provider}).to_a.map{|bson| c.build_from_bson(bson)}
end end
def provider_account provider, account
c = Provider::ProviderFactory.get_account_class(provider)
bson = collection.find({provider: provider, _id: account}).to_a.first
raise RecordNotFound.new("'Account #{account}' for provider '#{provider}' not found") unless bson
c.build_from_bson(bson)
end
def collection_name def collection_name
'provider_accounts' 'provider_accounts'
end end

View File

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

View File

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

View File

@ -4,6 +4,11 @@ module Devops
module Model module Model
class DeployEnvEc2 < CloudDeployEnv class DeployEnvEc2 < CloudDeployEnv
# attr_accessor :vpc_id
set_field_validators :vpc_id, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Vpc], order: 3
=begin =begin
@Deprecated @Deprecated
types :identifier => {:type => String, :empty => false}, types :identifier => {:type => String, :empty => false},
@ -34,6 +39,11 @@ module Devops
if self.subnets.size > 1 if self.subnets.size > 1
self.subnets = [ self.subnets[0] ] self.subnets = [ self.subnets[0] ]
end end
self.vpc_id = d["vpc_id"]
end
def to_hash
super().merge({"vpc_id" => self.vpc_id})
end end
def self.create hash def self.create hash

View File

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

View File

@ -4,14 +4,19 @@ module Devops
module Model module Model
module ModelWithProvider module ModelWithProvider
attr_accessor :provider, :provider_account # attr_accessor :provider, :provider_account
def ModelWithProvider.included(mod) 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::FieldType::String,
::Validators::FieldValidator::NotEmpty, ::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 end
def provider_instance def provider_instance

View File

@ -69,15 +69,20 @@ module Devops
def validate_fields! def validate_fields!
result = [] result = []
self.class.field_validators.each do |field, validation_method| orders = self.class.field_validators.keys.sort
begin orders.each do |order|
self.send(validation_method) self.class.field_validators[order].each do |elem|
rescue InvalidRecord => e field = elem[:field]
result << {key: field, message: e.message} validation_method = elem[: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 end
end
unless result.empty?
raise InvalidRecord.new(error_data: result)
end end
true true
end end
@ -150,6 +155,12 @@ module Devops
class << self class << self
attr_accessor :validators 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 attr_accessor :field_validators
def inherited(subclass) def inherited(subclass)
@ -168,14 +179,29 @@ 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 #
# 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 + "!" method_name = "validate_" + field.to_s + "!"
define_method(method_name) do 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, field).validate!
end end
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 end
# private class methods # private class methods

View File

@ -93,11 +93,16 @@ module Devops
def check_authorization user_id, env def check_authorization user_id, env
e = self.deploy_env(env) e = self.deploy_env(env)
return true if user_id == User::ROOT_USER_NAME return true if user_id == User::ROOT_USER_NAME
return true if is_sandbox?
return e.users.include? user_id return e.users.include? user_id
rescue RecordNotFound => e rescue RecordNotFound => e
return false return false
end end
def is_sandbox?
id.start_with?('sandbox-')
end
=begin =begin
def validate! def validate!
super super

View File

@ -6,16 +6,16 @@ module Devops
attr_accessor :availability_zone attr_accessor :availability_zone
set_field_validators :access_key_id, ::Validators::FieldValidator::NotNil, set_field_validators :access_key_id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::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::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :use_iam_profile, ::Validators::FieldValidator::Nil, set_field_validators :use_iam_profile, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::Boolean ::Validators::FieldValidator::FieldType::Boolean]
def initialize a={} def initialize a={}
super(a) super(a)
self.provider = Provider::Ec2::PROVIDER self.provider = Provider::Ec2::PROVIDER

View File

@ -7,22 +7,22 @@ module Devops
include ModelWithProvider 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::FieldType::String,
::Validators::FieldValidator::NotEmpty, ::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::FieldType::String,
::Validators::FieldValidator::NotEmpty, ::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::FieldType::String,
::Validators::FieldValidator::NotEmpty, ::Validators::FieldValidator::NotEmpty,
::Validators::FieldValidator::SshKey ::Validators::FieldValidator::SshKey]
ACCOUNT_FIELDS = { ACCOUNT_FIELDS = {
account_name: "Account name (id)", account_name: "Account name (id)",

View File

@ -19,37 +19,37 @@ module Devops
run_list: {type: Array, value_type: String, empty: true, nil: true} run_list: {type: Array, value_type: String, empty: true, nil: true}
# details: {type: Hash, nil: true} # Hash type isn't supported yet # details: {type: Hash, nil: true} # Hash type isn't supported yet
set_field_validators :id, ::Validators::FieldValidator::NotNil, set_field_validators :id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :provider, ::Validators::FieldValidator::NotNil, set_field_validators :provider, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :project, ::Validators::FieldValidator::NotNil, set_field_validators :project, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :deploy_env, ::Validators::FieldValidator::NotNil, set_field_validators :deploy_env, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :stack_template, ::Validators::FieldValidator::NotNil, set_field_validators :stack_template, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :name, ::Validators::FieldValidator::Nil, set_field_validators :name, [::Validators::FieldValidator::Nil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :owner, ::Validators::FieldValidator::NotNil, set_field_validators :owner, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :run_list, ::Validators::FieldValidator::NotNil, set_field_validators :run_list, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Array, ::Validators::FieldValidator::FieldType::Array,
::Validators::FieldValidator::RunList ::Validators::FieldValidator::RunList]
def initialize attrs={} def initialize attrs={}
# self.provider = self.class.provider # self.provider = self.class.provider

View File

@ -16,22 +16,22 @@ module Devops
template_body: {type: String, empty: false}, template_body: {type: String, empty: false},
owner: {type: String, empty: false} owner: {type: String, empty: false}
set_field_validators :id, ::Validators::FieldValidator::NotNil, set_field_validators :id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty, ::Validators::FieldValidator::NotEmpty,]
::Validators::FieldValidator::Name ::Validators::FieldValidator::Name
set_field_validators :provider, ::Validators::FieldValidator::NotNil, set_field_validators :provider, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :template_body, ::Validators::FieldValidator::NotNil, set_field_validators :template_body, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_field_validators :owner, ::Validators::FieldValidator::NotNil, set_field_validators :owner, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::NotEmpty ::Validators::FieldValidator::NotEmpty]
set_validators ::Validators::StackTemplate::TemplateContent set_validators ::Validators::StackTemplate::TemplateContent

View File

@ -17,15 +17,15 @@ module Devops
attr_accessor :id, :password, :privileges, :email attr_accessor :id, :password, :privileges, :email
set_field_validators :id, ::Validators::FieldValidator::NotNil, set_field_validators :id, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::FieldType::String,
::Validators::FieldValidator::Name ::Validators::FieldValidator::Name]
set_field_validators :password, ::Validators::FieldValidator::NotNil, set_field_validators :password, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String ::Validators::FieldValidator::FieldType::String]
set_field_validators :email, ::Validators::FieldValidator::NotNil, set_field_validators :email, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::String ::Validators::FieldValidator::FieldType::String]
set_field_validators :privileges, ::Validators::FieldValidator::NotNil, set_field_validators :privileges, [::Validators::FieldValidator::NotNil,
::Validators::FieldValidator::FieldType::Hash ::Validators::FieldValidator::FieldType::Hash]
def initialize p={} def initialize p={}
self.id = p['username'] self.id = p['username']
self.email = p['email'] self.email = p['email']

View File

@ -33,7 +33,7 @@ class MongoConnector
[:keys, :key, :key_insert, :key_delete] => :keys_connector, [:keys, :key, :key_insert, :key_delete] => :keys_connector,
[:save_report, :report, :reports, :set_report_status, :set_report_server_data, :add_report_subreports] => :reports_connector, [:save_report, :report, :reports, :set_report_status, :set_report_server_data, :add_report_subreports] => :reports_connector,
[:insert_statistic, :search_statistic] => :statistics_connector, [:insert_statistic, :search_statistic] => :statistics_connector,
[:provider_accounts, :provider_accounts_insert, :provider_accounts_delete, :provider_accounts_show] => :provider_accounts_connector [:provider_accounts, :provider_accounts_insert, :provider_accounts_delete, :provider_account] => :provider_accounts_connector
) )
def initialize(db, host, port=27017, user=nil, password=nil) def initialize(db, host, port=27017, user=nil, password=nil)

View File

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

View File

@ -4,14 +4,14 @@ module Validators
class Name < Base class Name < Base
MAX_NAME_LEN = 200 MAX_NAME_LEN = 200
NAME_REGEX = /\A\w{1,#{MAX_NAME_LEN}}\z/ NAME_REGEX = /\A[\w\-]{1,#{MAX_NAME_LEN}}\z/
def valid? def valid?
!NAME_REGEX.match(@value).nil? !NAME_REGEX.match(@value).nil?
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} symbols" "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

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

@ -0,0 +1,21 @@
require_relative "base"
module Validators
module FieldValidator
class Vpc < Base
def valid?
provider = ::Provider::ProviderFactory.get(@model.provider, @model.provider_account)
vpcs = provider.describe_vpcs
vpcs.keys.include?(@value)
rescue
raise "Invalid provider account '#{@model.provider_account}'"
end
def message
"Invalid vpc '#{@value}'."
end
end
end
end

View File

@ -1,6 +1,10 @@
require_relative "devops_error" require_relative "devops_error"
class InvalidRecord < ::Devops::Exception::DevopsError class InvalidRecord < ::Devops::Exception::DevopsError
# message could be a String or a hash like
# {
# error_data: [{:key=>:provider, :message=>"Value can not be undefined"}]
# }
def initialize msg def initialize msg
if msg.is_a?(String) if msg.is_a?(String)
super(msg) super(msg)
@ -9,6 +13,17 @@ class InvalidRecord < ::Devops::Exception::DevopsError
end end
end end
def message
if @object
messages = @object[:error_data].map do |error_item|
"#{error_item[:key]}: #{error_item[:message]}"
end
"Following errors occured: \n#{messages.join('\n')}"
else
super
end
end
def http_status def http_status
400 400
end end

View File

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

View File

@ -14,6 +14,18 @@ module Provider
"stack_#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" "stack_#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}"
end end
def networks_detail filters={}
networks(filters)
end
def networks filters={}
[]
end
def groups filters={}
{}
end
protected protected
def connection_compute options def connection_compute options
Fog::Compute.new( options ) Fog::Compute.new( options )

View File

@ -55,14 +55,8 @@ module Provider
end end
end end
def groups filters=nil def groups filters={}
buf = {} g = self.compute.describe_security_groups(filters)
buf = filters.select{|k,v| ["vpc-id"].include?(k)} unless filters.nil?
g = if buf.empty?
self.compute.describe_security_groups
else
self.compute.describe_security_groups(buf)
end
convert_groups(g.body["securityGroupInfo"]) convert_groups(g.body["securityGroupInfo"])
end end
@ -76,12 +70,8 @@ module Provider
end end
end end
def networks_detail def networks filters={}
self.networks self.compute.describe_subnets(filters).body["subnetSet"].select{|n| n["state"] == "available"}.map do |n|
end
def networks
self.compute.describe_subnets.body["subnetSet"].select{|n| n["state"] == "available"}.map do |n|
{ {
"cidr" => n["cidrBlock"], "cidr" => n["cidrBlock"],
"vpcId" => n["vpcId"], "vpcId" => n["vpcId"],
@ -219,7 +209,7 @@ module Provider
end end
def cloud_formation def cloud_formation
@cloud_formation ||= Fog::AWS::CloudFormation.new(connection_options) @cloud_formation ||= Fog::AWS::CloudFormation.new(connection_options)
end end
def create_stack(stack, out) def create_stack(stack, out)
@ -325,6 +315,10 @@ module Provider
def create_default_stack_name s def create_default_stack_name s
"stack-#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}".gsub('_', '-') "stack-#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}".gsub('_', '-')
end end
def describe_vpcs
self.compute.describe_vpcs.body["vpcSet"].select{|v| v["state"] == "available"}.map{|v| {"vpc_id" => v["vpcId"], "cidr" => v["cidrBlock"] } }
end
private private
def convert_groups list def convert_groups list

View File

@ -30,7 +30,7 @@ module Provider
PROVIDER PROVIDER
end end
def groups filter=nil def groups filters={}
convert_groups(compute.list_security_groups.body["security_groups"]) convert_groups(compute.list_security_groups.body["security_groups"])
end end
@ -55,8 +55,8 @@ module Provider
end end
end end
def networks_detail def networks_detail filters={}
net = self.network net = self.network(filters)
subnets = net.list_subnets.body["subnets"].select{|s| net.current_tenant["id"] == s["tenant_id"]} subnets = net.list_subnets.body["subnets"].select{|s| net.current_tenant["id"] == s["tenant_id"]}
net.list_networks.body["networks"].select{|n| n["router:external"] == false and n["status"] == "ACTIVE" and net.current_tenant["id"] == n["tenant_id"]}.map{|n| net.list_networks.body["networks"].select{|n| n["router:external"] == false and n["status"] == "ACTIVE" and net.current_tenant["id"] == n["tenant_id"]}.map{|n|
sn = subnets.detect{|s| n["subnets"][0] == s["id"]} sn = subnets.detect{|s| n["subnets"][0] == s["id"]}
@ -68,7 +68,7 @@ module Provider
} }
end end
def networks def networks filters={}
net = self.network net = self.network
net.list_networks.body["networks"].select{|n| n["router:external"] == false and n["status"] == "ACTIVE" and net.current_tenant["id"] == n["tenant_id"]}.map{|n| net.list_networks.body["networks"].select{|n| n["router:external"] == false and n["status"] == "ACTIVE" and net.current_tenant["id"] == n["tenant_id"]}.map{|n|
{ {

View File

@ -23,22 +23,10 @@ module Provider
[] []
end end
def groups filter=nil
{}
end
def images filters def images filters
[] []
end end
def networks
[]
end
def networks_detail
self.networks
end
def servers def servers
@@mongo.servers_find({:provider => PROVIDER}).map{|s| s.to_hash} @@mongo.servers_find({:provider => PROVIDER}).map{|s| s.to_hash}
end end

View File

@ -16,7 +16,7 @@ RSpec.describe Devops::Model::Image, type: :model do
describe 'validation' do describe 'validation' do
include_examples 'field type validation', :id, :not_nil, :non_empty_string, :field_validator include_examples 'field type validation', :id, :not_nil, :non_empty_string, :field_validator
include_examples 'field type validation', :remote_user, :not_nil, :non_empty_string, :only_word_symbols, :field_validator include_examples 'field type validation', :remote_user, :not_nil, :non_empty_string, :field_validator
include_examples 'field type validation', :name, :not_nil, :non_empty_string, :field_validator include_examples 'field type validation', :name, :not_nil, :non_empty_string, :field_validator
include_examples 'field type validation', :bootstrap_template, :maybe_nil, :non_empty_string, :only_word_symbols, :field_validator include_examples 'field type validation', :bootstrap_template, :maybe_nil, :non_empty_string, :only_word_symbols, :field_validator
@ -36,6 +36,12 @@ RSpec.describe Devops::Model::Image, type: :model do
it 'bootstrap_template should be included in available bootstrap templates' do it 'bootstrap_template should be included in available bootstrap templates' do
expect(build(:image, bootstrap_template: 'wrong')).not_to be_valid expect(build(:image, bootstrap_template: 'wrong')).not_to be_valid
end end
it 'remote_user should contain only a-zA-Z0-9_-.' do
expect(build(:image, remote_user: 'aA0-.')).to be_valid
expect(build(:image, remote_user: 'name/')).not_to be_valid
expect(build(:image, remote_user: 'name!')).not_to be_valid
end
end end
it '#to_hash_without_id returns provider, name, remote_user and bootstrap_template' do it '#to_hash_without_id returns provider, name, remote_user and bootstrap_template' do

View File

@ -4,20 +4,16 @@ RSpec.describe Devops::Model::Report, type: :model do
let(:report) { build(:report) } let(:report) { build(:report) }
describe '#initialize' do describe '#initialize' do
let(:given_moment) { Time.new(2007,11,1,15,25,0, "+01:00") }
it 'converts created_at to localtime' do it 'converts created_at to localtime' do
now = Time.now.utc converted = build(:report, created_at: given_moment).created_at
expect(now.zone).to eq 'UTC' expect(converted).to eq given_moment.localtime
expect(
build(:report, created_at: now).created_at.zone
).not_to eq 'UTC'
end end
it 'converts updated_at to localtime' do it 'converts updated_at to localtime' do
now = Time.now.utc converted = build(:report, updated_at: given_moment).updated_at
expect(now.zone).to eq 'UTC' expect(converted).to eq given_moment.localtime
expect(
build(:report, updated_at: now).updated_at.zone
).not_to eq 'UTC'
end end
end end

View File

@ -184,6 +184,7 @@ class StackBootstrapWorker < Worker
stack_servers_with_priority = {} stack_servers_with_priority = {}
stack_servers_info.each do |priority, info_array| stack_servers_info.each do |priority, info_array|
stack_servers_with_priority[priority] = info_array.map do |extended_info| stack_servers_with_priority[priority] = info_array.map do |extended_info|
@out.puts "Instance '#{extended_info["id"]}' has been launched with stack."
server_attrs = { server_attrs = {
'provider' => provider.name, 'provider' => provider.name,
'project' => project.id, 'project' => project.id,