From c671e7ed546da2c7713b5755bf4370cd59a9ce27 Mon Sep 17 00:00:00 2001 From: amartynov Date: Tue, 17 Nov 2015 12:14:02 +0300 Subject: [PATCH 1/4] #868: vpc support --- devops-service/app/api2/handlers/group.rb | 7 ++++-- devops-service/app/api2/handlers/network.rb | 6 ++++- devops-service/app/api2/handlers/provider.rb | 7 +++++- devops-service/app/api2/parsers/network.rb | 15 +++++++++++++ .../app/api2/parsers/security_groups.rb | 15 +++++++++++++ devops-service/app/api2/routes/group.rb | 4 +++- devops-service/app/api2/routes/network.rb | 3 +++ devops-service/app/api2/routes/provider.rb | 18 ++++++++++++++- .../db/mongo/connectors/provider_accounts.rb | 7 ++++++ .../models/deploy_env/cloud_deploy_env.rb | 14 ------------ .../mongo/models/deploy_env/deploy_env_ec2.rb | 10 +++++++++ devops-service/db/mongo/mongo_connector.rb | 2 +- .../db/validators/field_validators/vpc.rb | 21 ++++++++++++++++++ devops-service/providers/base_provider.rb | 9 ++++++++ devops-service/providers/ec2.rb | 22 +++++++++---------- devops-service/providers/openstack.rb | 8 +++---- devops-service/providers/static.rb | 8 ------- 17 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 devops-service/app/api2/parsers/network.rb create mode 100644 devops-service/app/api2/parsers/security_groups.rb create mode 100644 devops-service/db/validators/field_validators/vpc.rb diff --git a/devops-service/app/api2/handlers/group.rb b/devops-service/app/api2/handlers/group.rb index 82ed2d7..8b44aed 100644 --- a/devops-service/app/api2/handlers/group.rb +++ b/devops-service/app/api2/handlers/group.rb @@ -1,3 +1,4 @@ +require "app/api2/parsers/security_groups" require "providers/provider_factory" require_relative "request_handler" @@ -6,13 +7,15 @@ module Devops module Handler class Group < RequestHandler - # TODO: vpc support for ec2 + set_parser Devops::API2_0::Parser::SecurityGroupsParser + def groups provider groups_with_account(provider, nil) end 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 diff --git a/devops-service/app/api2/handlers/network.rb b/devops-service/app/api2/handlers/network.rb index 25c89ec..24403eb 100644 --- a/devops-service/app/api2/handlers/network.rb +++ b/devops-service/app/api2/handlers/network.rb @@ -1,3 +1,4 @@ +require "app/api2/parsers/network" require "providers/provider_factory" require_relative "request_handler" @@ -6,13 +7,16 @@ module Devops module Handler class Network < RequestHandler + set_parser Devops::API2_0::Parser::NetworkParser + def networks provider networks_with_account provider, nil end def networks_with_account 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 diff --git a/devops-service/app/api2/handlers/provider.rb b/devops-service/app/api2/handlers/provider.rb index a054f2c..8e5445d 100644 --- a/devops-service/app/api2/handlers/provider.rb +++ b/devops-service/app/api2/handlers/provider.rb @@ -33,12 +33,17 @@ module Devops end 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) ::Provider::ProviderFactory.delete_account(provider, account) account.to_hash end + def account_vpcs provider, name + Devops::Db.connector.provider_account(provider, name) + ::Provider::ProviderFactory.get(provider, name).describe_vpcs + end + end end end diff --git a/devops-service/app/api2/parsers/network.rb b/devops-service/app/api2/parsers/network.rb new file mode 100644 index 0000000..e808cc3 --- /dev/null +++ b/devops-service/app/api2/parsers/network.rb @@ -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 + diff --git a/devops-service/app/api2/parsers/security_groups.rb b/devops-service/app/api2/parsers/security_groups.rb new file mode 100644 index 0000000..80cb019 --- /dev/null +++ b/devops-service/app/api2/parsers/security_groups.rb @@ -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 + diff --git a/devops-service/app/api2/routes/group.rb b/devops-service/app/api2/routes/group.rb index 989c4fb..182d82f 100644 --- a/devops-service/app/api2/routes/group.rb +++ b/devops-service/app/api2/routes/group.rb @@ -13,6 +13,9 @@ module Devops # - headers : # - Accept: application/json # + # * Params: + # vpc-id - string + # # * *Returns* : # - ec2: # { @@ -43,7 +46,6 @@ module Devops # ] # } # } - # TODO: vpc support for ec2 app.get_with_headers "/groups/:provider", :headers => [:accept] do |provider| check_privileges("group", "r") check_provider(provider) diff --git a/devops-service/app/api2/routes/network.rb b/devops-service/app/api2/routes/network.rb index 5da6724..f984438 100644 --- a/devops-service/app/api2/routes/network.rb +++ b/devops-service/app/api2/routes/network.rb @@ -13,6 +13,9 @@ module Devops # - headers : # - Accept: application/json # + # * Params: + # vpc-id - string + # # * *Returns* : array of strings # - ec2: # [ diff --git a/devops-service/app/api2/routes/provider.rb b/devops-service/app/api2/routes/provider.rb index 49a797e..dd51af9 100644 --- a/devops-service/app/api2/routes/provider.rb +++ b/devops-service/app/api2/routes/provider.rb @@ -115,7 +115,23 @@ module Devops app.delete_with_headers "/provider/:provider/account/:account_name", :headers => [:accept, :content_type] do |provider, account_name| check_privileges("provider", "w") 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 puts "Provider routes initialized" diff --git a/devops-service/db/mongo/connectors/provider_accounts.rb b/devops-service/db/mongo/connectors/provider_accounts.rb index 3627562..4bd235a 100644 --- a/devops-service/db/mongo/connectors/provider_accounts.rb +++ b/devops-service/db/mongo/connectors/provider_accounts.rb @@ -13,6 +13,13 @@ module Connectors collection.find({provider: provider}).to_a.map{|bson| c.build_from_bson(bson)} 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 'provider_accounts' end 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 index 30adbf2..dc62b4d 100644 --- a/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb +++ b/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb @@ -12,21 +12,7 @@ module Devops class CloudDeployEnv < DeployEnvBase attr_accessor :flavor, :image, :subnets, :groups, :stack_template -=begin -@Deprecated - 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} -=end - #TODO: account validator set_validators ::Validators::DeployEnv::Flavor, ::Validators::DeployEnv::Image, ::Validators::DeployEnv::Groups, 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 39a455a..5377a57 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 @@ -4,6 +4,11 @@ module Devops module Model class DeployEnvEc2 < CloudDeployEnv + attr_accessor :vpc_id + + set_field_validators :vpc_id, ::Validators::FieldValidator::Nil, + ::Validators::FieldValidator::FieldType::String, + ::Validators::FieldValidator::Vpc =begin @Deprecated types :identifier => {:type => String, :empty => false}, @@ -34,6 +39,11 @@ module Devops if self.subnets.size > 1 self.subnets = [ self.subnets[0] ] end + self.vpc_id = d["vpc_id"] + end + + def to_hash + super().merge({"vpc_id" => self.vpc_id}) end def self.create hash diff --git a/devops-service/db/mongo/mongo_connector.rb b/devops-service/db/mongo/mongo_connector.rb index bda584e..baa47ff 100644 --- a/devops-service/db/mongo/mongo_connector.rb +++ b/devops-service/db/mongo/mongo_connector.rb @@ -33,7 +33,7 @@ class MongoConnector [:keys, :key, :key_insert, :key_delete] => :keys_connector, [:save_report, :report, :reports, :set_report_status, :set_report_server_data, :add_report_subreports] => :reports_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) diff --git a/devops-service/db/validators/field_validators/vpc.rb b/devops-service/db/validators/field_validators/vpc.rb new file mode 100644 index 0000000..f932dc6 --- /dev/null +++ b/devops-service/db/validators/field_validators/vpc.rb @@ -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 + diff --git a/devops-service/providers/base_provider.rb b/devops-service/providers/base_provider.rb index bf9ef34..090b5ed 100644 --- a/devops-service/providers/base_provider.rb +++ b/devops-service/providers/base_provider.rb @@ -14,6 +14,15 @@ module Provider "stack_#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" end + + def networks filters={} + [] + end + + def groups filters={} + {} + end + protected def connection_compute options Fog::Compute.new( options ) diff --git a/devops-service/providers/ec2.rb b/devops-service/providers/ec2.rb index 52644f8..a392139 100644 --- a/devops-service/providers/ec2.rb +++ b/devops-service/providers/ec2.rb @@ -51,14 +51,8 @@ module Provider end end - def groups filters=nil - buf = {} - 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 + def groups filters={} + g = self.compute.describe_security_groups(filters) convert_groups(g.body["securityGroupInfo"]) end @@ -72,12 +66,12 @@ module Provider end end - def networks_detail - self.networks + def networks_detail filters={} + self.networks(filters) end - def networks - self.compute.describe_subnets.body["subnetSet"].select{|n| n["state"] == "available"}.map do |n| + def networks filters={} + self.compute.describe_subnets(filters).body["subnetSet"].select{|n| n["state"] == "available"}.map do |n| { "cidr" => n["cidrBlock"], "vpcId" => n["vpcId"], @@ -327,6 +321,10 @@ module Provider def create_default_stack_name s "stack-#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}".gsub('_', '-') 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 def convert_groups list diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index 6e8249e..d4807e9 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -30,7 +30,7 @@ module Provider PROVIDER end - def groups filter=nil + def groups filters={} convert_groups(compute.list_security_groups.body["security_groups"]) end @@ -55,8 +55,8 @@ module Provider end end - def networks_detail - net = self.network + def networks_detail filters={} + net = self.network(filters) 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| sn = subnets.detect{|s| n["subnets"][0] == s["id"]} @@ -68,7 +68,7 @@ module Provider } end - def networks + def networks filters={} 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| { diff --git a/devops-service/providers/static.rb b/devops-service/providers/static.rb index 4f1d788..4436670 100644 --- a/devops-service/providers/static.rb +++ b/devops-service/providers/static.rb @@ -23,18 +23,10 @@ module Provider [] end - def groups filter=nil - {} - end - def images filters [] end - def networks - [] - end - def networks_detail self.networks end From 17f7812d65758036ff00c1f3ce973904ba439bde Mon Sep 17 00:00:00 2001 From: amartynov Date: Tue, 17 Nov 2015 17:38:58 +0300 Subject: [PATCH 2/4] #868: fixed error with networks for static provider --- devops-service/providers/base_provider.rb | 3 +++ devops-service/providers/ec2.rb | 4 ---- devops-service/providers/static.rb | 4 ---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/devops-service/providers/base_provider.rb b/devops-service/providers/base_provider.rb index 090b5ed..eee8cc1 100644 --- a/devops-service/providers/base_provider.rb +++ b/devops-service/providers/base_provider.rb @@ -14,6 +14,9 @@ module Provider "stack_#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}" end + def networks_detail filters={} + networks(filters) + end def networks filters={} [] diff --git a/devops-service/providers/ec2.rb b/devops-service/providers/ec2.rb index a392139..af5e7fa 100644 --- a/devops-service/providers/ec2.rb +++ b/devops-service/providers/ec2.rb @@ -66,10 +66,6 @@ module Provider end end - def networks_detail filters={} - self.networks(filters) - end - def networks filters={} self.compute.describe_subnets(filters).body["subnetSet"].select{|n| n["state"] == "available"}.map do |n| { diff --git a/devops-service/providers/static.rb b/devops-service/providers/static.rb index 4436670..e3fcb94 100644 --- a/devops-service/providers/static.rb +++ b/devops-service/providers/static.rb @@ -27,10 +27,6 @@ module Provider [] end - def networks_detail - self.networks - end - def servers @@mongo.servers_find({:provider => PROVIDER}).map{|s| s.to_hash} end From e6903adb921a7c710d48367ae265490f4a956175 Mon Sep 17 00:00:00 2001 From: amartynov Date: Thu, 19 Nov 2015 14:09:38 +0300 Subject: [PATCH 3/4] #868: validation order --- .../models/deploy_env/cloud_deploy_env.rb | 22 ++++----- .../models/deploy_env/deploy_env_base.rb | 18 +++---- .../mongo/models/deploy_env/deploy_env_ec2.rb | 6 +-- devops-service/db/mongo/models/image.rb | 18 +++---- .../db/mongo/models/model_with_provider.rb | 11 +++-- devops-service/db/mongo/models/mongo_model.rb | 48 ++++++++++++++----- .../provider_accounts/ec2_provider_account.rb | 10 ++-- .../provider_accounts/provider_account.rb | 14 +++--- devops-service/db/mongo/models/user.rb | 24 +++++----- .../db/validators/field_validators/base.rb | 5 +- .../field_validators/provider_account.rb | 17 +++++++ devops-service/providers/accounts_factory.rb | 10 +++- devops-service/providers/ec2.rb | 2 +- 13 files changed, 131 insertions(+), 74 deletions(-) create mode 100644 devops-service/db/validators/field_validators/provider_account.rb 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 index dc62b4d..a19abcc 100644 --- a/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb +++ b/devops-service/db/mongo/models/deploy_env/cloud_deploy_env.rb @@ -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={} 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 b5aec77..c832d20 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 @@ -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"] 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 5377a57..5e54ba0 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 @@ -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}, diff --git a/devops-service/db/mongo/models/image.rb b/devops-service/db/mongo/models/image.rb index 728a66a..5d68393 100644 --- a/devops-service/db/mongo/models/image.rb +++ b/devops-service/db/mongo/models/image.rb @@ -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! diff --git a/devops-service/db/mongo/models/model_with_provider.rb b/devops-service/db/mongo/models/model_with_provider.rb index 850b7ee..b7a5d36 100644 --- a/devops-service/db/mongo/models/model_with_provider.rb +++ b/devops-service/db/mongo/models/model_with_provider.rb @@ -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 diff --git a/devops-service/db/mongo/models/mongo_model.rb b/devops-service/db/mongo/models/mongo_model.rb index 3721a5c..894da96 100644 --- a/devops-service/db/mongo/models/mongo_model.rb +++ b/devops-service/db/mongo/models/mongo_model.rb @@ -68,15 +68,20 @@ module Devops 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} + 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 + result << {key: field, message: e.message} + end + end + unless result.empty? + raise InvalidRecord.new(error_data: result) end - end - unless result.empty? - raise InvalidRecord.new(error_data: result) 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 diff --git a/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb b/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb index 3f2fb41..95117bb 100644 --- a/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb +++ b/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb @@ -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 diff --git a/devops-service/db/mongo/models/provider_accounts/provider_account.rb b/devops-service/db/mongo/models/provider_accounts/provider_account.rb index 3a6fb59..d3c9c42 100644 --- a/devops-service/db/mongo/models/provider_accounts/provider_account.rb +++ b/devops-service/db/mongo/models/provider_accounts/provider_account.rb @@ -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)", diff --git a/devops-service/db/mongo/models/user.rb b/devops-service/db/mongo/models/user.rb index b16e032..e13b4f1 100644 --- a/devops-service/db/mongo/models/user.rb +++ b/devops-service/db/mongo/models/user.rb @@ -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'] diff --git a/devops-service/db/validators/field_validators/base.rb b/devops-service/db/validators/field_validators/base.rb index 8c60d57..c76395b 100644 --- a/devops-service/db/validators/field_validators/base.rb +++ b/devops-service/db/validators/field_validators/base.rb @@ -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! diff --git a/devops-service/db/validators/field_validators/provider_account.rb b/devops-service/db/validators/field_validators/provider_account.rb new file mode 100644 index 0000000..3d56074 --- /dev/null +++ b/devops-service/db/validators/field_validators/provider_account.rb @@ -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 diff --git a/devops-service/providers/accounts_factory.rb b/devops-service/providers/accounts_factory.rb index 7f212e9..07906e1 100644 --- a/devops-service/providers/accounts_factory.rb +++ b/devops-service/providers/accounts_factory.rb @@ -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 diff --git a/devops-service/providers/ec2.rb b/devops-service/providers/ec2.rb index af5e7fa..e593ad6 100644 --- a/devops-service/providers/ec2.rb +++ b/devops-service/providers/ec2.rb @@ -205,7 +205,7 @@ module Provider end def cloud_formation - @cloud_formation ||= Fog::AWS::CloudFormation.new(connection_options) + @cloud_formation ||= Fog::AWS::CloudFormation.new(connection_options) end def create_stack(stack, out) From 83f026e88a8239e616e3d5c0687772429a406041 Mon Sep 17 00:00:00 2001 From: amartynov Date: Thu, 3 Dec 2015 12:18:54 +0300 Subject: [PATCH 4/4] CID-15: fixed --- .../db/mongo/models/provider_accounts/ec2_provider_account.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb b/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb index 95117bb..74e48f6 100644 --- a/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb +++ b/devops-service/db/mongo/models/provider_accounts/ec2_provider_account.rb @@ -4,7 +4,7 @@ module Devops module Model class Ec2ProviderAccount < ProviderAccount -# attr_accessor :access_key_id, :availability_zone, :secret_access_key + attr_accessor :availability_zone set_field_validators :access_key_id, [::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String,